Optimize ecma_op_function_call (#4817)
Remove redundant isCallable checks JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik robert.fancsik@h-lab.eu
This commit is contained in:
+28
-78
@@ -4080,61 +4080,6 @@ jerry_property_descriptor_free (const jerry_property_descriptor_t *prop_desc_p)
|
||||
}
|
||||
} /* jerry_property_descriptor_free */
|
||||
|
||||
/**
|
||||
* Invoke function specified by a function value
|
||||
*
|
||||
* Note:
|
||||
* - returned value must be freed with jerry_release_value, when it is no longer needed.
|
||||
* - If function is invoked as constructor, it should support [[Construct]] method,
|
||||
* otherwise, if function is simply called - it should support [[Call]] method.
|
||||
*
|
||||
* @return returned jerry value of the invoked function
|
||||
*/
|
||||
static jerry_value_t
|
||||
jerry_invoke_function (bool is_invoke_as_constructor, /**< true - invoke function as constructor
|
||||
* (this_arg_p should be NULL, as it is ignored),
|
||||
* false - perform function call */
|
||||
const jerry_value_t func_obj_val, /**< function object to call */
|
||||
const jerry_value_t this_val, /**< object value of 'this' binding */
|
||||
const jerry_value_t args_p[], /**< function's call arguments */
|
||||
const jerry_size_t args_count) /**< number of the arguments */
|
||||
{
|
||||
JERRY_ASSERT (args_count == 0 || args_p != NULL);
|
||||
|
||||
if (ecma_is_value_error_reference (func_obj_val)
|
||||
|| ecma_is_value_error_reference (this_val))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < args_count; i++)
|
||||
{
|
||||
if (ecma_is_value_error_reference (args_p[i]))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_invoke_as_constructor)
|
||||
{
|
||||
JERRY_ASSERT (jerry_value_is_constructor (func_obj_val));
|
||||
|
||||
return jerry_return (ecma_op_function_construct (ecma_get_object_from_value (func_obj_val),
|
||||
ecma_get_object_from_value (func_obj_val),
|
||||
args_p,
|
||||
args_count));
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (jerry_value_is_function (func_obj_val));
|
||||
|
||||
return jerry_return (ecma_op_function_call (ecma_get_object_from_value (func_obj_val),
|
||||
this_val,
|
||||
args_p,
|
||||
args_count));
|
||||
}
|
||||
} /* jerry_invoke_function */
|
||||
|
||||
/**
|
||||
* Call function specified by a function value
|
||||
*
|
||||
@@ -4152,20 +4097,23 @@ jerry_call_function (const jerry_value_t func_obj_val, /**< function object to c
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (jerry_value_is_function (func_obj_val) && !ecma_is_value_error_reference (this_val))
|
||||
if (ecma_is_value_error_reference (this_val))
|
||||
{
|
||||
for (jerry_size_t i = 0; i < args_count; i++)
|
||||
{
|
||||
if (ecma_is_value_error_reference (args_p[i]))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
}
|
||||
|
||||
return jerry_invoke_function (false, func_obj_val, this_val, args_p, args_count);
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
|
||||
for (jerry_size_t i = 0; i < args_count; i++)
|
||||
{
|
||||
if (ecma_is_value_error_reference (args_p[i]))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
}
|
||||
|
||||
return jerry_return (ecma_op_function_validated_call (func_obj_val,
|
||||
this_val,
|
||||
args_p,
|
||||
args_count));
|
||||
} /* jerry_call_function */
|
||||
|
||||
/**
|
||||
@@ -4185,21 +4133,23 @@ jerry_construct_object (const jerry_value_t func_obj_val, /**< function object t
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (jerry_value_is_constructor (func_obj_val))
|
||||
if (!jerry_value_is_constructor (func_obj_val))
|
||||
{
|
||||
for (jerry_size_t i = 0; i < args_count; i++)
|
||||
{
|
||||
if (ecma_is_value_error_reference (args_p[i]))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_t this_val = ECMA_VALUE_UNDEFINED;
|
||||
return jerry_invoke_function (true, func_obj_val, this_val, args_p, args_count);
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p)));
|
||||
for (jerry_size_t i = 0; i < args_count; i++)
|
||||
{
|
||||
if (ecma_is_value_error_reference (args_p[i]))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_value_msg_p)));
|
||||
}
|
||||
}
|
||||
|
||||
return jerry_return (ecma_op_function_construct (ecma_get_object_from_value (func_obj_val),
|
||||
ecma_get_object_from_value (func_obj_val),
|
||||
args_p,
|
||||
args_count));
|
||||
} /* jerry_construct_object */
|
||||
|
||||
/**
|
||||
|
||||
@@ -241,19 +241,8 @@ ecma_builtin_async_from_sync_iterator_prototype_do (ecma_async_from_sync_iterato
|
||||
}
|
||||
|
||||
/* 8. */
|
||||
ecma_value_t call_result;
|
||||
|
||||
if (!ecma_op_is_callable (method))
|
||||
{
|
||||
ecma_free_value (method);
|
||||
call_result = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_expected_a_function));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *method_func_obj = ecma_get_object_from_value (method);
|
||||
call_result = ecma_op_function_call (method_func_obj, sync_iterator, &call_arg, arg_size);
|
||||
ecma_deref_object (method_func_obj);
|
||||
}
|
||||
ecma_value_t call_result = ecma_op_function_validated_call (method, sync_iterator, &call_arg, arg_size);
|
||||
ecma_free_value (method);
|
||||
|
||||
/* 9. */
|
||||
if (ECMA_IS_VALUE_ERROR (ecma_op_if_abrupt_reject_promise (&call_result, capability_obj_p)))
|
||||
|
||||
@@ -584,18 +584,10 @@ ecma_builtin_string_prototype_object_replace_helper (ecma_value_t this_value, /*
|
||||
|
||||
if (!ecma_is_value_undefined (replace_symbol) && !ecma_is_value_null (replace_symbol))
|
||||
{
|
||||
if (!ecma_op_is_callable (replace_symbol))
|
||||
{
|
||||
ecma_free_value (replace_symbol);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("@@replace is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *replace_method = ecma_get_object_from_value (replace_symbol);
|
||||
|
||||
ecma_value_t arguments[] = { this_value, replace_value };
|
||||
ecma_value_t replace_result = ecma_op_function_call (replace_method, search_value, arguments, 2);
|
||||
ecma_value_t replace_result = ecma_op_function_validated_call (replace_symbol, search_value, arguments, 2);
|
||||
ecma_free_value (replace_symbol);
|
||||
|
||||
ecma_deref_object (replace_method);
|
||||
return replace_result;
|
||||
}
|
||||
}
|
||||
@@ -800,16 +792,8 @@ ecma_builtin_string_prototype_object_search (ecma_value_t this_value, /**< this
|
||||
|
||||
if (!ecma_is_value_undefined (search_symbol) && !ecma_is_value_null (search_symbol))
|
||||
{
|
||||
if (!ecma_op_is_callable (search_symbol))
|
||||
{
|
||||
ecma_free_value (search_symbol);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("@@search is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *search_method = ecma_get_object_from_value (search_symbol);
|
||||
ecma_value_t search_result = ecma_op_function_call (search_method, regexp_value, &this_value, 1);
|
||||
|
||||
ecma_deref_object (search_method);
|
||||
ecma_value_t search_result = ecma_op_function_validated_call (search_symbol, regexp_value, &this_value, 1);
|
||||
ecma_free_value (search_symbol);
|
||||
return search_result;
|
||||
}
|
||||
}
|
||||
@@ -977,18 +961,10 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_value, /**< this a
|
||||
|
||||
if (!ecma_is_value_undefined (split_symbol) && !ecma_is_value_null (split_symbol))
|
||||
{
|
||||
if (!ecma_op_is_callable (split_symbol))
|
||||
{
|
||||
ecma_free_value (split_symbol);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("@@split is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *split_method_p = ecma_get_object_from_value (split_symbol);
|
||||
|
||||
ecma_value_t arguments[] = { this_value, limit_value };
|
||||
ecma_value_t split_result = ecma_op_function_call (split_method_p, separator_value, arguments, 2);
|
||||
ecma_value_t split_result = ecma_op_function_validated_call (split_symbol, separator_value, arguments, 2);
|
||||
ecma_free_value (split_symbol);
|
||||
|
||||
ecma_deref_object (split_method_p);
|
||||
return split_result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,29 +97,21 @@ ecma_async_generator_enqueue (vm_executable_object_t *async_generator_object_p,
|
||||
static ecma_value_t
|
||||
ecma_async_yield_call (ecma_value_t function, /**< function (takes reference) */
|
||||
vm_executable_object_t *async_generator_object_p, /**< async generator */
|
||||
ecma_value_t argument, /**< argument passed to the function */
|
||||
const char *error_msg_p) /**< error message when the function is not callable */
|
||||
ecma_value_t argument) /**< argument passed to the function */
|
||||
{
|
||||
if (!ecma_is_value_object (function) || !ecma_op_is_callable (function))
|
||||
{
|
||||
ecma_free_value (function);
|
||||
return ecma_raise_type_error (error_msg_p);
|
||||
}
|
||||
|
||||
ecma_object_t *return_obj_p = ecma_get_object_from_value (function);
|
||||
ecma_value_t iterator = async_generator_object_p->iterator;
|
||||
ecma_value_t result;
|
||||
|
||||
if (argument == ECMA_VALUE_EMPTY)
|
||||
{
|
||||
result = ecma_op_function_call (return_obj_p, iterator, NULL, 0);
|
||||
result = ecma_op_function_validated_call (function, iterator, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ecma_op_function_call (return_obj_p, iterator, &argument, 1);
|
||||
result = ecma_op_function_validated_call (function, iterator, &argument, 1);
|
||||
}
|
||||
|
||||
ecma_deref_object (return_obj_p);
|
||||
ecma_free_value (function);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
@@ -155,8 +147,7 @@ ecma_async_yield_throw (vm_executable_object_t *async_generator_object_p, /**< a
|
||||
|
||||
result = ecma_async_yield_call (result,
|
||||
async_generator_object_p,
|
||||
ECMA_VALUE_EMPTY,
|
||||
ECMA_ERR_MSG ("Iterator 'return' is not callable"));
|
||||
ECMA_VALUE_EMPTY);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
@@ -169,8 +160,7 @@ ecma_async_yield_throw (vm_executable_object_t *async_generator_object_p, /**< a
|
||||
|
||||
result = ecma_async_yield_call (result,
|
||||
async_generator_object_p,
|
||||
value,
|
||||
ECMA_ERR_MSG ("Iterator 'throw' is not callable"));
|
||||
value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
@@ -419,8 +409,7 @@ ecma_await_continue (vm_executable_object_t *executable_object_p, /**< executabl
|
||||
|
||||
result = ecma_async_yield_call (result,
|
||||
executable_object_p,
|
||||
value,
|
||||
ECMA_ERR_MSG ("Iterator 'return' is not callable"));
|
||||
value);
|
||||
ecma_free_value (value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
|
||||
@@ -90,6 +90,23 @@ ecma_op_function_form_name (ecma_string_t *prop_name_p, /**< property name */
|
||||
} /* ecma_op_function_form_name */
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
/**
|
||||
* IsCallable operation for proxy object.
|
||||
*
|
||||
* @return true - if the given proxy object is callable;
|
||||
* false - otherwise
|
||||
*/
|
||||
extern inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_proxy_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
|
||||
return (obj_p->u2.prototype_cp & ECMA_PROXY_IS_CALLABLE) != 0;
|
||||
} /* ecma_op_proxy_object_is_callable */
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
/**
|
||||
* IsCallable operation.
|
||||
*
|
||||
@@ -108,7 +125,7 @@ ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
if (ECMA_OBJECT_TYPE_IS_PROXY (type))
|
||||
{
|
||||
return (obj_p->u2.prototype_cp & ECMA_PROXY_IS_CALLABLE) != 0;
|
||||
return ecma_op_proxy_object_is_callable (obj_p);
|
||||
}
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
@@ -1022,6 +1039,76 @@ ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< construc
|
||||
return proto_obj_p;
|
||||
} /* ecma_op_get_prototype_from_constructor */
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
/**
|
||||
* Perform a JavaScript class function object method call.
|
||||
*
|
||||
* The input function object should be a JavaScript class constructor
|
||||
*
|
||||
* @return the result of the function call.
|
||||
*/
|
||||
static ecma_value_t JERRY_ATTR_NOINLINE
|
||||
ecma_op_function_call_constructor (vm_frame_ctx_shared_args_t *shared_args_p, /**< shared data */
|
||||
ecma_object_t *scope_p, /**< lexical environment to use */
|
||||
ecma_value_t this_binding) /**< value of 'ThisBinding' */
|
||||
{
|
||||
shared_args_p->header.status_flags |= VM_FRAME_CTX_SHARED_NON_ARROW_FUNC;
|
||||
|
||||
ecma_value_t ret_value;
|
||||
|
||||
if (JERRY_CONTEXT (current_new_target_p) == NULL)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor requires 'new'"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) shared_args_p->header.function_object_p;
|
||||
if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
|
||||
{
|
||||
this_binding = ECMA_VALUE_UNINITIALIZED;
|
||||
}
|
||||
|
||||
ecma_op_create_environment_record (scope_p, this_binding, shared_args_p->header.function_object_p);
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
|
||||
JERRY_CONTEXT (global_object_p) = ecma_op_function_get_realm (shared_args_p->header.bytecode_header_p);
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
|
||||
ret_value = vm_run (&shared_args_p->header, this_binding, scope_p);
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
JERRY_CONTEXT (global_object_p) = saved_global_object_p;
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
|
||||
/* ECMAScript v6, 9.2.2.13 */
|
||||
if (JERRY_UNLIKELY (this_binding == ECMA_VALUE_UNINITIALIZED))
|
||||
{
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value) && !ecma_is_value_object (ret_value))
|
||||
{
|
||||
if (!ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ecma_free_value (ret_value);
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only return object or undefined"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_op_get_this_binding (scope_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if (JERRY_UNLIKELY (shared_args_p->header.status_flags & VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV))
|
||||
{
|
||||
ecma_deref_object (scope_p);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_function_call_constructor */
|
||||
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
/**
|
||||
* Perform a JavaScript function object method call.
|
||||
*
|
||||
@@ -1031,7 +1118,7 @@ ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< construc
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t this_arg_value, /**< 'this' argument's value */
|
||||
ecma_value_t this_binding, /**< 'this' argument's value */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
uint32_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
@@ -1050,8 +1137,6 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ext_func_p->u.function.scope_cp);
|
||||
|
||||
/* 8. */
|
||||
ecma_value_t this_binding = this_arg_value;
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
|
||||
uint16_t status_flags = bytecode_data_p->status_flags;
|
||||
|
||||
@@ -1061,29 +1146,50 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_global_object_t *realm_p = ecma_op_function_get_realm (bytecode_data_p);
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
|
||||
/* 1. */
|
||||
#if JERRY_ESNEXT
|
||||
if (JERRY_UNLIKELY (CBC_FUNCTION_IS_ARROW (status_flags)))
|
||||
/* 5. */
|
||||
if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
|
||||
{
|
||||
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
||||
|
||||
if (ecma_is_value_undefined (arrow_func_p->new_target))
|
||||
{
|
||||
JERRY_CONTEXT (current_new_target_p) = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_CONTEXT (current_new_target_p) = ecma_get_object_from_value (arrow_func_p->new_target);
|
||||
}
|
||||
this_binding = arrow_func_p->this_binding;
|
||||
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV;
|
||||
scope_p = ecma_create_decl_lex_env (scope_p);
|
||||
}
|
||||
else
|
||||
|
||||
/* 1. */
|
||||
switch (CBC_FUNCTION_GET_TYPE (status_flags))
|
||||
{
|
||||
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_NON_ARROW_FUNC;
|
||||
#if JERRY_ESNEXT
|
||||
case CBC_FUNCTION_CONSTRUCTOR:
|
||||
{
|
||||
return ecma_op_function_call_constructor (&shared_args, scope_p, this_binding);
|
||||
}
|
||||
case CBC_FUNCTION_ARROW:
|
||||
{
|
||||
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
||||
|
||||
if (ecma_is_value_undefined (arrow_func_p->new_target))
|
||||
{
|
||||
JERRY_CONTEXT (current_new_target_p) = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_CONTEXT (current_new_target_p) = ecma_get_object_from_value (arrow_func_p->new_target);
|
||||
}
|
||||
|
||||
this_binding = arrow_func_p->this_binding;
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* JERRY_ESNEXT */
|
||||
default:
|
||||
{
|
||||
#if JERRY_ESNEXT
|
||||
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_NON_ARROW_FUNC;
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
|
||||
{
|
||||
if (status_flags & CBC_CODE_FLAGS_STRICT_MODE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (ecma_is_value_undefined (this_binding)
|
||||
|| ecma_is_value_null (this_binding))
|
||||
{
|
||||
@@ -1102,73 +1208,21 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if JERRY_ESNEXT
|
||||
}
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
/* 5. */
|
||||
if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
|
||||
{
|
||||
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV;
|
||||
scope_p = ecma_create_decl_lex_env (scope_p);
|
||||
}
|
||||
|
||||
ecma_value_t ret_value;
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
if (JERRY_UNLIKELY (CBC_FUNCTION_GET_TYPE (status_flags) == CBC_FUNCTION_CONSTRUCTOR))
|
||||
{
|
||||
if (JERRY_CONTEXT (current_new_target_p) == NULL)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor requires 'new'"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ecma_value_t lexical_this = this_binding;
|
||||
|
||||
if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
|
||||
{
|
||||
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_HERITAGE_PRESENT;
|
||||
lexical_this = ECMA_VALUE_UNINITIALIZED;
|
||||
}
|
||||
|
||||
ecma_op_create_environment_record (scope_p, lexical_this, func_obj_p);
|
||||
}
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
|
||||
JERRY_CONTEXT (global_object_p) = realm_p;
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
|
||||
ret_value = vm_run (&shared_args.header, this_binding, scope_p);
|
||||
ecma_value_t ret_value = vm_run (&shared_args.header, this_binding, scope_p);
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
JERRY_CONTEXT (global_object_p) = saved_global_object_p;
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
/* ECMAScript v6, 9.2.2.13 */
|
||||
if (JERRY_UNLIKELY (shared_args.header.status_flags & VM_FRAME_CTX_SHARED_HERITAGE_PRESENT))
|
||||
{
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value) && !ecma_is_value_object (ret_value))
|
||||
{
|
||||
if (!ecma_is_value_undefined (ret_value))
|
||||
{
|
||||
ecma_free_value (ret_value);
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only return object or undefined"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_op_get_this_binding (scope_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
if (JERRY_UNLIKELY (shared_args.header.status_flags & VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV))
|
||||
{
|
||||
ecma_deref_object (scope_p);
|
||||
@@ -1350,11 +1404,30 @@ ecma_op_function_call_bound (ecma_object_t *func_obj_p, /**< Function object */
|
||||
} /* ecma_op_function_call_bound */
|
||||
|
||||
/**
|
||||
* [[Call]] implementation for Function objects,
|
||||
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
|
||||
* or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
|
||||
* and for built-in Function objects
|
||||
* from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
|
||||
* General [[Call]] implementation
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_function_validated_call (ecma_value_t callee, /**< callee */
|
||||
ecma_value_t this_arg_value, /**< 'this' argument's value */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
uint32_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
if (!ecma_is_value_object (callee))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_expected_a_function));
|
||||
}
|
||||
|
||||
return ecma_op_function_call (ecma_get_object_from_value (callee),
|
||||
this_arg_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
} /* ecma_op_function_validated_call */
|
||||
|
||||
/**
|
||||
* General [[Call]] implementation
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
@@ -1367,21 +1440,12 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
{
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
JERRY_ASSERT (ecma_op_object_is_callable (func_obj_p));
|
||||
|
||||
ECMA_CHECK_STACK_USAGE ();
|
||||
|
||||
const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
|
||||
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
if (ECMA_OBJECT_TYPE_IS_PROXY (type))
|
||||
{
|
||||
return ecma_proxy_object_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target_p);
|
||||
|
||||
if (JERRY_UNLIKELY (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_DIRECT_EVAL)))
|
||||
{
|
||||
JERRY_CONTEXT (current_new_target_p) = NULL;
|
||||
@@ -1390,27 +1454,47 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
|
||||
ecma_value_t result;
|
||||
|
||||
if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
|
||||
switch (ecma_get_object_type (func_obj_p))
|
||||
{
|
||||
result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
else if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
|
||||
{
|
||||
result = ecma_op_function_call_native_built_in (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
|
||||
{
|
||||
result = ecma_op_function_call_native (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
|
||||
{
|
||||
result = ecma_op_function_call_native_built_in (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
break;
|
||||
}
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
result = ecma_proxy_object_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
break;
|
||||
}
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
#if JERRY_ESNEXT
|
||||
else if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION))
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_class_constructor_new));
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION:
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_class_constructor_new));
|
||||
break;
|
||||
}
|
||||
#endif /* JERRY_ESNEXT */
|
||||
else
|
||||
{
|
||||
result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
|
||||
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
|
||||
{
|
||||
result = ecma_op_function_call_native (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_expected_a_function));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
@@ -1704,39 +1788,43 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
|
||||
const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
|
||||
|
||||
if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
|
||||
switch (ecma_get_object_type (func_obj_p))
|
||||
{
|
||||
return ecma_op_function_construct_simple (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
|
||||
if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
|
||||
{
|
||||
return ecma_op_function_construct_built_in (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
return ecma_op_function_construct_simple (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
|
||||
{
|
||||
return ecma_op_function_construct_built_in (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
if (ECMA_OBJECT_TYPE_IS_PROXY (type))
|
||||
{
|
||||
return ecma_proxy_object_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
return ecma_proxy_object_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
|
||||
{
|
||||
return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
if (type == ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION)
|
||||
{
|
||||
return ecma_op_function_construct_constructor (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_CONSTRUCTOR_FUNCTION:
|
||||
{
|
||||
return ecma_op_function_construct_constructor (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
#endif /* JERRY_ESNEXT */
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
|
||||
{
|
||||
return ecma_op_function_construct_native (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
|
||||
return ecma_op_function_construct_native (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
} /* ecma_op_function_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,9 @@ ecma_value_t ecma_op_function_form_name (ecma_string_t *prop_name_p, char *prefi
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
bool ecma_op_is_callable (ecma_value_t value);
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
bool ecma_op_proxy_object_is_callable (ecma_object_t *obj_p);
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
bool ecma_op_object_is_callable (ecma_object_t *obj_p);
|
||||
bool ecma_is_constructor (ecma_value_t value);
|
||||
bool ecma_object_is_constructor (ecma_object_t *obj_p);
|
||||
@@ -91,6 +94,10 @@ ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, ecma_builtin_
|
||||
ecma_value_t
|
||||
ecma_op_function_has_instance (ecma_object_t *func_obj_p, ecma_value_t value);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_function_validated_call (ecma_value_t callee, ecma_value_t this_arg_value,
|
||||
const ecma_value_t *arguments_list_p, uint32_t arguments_list_len);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_function_call (ecma_object_t *func_obj_p, ecma_value_t this_arg_value,
|
||||
const ecma_value_t *arguments_list_p, uint32_t arguments_list_len);
|
||||
|
||||
@@ -248,18 +248,11 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */
|
||||
}
|
||||
|
||||
/* 3. */
|
||||
if (!ecma_op_is_callable (method))
|
||||
{
|
||||
ecma_free_value (method);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator is not function"));
|
||||
}
|
||||
|
||||
ecma_object_t *method_obj_p = ecma_get_object_from_value (method);
|
||||
ecma_value_t iterator = ecma_op_function_call (method_obj_p, value, NULL, 0);
|
||||
ecma_value_t iterator = ecma_op_function_validated_call (method, value, NULL, 0);
|
||||
|
||||
if (use_default_method)
|
||||
{
|
||||
ecma_deref_object (method_obj_p);
|
||||
ecma_free_value (method);
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
@@ -284,7 +277,7 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */
|
||||
return next_method;
|
||||
}
|
||||
|
||||
if (ecma_is_value_object (next_method) && ecma_op_is_callable (next_method))
|
||||
if (ecma_op_is_callable (next_method))
|
||||
{
|
||||
*next_method_p = next_method;
|
||||
}
|
||||
@@ -363,15 +356,7 @@ ecma_op_iterator_return (ecma_value_t iterator, /**< iterator value */
|
||||
return ecma_create_iter_result_object (value, ECMA_VALUE_TRUE);
|
||||
}
|
||||
|
||||
if (!ecma_op_is_callable (func_return))
|
||||
{
|
||||
ecma_free_value (func_return);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *return_obj_p = ecma_get_object_from_value (func_return);
|
||||
|
||||
ecma_value_t result = ecma_op_function_call (return_obj_p, iterator, &value, 1);
|
||||
ecma_value_t result = ecma_op_function_validated_call (func_return, iterator, &value, 1);
|
||||
ecma_free_value (func_return);
|
||||
|
||||
return result;
|
||||
@@ -415,15 +400,7 @@ ecma_op_iterator_throw (ecma_value_t iterator, /**< iterator value */
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'throw' is not available"));
|
||||
}
|
||||
|
||||
if (!ecma_is_value_object (func_throw) || !ecma_op_is_callable (func_throw))
|
||||
{
|
||||
ecma_free_value (func_throw);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'throw' is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *return_obj_p = ecma_get_object_from_value (func_throw);
|
||||
|
||||
ecma_value_t result = ecma_op_function_call (return_obj_p, iterator, &value, 1);
|
||||
ecma_value_t result = ecma_op_function_validated_call (func_throw, iterator, &value, 1);
|
||||
ecma_free_value (func_throw);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3296,18 +3296,10 @@ ecma_op_invoke (ecma_value_t object, /**< Object value */
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
if (!ecma_op_is_callable (func))
|
||||
{
|
||||
ecma_free_value (func);
|
||||
ecma_deref_object (object_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not callable"));
|
||||
}
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (func);
|
||||
ecma_value_t call_result = ecma_op_function_call (func_obj_p, this_arg, args_p, args_len);
|
||||
ecma_value_t call_result = ecma_op_function_validated_call (func, this_arg, args_p, args_len);
|
||||
ecma_free_value (func);
|
||||
|
||||
ecma_deref_object (object_p);
|
||||
ecma_deref_object (func_obj_p);
|
||||
|
||||
return call_result;
|
||||
} /* ecma_op_invoke */
|
||||
|
||||
@@ -1771,6 +1771,12 @@ ecma_proxy_object_call (ecma_object_t *obj_p, /**< proxy object */
|
||||
uint32_t argc) /**< number of arguments */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
|
||||
if (!ecma_op_proxy_object_is_callable (obj_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_expected_a_function));
|
||||
}
|
||||
|
||||
ECMA_CHECK_STACK_USAGE ();
|
||||
|
||||
ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
|
||||
|
||||
+35
-43
@@ -380,58 +380,50 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result) && !ecma_is_value_undefined (result))
|
||||
{
|
||||
if (!ecma_op_is_callable (result))
|
||||
ecma_object_t *return_obj_p = ecma_get_object_from_value (result);
|
||||
result = ecma_op_function_validated_call (result, iterator, NULL, 0);
|
||||
ecma_deref_object (return_obj_p);
|
||||
|
||||
if (context_type == VM_CONTEXT_FOR_AWAIT_OF && !ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
ecma_free_value (result);
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' is not callable"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *return_obj_p = ecma_get_object_from_value (result);
|
||||
result = ecma_op_function_call (return_obj_p, iterator, NULL, 0);
|
||||
ecma_deref_object (return_obj_p);
|
||||
ecma_extended_object_t *async_generator_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p);
|
||||
|
||||
if (context_type == VM_CONTEXT_FOR_AWAIT_OF && !ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
ecma_extended_object_t *async_generator_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p);
|
||||
|
||||
result = ecma_promise_async_await (async_generator_object_p, result);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD
|
||||
| (ECMA_AWAIT_FOR_CLOSE << ECMA_AWAIT_STATE_SHIFT));
|
||||
async_generator_object_p->u.cls.u2.executable_obj_flags |= extra_flags;
|
||||
|
||||
stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p);
|
||||
|
||||
VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FINALLY_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p += PARSER_FINALLY_CONTEXT_STACK_ALLOCATION;
|
||||
|
||||
stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, context_end);
|
||||
if (finally_type == VM_CONTEXT_FINALLY_THROW)
|
||||
{
|
||||
stack_top_p[-2] = exception;
|
||||
}
|
||||
|
||||
frame_ctx_p->call_operation = VM_EXEC_RETURN;
|
||||
frame_ctx_p->byte_code_p = vm_stack_resume_executable_object_with_context_end;
|
||||
frame_ctx_p->stack_top_p = stack_top_p;
|
||||
return VM_CONTEXT_FOUND_AWAIT;
|
||||
}
|
||||
}
|
||||
result = ecma_promise_async_await (async_generator_object_p, result);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
bool is_object = ecma_is_value_object (result);
|
||||
uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD
|
||||
| (ECMA_AWAIT_FOR_CLOSE << ECMA_AWAIT_STATE_SHIFT));
|
||||
async_generator_object_p->u.cls.u2.executable_obj_flags |= extra_flags;
|
||||
|
||||
ecma_free_value (result);
|
||||
result = ECMA_VALUE_UNDEFINED;
|
||||
stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p);
|
||||
|
||||
if (!is_object)
|
||||
VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FINALLY_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p += PARSER_FINALLY_CONTEXT_STACK_ALLOCATION;
|
||||
|
||||
stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, context_end);
|
||||
if (finally_type == VM_CONTEXT_FINALLY_THROW)
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' result is not object"));
|
||||
stack_top_p[-2] = exception;
|
||||
}
|
||||
|
||||
frame_ctx_p->call_operation = VM_EXEC_RETURN;
|
||||
frame_ctx_p->byte_code_p = vm_stack_resume_executable_object_with_context_end;
|
||||
frame_ctx_p->stack_top_p = stack_top_p;
|
||||
return VM_CONTEXT_FOUND_AWAIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
bool is_object = ecma_is_value_object (result);
|
||||
|
||||
ecma_free_value (result);
|
||||
result = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
if (!is_object)
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' result is not object"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-15
@@ -788,22 +788,11 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len;
|
||||
ecma_value_t this_value = is_call_prop ? stack_top_p[-3] : ECMA_VALUE_UNDEFINED;
|
||||
ecma_value_t func_value = stack_top_p[-1];
|
||||
ecma_value_t completion_value;
|
||||
|
||||
if (!ecma_is_value_object (func_value)
|
||||
|| !ecma_op_object_is_callable (ecma_get_object_from_value (func_value)))
|
||||
{
|
||||
completion_value = ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_expected_a_function));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value);
|
||||
|
||||
completion_value = ecma_op_function_call (func_obj_p,
|
||||
this_value,
|
||||
stack_top_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
ecma_value_t completion_value = ecma_op_function_validated_call (func_value,
|
||||
this_value,
|
||||
stack_top_p,
|
||||
arguments_list_len);
|
||||
|
||||
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user