Support parsing async modifiers for functions. (#3460)

Only parsing is implemented, so the async functions currently behave
like normal function except they return with a resolved Promise object
when the function is terminated correctly.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2019-12-20 09:55:41 +01:00
committed by GitHub
parent 2a29b72a83
commit 8cb2be6001
22 changed files with 873 additions and 234 deletions
@@ -42,83 +42,6 @@
* @{
*/
/**
* The common function for 'reject' and 'resolve'.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argument */
ecma_value_t argument, /**< argument for reject or resolve */
bool is_resolve) /**< whether it is for resolve routine */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not an object."));
}
if (is_resolve
&& ecma_is_value_object (argument)
&& ecma_is_promise (ecma_get_object_from_value (argument)))
{
ecma_object_t *ctor_obj_p = ecma_get_object_from_value (argument);
ecma_value_t x_ctor = ecma_op_object_get_by_magic_id (ctor_obj_p, LIT_MAGIC_STRING_CONSTRUCTOR);
if (ECMA_IS_VALUE_ERROR (x_ctor))
{
return x_ctor;
}
bool is_same_value = ecma_op_same_value (x_ctor, this_arg);
ecma_free_value (x_ctor);
if (is_same_value)
{
return ecma_copy_value (argument);
}
}
ecma_value_t capability = ecma_promise_new_capability (this_arg);
if (ECMA_IS_VALUE_ERROR (capability))
{
return capability;
}
ecma_string_t *property_str_p;
if (is_resolve)
{
property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
}
else
{
property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
}
ecma_value_t func = ecma_op_object_get (ecma_get_object_from_value (capability), property_str_p);
ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (func),
ECMA_VALUE_UNDEFINED,
&argument,
1);
ecma_free_value (func);
if (ECMA_IS_VALUE_ERROR (call_ret))
{
return call_ret;
}
ecma_free_value (call_ret);
ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
ecma_value_t promise_new = ecma_op_object_get (ecma_get_object_from_value (capability), promise_str_p);
ecma_free_value (capability);
return promise_new;
} /* ecma_builtin_promise_reject_or_resolve */
/**
* Reject the promise if the value is error.
*
@@ -169,7 +92,7 @@ static ecma_value_t
ecma_builtin_promise_reject (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t reason) /**< the reason for reject */
{
return ecma_builtin_promise_reject_or_resolve (this_arg, reason, false);
return ecma_promise_reject_or_resolve (this_arg, reason, false);
} /* ecma_builtin_promise_reject */
/**
@@ -185,7 +108,7 @@ static ecma_value_t
ecma_builtin_promise_resolve (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t argument) /**< the argument for resolve */
{
return ecma_builtin_promise_reject_or_resolve (this_arg, argument, true);
return ecma_promise_reject_or_resolve (this_arg, argument, true);
} /* ecma_builtin_promise_resolve */
/**
@@ -720,6 +720,85 @@ ecma_promise_new_capability (ecma_value_t constructor)
return ecma_make_object_value (capability_p);
} /* ecma_promise_new_capability */
/**
* The common function for 'reject' and 'resolve'.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argument */
ecma_value_t value, /**< rejected or resolved value */
bool is_resolve) /**< the operation is resolve */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not an object."));
}
if (is_resolve
&& ecma_is_value_object (value)
&& ecma_is_promise (ecma_get_object_from_value (value)))
{
ecma_object_t *object_p = ecma_get_object_from_value (value);
ecma_value_t constructor = ecma_op_object_get_by_magic_id (object_p, LIT_MAGIC_STRING_CONSTRUCTOR);
if (ECMA_IS_VALUE_ERROR (constructor))
{
return constructor;
}
/* The this_arg must be an object. */
bool is_same_value = (constructor == this_arg);
ecma_free_value (constructor);
if (is_same_value)
{
return ecma_copy_value (value);
}
}
ecma_value_t capability = ecma_promise_new_capability (this_arg);
if (ECMA_IS_VALUE_ERROR (capability))
{
return capability;
}
ecma_string_t *property_str_p;
if (is_resolve)
{
property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
}
else
{
property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
}
ecma_value_t func = ecma_op_object_get (ecma_get_object_from_value (capability), property_str_p);
ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (func),
ECMA_VALUE_UNDEFINED,
&value,
1);
ecma_free_value (func);
if (ECMA_IS_VALUE_ERROR (call_ret))
{
return call_ret;
}
ecma_free_value (call_ret);
ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
ecma_value_t promise = ecma_op_object_get (ecma_get_object_from_value (capability), promise_str_p);
ecma_free_value (capability);
return promise;
} /* ecma_promise_reject_or_resolve */
/**
* It performs the "then" operation on promiFulfilled
* and onRejected as its settlement actions.
@@ -69,17 +69,13 @@ typedef struct
} ecma_promise_object_t;
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_promise_executor_type_t type);
uint8_t ecma_promise_get_state (ecma_object_t *promise_p);
ecma_value_t ecma_promise_get_result (ecma_object_t *promise_p);
ecma_value_t ecma_promise_new_capability (ecma_value_t constructor);
ecma_value_t
ecma_promise_then (ecma_value_t promise,
ecma_value_t on_fulfilled,
ecma_value_t on_rejected);
ecma_promise_resolving_functions_t *
ecma_promise_create_resolving_functions (ecma_object_t *object_p);
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);
ecma_promise_resolving_functions_t *ecma_promise_create_resolving_functions (ecma_object_t *object_p);
void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs);
/**