Add notification callback for Promise operations (#4595)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-02-18 11:29:52 +01:00
committed by GitHub
parent c14702c129
commit 01e0388d77
18 changed files with 703 additions and 46 deletions
+11
View File
@@ -53,6 +53,17 @@ To see how a profile file should be created, or what configuration options are a
| CMake: | `-DJERRY_PROFILE="path"` |
| Python: | `--profile="path"` |
### Promise callback
Enables Promise event notification support. This feature allows setting a user callback, which is called when certain Promise related events occur such as
creating a new Promise, resolving a Promise with a value, etc.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_PROMISE_CALLBACK=0/1` |
| CMake: | `-DJERRY_PROMISE_CALLBACK=ON/OFF` |
| Python: | `--promise-callback=ON/OFF` |
### External context
Enables external context support in the engine. By default, JerryScript uses a statically allocated context to store the current state of the engine internals.
+151
View File
@@ -157,6 +157,8 @@ Possible compile time enabled feature types:
- JERRY_FEATURE_WEAKSET - WeakSet support
- JERRY_FEATURE_BIGINT - BigInt support
- JERRY_FEATURE_REALM - realm support
- JERRY_FEATURE_GLOBAL_THIS - GlobalThisValue support
- JERRY_FEATURE_PROMISE_CALLBACK - Promise callback support
*New in version 2.0*.
@@ -164,6 +166,8 @@ Possible compile time enabled feature types:
*Changed in version 2.4*: Added `JERRY_FEATURE_BIGINT`, `JERRY_FEATURE_REALM` values.
*Changed in version [[NEXT_RELEASE]]*: Added `JERRY_FEATURE_GLOBAL_THIS`, `JERRY_FEATURE_PROMISE_CALLBACK` values.
## jerry_container_type_t
Container object types:
@@ -883,6 +887,80 @@ Possible values:
- [jerry_get_promise_result](#jerry_get_promise_result)
## jerry_promise_event_type_t
Event types for [jerry_promise_callback_t](#jerry_promise_callback_t) callback function.
The description of the `object` and `value` arguments are provided for each type.
Possible values:
- JERRY_PROMISE_EVENT_CREATE - A new Promise object is created.
- object - the new Promise object
- value - parent Promise for `then` chains, undefined otherwise.
- JERRY_PROMISE_EVENT_RESOLVE - Called when a Promise is about to be resolved.
- object - the Promise object
- value - value for resolving.
- JERRY_PROMISE_EVENT_REJECT - Called when a Promise is about to be rejected.
- object - the Promise object
- value - value for rejecting.
- JERRY_PROMISE_EVENT_BEFORE_REACTION_JOB - Called before executing a Promise reaction job.
- object - the Promise object
- value - undefined
- JERRY_PROMISE_EVENT_AFTER_REACTION_JOB - Called after a Promise reaction job is completed.
- object - the Promise object
- value - undefined
- JERRY_PROMISE_EVENT_ASYNC_AWAIT - Called when an async function awaits the result of a Promise object.
- object - internal object representing the execution status
- value - the Promise object
- JERRY_PROMISE_EVENT_ASYNC_BEFORE_RESOLVE - Called when an async function is continued with resolve.
- object - internal object representing the execution status
- value - value for resolving
- JERRY_PROMISE_EVENT_ASYNC_BEFORE_REJECT - Called when an async function is continued with reject.
- object - internal object representing the execution status
- value - value for rejecting
- JERRY_PROMISE_EVENT_ASYNC_AFTER_RESOLVE - Called when an async function resolve is completed.
- object - internal object representing the execution status
- value - value for resolving
- JERRY_PROMISE_EVENT_ASYNC_AFTER_REJECT - Called when an async function reject is completed.
- object - internal object representing the execution status
- value - value for rejecting
*New in version [[NEXT_RELEASE]]*.
**See also**
- [jerry_promise_callback_t](#jerry_promise_callback_t)
- [jerry_promise_set_callback](#jerry_promise_set_callback)
## jerry_promise_callback_t
**Summary**
Notification callback for tracking Promise and async function operations. The arguments
passed to the callback depends on the `event_type` which is detailed in the
description of [jerry_promise_event_type_t](#jerry_promise_event_type_t).
**Prototype**
```c
typedef void (*jerry_promise_callback_t) (jerry_promise_event_type_t event_type,
const jerry_value_t object, const jerry_value_t value,
void *user_p);
```
- `event_type` - type of the event notification.
- `object` - object corresponding to the event.
- `value` - optional value argument.
- `user_data_p` - optional user data pointer supplied via the (jerry_promise_set_callback)[#jerry_promise_set_callback] method.
*New in version [[NEXT_RELEASE]]*.
**See also**
- [jerry_promise_event_type_t](#jerry_promise_event_type_t)
- [jerry_promise_set_callback](#jerry_promise_set_callback)
## jerry_typedarray_type_t
Enum which describes the TypedArray types.
@@ -4213,6 +4291,79 @@ example (void)
- [jerry_create_promise](#jerry_create_promise)
- [jerry_promise_state_t](#jerry_promise_state_t)
## jerry_promise_set_callback
**Summary**
Sets a callback for tracking Promise and async operations.
*Notes*:
- This API depends on a build option (`JERRY_PROMISE_CALLBACK`) and can be checked
in runtime with the `JERRY_FEATURE_PROMISE_CALLBACK` feature enum value,
see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
**Prototype**
```c
void jerry_promise_set_callback (jerry_promise_callback_t callback, void *user_p);
```
- `callback` - callback function, the previously set value is overwritten,
and setting NULL disables the tracking
- `user_p` - pointer passed to the callback function, can be NULL
*New in version [[NEXT_RELEASE]]*.
**Example**
[doctest]: # ()
```c
#include <stdio.h>
#include <string.h>
#include "jerryscript.h"
static void
promise_callback (jerry_promise_event_type_t event_type, /**< event type */
const jerry_value_t object, /**< target object */
const jerry_value_t value, /**< optional argument */
void *user_p) /**< user pointer passed to the callback */
{
if (event_type == JERRY_PROMISE_EVENT_CREATE)
{
printf ("A new promise is created\n");
if (!jerry_value_is_undefined (value))
{
printf (" The Promise is created by Promise.then() built-in.\n");
}
}
} /* promise_callback */
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_promise_set_callback (promise_callback, NULL);
const char *source_p = "var p = Promise.resolve(0)\n"
"p.then(function (v) { return v; })";
jerry_release_value (jerry_eval ((const jerry_char_t *) source_p,
strlen (source_p),
JERRY_PARSE_NO_OPTS));
jerry_cleanup ();
return 0;
} /* main */
```
**See also**
- [jerry_create_promise](#jerry_create_promise)
- [jerry_promise_state_t](#jerry_promise_state_t)
## jerry_from_property_descriptor
**Summary**
+5
View File
@@ -30,6 +30,7 @@ set(JERRY_MEM_STATS OFF CACHE BOOL "Enable memory sta
set(JERRY_MEM_GC_BEFORE_EACH_ALLOC OFF CACHE BOOL "Enable mem-stress test?")
set(JERRY_PARSER_DUMP_BYTE_CODE OFF CACHE BOOL "Enable parser byte-code dumps?")
set(JERRY_PROFILE "es.next" CACHE STRING "Use default or other profile?")
set(JERRY_PROMISE_CALLBACK OFF CACHE BOOL "Enable Promise callbacks?")
set(JERRY_REGEXP_STRICT_MODE OFF CACHE BOOL "Enable regexp strict mode?")
set(JERRY_REGEXP_DUMP_BYTE_CODE OFF CACHE BOOL "Enable regexp byte-code dumps?")
set(JERRY_SNAPSHOT_EXEC OFF CACHE BOOL "Enable executing snapshot files?")
@@ -87,6 +88,7 @@ message(STATUS "JERRY_MEM_STATS " ${JERRY_MEM_STATS})
message(STATUS "JERRY_MEM_GC_BEFORE_EACH_ALLOC " ${JERRY_MEM_GC_BEFORE_EACH_ALLOC})
message(STATUS "JERRY_PARSER_DUMP_BYTE_CODE " ${JERRY_PARSER_DUMP_BYTE_CODE} ${JERRY_PARSER_DUMP_MESSAGE})
message(STATUS "JERRY_PROFILE " ${JERRY_PROFILE})
message(STATUS "JERRY_PROMISE_CALLBACK " ${JERRY_PROMISE_CALLBACK})
message(STATUS "JERRY_REGEXP_STRICT_MODE " ${JERRY_REGEXP_STRICT_MODE})
message(STATUS "JERRY_REGEXP_DUMP_BYTE_CODE " ${JERRY_REGEXP_DUMP_BYTE_CODE})
message(STATUS "JERRY_SNAPSHOT_EXEC " ${JERRY_SNAPSHOT_EXEC} ${JERRY_SNAPSHOT_EXEC_MESSAGE})
@@ -582,6 +584,9 @@ else()
message(FATAL_ERROR "Profile file: '${JERRY_PROFILE}' doesn't exist!")
endif()
# Promise callback
jerry_add_define01(JERRY_PROMISE_CALLBACK)
# RegExp strict mode
jerry_add_define01(JERRY_REGEXP_STRICT_MODE)
+24 -1
View File
@@ -1467,6 +1467,9 @@ jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check *
#if JERRY_BUILTIN_REALMS
|| feature == JERRY_FEATURE_REALM
#endif /* JERRY_BUILTIN_REALMS */
#if JERRY_PROMISE_CALLBACK
|| feature == JERRY_FEATURE_PROMISE_CALLBACK
#endif /* JERRY_PROMISE_CALLBACK */
);
} /* jerry_is_feature_enabled */
@@ -2194,7 +2197,7 @@ jerry_create_promise (void)
JERRY_CONTEXT (current_new_target_p) = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
}
ecma_value_t promise_value = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY);
ecma_value_t promise_value = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED);
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
return promise_value;
@@ -4353,6 +4356,26 @@ jerry_get_promise_state (const jerry_value_t promise) /**< promise object to get
#endif /* JERRY_BUILTIN_PROMISE */
} /* jerry_get_promise_state */
/**
* Sets a callback for tracking Promise and async operations.
*
* Note:
* the previous callback is overwritten
*/
void jerry_promise_set_callback (jerry_promise_callback_t callback, /**< notification callback */
void *user_p) /**< user pointer passed to the callback */
{
jerry_assert_api_available ();
#if JERRY_BUILTIN_PROMISE && JERRY_PROMISE_CALLBACK
JERRY_CONTEXT (promise_callback) = callback;
JERRY_CONTEXT (promise_callback_user_p) = user_p;
#else /* !JERRY_BUILTIN_PROMISE && !JERRY_PROMISE_CALLBACK */
JERRY_UNUSED (callback);
JERRY_UNUSED (user_p);
#endif /* JERRY_BUILTIN_PROMISE && JERRY_PROMISE_CALLBACK */
} /* jerry_promise_set_callback */
/**
* Get the well-knwon symbol represented by the given `symbol` enum value.
*
+21 -1
View File
@@ -348,6 +348,15 @@
# define JERRY_PROPRETY_HASHMAP 1
#endif /* !defined (JERRY_PROPRETY_HASHMAP) */
/**
* Enables/disables the Promise event callbacks
*
* Default value: 0
*/
#ifndef JERRY_PROMISE_CALLBACK
# define JERRY_PROMISE_CALLBACK 0
#endif /* !defined (JERRY_PROMISE_CALLBACK) */
/**
* Enable/Disable byte code dump functions for RegExp objects.
* To dump the RegExp byte code the engine must be initialized with
@@ -666,6 +675,10 @@
|| ((JERRY_PROPRETY_HASHMAP != 0) && (JERRY_PROPRETY_HASHMAP != 1))
# error "Invalid value for 'JERRY_PROPRETY_HASHMAP' macro."
#endif
#if !defined (JERRY_PROMISE_CALLBACK) \
|| ((JERRY_PROMISE_CALLBACK != 0) && (JERRY_PROMISE_CALLBACK != 1))
# error "Invalid value for 'JERRY_PROMISE_CALLBACK' macro."
#endif
#if !defined (JERRY_REGEXP_DUMP_BYTE_CODE) \
|| ((JERRY_REGEXP_DUMP_BYTE_CODE != 0) && (JERRY_REGEXP_DUMP_BYTE_CODE != 1))
# error "Invalid value for 'JERRY_REGEXP_DUMP_BYTE_CODE' macro."
@@ -702,14 +715,21 @@
/**
* Cross component requirements check.
*/
/**
* The date module can only use the float 64 number types.
* Do a check for this.
*/
#if JERRY_BUILTIN_DATE && !JERRY_NUMBER_TYPE_FLOAT64
# error "Date does not support float32"
#endif
/**
* Promise support must be enabled if Promise callback support is enabled.
*/
#if JERRY_PROMISE_CALLBACK && !JERRY_BUILTIN_PROMISE
# error "Promise callback support depends on Promise support"
#endif /* JERRY_PROMISE_CALLBACK && !JERRY_BUILTIN_PROMISE */
/**
* Wrap container types into a single guard
*/
@@ -375,7 +375,7 @@ ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t iterable, /**< the items to be resolved */
bool is_race) /**< indicates whether it is race function */
{
ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg);
ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg, ECMA_VALUE_UNDEFINED);
if (JERRY_UNLIKELY (capability_obj_p == NULL))
{
@@ -455,7 +455,7 @@ ecma_builtin_promise_dispatch_construct (const ecma_value_t *arguments_list_p, /
return ecma_raise_type_error (ECMA_ERR_MSG ("First parameter must be callable"));
}
return ecma_op_create_promise_object (arguments_list_p[0], ECMA_PROMISE_EXECUTOR_FUNCTION);
return ecma_op_create_promise_object (arguments_list_p[0], ECMA_VALUE_UNDEFINED);
} /* ecma_builtin_promise_dispatch_construct */
/**
@@ -57,7 +57,7 @@ ecma_async_generator_enqueue (vm_executable_object_t *async_generator_object_p,
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
ecma_value_t result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY);
ecma_value_t result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED);
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
task_p->promise = result;
+63 -4
View File
@@ -186,6 +186,17 @@ ecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the
LIT_INTERNAL_MAGIC_PROMISE_CAPABILITY));
ecma_promise_capabality_t *capability_p;
capability_p = (ecma_promise_capabality_t *) ecma_get_object_from_value (job_p->capability);
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_BEFORE_REACTION_JOB,
capability_p->header.u.class_prop.u.promise,
ECMA_VALUE_UNDEFINED,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
/* 3. */
ecma_value_t handler = job_p->handler;
@@ -232,6 +243,17 @@ ecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the
}
ecma_free_value (handler_result);
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_AFTER_REACTION_JOB,
capability_p->header.u.class_prop.u.promise,
ECMA_VALUE_UNDEFINED,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_free_promise_reaction_job (job_p);
return status;
@@ -246,6 +268,23 @@ ecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the
static ecma_value_t
ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_p) /**< the job to be operated */
{
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
jerry_promise_event_type_t type = JERRY_PROMISE_EVENT_ASYNC_BEFORE_RESOLVE;
if (ecma_job_queue_get_type (&job_p->header) == ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED)
{
type = JERRY_PROMISE_EVENT_ASYNC_BEFORE_REJECT;
}
JERRY_CONTEXT (promise_callback) (type,
job_p->executable_object,
job_p->argument,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_object_t *object_p = ecma_get_object_from_value (job_p->executable_object);
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
@@ -284,6 +323,8 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
}
}
ecma_value_t result;
if (executable_object_p->extended_object.u.class_prop.extra_info & ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD)
{
job_p->argument = ecma_await_continue (executable_object_p, job_p->argument);
@@ -297,9 +338,8 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
{
/* Continue iteration. */
JERRY_ASSERT (job_p->argument == ECMA_VALUE_UNDEFINED);
ecma_free_promise_async_reaction_job (job_p);
return ECMA_VALUE_UNDEFINED;
result = ECMA_VALUE_UNDEFINED;
goto free_job;
}
if (ECMA_AWAIT_GET_STATE (executable_object_p) <= ECMA_AWAIT_YIELD_END)
@@ -316,7 +356,7 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
executable_object_p->extended_object.u.class_prop.extra_info &= ECMA_AWAIT_CLEAR_MASK;
}
ecma_value_t result = opfunc_resume_executable_object (executable_object_p, job_p->argument);
result = opfunc_resume_executable_object (executable_object_p, job_p->argument);
/* Argument reference has been taken by opfunc_resume_executable_object. */
job_p->argument = ECMA_VALUE_UNDEFINED;
@@ -327,6 +367,25 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
result = ECMA_VALUE_UNDEFINED;
}
free_job:
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
jerry_promise_event_type_t type = JERRY_PROMISE_EVENT_ASYNC_AFTER_RESOLVE;
if (ecma_job_queue_get_type (&job_p->header) == ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED)
{
type = JERRY_PROMISE_EVENT_ASYNC_AFTER_REJECT;
}
JERRY_CONTEXT (promise_callback) (type,
job_p->executable_object,
job_p->argument,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_free_promise_async_reaction_job (job_p);
return result;
} /* ecma_process_promise_async_reaction_job */
@@ -211,6 +211,16 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
JERRY_ASSERT (ecma_promise_get_flags (obj_p) & ECMA_PROMISE_IS_PENDING);
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_REJECT,
promise,
reason,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_promise_set_state (obj_p, false);
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (reason));
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
@@ -272,6 +282,16 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */
ecma_free_value (then);
}
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_RESOLVE,
promise,
value,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_promise_set_state (obj_p, true);
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (value));
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
@@ -301,9 +321,10 @@ ecma_promise_reject_handler (ecma_object_t *function_obj_p, /**< function object
const uint32_t args_count) /**< argument number */
{
ecma_promise_resolver_t *function_p = (ecma_promise_resolver_t *) function_obj_p;
ecma_value_t promise = function_p->promise;
/* 1. */
ecma_object_t *promise_obj_p = ecma_get_object_from_value (function_p->promise);
ecma_object_t *promise_obj_p = ecma_get_object_from_value (promise);
JERRY_ASSERT (ecma_is_promise (promise_obj_p));
/* 3., 4. */
@@ -314,7 +335,7 @@ ecma_promise_reject_handler (ecma_object_t *function_obj_p, /**< function object
/* 6. */
ecma_value_t reject_value = (args_count == 0) ? ECMA_VALUE_UNDEFINED : args_p[0];
ecma_reject_promise (function_p->promise, reject_value);
ecma_reject_promise (promise, reject_value);
}
return ECMA_VALUE_UNDEFINED;
@@ -333,9 +354,10 @@ ecma_promise_resolve_handler (ecma_object_t *function_obj_p, /**< function objec
const uint32_t args_count) /**< argument number */
{
ecma_promise_resolver_t *function_p = (ecma_promise_resolver_t *) function_obj_p;
ecma_value_t promise = function_p->promise;
/* 1. */
ecma_object_t *promise_obj_p = ecma_get_object_from_value (function_p->promise);
ecma_object_t *promise_obj_p = ecma_get_object_from_value (promise);
JERRY_ASSERT (ecma_is_promise (promise_obj_p));
/* 3., 4. */
@@ -344,14 +366,14 @@ ecma_promise_resolve_handler (ecma_object_t *function_obj_p, /**< function objec
/* 5. */
((ecma_extended_object_t *) promise_obj_p)->u.class_prop.extra_info |= ECMA_PROMISE_ALREADY_RESOLVED;
ecma_fulfill_promise (function_p->promise, (args_count == 0) ? ECMA_VALUE_UNDEFINED : args_p[0]);
ecma_fulfill_promise (promise, (args_count == 0) ? ECMA_VALUE_UNDEFINED : args_p[0]);
}
return ECMA_VALUE_UNDEFINED;
} /* ecma_promise_resolve_handler */
/**
* Helper function for PromiseCreateResovingFucntions.
* Helper function for PromiseCreateResolvingFunctions.
*
* See also: ES2015 25.4.1.3 2. - 7.
*
@@ -370,7 +392,7 @@ ecma_promise_create_resolving_functions_helper (ecma_object_t *promise_p, /**< P
} /* ecma_promise_create_resolving_functions_helper */
/**
* Create a PromiseCreateResovingFucntions.
* Perform PromiseCreateResolvingFunctions.
*
* See also: ES2015 25.4.1.3
*
@@ -401,10 +423,12 @@ ecma_promise_create_resolving_functions (ecma_promise_object_t *promise_p) /**<
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or object */
ecma_promise_executor_type_t type) /**< indicates the type of executor */
ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or ECMA_VALUE_EMPTY */
ecma_value_t parent) /**< parent promise if available */
{
JERRY_UNUSED (parent);
JERRY_ASSERT (JERRY_CONTEXT (current_new_target_p) != NULL);
/* 3. */
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target_p),
ECMA_BUILTIN_ID_PROMISE_PROTOTYPE);
@@ -437,10 +461,20 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
ecma_promise_create_resolving_functions (promise_object_p);
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_CREATE,
ecma_make_object_value (object_p),
parent,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
/* 9. */
ecma_value_t completion = ECMA_VALUE_UNDEFINED;
if (type == ECMA_PROMISE_EXECUTOR_FUNCTION)
if (executor != ECMA_VALUE_EMPTY)
{
JERRY_ASSERT (ecma_op_is_callable (executor));
@@ -450,11 +484,6 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
argv,
2);
}
else
{
JERRY_ASSERT (type == ECMA_PROMISE_EXECUTOR_EMPTY);
JERRY_UNUSED (executor);
}
ecma_value_t status = ECMA_VALUE_EMPTY;
@@ -479,7 +508,6 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
/* 11. */
ecma_free_value (status);
return ecma_make_object_value (object_p);
} /* ecma_op_create_promise_object */
@@ -614,7 +642,8 @@ ecma_op_get_capabilities_executor_cb (ecma_object_t *function_obj_p, /**< functi
* new PromiseCapability object - otherwise
*/
ecma_object_t *
ecma_promise_new_capability (ecma_value_t constructor)
ecma_promise_new_capability (ecma_value_t constructor, /**< constructor function */
ecma_value_t parent) /**< parent promise if available */
{
/* 1. */
if (!ecma_is_constructor (constructor))
@@ -646,10 +675,22 @@ ecma_promise_new_capability (ecma_value_t constructor)
/* 7. */
ecma_value_t executor = ecma_make_object_value (executor_p);
ecma_value_t promise = ecma_op_function_construct (constructor_obj_p,
constructor_obj_p,
&executor,
1);
ecma_value_t promise;
if (constructor_obj_p == ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE))
{
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = constructor_obj_p;
promise = ecma_op_create_promise_object (executor, parent);
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
}
else
{
promise = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, &executor, 1);
}
ecma_deref_object (executor_p);
if (ECMA_IS_VALUE_ERROR (promise))
@@ -723,7 +764,7 @@ ecma_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argument */
}
}
ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg);
ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg, ECMA_VALUE_UNDEFINED);
if (JERRY_UNLIKELY (capability_obj_p == NULL))
{
@@ -868,7 +909,7 @@ ecma_promise_then (ecma_value_t promise, /**< the promise which call 'then' */
return species;
}
ecma_object_t *result_capability_obj_p = ecma_promise_new_capability (species);
ecma_object_t *result_capability_obj_p = ecma_promise_new_capability (species, promise);
ecma_free_value (species);
if (JERRY_UNLIKELY (result_capability_obj_p == NULL))
@@ -1104,6 +1145,16 @@ void
ecma_promise_async_then (ecma_value_t promise, /**< promise object */
ecma_value_t executable_object) /**< executable object of the async function */
{
#if JERRY_PROMISE_CALLBACK
if (JERRY_UNLIKELY (JERRY_CONTEXT (promise_callback) != NULL))
{
JERRY_CONTEXT (promise_callback) (JERRY_PROMISE_EVENT_ASYNC_AWAIT,
executable_object,
promise,
JERRY_CONTEXT (promise_callback_user_p));
}
#endif /* JERRY_PROMISE_CALLBACK */
ecma_object_t *promise_obj_p = ecma_get_object_from_value (promise);
uint16_t flags = ecma_promise_get_flags (promise_obj_p);
@@ -37,15 +37,6 @@ typedef enum
ECMA_PROMISE_HANDLED = (1 << 3), /**< ES11: 25.6.6 [[PromiseIsHandled]] internal slot */
} ecma_promise_flags_t;
/**
* Indicates the type of the executor in promise construct.
*/
typedef enum
{
ECMA_PROMISE_EXECUTOR_FUNCTION, /**< the executor is a function, it is for the usual constructor */
ECMA_PROMISE_EXECUTOR_EMPTY /**< the executor is empty, it is for external C API */
} ecma_promise_executor_type_t;
/**
* Description of a promise resolving function.
*/
@@ -104,12 +95,12 @@ typedef struct
*/
bool ecma_is_promise (ecma_object_t *obj_p);
ecma_value_t ecma_op_create_promise_object (ecma_value_t executor, ecma_promise_executor_type_t type);
ecma_value_t ecma_op_create_promise_object (ecma_value_t executor, ecma_value_t parent);
uint16_t ecma_promise_get_flags (ecma_object_t *promise_p);
ecma_value_t ecma_promise_get_result (ecma_object_t *promise_p);
void ecma_reject_promise (ecma_value_t promise, ecma_value_t reason);
void ecma_fulfill_promise (ecma_value_t promise, ecma_value_t value);
ecma_object_t *ecma_promise_new_capability (ecma_value_t constructor);
ecma_object_t *ecma_promise_new_capability (ecma_value_t constructor, ecma_value_t parent);
ecma_value_t ecma_promise_reject_or_resolve (ecma_value_t this_arg, ecma_value_t value, bool is_resolve);
ecma_value_t ecma_promise_then (ecma_value_t promise, ecma_value_t on_fulfilled, ecma_value_t on_rejected);
+50
View File
@@ -107,6 +107,7 @@ typedef enum
JERRY_FEATURE_BIGINT, /**< BigInt support */
JERRY_FEATURE_REALM, /**< realm support */
JERRY_FEATURE_GLOBAL_THIS, /**< GlobalThisValue support */
JERRY_FEATURE_PROMISE_CALLBACK, /**< Promise callback support */
JERRY_FEATURE__COUNT /**< number of features. NOTE: must be at the end of the list */
} jerry_feature_t;
@@ -726,9 +727,11 @@ bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_pr
jerry_value_t jerry_object_get_property_names (const jerry_value_t obj_val, jerry_property_filter_t filter);
jerry_value_t jerry_from_property_descriptor (const jerry_property_descriptor_t *src_prop_desc_p);
jerry_value_t jerry_to_property_descriptor (jerry_value_t obj_value, jerry_property_descriptor_t *out_prop_desc_p);
/**
* Promise functions.
*/
jerry_value_t jerry_resolve_or_reject_promise (jerry_value_t promise, jerry_value_t argument, bool is_resolve);
/**
@@ -745,6 +748,53 @@ typedef enum
jerry_value_t jerry_get_promise_result (const jerry_value_t promise);
jerry_promise_state_t jerry_get_promise_state (const jerry_value_t promise);
/**
* Event types for jerry_promise_callback_t callback function.
* The description of the 'object' and 'value' arguments are provided for each type.
*/
typedef enum
{
JERRY_PROMISE_EVENT_CREATE = 0u, /**< a new Promise object is created
* object: the new Promise object
* value: parent Promise for `then` chains, undefined otherwise */
JERRY_PROMISE_EVENT_RESOLVE, /**< called when a Promise is about to be resolved
* object: the Promise object
* value: value for resolving */
JERRY_PROMISE_EVENT_REJECT, /**< called when a Promise is about to be rejected
* object: the Promise object
* value: value for rejecting */
JERRY_PROMISE_EVENT_BEFORE_REACTION_JOB, /**< called before executing a Promise reaction job
* object: the Promise object
* value: undefined */
JERRY_PROMISE_EVENT_AFTER_REACTION_JOB, /**< called after a Promise reaction job is completed
* object: the Promise object
* value: undefined */
JERRY_PROMISE_EVENT_ASYNC_AWAIT, /**< called when an async function awaits the result of a Promise object
* object: internal object representing the execution status
* value: the Promise object */
JERRY_PROMISE_EVENT_ASYNC_BEFORE_RESOLVE, /**< called when an async function is continued with resolve
* object: internal object representing the execution status
* value: value for resolving */
JERRY_PROMISE_EVENT_ASYNC_BEFORE_REJECT, /**< called when an async function is continued with reject
* object: internal object representing the execution status
* value: value for rejecting */
JERRY_PROMISE_EVENT_ASYNC_AFTER_RESOLVE, /**< called when an async function resolve is completed
* object: internal object representing the execution status
* value: value for resolving */
JERRY_PROMISE_EVENT_ASYNC_AFTER_REJECT, /**< called when an async function reject is completed
* object: internal object representing the execution status
* value: value for rejecting */
} jerry_promise_event_type_t;
/**
* Notification callback for tracking Promise and async function operations.
*/
typedef void (*jerry_promise_callback_t) (jerry_promise_event_type_t event_type,
const jerry_value_t object, const jerry_value_t value,
void *user_p);
void jerry_promise_set_callback (jerry_promise_callback_t callback, void *user_p);
/**
* Symbol functions.
*/
+4
View File
@@ -183,6 +183,10 @@ struct jerry_context_t
#if JERRY_BUILTIN_PROMISE
ecma_job_queue_item_t *job_queue_head_p; /**< points to the head item of the job queue */
ecma_job_queue_item_t *job_queue_tail_p; /**< points to the tail item of the job queue */
#if JERRY_PROMISE_CALLBACK
void *promise_callback_user_p; /**< user pointer for promise callback */
jerry_promise_callback_t promise_callback; /**< user function for tracking Promise object operations */
#endif /* JERRY_PROMISE_CALLBACK */
#endif /* JERRY_BUILTIN_PROMISE */
#if JERRY_VM_EXEC_STOP
+1 -1
View File
@@ -901,7 +901,7 @@ opfunc_async_create_and_await (vm_frame_ctx_t *frame_ctx_p, /**< frame context *
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = promise_p;
result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY);
result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED);
JERRY_ASSERT (ecma_is_value_object (result));
executable_object_p->frame_ctx.block_result = result;
+1 -1
View File
@@ -2719,7 +2719,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
JERRY_CONTEXT (current_new_target_p) = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY);
result = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_VALUE_UNDEFINED);
JERRY_CONTEXT (current_new_target_p) = old_new_target_p;
}
+1
View File
@@ -66,6 +66,7 @@ set(SOURCE_UNIT_TEST_MAIN_MODULES
test-number-to-string.c
test-objects-foreach.c
test-poolman.c
test-promise-callback.c
test-promise.c
test-proxy.c
test-realm.c
+286
View File
@@ -0,0 +1,286 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "jerryscript.h"
#include "test-common.h"
/* Note: RS = ReSolve, RJ = ReJect */
typedef enum
{
C = JERRY_PROMISE_EVENT_CREATE, /**< same as JERRY_PROMISE_CALLBACK_CREATE with undefined value */
RS = JERRY_PROMISE_EVENT_RESOLVE, /**< same as JERRY_PROMISE_CALLBACK_RESOLVE */
RJ = JERRY_PROMISE_EVENT_REJECT, /**< same as JERRY_PROMISE_CALLBACK_REJECT */
BR = JERRY_PROMISE_EVENT_BEFORE_REACTION_JOB, /**< same as JERRY_PROMISE_CALLBACK_BEFORE_REACTION_JOB */
AR = JERRY_PROMISE_EVENT_AFTER_REACTION_JOB, /**< same as JERRY_PROMISE_CALLBACK_AFTER_REACTION_JOB */
A = JERRY_PROMISE_EVENT_ASYNC_AWAIT, /**< same as JERRY_PROMISE_CALLBACK_ASYNC_AWAIT */
BRS = JERRY_PROMISE_EVENT_ASYNC_BEFORE_RESOLVE, /**< same as JERRY_PROMISE_CALLBACK_ASYNC_BEFORE_RESOLVE */
BRJ = JERRY_PROMISE_EVENT_ASYNC_BEFORE_REJECT, /**< same as JERRY_PROMISE_CALLBACK_ASYNC_BEFORE_REJECT */
ARS = JERRY_PROMISE_EVENT_ASYNC_AFTER_RESOLVE, /**< same as JERRY_PROMISE_CALLBACK_ASYNC_AFTER_RESOLVE */
ARJ = JERRY_PROMISE_EVENT_ASYNC_AFTER_REJECT, /**< same as JERRY_PROMISE_CALLBACK_ASYNC_AFTER_REJECT */
CP = UINT8_MAX - 1, /**< same as JERRY_PROMISE_CALLBACK_CREATE with Promise value */
E = UINT8_MAX, /**< marks the end of the event list */
} jerry_promise_callback_event_abbreviations_t;
static int user;
static const uint8_t *next_event_p;
static void
promise_callback (jerry_promise_event_type_t event_type, /**< event type */
const jerry_value_t object, /**< target object */
const jerry_value_t value, /**< optional argument */
void *user_p) /**< user pointer passed to the callback */
{
TEST_ASSERT (user_p == (void *) &user);
switch (event_type)
{
case JERRY_PROMISE_EVENT_CREATE:
{
TEST_ASSERT (jerry_value_is_promise (object));
if (jerry_value_is_undefined (value))
{
break;
}
TEST_ASSERT (jerry_value_is_promise (value));
TEST_ASSERT (*next_event_p++ == CP);
return;
}
case JERRY_PROMISE_EVENT_RESOLVE:
case JERRY_PROMISE_EVENT_REJECT:
{
TEST_ASSERT (jerry_value_is_promise (object));
break;
}
case JERRY_PROMISE_EVENT_BEFORE_REACTION_JOB:
case JERRY_PROMISE_EVENT_AFTER_REACTION_JOB:
{
TEST_ASSERT (jerry_value_is_promise (object));
TEST_ASSERT (jerry_value_is_undefined (value));
break;
}
case JERRY_PROMISE_EVENT_ASYNC_AWAIT:
{
TEST_ASSERT (jerry_value_is_object (object));
TEST_ASSERT (jerry_value_is_promise (value));
break;
}
default:
{
TEST_ASSERT (event_type == JERRY_PROMISE_EVENT_ASYNC_BEFORE_RESOLVE
|| event_type == JERRY_PROMISE_EVENT_ASYNC_BEFORE_REJECT
|| event_type == JERRY_PROMISE_EVENT_ASYNC_AFTER_RESOLVE
|| event_type == JERRY_PROMISE_EVENT_ASYNC_AFTER_REJECT);
TEST_ASSERT (jerry_value_is_object (object));
break;
}
}
TEST_ASSERT (*next_event_p++ == (uint8_t) event_type);
} /* promise_callback */
static void
run_eval (const uint8_t *event_list_p, /**< event list */
const char *source_p) /**< source code */
{
next_event_p = event_list_p;
jerry_value_t result = jerry_eval ((const jerry_char_t *) source_p, strlen (source_p), 0);
TEST_ASSERT (!jerry_value_is_error (result));
jerry_release_value (result);
result = jerry_run_all_enqueued_jobs ();
TEST_ASSERT (!jerry_value_is_error (result));
jerry_release_value (result);
TEST_ASSERT (*next_event_p == UINT8_MAX);
} /* run_eval */
int
main (void)
{
TEST_INIT ();
if (!jerry_is_feature_enabled (JERRY_FEATURE_PROMISE))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n");
return 0;
}
/* The test system enables this feature when Promises are enabled. */
TEST_ASSERT (jerry_is_feature_enabled (JERRY_FEATURE_PROMISE_CALLBACK));
jerry_init (JERRY_INIT_EMPTY);
jerry_promise_set_callback (promise_callback, (void *) &user);
/* Test promise creation. */
static uint8_t events1[] = { C, C, C, E };
run_eval (events1,
"'use strict'\n"
"new Promise((res, rej) => {})\n"
"new Promise((res, rej) => {})\n"
"new Promise((res, rej) => {})\n");
/* Test then call. */
static uint8_t events2[] = { C, CP, E };
run_eval (events2,
"'use strict'\n"
"var promise = new Promise((res, rej) => {})\n"
"promise.then(() => {}, () => {})\n");
/* Test then call with extended Promise. */
static uint8_t events3[] = { C, C, E };
run_eval (events3,
"'use strict'\n"
"var P = class extends Promise {}\n"
"var promise = new P((res, rej) => {})\n"
"promise.then(() => {})\n");
/* Test resolve and reject calls. */
static uint8_t events4[] = { C, C, RS, RJ, E };
run_eval (events4,
"'use strict'\n"
"var resolve\n"
"var reject\n"
"new Promise((res, rej) => resolve = res)\n"
"new Promise((res, rej) => reject = rej)\n"
"resolve(1)\n"
"reject(1)\n");
/* Test then and resolve calls. */
static uint8_t events5[] = { C, CP, RS, BR, RS, AR, E };
run_eval (events5,
"'use strict'\n"
"var resolve\n"
"var promise = new Promise((res, rej) => resolve = res)\n"
"promise.then(() => {})\n"
"resolve(1)\n");
/* Test resolve and then calls. */
static uint8_t events6[] = { C, RS, CP, BR, RS, AR, E };
run_eval (events6,
"'use strict'\n"
"var promise = new Promise((res, rej) => res(1))\n"
"promise.then(() => {})\n");
/* Test Promise.resolve. */
static uint8_t events7[] = { C, RS, CP, BR, RS, AR, E };
run_eval (events7,
"Promise.resolve(4).then(() => {})\n");
/* Test Promise.reject. */
static uint8_t events8[] = { C, RJ, CP, BR, RJ, AR, E };
run_eval (events8,
"Promise.reject(4).then(() => {})\n");
/* Test Promise.race without resolve */
static uint8_t events9[] = { C, C, C, CP, CP, E };
run_eval (events9,
"'use strict'\n"
"var p1 = new Promise((res, rej) => {})\n"
"var p2 = new Promise((res, rej) => {})\n"
"Promise.race([p1,p2])\n");
/* Test Promise.race with resolve. */
static uint8_t events10[] = { C, RS, C, RJ, C, CP, CP, BR, RS, RS, AR, BR, RS, AR, E };
run_eval (events10,
"'use strict'\n"
"var p1 = new Promise((res, rej) => res(1))\n"
"var p2 = new Promise((res, rej) => rej(1))\n"
"Promise.race([p1,p2])\n");
/* Test Promise.all without resolve. */
static uint8_t events11[] = { C, C, C, CP, CP, E };
run_eval (events11,
"'use strict'\n"
"var p1 = new Promise((res, rej) => {})\n"
"var p2 = new Promise((res, rej) => {})\n"
"Promise.all([p1,p2])\n");
/* Test Promise.all with resolve. */
static uint8_t events12[] = { C, RS, C, RJ, C, CP, CP, BR, RS, AR, BR, RJ, RS, AR, E };
run_eval (events12,
"'use strict'\n"
"var p1 = new Promise((res, rej) => res(1))\n"
"var p2 = new Promise((res, rej) => rej(1))\n"
"Promise.all([p1,p2])\n");
/* Test async function. */
static uint8_t events13[] = { C, RS, E };
run_eval (events13,
"'use strict'\n"
"async function f() {}\n"
"f()\n");
/* Test await with resolved Promise. */
static uint8_t events14[] = { C, RS, A, C, BRS, RS, ARS, E };
run_eval (events14,
"'use strict'\n"
"async function f(p) { await p }\n"
"f(Promise.resolve(1))\n");
/* Test await with non-Promise value. */
static uint8_t events15[] = { C, RS, A, C, BRS, C, RS, A, ARS, BRS, RS, ARS, E };
run_eval (events15,
"'use strict'\n"
"async function f(p) { await p; await 'X' }\n"
"f(Promise.resolve(1))\n");
/* Test await with rejected Promise. */
static uint8_t events16[] = { C, RJ, A, C, BRJ, C, RS, RS, ARJ, E };
run_eval (events16,
"'use strict'\n"
"async function f(p) { try { await p; } catch (e) { Promise.resolve(1) } }\n"
"f(Promise.reject(1))\n");
/* Test async generator function. */
static uint8_t events17[] = { C, RS, C, A, BRS, RS, ARS, E };
run_eval (events17,
"'use strict'\n"
"async function *f(p) { await p; return 4 }\n"
"f(Promise.resolve(1)).next()\n");
/* Test yield* operation. */
static uint8_t events18[] = { C, C, RS, A, BRS, C, RS, A, ARS, BRS, RS, ARS, E };
run_eval (events18,
"'use strict'\n"
"async function *f(p) { yield 1 }\n"
"async function *g() { yield* f() }\n"
"g().next()\n");
jerry_cleanup ();
return 0;
} /* main */
+3
View File
@@ -138,6 +138,8 @@ def get_arguments():
help=devhelp('enable mem-stress test (%(choices)s)'))
coregrp.add_argument('--profile', metavar='FILE',
help='specify profile file')
coregrp.add_argument('--promise-callback', metavar='X', choices=['ON', 'OFF'], type=str.upper,
help='enable promise callback (%(choices)s)')
coregrp.add_argument('--regexp-strict-mode', metavar='X', choices=['ON', 'OFF'], type=str.upper,
help=devhelp('enable regexp strict mode (%(choices)s)'))
coregrp.add_argument('--show-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper,
@@ -212,6 +214,7 @@ def generate_build_options(arguments):
build_options_append('JERRY_MEM_STATS', arguments.mem_stats)
build_options_append('JERRY_MEM_GC_BEFORE_EACH_ALLOC', arguments.mem_stress_test)
build_options_append('JERRY_PROFILE', arguments.profile)
build_options_append('JERRY_PROMISE_CALLBACK', arguments.promise_callback)
build_options_append('JERRY_REGEXP_STRICT_MODE', arguments.regexp_strict_mode)
build_options_append('JERRY_PARSER_DUMP_BYTE_CODE', arguments.show_opcodes)
build_options_append('JERRY_REGEXP_DUMP_BYTE_CODE', arguments.show_regexp_opcodes)
+4 -2
View File
@@ -57,9 +57,11 @@ OPTIONS_DOCTESTS = ['--doctests=on', '--jerry-cmdline=off', '--error-messages=on
# Test options for unittests
JERRY_UNITTESTS_OPTIONS = [
Options('unittests-es.next',
OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ESNEXT),
OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ESNEXT
+ ['--promise-callback=on']),
Options('doctests-es.next',
OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ESNEXT),
OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ESNEXT
+ ['--promise-callback=on']),
Options('unittests-es5.1',
OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51),
Options('doctests-es5.1',