Add promise C API (#1796)
Add API: jerry_create_promise, jerry_value_is_promise and jerry_resolve_or_reject_promise. related issue: 1794 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
+136
-2
@@ -1072,6 +1072,47 @@ jerry_value_is_object (const jerry_value_t value)
|
|||||||
- [jerry_release_value](#jerry_release_value)
|
- [jerry_release_value](#jerry_release_value)
|
||||||
|
|
||||||
|
|
||||||
|
## jerry_value_is_promise
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
Returns whether the given `jerry_value_t` is a promise value.
|
||||||
|
|
||||||
|
*Note*: This API depends on the ES2015-subset profile.
|
||||||
|
|
||||||
|
**Prototype**
|
||||||
|
|
||||||
|
```c
|
||||||
|
bool
|
||||||
|
jerry_value_is_promise (const jerry_value_t value)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `value` - api value
|
||||||
|
- return value
|
||||||
|
- true, if the given `jerry_value_t` is a promise
|
||||||
|
- false, otherwise
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
jerry_value_t value;
|
||||||
|
... // create or acquire value
|
||||||
|
|
||||||
|
if (jerry_value_is_promise (value))
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
jerry_release_value (value);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**See also**
|
||||||
|
|
||||||
|
- [jerry_release_value](#jerry_release_value)
|
||||||
|
|
||||||
|
|
||||||
## jerry_value_is_string
|
## jerry_value_is_string
|
||||||
|
|
||||||
**Summary**
|
**Summary**
|
||||||
@@ -1980,6 +2021,64 @@ jerry_value_to_string (const jerry_value_t value);
|
|||||||
- [jerry_value_to_primitive](#jerry_value_to_primitive)
|
- [jerry_value_to_primitive](#jerry_value_to_primitive)
|
||||||
|
|
||||||
|
|
||||||
|
# Functions for promise objects
|
||||||
|
|
||||||
|
These APIs all depends on the ES2015-subset profile.
|
||||||
|
|
||||||
|
## jerry_resolve_or_reject_promise
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
Resolve or reject the promise with an argument.
|
||||||
|
|
||||||
|
**Prototype**
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t
|
||||||
|
jerry_resolve_or_reject_promise (jerry_value_t promise,
|
||||||
|
jerry_value_t argument,
|
||||||
|
bool is_resolve)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `promise` - the promise value
|
||||||
|
- `argument` - the argument for resolve or reject
|
||||||
|
- `is_resolve` - whether the promise should be resolved or rejected
|
||||||
|
- return value
|
||||||
|
- undefined jerry value - resolve or reject successed
|
||||||
|
- jerry value with error flag - otherwise
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
jerry_value_t promise = ... // acquire/create a promise object.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
bool is_resolve = ... // whether the promise should be resolved or rejected
|
||||||
|
jerry_value_t argument = ... // prepare the argumnent for the resolve or reject.
|
||||||
|
|
||||||
|
jerry_value_t is_ok = jerry_resolve_or_reject_promise (promise,
|
||||||
|
argument,
|
||||||
|
is_resolve);
|
||||||
|
|
||||||
|
if (jerry_value_has_error_flag (is_ok))
|
||||||
|
{
|
||||||
|
// handle the error.
|
||||||
|
}
|
||||||
|
|
||||||
|
jerry_release_value (is_ok);
|
||||||
|
jerry_release_value (argument);
|
||||||
|
jerry_release_value (promise);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**See also**
|
||||||
|
|
||||||
|
- [jerry_release_value](#jerry_release_value)
|
||||||
|
- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
|
||||||
|
|
||||||
|
|
||||||
# Acquire and release API values
|
# Acquire and release API values
|
||||||
|
|
||||||
## jerry_acquire_value
|
## jerry_acquire_value
|
||||||
@@ -2425,6 +2524,41 @@ jerry_create_object (void);
|
|||||||
- [jerry_release_value](#jerry_release_value)
|
- [jerry_release_value](#jerry_release_value)
|
||||||
|
|
||||||
|
|
||||||
|
## jerry_create_promise
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
Create an empty promise object which can be resolved or rejected later
|
||||||
|
by calling jerry_resolve_or_reject_promise.
|
||||||
|
|
||||||
|
*Note*: This API depends on the ES2015-subset profile.
|
||||||
|
|
||||||
|
**Prototype**
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t
|
||||||
|
jerry_create_promise (void)
|
||||||
|
```
|
||||||
|
|
||||||
|
- return value - value of the newly created promise
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
```c
|
||||||
|
{
|
||||||
|
jerry_value_t p = jerry_create_promise ();
|
||||||
|
|
||||||
|
...// usage of the promise
|
||||||
|
|
||||||
|
jerry_release_value (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
**See also**
|
||||||
|
|
||||||
|
- [jerry_resolve_or_reject_promise](#jerry_resolve_or_reject_promise)
|
||||||
|
- [jerry_release_value](#jerry_release_value)
|
||||||
|
|
||||||
|
|
||||||
## jerry_create_string
|
## jerry_create_string
|
||||||
|
|
||||||
**Summary**
|
**Summary**
|
||||||
@@ -3528,7 +3662,7 @@ static const jerry_object_native_info_t native_obj_type_info =
|
|||||||
{
|
{
|
||||||
// The type of this's native pointer matches what is expected.
|
// The type of this's native pointer matches what is expected.
|
||||||
// Only now is it safe to cast to native_obj_t * and dereference the
|
// Only now is it safe to cast to native_obj_t * and dereference the
|
||||||
// pointer:
|
// pointer:
|
||||||
native_obj_t *native_obj = native_p;
|
native_obj_t *native_obj = native_p;
|
||||||
native_obj->bar = ...; // Safe to access now!
|
native_obj->bar = ...; // Safe to access now!
|
||||||
}
|
}
|
||||||
@@ -3582,7 +3716,7 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val,
|
|||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a
|
See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a
|
||||||
best-practice example.
|
best-practice example.
|
||||||
|
|
||||||
**See also**
|
**See also**
|
||||||
|
|
||||||
|
|||||||
@@ -683,7 +683,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_raise_type_error (ECMA_ERR_MSG ("First parameter must be callable."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ecma_op_create_promise_object (arguments_list_p[0], true);
|
return ecma_op_create_promise_object (arguments_list_p[0], ECMA_PROMISE_EXECUTOR_FUNCTION);
|
||||||
} /* ecma_builtin_promise_dispatch_construct */
|
} /* ecma_builtin_promise_dispatch_construct */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -223,10 +223,14 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
|
|||||||
{
|
{
|
||||||
ecma_job_promise_resolve_thenable_t *job_p = (ecma_job_promise_resolve_thenable_t *) obj_p;
|
ecma_job_promise_resolve_thenable_t *job_p = (ecma_job_promise_resolve_thenable_t *) obj_p;
|
||||||
ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
|
ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
|
||||||
ecma_promise_resolving_functions_t *funcs;
|
ecma_string_t str_resolve, str_reject;
|
||||||
funcs = ecma_promise_create_resolving_functions (promise_p);
|
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||||
|
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||||
|
|
||||||
ecma_value_t argv[] = { funcs->resolve, funcs->reject };
|
ecma_value_t resolve = ecma_op_object_get (promise_p, &str_resolve);
|
||||||
|
ecma_value_t reject = ecma_op_object_get (promise_p, &str_reject);
|
||||||
|
|
||||||
|
ecma_value_t argv[] = { resolve, reject };
|
||||||
ecma_value_t ret;
|
ecma_value_t ret;
|
||||||
ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then),
|
ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then),
|
||||||
job_p->thenable,
|
job_p->thenable,
|
||||||
@@ -237,7 +241,7 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
|
|||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (then_call_result))
|
if (ECMA_IS_VALUE_ERROR (then_call_result))
|
||||||
{
|
{
|
||||||
ret = ecma_op_function_call (ecma_get_object_from_value (funcs->reject),
|
ret = ecma_op_function_call (ecma_get_object_from_value (reject),
|
||||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||||
&then_call_result,
|
&then_call_result,
|
||||||
1);
|
1);
|
||||||
@@ -245,7 +249,8 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
|
|||||||
ecma_free_value (then_call_result);
|
ecma_free_value (then_call_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_promise_free_resolving_functions (funcs);
|
ecma_free_value (resolve);
|
||||||
|
ecma_free_value (reject);
|
||||||
ecma_free_promise_resolve_thenable_job (job_p);
|
ecma_free_promise_resolve_thenable_job (job_p);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ ecma_call_builtin_executor (ecma_object_t *executor_p, /**< the executor object
|
|||||||
*
|
*
|
||||||
* @return pointer to the resolving functions
|
* @return pointer to the resolving functions
|
||||||
*/
|
*/
|
||||||
ecma_promise_resolving_functions_t *
|
static ecma_promise_resolving_functions_t *
|
||||||
ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promise object */
|
ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promise object */
|
||||||
{
|
{
|
||||||
/* 1. */
|
/* 1. */
|
||||||
@@ -455,7 +455,7 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promi
|
|||||||
/**
|
/**
|
||||||
* Free the heap and the member of the resolving functions.
|
* Free the heap and the member of the resolving functions.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs) /**< points to the functions */
|
ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs) /**< points to the functions */
|
||||||
{
|
{
|
||||||
ecma_free_value (funcs->resolve);
|
ecma_free_value (funcs->resolve);
|
||||||
@@ -473,7 +473,7 @@ ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs
|
|||||||
*/
|
*/
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or object */
|
ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or object */
|
||||||
bool is_func) /**< indicates whether executor is a function */
|
ecma_promise_executor_type_t type) /**< indicates the type of executor */
|
||||||
{
|
{
|
||||||
/* 3. */
|
/* 3. */
|
||||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE_PROTOTYPE);
|
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
|
|||||||
/* 8. */
|
/* 8. */
|
||||||
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
|
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
|
||||||
|
|
||||||
/* 9. */
|
ecma_string_t str_resolve, str_reject;
|
||||||
ecma_value_t completion;
|
ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||||
|
ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||||
|
ecma_op_object_put (object_p,
|
||||||
|
&str_resolve,
|
||||||
|
funcs->resolve,
|
||||||
|
false);
|
||||||
|
ecma_op_object_put (object_p,
|
||||||
|
&str_reject,
|
||||||
|
funcs->reject,
|
||||||
|
false);
|
||||||
|
|
||||||
if (is_func)
|
/* 9. */
|
||||||
|
ecma_value_t completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||||
|
|
||||||
|
if (type == ECMA_PROMISE_EXECUTOR_FUNCTION)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (ecma_op_is_callable (executor));
|
JERRY_ASSERT (ecma_op_is_callable (executor));
|
||||||
|
|
||||||
@@ -509,7 +521,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
|||||||
argv,
|
argv,
|
||||||
2);
|
2);
|
||||||
}
|
}
|
||||||
else
|
else if (type == ECMA_PROMISE_EXECUTOR_OBJECT)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (ecma_is_value_object (executor));
|
JERRY_ASSERT (ecma_is_value_object (executor));
|
||||||
|
|
||||||
@@ -517,6 +529,11 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
|||||||
funcs->resolve,
|
funcs->resolve,
|
||||||
funcs->reject);
|
funcs->reject);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (type == ECMA_PROMISE_EXECUTOR_EMPTY);
|
||||||
|
JERRY_UNUSED (executor);
|
||||||
|
}
|
||||||
|
|
||||||
ecma_value_t status = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
ecma_value_t status = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||||
|
|
||||||
@@ -572,7 +589,7 @@ ecma_promise_new_capability (void)
|
|||||||
false);
|
false);
|
||||||
|
|
||||||
/* 6. */
|
/* 6. */
|
||||||
ecma_value_t promise = ecma_op_create_promise_object (executor, false);
|
ecma_value_t promise = ecma_op_create_promise_object (executor, ECMA_PROMISE_EXECUTOR_OBJECT);
|
||||||
|
|
||||||
/* 10. */
|
/* 10. */
|
||||||
ecma_op_object_put (capability_p,
|
ecma_op_object_put (capability_p,
|
||||||
|
|||||||
@@ -37,6 +37,16 @@ typedef enum
|
|||||||
ECMA_PROMISE_STATE__COUNT /**< number of states */
|
ECMA_PROMISE_STATE__COUNT /**< number of states */
|
||||||
} ecma_promise_state_t;
|
} ecma_promise_state_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_OBJECT, /**< the executor is an object, it is for the `then` routine */
|
||||||
|
ECMA_PROMISE_EXECUTOR_EMPTY /**< the executor is empty, it is for external C API */
|
||||||
|
} ecma_promise_executor_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of the promise resolving functions.
|
* Description of the promise resolving functions.
|
||||||
*/
|
*/
|
||||||
@@ -81,10 +91,7 @@ void ecma_promise_set_result (ecma_object_t *obj_p, ecma_value_t result);
|
|||||||
uint8_t ecma_promise_get_state (ecma_object_t *obj_p);
|
uint8_t ecma_promise_get_state (ecma_object_t *obj_p);
|
||||||
void ecma_promise_set_state (ecma_object_t *obj_p, uint8_t state);
|
void ecma_promise_set_state (ecma_object_t *obj_p, uint8_t state);
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
ecma_op_create_promise_object (ecma_value_t executor, bool is_func);
|
ecma_op_create_promise_object (ecma_value_t executor, ecma_promise_executor_type_t type);
|
||||||
ecma_promise_resolving_functions_t *
|
|
||||||
ecma_promise_create_resolving_functions (ecma_object_t *obj_p);
|
|
||||||
void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs);
|
|
||||||
ecma_value_t ecma_promise_new_capability (void);
|
ecma_value_t ecma_promise_new_capability (void);
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
ecma_promise_then (ecma_value_t promise,
|
ecma_promise_then (ecma_value_t promise,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "ecma-literal-storage.h"
|
#include "ecma-literal-storage.h"
|
||||||
#include "ecma-objects.h"
|
#include "ecma-objects.h"
|
||||||
#include "ecma-objects-general.h"
|
#include "ecma-objects-general.h"
|
||||||
|
#include "ecma-promise-object.h"
|
||||||
#include "jcontext.h"
|
#include "jcontext.h"
|
||||||
#include "jerryscript.h"
|
#include "jerryscript.h"
|
||||||
#include "jerry-debugger.h"
|
#include "jerry-debugger.h"
|
||||||
@@ -552,6 +553,25 @@ jerry_value_is_object (const jerry_value_t value) /**< api value */
|
|||||||
return ecma_is_value_object (value);
|
return ecma_is_value_object (value);
|
||||||
} /* jerry_value_is_object */
|
} /* jerry_value_is_object */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the specified value is promise.
|
||||||
|
*
|
||||||
|
* @return true - if the specified value is promise,
|
||||||
|
* false - otherwise
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
jerry_value_is_promise (const jerry_value_t value) /**< api value */
|
||||||
|
{
|
||||||
|
jerry_assert_api_available ();
|
||||||
|
|
||||||
|
return (ecma_is_value_object (value)
|
||||||
|
&& ecma_is_promise (ecma_get_object_from_value (value)));
|
||||||
|
} /* jerry_value_is_promise */
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the specified value is string.
|
* Check if the specified value is string.
|
||||||
*
|
*
|
||||||
@@ -1018,6 +1038,27 @@ jerry_create_object (void)
|
|||||||
return ecma_make_object_value (ecma_op_create_object_object_noarg ());
|
return ecma_make_object_value (ecma_op_create_object_object_noarg ());
|
||||||
} /* jerry_create_object */
|
} /* jerry_create_object */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty Promise object which can be resolve/reject later
|
||||||
|
* by calling jerry_resolve_or_reject_promise.
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* returned value must be freed with jerry_release_value, when it is no longer needed.
|
||||||
|
*
|
||||||
|
* @return value of the created object
|
||||||
|
*/
|
||||||
|
jerry_value_t
|
||||||
|
jerry_create_promise (void)
|
||||||
|
{
|
||||||
|
jerry_assert_api_available ();
|
||||||
|
|
||||||
|
return ecma_op_create_promise_object (ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY), ECMA_PROMISE_EXECUTOR_EMPTY);
|
||||||
|
} /* jerry_create_promise */
|
||||||
|
|
||||||
|
#endif /* CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create string from a valid UTF-8 string
|
* Create string from a valid UTF-8 string
|
||||||
*
|
*
|
||||||
@@ -2120,6 +2161,51 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
|||||||
return false;
|
return false;
|
||||||
} /* jerry_foreach_object_property */
|
} /* jerry_foreach_object_property */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve or reject the promise with an argument.
|
||||||
|
*
|
||||||
|
* @return undefined value - if success
|
||||||
|
* value marked with error flag - otherwise
|
||||||
|
*/
|
||||||
|
jerry_value_t
|
||||||
|
jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value */
|
||||||
|
jerry_value_t argument, /**< the argument */
|
||||||
|
bool is_resolve) /**< whether the promise should be resolved or rejected */
|
||||||
|
{
|
||||||
|
jerry_assert_api_available ();
|
||||||
|
|
||||||
|
if (!ecma_is_value_object (promise) || !ecma_is_promise (ecma_get_object_from_value (promise)))
|
||||||
|
{
|
||||||
|
return ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p));
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_string_t str;
|
||||||
|
|
||||||
|
if (is_resolve)
|
||||||
|
{
|
||||||
|
ecma_init_ecma_magic_string (&str, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ecma_init_ecma_magic_string (&str, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_value_t function = ecma_op_object_get (ecma_get_object_from_value (promise), &str);
|
||||||
|
|
||||||
|
ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function),
|
||||||
|
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||||
|
&argument,
|
||||||
|
1);
|
||||||
|
|
||||||
|
ecma_free_value (function);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} /* jerry_resolve_or_reject_promise */
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate UTF-8 string
|
* Validate UTF-8 string
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ bool jerry_value_is_function (const jerry_value_t value);
|
|||||||
bool jerry_value_is_number (const jerry_value_t value);
|
bool jerry_value_is_number (const jerry_value_t value);
|
||||||
bool jerry_value_is_null (const jerry_value_t value);
|
bool jerry_value_is_null (const jerry_value_t value);
|
||||||
bool jerry_value_is_object (const jerry_value_t value);
|
bool jerry_value_is_object (const jerry_value_t value);
|
||||||
|
bool jerry_value_is_promise (const jerry_value_t value);
|
||||||
bool jerry_value_is_string (const jerry_value_t value);
|
bool jerry_value_is_string (const jerry_value_t value);
|
||||||
bool jerry_value_is_undefined (const jerry_value_t value);
|
bool jerry_value_is_undefined (const jerry_value_t value);
|
||||||
|
|
||||||
@@ -332,6 +333,7 @@ jerry_value_t jerry_create_number_infinity (bool sign);
|
|||||||
jerry_value_t jerry_create_number_nan (void);
|
jerry_value_t jerry_create_number_nan (void);
|
||||||
jerry_value_t jerry_create_null (void);
|
jerry_value_t jerry_create_null (void);
|
||||||
jerry_value_t jerry_create_object (void);
|
jerry_value_t jerry_create_object (void);
|
||||||
|
jerry_value_t jerry_create_promise (void);
|
||||||
jerry_value_t jerry_create_string_from_utf8 (const jerry_char_t *str_p);
|
jerry_value_t jerry_create_string_from_utf8 (const jerry_char_t *str_p);
|
||||||
jerry_value_t jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, jerry_size_t str_size);
|
jerry_value_t jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, jerry_size_t str_size);
|
||||||
jerry_value_t jerry_create_string (const jerry_char_t *str_p);
|
jerry_value_t jerry_create_string (const jerry_char_t *str_p);
|
||||||
@@ -387,6 +389,11 @@ void jerry_set_object_native_pointer (const jerry_value_t obj_val,
|
|||||||
bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_property_foreach_t foreach_p,
|
bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_property_foreach_t foreach_p,
|
||||||
void *user_data_p);
|
void *user_data_p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promise resolve/reject functions.
|
||||||
|
*/
|
||||||
|
jerry_value_t jerry_resolve_or_reject_promise (jerry_value_t promise, jerry_value_t argument, bool is_resolve);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input validator functions.
|
* Input validator functions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ typedef enum
|
|||||||
LIT_INTERNAL_MAGIC_STRING_PROMISE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< [[Promise]] of promise
|
LIT_INTERNAL_MAGIC_STRING_PROMISE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< [[Promise]] of promise
|
||||||
* reject or resolve functions */
|
* reject or resolve functions */
|
||||||
LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED, /**< [[AlreadyResolved]] of promise reject or resolve functions */
|
LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED, /**< [[AlreadyResolved]] of promise reject or resolve functions */
|
||||||
|
LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION, /**< the resolve funtion of the promise object */
|
||||||
|
LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION, /**< the reject function of the promise object */
|
||||||
LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< number of internal magic strings which will be used as properties' names,
|
LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< number of internal magic strings which will be used as properties' names,
|
||||||
* and the properties need to be marked during gc. */
|
* and the properties need to be marked during gc. */
|
||||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< native handle package
|
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< native handle package
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ if (NOT IS_ABSOLUTE ${FEATURE_PROFILE})
|
|||||||
set(FEATURE_PROFILE "${CMAKE_SOURCE_DIR}/jerry-core/profiles/${FEATURE_PROFILE}.profile")
|
set(FEATURE_PROFILE "${CMAKE_SOURCE_DIR}/jerry-core/profiles/${FEATURE_PROFILE}.profile")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT ${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/es5.1.profile")
|
if(${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/minimal.profile")
|
||||||
message(FATAL_ERROR "FEATURE_PROFILE='${FEATURE_PROFILE}' isn't supported with UNITTESTS=ON")
|
message(FATAL_ERROR "minimal profile isn't supported in unit-core")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Unit tests main modules
|
# Unit tests main modules
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
/* 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 "jerryscript-port.h"
|
||||||
|
#include "jerryscript-port-default.h"
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||||
|
|
||||||
|
const char *test_source = (
|
||||||
|
"var p1 = create_promise1();"
|
||||||
|
"var p2 = create_promise2();"
|
||||||
|
"p1.then(function(x) { "
|
||||||
|
" assert(x==='resolved'); "
|
||||||
|
"}); "
|
||||||
|
"p2.catch(function(x) { "
|
||||||
|
" assert(x==='rejected'); "
|
||||||
|
"}); "
|
||||||
|
);
|
||||||
|
|
||||||
|
static int count_in_assert = 0;
|
||||||
|
static jerry_value_t my_promise1;
|
||||||
|
static jerry_value_t my_promise2;
|
||||||
|
const jerry_char_t s1[] = "resolved";
|
||||||
|
const jerry_char_t s2[] = "rejected";
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
jerry_value_t ret = jerry_create_promise ();
|
||||||
|
my_promise1 = jerry_acquire_value (ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} /* create_promise1_handler */
|
||||||
|
|
||||||
|
static jerry_value_t
|
||||||
|
create_promise2_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);
|
||||||
|
|
||||||
|
jerry_value_t ret = jerry_create_promise ();
|
||||||
|
my_promise2 = jerry_acquire_value (ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} /* create_promise2_handler */
|
||||||
|
|
||||||
|
static jerry_value_t
|
||||||
|
assert_handler (const jerry_value_t func_obj_val, /**< function object */
|
||||||
|
const jerry_value_t this_val, /**< this arg */
|
||||||
|
const jerry_value_t args_p[], /**< function arguments */
|
||||||
|
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||||
|
{
|
||||||
|
JERRY_UNUSED (func_obj_val);
|
||||||
|
JERRY_UNUSED (this_val);
|
||||||
|
|
||||||
|
count_in_assert++;
|
||||||
|
|
||||||
|
if (args_cnt == 1
|
||||||
|
&& jerry_value_is_boolean (args_p[0])
|
||||||
|
&& jerry_get_boolean_value (args_p[0]))
|
||||||
|
{
|
||||||
|
return jerry_create_boolean (true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TEST_ASSERT (false);
|
||||||
|
}
|
||||||
|
} /* assert_handler */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a JavaScript function in the global object.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
register_js_function (const char *name_p, /**< name of the function */
|
||||||
|
jerry_external_handler_t handler_p) /**< function callback */
|
||||||
|
{
|
||||||
|
jerry_value_t global_obj_val = jerry_get_global_object ();
|
||||||
|
|
||||||
|
jerry_value_t function_val = jerry_create_external_function (handler_p);
|
||||||
|
jerry_value_t function_name_val = jerry_create_string ((const jerry_char_t *) name_p);
|
||||||
|
jerry_value_t result_val = jerry_set_property (global_obj_val, function_name_val, function_val);
|
||||||
|
|
||||||
|
jerry_release_value (function_name_val);
|
||||||
|
jerry_release_value (function_val);
|
||||||
|
jerry_release_value (global_obj_val);
|
||||||
|
|
||||||
|
jerry_release_value (result_val);
|
||||||
|
} /* register_js_function */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
jerry_port_default_jobqueue_init ();
|
||||||
|
jerry_init (JERRY_INIT_EMPTY);
|
||||||
|
|
||||||
|
register_js_function ("create_promise1", create_promise1_handler);
|
||||||
|
register_js_function ("create_promise2", create_promise2_handler);
|
||||||
|
register_js_function ("assert", assert_handler);
|
||||||
|
|
||||||
|
jerry_value_t parsed_code_val = jerry_parse ((jerry_char_t *) test_source, strlen (test_source), false);
|
||||||
|
TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
|
||||||
|
|
||||||
|
jerry_value_t res = jerry_run (parsed_code_val);
|
||||||
|
TEST_ASSERT (!jerry_value_has_error_flag (res));
|
||||||
|
|
||||||
|
jerry_release_value (res);
|
||||||
|
jerry_release_value (parsed_code_val);
|
||||||
|
|
||||||
|
/* Test jerry_create_promise and jerry_value_is_promise. */
|
||||||
|
TEST_ASSERT (jerry_value_is_promise (my_promise1));
|
||||||
|
TEST_ASSERT (jerry_value_is_promise (my_promise2));
|
||||||
|
|
||||||
|
TEST_ASSERT (count_in_assert == 0);
|
||||||
|
|
||||||
|
/* Test jerry_resolve_or_reject_promise. */
|
||||||
|
jerry_value_t str_resolve = jerry_create_string (s1);
|
||||||
|
jerry_value_t str_reject = jerry_create_string (s2);
|
||||||
|
|
||||||
|
jerry_resolve_or_reject_promise (my_promise1, str_resolve, true);
|
||||||
|
jerry_resolve_or_reject_promise (my_promise2, str_reject, false);
|
||||||
|
|
||||||
|
/* The resolve/reject function should be invalid after the promise has the result. */
|
||||||
|
jerry_resolve_or_reject_promise (my_promise2, str_resolve, true);
|
||||||
|
jerry_resolve_or_reject_promise (my_promise1, str_reject, false);
|
||||||
|
|
||||||
|
/* Run the jobqueue. */
|
||||||
|
res = jerry_port_default_jobqueue_run ();
|
||||||
|
|
||||||
|
TEST_ASSERT (!jerry_value_has_error_flag (res));
|
||||||
|
TEST_ASSERT (count_in_assert == 2);
|
||||||
|
|
||||||
|
jerry_release_value (my_promise1);
|
||||||
|
jerry_release_value (my_promise2);
|
||||||
|
jerry_release_value (str_resolve);
|
||||||
|
jerry_release_value (str_reject);
|
||||||
|
|
||||||
|
jerry_cleanup ();
|
||||||
|
} /* main */
|
||||||
|
|
||||||
|
#else /* CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
} /* main */
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
+2
-2
@@ -42,9 +42,9 @@ def get_binary_path(bin_dir_path):
|
|||||||
# Test options for unittests
|
# Test options for unittests
|
||||||
JERRY_UNITTESTS_OPTIONS = [
|
JERRY_UNITTESTS_OPTIONS = [
|
||||||
Options('unittests',
|
Options('unittests',
|
||||||
['--unittests', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on']),
|
['--unittests', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']),
|
||||||
Options('unittests-debug',
|
Options('unittests-debug',
|
||||||
['--unittests', '--debug', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on'])
|
['--unittests', '--debug', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset'])
|
||||||
]
|
]
|
||||||
|
|
||||||
# Test options for jerry-tests
|
# Test options for jerry-tests
|
||||||
|
|||||||
Reference in New Issue
Block a user