Add promise C API#1796
Conversation
zherczeg
left a comment
There was a problem hiding this comment.
Good patch! Please add documentation for the new functions.
| bool | ||
| jerry_value_is_promise (const jerry_value_t value) /**< api value */ | ||
| { | ||
| jerry_assert_api_available (); |
There was a problem hiding this comment.
Please add newlines before other ifdefs in this file.
|
|
||
| static jerry_value_t | ||
| create_promise1_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ | ||
| const jerry_value_t this_val __attribute__((unused)), /**< this value */ |
|
|
||
| static jerry_value_t | ||
| create_promise2_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ | ||
| const jerry_value_t this_val __attribute__((unused)), /**< this value */ |
| jerry_assert_api_available (); | ||
| #ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN | ||
| return ecma_op_create_promise_object (ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY), ECMA_PROMISE_EXECUTOR_EMPTY); | ||
| #else /* CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */ |
There was a problem hiding this comment.
Maybe better to exclude the implementation so you get a linker error?
I don't know... returning an error adds code space.
| */ | ||
| static jerry_value_t | ||
| jerry_resolve_or_reject_promise (jerry_value_t promise, | ||
| jerry_value_t argument, |
There was a problem hiding this comment.
I think it makes sense to expose something like this in the public API.
I think people will be writing code like in this example a lot, so you naturally have a bool to make the decision whether resolve or reject should be called.
In an earlier sketch, I used an enum, I think that has a bit better readability vs bool, but I'm not feeling strongly about it.
There was a problem hiding this comment.
My thought is the C api should be similar with js api, so it will be easy to use. In JS world, usually the code is like
var p = new Promise(function(resolve, reject)
{
....
if (some condition)
{
var reason = .....//prepare the reason
reject (reason)
}
var argument = .... //prepare the argument
resolve(argument)
})in your example,
static void my_get_batt_info_cb (const batt_info_t *info, void *cb_data)
{
jerry_value_t promise = (jerry_value_t)(uintptr_t) cb_data;
// do stuff with *info and assign result + should_call_resolve:
jerry_value_t result = ...;
bool should_call_resolve = ...;
jerry_call_resolve_reject(promise, result, should_call_resolve);
jerry_value_release(promise);
}there should be some if-else or branch code in result = and should_call_resolve = , e.g.
if (some condition)
{ result = some_error_reason; should_call_resolve = false; }
else
{result = some_argument; should_call_resolve = true;}why just directly call the resolve/reject in the branch?
There was a problem hiding this comment.
why just directly call the resolve/reject in the branch?
Code space savings. You'd have 2x function calls vs 1x.
Often you already have the bool should_call_resolve one way or another, for example in your snippet, there is some_condition. In this case, some_condition == !should_call_resolve.
There was a problem hiding this comment.
Ok, it makes sense :)
|
@jprestwo any feedback on this API? |
|
|
||
| ```c | ||
| jerry_value_t | ||
| jerry_promise_get_resolve (jerry_value_t promise) |
There was a problem hiding this comment.
What I don't understand is that we have one function to resolve/reject, but two functions for getting functions. I think it would be better to have a boolean parameter here as well.
There was a problem hiding this comment.
My gut says that if your project needs access to the functions, you probably are going to need both.
Would it make sense to have:
bool jerry_promise_get_resolve (
jerry_value_t promise, jerry_value_t *resolve_out_p, jerry_value_t *reject_out_p)
There was a problem hiding this comment.
Hmm I wonder if we're adding the resolve/reject getter prematurely...
Maybe just remove it and get on with life until someone comes along that has a clear use for it?
zherczeg
left a comment
There was a problem hiding this comment.
LGTM after some style fixes.
| - [jerry_value_to_primitive](#jerry_value_to_primitive) | ||
|
|
||
|
|
||
| # Functions for promise value |
|
|
||
| ... | ||
|
|
||
| bool is_resolve = ... // whether the promise should be resolve or reject |
|
|
||
| **Summary** | ||
|
|
||
| Create an empty Promise object which can be resolve/reject later |
| jerry_create_promise (void) | ||
| ``` | ||
|
|
||
| - return value - value of the created promise |
| */ | ||
| typedef enum | ||
| { | ||
| ECMA_PROMISE_EXECUTOR_FUNCTION, /**< the executor is a function, it is for the usual constructor */ |
| } /* jerry_value_is_promise */ | ||
|
|
||
|
|
||
| /** |
| * false - otherwise | ||
| */ | ||
| bool | ||
| jerry_value_is_promise (const jerry_value_t value) /**< api value */ |
There was a problem hiding this comment.
Please use the same order of functions as 'jerryscript.h'.
| const jerry_char_t s2[] = "rejected"; | ||
|
|
||
| static jerry_value_t | ||
| create_promise1_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ |
There was a problem hiding this comment.
JERRY_UNUSED must be available here since test-common.h includes jrt.h
static jerry_value_t
create_promise1_handler (const jerry_value_t func_obj_val , /**< function object */
const jerry_value_t this_val, /**< this value */
const jerry_value_t args_p[], /**< arguments list */
const jerry_length_t args_cnt) /**< arguments length */
{
JERRY_UNUSED (func_obj_val);
JERRY_UNUSED (this_val);
JERRY_UNUSED (args_p);
JERRY_UNUSED (args_cnt);
...| } /* create_promise1_handler */ | ||
|
|
||
| static jerry_value_t | ||
| create_promise2_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ |
| } /* create_promise2_handler */ | ||
|
|
||
| static jerry_value_t | ||
| assert_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ |
| if(NOT ${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/es5.1.profile") | ||
| message(FATAL_ERROR "FEATURE_PROFILE='${FEATURE_PROFILE}' isn't supported with UNITTESTS=ON") | ||
| if(${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/minimal.profile") | ||
| message(FATAL_ERROR "minimal profile isn't supported in unit-core") |
There was a problem hiding this comment.
Is this change related to this this PR? It looks to me if promise is not available than the test-promise returns zero, which is good. Am I missing something?
There was a problem hiding this comment.
Before this change, I cannot ./tools/build.py --unittest --profile=es2015-subset, because it's profile is not es5.1.
There was a problem hiding this comment.
And also I changed the run-test.py, now es2015-subset profile is passed to unittest
# Test options for unittests
JERRY_UNITTESTS_OPTIONS = [
Options('unittests',
['--unittests', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']),
Options('unittests-debug',
['--unittests', '--debug', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset'])
]
There was a problem hiding this comment.
I see. Thanks for the explanation.
related issue: 1794 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang [email protected]
LaszloLango
left a comment
There was a problem hiding this comment.
Thanks for the update. LGTM
|
💯 |
related issue: 1794
unittest support es2015-subset profile
doc will be added later when we reach the consensus