Skip to content

Commit 3e93981

Browse files
committed
Add promise C API
related issue: 1794 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang [email protected]
1 parent 894aa6d commit 3e93981

11 files changed

+456
-23
lines changed

docs/02.API-REFERENCE.md

+136-2
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,47 @@ jerry_value_is_object (const jerry_value_t value)
10721072
- [jerry_release_value](#jerry_release_value)
10731073

10741074

1075+
## jerry_value_is_promise
1076+
1077+
**Summary**
1078+
1079+
Returns whether the given `jerry_value_t` is a promise value.
1080+
1081+
*Note*: This API depends on the ES2015-subset profile.
1082+
1083+
**Prototype**
1084+
1085+
```c
1086+
bool
1087+
jerry_value_is_promise (const jerry_value_t value)
1088+
```
1089+
1090+
- `value` - api value
1091+
- return value
1092+
- true, if the given `jerry_value_t` is a promise
1093+
- false, otherwise
1094+
1095+
**Example**
1096+
1097+
```c
1098+
{
1099+
jerry_value_t value;
1100+
... // create or acquire value
1101+
1102+
if (jerry_value_is_promise (value))
1103+
{
1104+
...
1105+
}
1106+
1107+
jerry_release_value (value);
1108+
}
1109+
```
1110+
1111+
**See also**
1112+
1113+
- [jerry_release_value](#jerry_release_value)
1114+
1115+
10751116
## jerry_value_is_string
10761117

10771118
**Summary**
@@ -1980,6 +2021,64 @@ jerry_value_to_string (const jerry_value_t value);
19802021
- [jerry_value_to_primitive](#jerry_value_to_primitive)
19812022

19822023

2024+
# Functions for promise objects
2025+
2026+
These APIs all depends on the ES2015-subset profile.
2027+
2028+
## jerry_resolve_or_reject_promise
2029+
2030+
**Summary**
2031+
2032+
Resolve or reject the promise with an argument.
2033+
2034+
**Prototype**
2035+
2036+
```c
2037+
jerry_value_t
2038+
jerry_resolve_or_reject_promise (jerry_value_t promise,
2039+
jerry_value_t argument,
2040+
bool is_resolve)
2041+
```
2042+
2043+
- `promise` - the promise value
2044+
- `argument` - the argument for resolve or reject
2045+
- `is_resolve` - whether the promise should be resolved or rejected
2046+
- return value
2047+
- undefined jerry value - resolve or reject successed
2048+
- jerry value with error flag - otherwise
2049+
2050+
**Example**
2051+
2052+
```c
2053+
{
2054+
jerry_value_t promise = ... // acquire/create a promise object.
2055+
2056+
...
2057+
2058+
bool is_resolve = ... // whether the promise should be resolved or rejected
2059+
jerry_value_t argument = ... // prepare the argumnent for the resolve or reject.
2060+
2061+
jerry_value_t is_ok = jerry_resolve_or_reject_promise (promise,
2062+
argument,
2063+
is_resolve);
2064+
2065+
if (jerry_value_has_error_flag (is_ok))
2066+
{
2067+
// handle the error.
2068+
}
2069+
2070+
jerry_release_value (is_ok);
2071+
jerry_release_value (argument);
2072+
jerry_release_value (promise);
2073+
}
2074+
```
2075+
2076+
**See also**
2077+
2078+
- [jerry_release_value](#jerry_release_value)
2079+
- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
2080+
2081+
19832082
# Acquire and release API values
19842083

19852084
## jerry_acquire_value
@@ -2425,6 +2524,41 @@ jerry_create_object (void);
24252524
- [jerry_release_value](#jerry_release_value)
24262525

24272526

2527+
## jerry_create_promise
2528+
2529+
**Summary**
2530+
2531+
Create an empty promise object which can be resolved or rejected later
2532+
by calling jerry_resolve_or_reject_promise.
2533+
2534+
*Note*: This API depends on the ES2015-subset profile.
2535+
2536+
**Prototype**
2537+
2538+
```c
2539+
jerry_value_t
2540+
jerry_create_promise (void)
2541+
```
2542+
2543+
- return value - value of the newly created promise
2544+
2545+
**Example**
2546+
2547+
```c
2548+
{
2549+
jerry_value_t p = jerry_create_promise ();
2550+
2551+
...// usage of the promise
2552+
2553+
jerry_release_value (p);
2554+
}
2555+
2556+
**See also**
2557+
2558+
- [jerry_resolve_or_reject_promise](#jerry_resolve_or_reject_promise)
2559+
- [jerry_release_value](#jerry_release_value)
2560+
2561+
24282562
## jerry_create_string
24292563

24302564
**Summary**
@@ -3528,7 +3662,7 @@ static const jerry_object_native_info_t native_obj_type_info =
35283662
{
35293663
// The type of this's native pointer matches what is expected.
35303664
// Only now is it safe to cast to native_obj_t * and dereference the
3531-
// pointer:
3665+
// pointer:
35323666
native_obj_t *native_obj = native_p;
35333667
native_obj->bar = ...; // Safe to access now!
35343668
}
@@ -3582,7 +3716,7 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val,
35823716
**Example**
35833717

35843718
See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a
3585-
best-practice example.
3719+
best-practice example.
35863720

35873721
**See also**
35883722

jerry-core/ecma/builtin-objects/ecma-builtin-promise.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ ecma_builtin_promise_dispatch_construct (const ecma_value_t *arguments_list_p, /
683683
return ecma_raise_type_error (ECMA_ERR_MSG ("First parameter must be callable."));
684684
}
685685

686-
return ecma_op_create_promise_object (arguments_list_p[0], true);
686+
return ecma_op_create_promise_object (arguments_list_p[0], ECMA_PROMISE_EXECUTOR_FUNCTION);
687687
} /* ecma_builtin_promise_dispatch_construct */
688688

689689
/**

jerry-core/ecma/operations/ecma-jobqueue.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,14 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
223223
{
224224
ecma_job_promise_resolve_thenable_t *job_p = (ecma_job_promise_resolve_thenable_t *) obj_p;
225225
ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
226-
ecma_promise_resolving_functions_t *funcs;
227-
funcs = ecma_promise_create_resolving_functions (promise_p);
226+
ecma_string_t str_resolve, str_reject;
227+
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
228+
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
228229

229-
ecma_value_t argv[] = { funcs->resolve, funcs->reject };
230+
ecma_value_t resolve = ecma_op_object_get (promise_p, &str_resolve);
231+
ecma_value_t reject = ecma_op_object_get (promise_p, &str_reject);
232+
233+
ecma_value_t argv[] = { resolve, reject };
230234
ecma_value_t ret;
231235
ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then),
232236
job_p->thenable,
@@ -237,15 +241,16 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
237241

238242
if (ECMA_IS_VALUE_ERROR (then_call_result))
239243
{
240-
ret = ecma_op_function_call (ecma_get_object_from_value (funcs->reject),
244+
ret = ecma_op_function_call (ecma_get_object_from_value (reject),
241245
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
242246
&then_call_result,
243247
1);
244248

245249
ecma_free_value (then_call_result);
246250
}
247251

248-
ecma_promise_free_resolving_functions (funcs);
252+
ecma_free_value (resolve);
253+
ecma_free_value (reject);
249254
ecma_free_promise_resolve_thenable_job (job_p);
250255

251256
return ret;

jerry-core/ecma/operations/ecma-promise-object.c

+24-7
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ ecma_call_builtin_executor (ecma_object_t *executor_p, /**< the executor object
404404
*
405405
* @return pointer to the resolving functions
406406
*/
407-
ecma_promise_resolving_functions_t *
407+
static ecma_promise_resolving_functions_t *
408408
ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promise object */
409409
{
410410
/* 1. */
@@ -455,7 +455,7 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promi
455455
/**
456456
* Free the heap and the member of the resolving functions.
457457
*/
458-
void
458+
static void
459459
ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs) /**< points to the functions */
460460
{
461461
ecma_free_value (funcs->resolve);
@@ -473,7 +473,7 @@ ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs
473473
*/
474474
ecma_value_t
475475
ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or object */
476-
bool is_func) /**< indicates whether executor is a function */
476+
ecma_promise_executor_type_t type) /**< indicates the type of executor */
477477
{
478478
/* 3. */
479479
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE_PROTOTYPE);
@@ -496,10 +496,22 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
496496
/* 8. */
497497
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
498498

499+
ecma_string_t str_resolve, str_reject;
500+
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
501+
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
502+
ecma_op_object_put (object_p,
503+
&str_resolve,
504+
funcs->resolve,
505+
false);
506+
ecma_op_object_put (object_p,
507+
&str_reject,
508+
funcs->reject,
509+
false);
510+
499511
/* 9. */
500-
ecma_value_t completion;
512+
ecma_value_t completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
501513

502-
if (is_func)
514+
if (type == ECMA_PROMISE_EXECUTOR_FUNCTION)
503515
{
504516
JERRY_ASSERT (ecma_op_is_callable (executor));
505517

@@ -509,14 +521,19 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
509521
argv,
510522
2);
511523
}
512-
else
524+
else if (type == ECMA_PROMISE_EXECUTOR_OBJECT)
513525
{
514526
JERRY_ASSERT (ecma_is_value_object (executor));
515527

516528
completion = ecma_call_builtin_executor (ecma_get_object_from_value (executor),
517529
funcs->resolve,
518530
funcs->reject);
519531
}
532+
else
533+
{
534+
JERRY_ASSERT (type == ECMA_PROMISE_EXECUTOR_EMPTY);
535+
JERRY_UNUSED (executor);
536+
}
520537

521538
ecma_value_t status = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
522539

@@ -572,7 +589,7 @@ ecma_promise_new_capability (void)
572589
false);
573590

574591
/* 6. */
575-
ecma_value_t promise = ecma_op_create_promise_object (executor, false);
592+
ecma_value_t promise = ecma_op_create_promise_object (executor, ECMA_PROMISE_EXECUTOR_OBJECT);
576593

577594
/* 10. */
578595
ecma_op_object_put (capability_p,

jerry-core/ecma/operations/ecma-promise-object.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ typedef enum
3737
ECMA_PROMISE_STATE__COUNT /**< number of states */
3838
} ecma_promise_state_t;
3939

40+
/**
41+
* Indicates the type of the executor in promise construct.
42+
*/
43+
typedef enum
44+
{
45+
ECMA_PROMISE_EXECUTOR_FUNCTION, /**< the executor is a function, it is for the usual constructor */
46+
ECMA_PROMISE_EXECUTOR_OBJECT, /**< the executor is an object, it is for the `then` routine */
47+
ECMA_PROMISE_EXECUTOR_EMPTY /**< the executor is empty, it is for external C API */
48+
} ecma_promise_executor_type_t;
49+
4050
/**
4151
* Description of the promise resolving functions.
4252
*/
@@ -81,10 +91,7 @@ void ecma_promise_set_result (ecma_object_t *obj_p, ecma_value_t result);
8191
uint8_t ecma_promise_get_state (ecma_object_t *obj_p);
8292
void ecma_promise_set_state (ecma_object_t *obj_p, uint8_t state);
8393
ecma_value_t
84-
ecma_op_create_promise_object (ecma_value_t executor, bool is_func);
85-
ecma_promise_resolving_functions_t *
86-
ecma_promise_create_resolving_functions (ecma_object_t *obj_p);
87-
void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs);
94+
ecma_op_create_promise_object (ecma_value_t executor, ecma_promise_executor_type_t type);
8895
ecma_value_t ecma_promise_new_capability (void);
8996
ecma_value_t
9097
ecma_promise_then (ecma_value_t promise,

0 commit comments

Comments
 (0)