Rework frame context (#4200)
A new shared frame context data is created which allows sharing data between the function call and vm main loop. Furthermore rest arguments and current function object handling is reworked. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -4055,7 +4055,7 @@ jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
|
|||||||
{
|
{
|
||||||
if (JERRY_CONTEXT (vm_top_context_p) != NULL)
|
if (JERRY_CONTEXT (vm_top_context_p) != NULL)
|
||||||
{
|
{
|
||||||
return ecma_copy_value (ecma_get_resource_name (JERRY_CONTEXT (vm_top_context_p)->bytecode_header_p));
|
return ecma_copy_value (ecma_get_resource_name (JERRY_CONTEXT (vm_top_context_p)->shared_p->bytecode_header_p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ecma_is_value_object (value))
|
else if (ecma_is_value_object (value))
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the
|
|||||||
uint32_t frame_count = 0;
|
uint32_t frame_count = 0;
|
||||||
while (iter_frame_ctx_p != NULL)
|
while (iter_frame_ctx_p != NULL)
|
||||||
{
|
{
|
||||||
if (!(iter_frame_ctx_p->bytecode_header_p->status_flags & (CBC_CODE_FLAGS_STATIC_FUNCTION)))
|
if (!(iter_frame_ctx_p->shared_p->bytecode_header_p->status_flags & (CBC_CODE_FLAGS_STATIC_FUNCTION)))
|
||||||
{
|
{
|
||||||
frame_count++;
|
frame_count++;
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the
|
|||||||
|
|
||||||
while (frame_ctx_p != NULL && min_depth_offset++ < max_depth)
|
while (frame_ctx_p != NULL && min_depth_offset++ < max_depth)
|
||||||
{
|
{
|
||||||
if (frame_ctx_p->bytecode_header_p->status_flags
|
if (frame_ctx_p->shared_p->bytecode_header_p->status_flags
|
||||||
& (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
|
& (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
|
||||||
{
|
{
|
||||||
frame_ctx_p = frame_ctx_p->prev_context_p;
|
frame_ctx_p = frame_ctx_p->prev_context_p;
|
||||||
@@ -183,10 +183,10 @@ jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the
|
|||||||
jerry_debugger_frame_t *frame_p = backtrace_p->frames + current_frame;
|
jerry_debugger_frame_t *frame_p = backtrace_p->frames + current_frame;
|
||||||
|
|
||||||
jmem_cpointer_t byte_code_cp;
|
jmem_cpointer_t byte_code_cp;
|
||||||
JMEM_CP_SET_NON_NULL_POINTER (byte_code_cp, frame_ctx_p->bytecode_header_p);
|
JMEM_CP_SET_NON_NULL_POINTER (byte_code_cp, frame_ctx_p->shared_p->bytecode_header_p);
|
||||||
memcpy (frame_p->byte_code_cp, &byte_code_cp, sizeof (jmem_cpointer_t));
|
memcpy (frame_p->byte_code_cp, &byte_code_cp, sizeof (jmem_cpointer_t));
|
||||||
|
|
||||||
uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p);
|
uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->shared_p->bytecode_header_p);
|
||||||
memcpy (frame_p->offset, &offset, sizeof (uint32_t));
|
memcpy (frame_p->offset, &offset, sizeof (uint32_t));
|
||||||
|
|
||||||
frame_ctx_p = frame_ctx_p->prev_context_p;
|
frame_ctx_p = frame_ctx_p->prev_context_p;
|
||||||
@@ -1167,10 +1167,10 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
|
|||||||
vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
|
vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
|
||||||
|
|
||||||
jmem_cpointer_t byte_code_header_cp;
|
jmem_cpointer_t byte_code_header_cp;
|
||||||
JMEM_CP_SET_NON_NULL_POINTER (byte_code_header_cp, frame_ctx_p->bytecode_header_p);
|
JMEM_CP_SET_NON_NULL_POINTER (byte_code_header_cp, frame_ctx_p->shared_p->bytecode_header_p);
|
||||||
memcpy (breakpoint_hit_p->byte_code_cp, &byte_code_header_cp, sizeof (jmem_cpointer_t));
|
memcpy (breakpoint_hit_p->byte_code_cp, &byte_code_header_cp, sizeof (jmem_cpointer_t));
|
||||||
|
|
||||||
uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p);
|
uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->shared_p->bytecode_header_p);
|
||||||
memcpy (breakpoint_hit_p->offset, &offset, sizeof (uint32_t));
|
memcpy (breakpoint_hit_p->offset, &offset, sizeof (uint32_t));
|
||||||
|
|
||||||
if (!jerry_debugger_send (sizeof (jerry_debugger_send_breakpoint_hit_t)))
|
if (!jerry_debugger_send (sizeof (jerry_debugger_send_breakpoint_hit_t)))
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ ecma_gc_mark_executable_object (ecma_object_t *object_p) /**< object */
|
|||||||
ecma_gc_set_object_visited (ecma_get_object_from_value (executable_object_p->frame_ctx.this_binding));
|
ecma_gc_set_object_visited (ecma_get_object_from_value (executable_object_p->frame_ctx.this_binding));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->frame_ctx.bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->shared.bytecode_header_p;
|
||||||
size_t register_end;
|
size_t register_end;
|
||||||
|
|
||||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
@@ -953,7 +953,7 @@ ecma_gc_free_executable_object (ecma_object_t *object_p) /**< object */
|
|||||||
{
|
{
|
||||||
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
|
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->frame_ctx.bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->shared.bytecode_header_p;
|
||||||
size_t size, register_end;
|
size_t size, register_end;
|
||||||
|
|
||||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ ecma_init (void)
|
|||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
JERRY_CONTEXT (current_new_target) = NULL;
|
JERRY_CONTEXT (current_new_target) = NULL;
|
||||||
JERRY_CONTEXT (current_function_obj_p) = NULL;
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
} /* ecma_init */
|
} /* ecma_init */
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ ecma_finalize (void)
|
|||||||
{
|
{
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
JERRY_ASSERT (JERRY_CONTEXT (current_new_target) == NULL);
|
JERRY_ASSERT (JERRY_CONTEXT (current_new_target) == NULL);
|
||||||
JERRY_ASSERT (JERRY_CONTEXT (current_function_obj_p) == NULL);
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
ecma_finalize_global_environment ();
|
ecma_finalize_global_environment ();
|
||||||
|
|||||||
@@ -878,6 +878,14 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
return ecma_builtin_dispatch_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
return ecma_builtin_dispatch_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm_frame_ctx_shared_args_t shared_args;
|
||||||
|
shared_args.header.status_flags = VM_FRAME_CTX_SHARED_HAS_ARG_LIST;
|
||||||
|
shared_args.arg_list_p = arguments_list_p;
|
||||||
|
shared_args.arg_list_len = arguments_list_len;
|
||||||
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
|
shared_args.function_object_p = func_obj_p;
|
||||||
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
|
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
|
||||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
|
||||||
|
|
||||||
@@ -886,25 +894,14 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
|
|
||||||
/* 8. */
|
/* 8. */
|
||||||
ecma_value_t this_binding = this_arg_value;
|
ecma_value_t this_binding = this_arg_value;
|
||||||
bool free_this_binding = false;
|
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
|
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;
|
uint16_t status_flags = bytecode_data_p->status_flags;
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
shared_args.header.bytecode_header_p = bytecode_data_p;
|
||||||
uint16_t function_type = CBC_FUNCTION_GET_TYPE (status_flags);
|
|
||||||
|
|
||||||
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR)
|
|
||||||
&& JERRY_CONTEXT (current_new_target) == NULL)
|
|
||||||
{
|
|
||||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
|
|
||||||
}
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
|
||||||
|
|
||||||
/* 1. */
|
/* 1. */
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
|
|
||||||
|
|
||||||
if (JERRY_UNLIKELY (CBC_FUNCTION_IS_ARROW (status_flags)))
|
if (JERRY_UNLIKELY (CBC_FUNCTION_IS_ARROW (status_flags)))
|
||||||
{
|
{
|
||||||
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
||||||
@@ -921,8 +918,9 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JERRY_CONTEXT (current_function_obj_p) = func_obj_p;
|
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_NON_ARROW_FUNC;
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
|
if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
|
||||||
{
|
{
|
||||||
if (ecma_is_value_undefined (this_binding)
|
if (ecma_is_value_undefined (this_binding)
|
||||||
@@ -935,7 +933,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
{
|
{
|
||||||
/* 3., 4. */
|
/* 3., 4. */
|
||||||
this_binding = ecma_op_to_object (this_binding);
|
this_binding = ecma_op_to_object (this_binding);
|
||||||
free_this_binding = true;
|
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_FREE_THIS;
|
||||||
|
|
||||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
|
||||||
}
|
}
|
||||||
@@ -945,45 +943,45 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
/* 5. */
|
/* 5. */
|
||||||
ecma_object_t *local_env_p;
|
if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
|
||||||
if (status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED)
|
|
||||||
{
|
{
|
||||||
local_env_p = scope_p;
|
shared_args.header.status_flags |= VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV;
|
||||||
|
scope_p = ecma_create_decl_lex_env (scope_p);
|
||||||
|
|
||||||
|
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED))
|
||||||
|
{
|
||||||
|
ecma_op_create_arguments_object (func_obj_p, scope_p, &shared_args);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
local_env_p = ecma_create_decl_lex_env (scope_p);
|
|
||||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED)
|
|
||||||
{
|
|
||||||
ecma_op_create_arguments_object (func_obj_p,
|
|
||||||
local_env_p,
|
|
||||||
arguments_list_p,
|
|
||||||
arguments_list_len,
|
|
||||||
bytecode_data_p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecma_value_t ret_value;
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
// ECMAScript v6, 9.2.2.8
|
if (JERRY_UNLIKELY (CBC_FUNCTION_GET_TYPE (status_flags) == CBC_FUNCTION_CONSTRUCTOR))
|
||||||
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_CONSTRUCTOR))
|
|
||||||
{
|
{
|
||||||
ecma_value_t lexical_this;
|
if (JERRY_CONTEXT (current_new_target) == NULL)
|
||||||
lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
|
{
|
||||||
: this_binding);
|
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
|
||||||
ecma_op_init_this_binding (local_env_p, lexical_this);
|
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_init_this_binding (scope_p, lexical_this);
|
||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
}
|
|
||||||
|
|
||||||
ecma_value_t ret_value = vm_run (bytecode_data_p,
|
ret_value = vm_run (&shared_args.header, this_binding, scope_p);
|
||||||
this_binding,
|
|
||||||
local_env_p,
|
|
||||||
arguments_list_p,
|
|
||||||
arguments_list_len);
|
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
JERRY_CONTEXT (current_function_obj_p) = old_function_object_p;
|
|
||||||
|
|
||||||
/* ECMAScript v6, 9.2.2.13 */
|
/* ECMAScript v6, 9.2.2.13 */
|
||||||
if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
|
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_ERROR (ret_value) && !ecma_is_value_object (ret_value))
|
||||||
{
|
{
|
||||||
@@ -994,19 +992,20 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret_value = ecma_op_get_this_binding (local_env_p);
|
ret_value = ecma_op_get_this_binding (scope_p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
|
if (JERRY_UNLIKELY (shared_args.header.status_flags & VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV))
|
||||||
{
|
{
|
||||||
ecma_deref_object (local_env_p);
|
ecma_deref_object (scope_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JERRY_UNLIKELY (free_this_binding))
|
if (JERRY_UNLIKELY (shared_args.header.status_flags & VM_FRAME_CTX_SHARED_FREE_THIS))
|
||||||
{
|
{
|
||||||
ecma_free_value (this_binding);
|
ecma_free_value (this_binding);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,10 +43,9 @@ void
|
|||||||
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
|
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
|
||||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||||
object is created for */
|
object is created for */
|
||||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
vm_frame_ctx_shared_args_t *shared_p) /**< shared context dta */
|
||||||
uint32_t arguments_number, /**< length of arguments list */
|
|
||||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
|
|
||||||
{
|
{
|
||||||
|
const ecma_compiled_code_t *bytecode_data_p = shared_p->header.bytecode_header_p;
|
||||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||||
|
|
||||||
uint32_t formal_params_number;
|
uint32_t formal_params_number;
|
||||||
@@ -65,8 +64,8 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
|||||||
}
|
}
|
||||||
|
|
||||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||||
|
|
||||||
ecma_object_t *obj_p;
|
ecma_object_t *obj_p;
|
||||||
|
uint32_t arguments_number = shared_p->arg_list_len;
|
||||||
|
|
||||||
if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
|
if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
|
||||||
&& arguments_number > 0
|
&& arguments_number > 0
|
||||||
@@ -125,6 +124,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
|||||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
const ecma_value_t *arguments_list_p = shared_p->arg_list_p;
|
||||||
prop_value_p->value = ecma_copy_value_if_not_object (arguments_list_p[index]);
|
prop_value_p->value = ecma_copy_value_if_not_object (arguments_list_p[index]);
|
||||||
|
|
||||||
ecma_deref_ecma_string (index_string_p);
|
ecma_deref_ecma_string (index_string_p);
|
||||||
|
|||||||
@@ -18,11 +18,11 @@
|
|||||||
|
|
||||||
#include "ecma-globals.h"
|
#include "ecma-globals.h"
|
||||||
#include "ecma-helpers.h"
|
#include "ecma-helpers.h"
|
||||||
|
#include "vm-defines.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, ecma_object_t *lex_env_p,
|
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, ecma_object_t *lex_env_p,
|
||||||
const ecma_value_t *arguments_list_p, uint32_t arguments_number,
|
vm_frame_ctx_shared_args_t *shared_p);
|
||||||
const ecma_compiled_code_t *bytecode_data_p);
|
|
||||||
|
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
ecma_op_arguments_object_delete (ecma_object_t *object_p, ecma_string_t *property_name_p, bool is_throw);
|
ecma_op_arguments_object_delete (ecma_object_t *object_p, ecma_string_t *property_name_p, bool is_throw);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ extern "C"
|
|||||||
/**
|
/**
|
||||||
* Jerry snapshot format version.
|
* Jerry snapshot format version.
|
||||||
*/
|
*/
|
||||||
#define JERRY_SNAPSHOT_VERSION (57u)
|
#define JERRY_SNAPSHOT_VERSION (58u)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
|
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
|
||||||
|
|||||||
@@ -137,9 +137,6 @@ struct jerry_context_t
|
|||||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||||
const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */
|
const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */
|
||||||
const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */
|
const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
|
||||||
ecma_value_t *computed_class_fields_p; /**< names of the computed class fields */
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
|
||||||
jmem_cpointer_t string_list_first_cp; /**< first item of the literal string list */
|
jmem_cpointer_t string_list_first_cp; /**< first item of the literal string list */
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
jmem_cpointer_t symbol_list_first_cp; /**< first item of the global symbol list */
|
jmem_cpointer_t symbol_list_first_cp; /**< first item of the global symbol list */
|
||||||
@@ -233,8 +230,6 @@ struct jerry_context_t
|
|||||||
* * Any other valid function object pointer: the current "new.target" is valid and it is constructor call.
|
* * Any other valid function object pointer: the current "new.target" is valid and it is constructor call.
|
||||||
*/
|
*/
|
||||||
ecma_object_t *current_new_target;
|
ecma_object_t *current_new_target;
|
||||||
ecma_object_t *current_function_obj_p; /** currently invoked function object
|
|
||||||
(Note: currently used only in generator functions) */
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ JERRY_STATIC_ASSERT ((sizeof (cbc_uint16_arguments_t) % sizeof (jmem_cpointer_t)
|
|||||||
*/
|
*/
|
||||||
JERRY_STATIC_ASSERT (CBC_END == 238,
|
JERRY_STATIC_ASSERT (CBC_END == 238,
|
||||||
number_of_cbc_opcodes_changed);
|
number_of_cbc_opcodes_changed);
|
||||||
JERRY_STATIC_ASSERT (CBC_EXT_END == 140,
|
JERRY_STATIC_ASSERT (CBC_EXT_END == 141,
|
||||||
number_of_cbc_ext_opcodes_changed);
|
number_of_cbc_ext_opcodes_changed);
|
||||||
|
|
||||||
#if ENABLED (JERRY_PARSER)
|
#if ENABLED (JERRY_PARSER)
|
||||||
|
|||||||
@@ -594,6 +594,8 @@
|
|||||||
VM_OC_EXT_VAR_EVAL) \
|
VM_OC_EXT_VAR_EVAL) \
|
||||||
CBC_OPCODE (CBC_EXT_COPY_FROM_ARG, CBC_HAS_LITERAL_ARG, 0, \
|
CBC_OPCODE (CBC_EXT_COPY_FROM_ARG, CBC_HAS_LITERAL_ARG, 0, \
|
||||||
VM_OC_COPY_FROM_ARG) \
|
VM_OC_COPY_FROM_ARG) \
|
||||||
|
CBC_OPCODE (CBC_EXT_PUSH_REST_OBJECT, CBC_NO_FLAG, 1, \
|
||||||
|
VM_OC_PUSH_REST_OBJECT) \
|
||||||
CBC_OPCODE (CBC_EXT_STRING_CONCAT, CBC_NO_FLAG, -1, \
|
CBC_OPCODE (CBC_EXT_STRING_CONCAT, CBC_NO_FLAG, -1, \
|
||||||
VM_OC_STRING_CONCAT | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
|
VM_OC_STRING_CONCAT | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
|
||||||
CBC_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
|
CBC_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
|
||||||
@@ -862,9 +864,8 @@ typedef enum
|
|||||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
||||||
CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 6), /**< this function is a static snapshot function */
|
CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 6), /**< this function is a static snapshot function */
|
||||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 7), /**< this function should be ignored by debugger */
|
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 7), /**< this function should be ignored by debugger */
|
||||||
CBC_CODE_FLAGS_REST_PARAMETER = (1u << 8), /**< this function has rest parameter */
|
CBC_CODE_FLAGS_HAS_TAGGED_LITERALS = (1u << 8), /**< this function has tagged template literal list */
|
||||||
CBC_CODE_FLAGS_HAS_TAGGED_LITERALS = (1u << 9), /**< this function has tagged template literal list */
|
CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED = (1u << 9), /**< compiled code needs a lexical block */
|
||||||
CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED = (1u << 10), /**< compiled code needs a lexical block */
|
|
||||||
|
|
||||||
/* Bits from bit 12 is reserved for function types (see CBC_FUNCTION_TYPE_SHIFT).
|
/* Bits from bit 12 is reserved for function types (see CBC_FUNCTION_TYPE_SHIFT).
|
||||||
* Note: the last bits are used for type flags because < and >= operators can be used to
|
* Note: the last bits are used for type flags because < and >= operators can be used to
|
||||||
|
|||||||
@@ -555,13 +555,6 @@ parse_print_literal (ecma_compiled_code_t *compiled_code_p, /**< compiled code *
|
|||||||
ident_end = args_p->ident_end;
|
ident_end = args_p->ident_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
|
||||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_REST_PARAMETER)
|
|
||||||
{
|
|
||||||
argument_end++;
|
|
||||||
}
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
|
||||||
|
|
||||||
if (literal_index < argument_end)
|
if (literal_index < argument_end)
|
||||||
{
|
{
|
||||||
JERRY_DEBUG_MSG (" arg:%d", literal_index);
|
JERRY_DEBUG_MSG (" arg:%d", literal_index);
|
||||||
@@ -1437,11 +1430,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
|||||||
function_type = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
function_type = CBC_FUNCTION_TO_TYPE_BITS (CBC_FUNCTION_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
|
||||||
{
|
|
||||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_REST_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||||
{
|
{
|
||||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_TAGGED_LITERALS;
|
compiled_code_p->status_flags |= CBC_CODE_FLAGS_HAS_TAGGED_LITERALS;
|
||||||
@@ -1870,9 +1858,16 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
|
|||||||
|
|
||||||
context_p->status_flags |= PARSER_FUNCTION_HAS_COMPLEX_ARGUMENT;
|
context_p->status_flags |= PARSER_FUNCTION_HAS_COMPLEX_ARGUMENT;
|
||||||
|
|
||||||
|
if (!(context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM))
|
||||||
|
{
|
||||||
parser_emit_cbc_literal (context_p,
|
parser_emit_cbc_literal (context_p,
|
||||||
CBC_PUSH_LITERAL,
|
CBC_PUSH_LITERAL,
|
||||||
(uint16_t) (PARSER_REGISTER_START + context_p->argument_count));
|
(uint16_t) (PARSER_REGISTER_START + context_p->argument_count));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_REST_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t flags = (PARSER_PATTERN_BINDING
|
uint32_t flags = (PARSER_PATTERN_BINDING
|
||||||
| PARSER_PATTERN_TARGET_ON_STACK
|
| PARSER_PATTERN_TARGET_ON_STACK
|
||||||
@@ -1990,7 +1985,7 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
|
|||||||
|
|
||||||
if (literal_index >= PARSER_REGISTER_START)
|
if (literal_index >= PARSER_REGISTER_START)
|
||||||
{
|
{
|
||||||
opcode = CBC_ASSIGN_SET_IDENT;
|
opcode = CBC_MOV_IDENT;
|
||||||
}
|
}
|
||||||
else if (!scanner_literal_is_created (context_p, literal_index))
|
else if (!scanner_literal_is_created (context_p, literal_index))
|
||||||
{
|
{
|
||||||
@@ -1999,6 +1994,24 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
|
|||||||
|
|
||||||
parser_emit_cbc_literal (context_p, opcode, literal_index);
|
parser_emit_cbc_literal (context_p, opcode, literal_index);
|
||||||
}
|
}
|
||||||
|
else if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
|
||||||
|
{
|
||||||
|
parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_REST_OBJECT);
|
||||||
|
|
||||||
|
uint16_t opcode = CBC_MOV_IDENT;
|
||||||
|
|
||||||
|
if (literal_index < PARSER_REGISTER_START)
|
||||||
|
{
|
||||||
|
opcode = CBC_INIT_ARG_OR_CATCH;
|
||||||
|
|
||||||
|
if (scanner_literal_is_created (context_p, literal_index))
|
||||||
|
{
|
||||||
|
opcode = CBC_ASSIGN_LET_CONST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_emit_cbc_literal (context_p, opcode, literal_index);
|
||||||
|
}
|
||||||
else if (has_complex_argument && literal_index < PARSER_REGISTER_START)
|
else if (has_complex_argument && literal_index < PARSER_REGISTER_START)
|
||||||
{
|
{
|
||||||
uint16_t opcode = CBC_INIT_ARG_OR_FUNC;
|
uint16_t opcode = CBC_INIT_ARG_OR_FUNC;
|
||||||
|
|||||||
+24
-19
@@ -652,7 +652,7 @@ vm_executable_object_t *
|
|||||||
opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||||
vm_create_executable_object_type_t type) /**< executable object type */
|
vm_create_executable_object_type_t type) /**< executable object type */
|
||||||
{
|
{
|
||||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->shared_p->bytecode_header_p;
|
||||||
size_t size, register_end;
|
size_t size, register_end;
|
||||||
|
|
||||||
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_header_p);
|
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_header_p);
|
||||||
@@ -680,13 +680,15 @@ opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context
|
|||||||
{
|
{
|
||||||
ecma_builtin_id_t default_proto_id = ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE;
|
ecma_builtin_id_t default_proto_id = ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE;
|
||||||
|
|
||||||
if (CBC_FUNCTION_GET_TYPE (frame_ctx_p->bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC_GENERATOR)
|
if (CBC_FUNCTION_GET_TYPE (bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC_GENERATOR)
|
||||||
{
|
{
|
||||||
default_proto_id = ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE;
|
default_proto_id = ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE;
|
||||||
class_id = LIT_MAGIC_STRING_ASYNC_GENERATOR_UL;
|
class_id = LIT_MAGIC_STRING_ASYNC_GENERATOR_UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_function_obj_p), default_proto_id);
|
JERRY_ASSERT (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_NON_ARROW_FUNC);
|
||||||
|
proto_p = ecma_op_get_prototype_from_constructor (VM_FRAME_CTX_GET_FUNCTION_OBJECT (frame_ctx_p),
|
||||||
|
default_proto_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_object_t *object_p = ecma_create_object (proto_p,
|
ecma_object_t *object_p = ecma_create_object (proto_p,
|
||||||
@@ -704,10 +706,15 @@ opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context
|
|||||||
executable_object_p->extended_object.u.class_prop.extra_info = 0;
|
executable_object_p->extended_object.u.class_prop.extra_info = 0;
|
||||||
ECMA_SET_INTERNAL_VALUE_ANY_POINTER (executable_object_p->extended_object.u.class_prop.u.head, NULL);
|
ECMA_SET_INTERNAL_VALUE_ANY_POINTER (executable_object_p->extended_object.u.class_prop.u.head, NULL);
|
||||||
|
|
||||||
JERRY_ASSERT (!frame_ctx_p->is_eval_code);
|
JERRY_ASSERT (!(frame_ctx_p->status_flags & VM_FRAME_CTX_DIRECT_EVAL));
|
||||||
|
|
||||||
|
/* Copy shared data and frame context. */
|
||||||
|
vm_frame_ctx_shared_t *new_shared_p = &(executable_object_p->shared);
|
||||||
|
*new_shared_p = *(frame_ctx_p->shared_p);
|
||||||
|
|
||||||
vm_frame_ctx_t *new_frame_ctx_p = &(executable_object_p->frame_ctx);
|
vm_frame_ctx_t *new_frame_ctx_p = &(executable_object_p->frame_ctx);
|
||||||
*new_frame_ctx_p = *frame_ctx_p;
|
*new_frame_ctx_p = *frame_ctx_p;
|
||||||
|
new_frame_ctx_p->shared_p = new_shared_p;
|
||||||
|
|
||||||
/* The old register values are discarded. */
|
/* The old register values are discarded. */
|
||||||
ecma_value_t *new_registers_p = VM_GET_REGISTERS (new_frame_ctx_p);
|
ecma_value_t *new_registers_p = VM_GET_REGISTERS (new_frame_ctx_p);
|
||||||
@@ -782,7 +789,7 @@ ecma_value_t
|
|||||||
opfunc_resume_executable_object (vm_executable_object_t *executable_object_p, /**< executable object */
|
opfunc_resume_executable_object (vm_executable_object_t *executable_object_p, /**< executable object */
|
||||||
ecma_value_t value) /**< value pushed onto the stack (takes the reference) */
|
ecma_value_t value) /**< value pushed onto the stack (takes the reference) */
|
||||||
{
|
{
|
||||||
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->frame_ctx.bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = executable_object_p->shared.bytecode_header_p;
|
||||||
ecma_value_t *register_p = VM_GET_REGISTERS (&executable_object_p->frame_ctx);
|
ecma_value_t *register_p = VM_GET_REGISTERS (&executable_object_p->frame_ctx);
|
||||||
ecma_value_t *register_end_p;
|
ecma_value_t *register_end_p;
|
||||||
|
|
||||||
@@ -926,8 +933,9 @@ opfunc_async_create_and_await (vm_frame_ctx_t *frame_ctx_p, /**< frame context *
|
|||||||
uint16_t extra_flags) /**< extra flags */
|
uint16_t extra_flags) /**< extra flags */
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (frame_ctx_p->block_result == ECMA_VALUE_UNDEFINED);
|
JERRY_ASSERT (frame_ctx_p->block_result == ECMA_VALUE_UNDEFINED);
|
||||||
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (frame_ctx_p->bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC
|
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (frame_ctx_p->shared_p->bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC
|
||||||
|| CBC_FUNCTION_GET_TYPE (frame_ctx_p->bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC_ARROW);
|
|| (CBC_FUNCTION_GET_TYPE (frame_ctx_p->shared_p->bytecode_header_p->status_flags)
|
||||||
|
== CBC_FUNCTION_ASYNC_ARROW));
|
||||||
|
|
||||||
ecma_object_t *promise_p = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
|
ecma_object_t *promise_p = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
|
||||||
ecma_value_t result = ecma_promise_reject_or_resolve (ecma_make_object_value (promise_p), value, true);
|
ecma_value_t result = ecma_promise_reject_or_resolve (ecma_make_object_value (promise_p), value, true);
|
||||||
@@ -982,33 +990,30 @@ ecma_op_init_class_fields (ecma_value_t function_object, /**< the function itsel
|
|||||||
return ECMA_VALUE_UNDEFINED;
|
return ECMA_VALUE_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
|
vm_frame_ctx_shared_class_fields_t shared_class_fields;
|
||||||
ecma_value_t *computed_class_fields_p = NULL;
|
shared_class_fields.header.status_flags = VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS;
|
||||||
|
shared_class_fields.computed_class_fields_p = NULL;
|
||||||
|
|
||||||
name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED);
|
name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED);
|
||||||
ecma_property_t *class_field_property_p = ecma_find_named_property (function_object_p, name_p);
|
ecma_property_t *class_field_property_p = ecma_find_named_property (function_object_p, name_p);
|
||||||
|
|
||||||
if (class_field_property_p != NULL)
|
if (class_field_property_p != NULL)
|
||||||
{
|
{
|
||||||
ecma_property_value_t *class_field_property_value_p = ECMA_PROPERTY_VALUE_PTR (class_field_property_p);
|
ecma_value_t value = ECMA_PROPERTY_VALUE_PTR (class_field_property_p)->value;
|
||||||
computed_class_fields_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, class_field_property_value_p->value);
|
shared_class_fields.computed_class_fields_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
|
||||||
JERRY_ASSERT (ecma_op_is_callable (property_value_p->value));
|
JERRY_ASSERT (ecma_op_is_callable (property_value_p->value));
|
||||||
|
|
||||||
ecma_extended_object_t *ext_function_p;
|
ecma_extended_object_t *ext_function_p;
|
||||||
ext_function_p = (ecma_extended_object_t *) ecma_get_object_from_value (property_value_p->value);
|
ext_function_p = (ecma_extended_object_t *) ecma_get_object_from_value (property_value_p->value);
|
||||||
|
shared_class_fields.header.bytecode_header_p = ecma_op_function_get_compiled_code (ext_function_p);
|
||||||
|
|
||||||
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
|
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
|
||||||
ext_function_p->u.function.scope_cp);
|
ext_function_p->u.function.scope_cp);
|
||||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_function_p);
|
|
||||||
|
|
||||||
ecma_value_t *old_computed_class_fields_p = JERRY_CONTEXT (computed_class_fields_p);
|
ecma_value_t result = vm_run (&shared_class_fields.header, this_val, scope_p);
|
||||||
JERRY_CONTEXT (computed_class_fields_p) = computed_class_fields_p;
|
|
||||||
|
|
||||||
ecma_value_t result = vm_run (bytecode_data_p, this_val, scope_p, NULL, 0);
|
|
||||||
|
|
||||||
JERRY_CONTEXT (computed_class_fields_p) = old_computed_class_fields_p;
|
|
||||||
|
|
||||||
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (result) || result == ECMA_VALUE_UNDEFINED);
|
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (result) || result == ECMA_VALUE_UNDEFINED);
|
||||||
return result;
|
return result;
|
||||||
@@ -1578,7 +1583,7 @@ opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, /**< vm stack top
|
|||||||
return ECMA_VALUE_ERROR;
|
return ECMA_VALUE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_strict = (frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
bool is_strict = (frame_ctx_p->status_flags & VM_FRAME_CTX_IS_STRICT) != 0;
|
||||||
|
|
||||||
ecma_value_t result = ecma_op_object_put_with_receiver (base_obj_p,
|
ecma_value_t result = ecma_op_object_put_with_receiver (base_obj_p,
|
||||||
prop_name_p,
|
prop_name_p,
|
||||||
|
|||||||
@@ -35,12 +35,81 @@
|
|||||||
*/
|
*/
|
||||||
#define VM_MINUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) - (value))
|
#define VM_MINUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) - (value))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag bits of vm_frame_ctx_shared_t
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VM_FRAME_CTX_SHARED_HAS_ARG_LIST = (1 << 0), /**< has argument list */
|
||||||
|
VM_FRAME_CTX_SHARED_DIRECT_EVAL = (1 << 1), /**< direct eval call */
|
||||||
|
VM_FRAME_CTX_SHARED_FREE_THIS = (1 << 2), /**< free this binding */
|
||||||
|
VM_FRAME_CTX_SHARED_FREE_LOCAL_ENV = (1 << 3), /**< free local environment */
|
||||||
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
|
VM_FRAME_CTX_SHARED_NON_ARROW_FUNC = (1 << 4), /**< non-arrow function */
|
||||||
|
VM_FRAME_CTX_SHARED_HERITAGE_PRESENT = (1 << 5), /**< class heritage present */
|
||||||
|
VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS = (1 << 6), /**< has class fields */
|
||||||
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
} vm_frame_ctx_shared_flags_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared data between the interpreter and the caller
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
|
||||||
|
uint32_t status_flags; /**< combination of vm_frame_ctx_shared_flags_t bits */
|
||||||
|
} vm_frame_ctx_shared_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared data extended with arguments
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vm_frame_ctx_shared_t header; /**< shared data header */
|
||||||
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
|
ecma_object_t *function_object_p; /**< function obj */
|
||||||
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
const ecma_value_t *arg_list_p; /**< arguments list */
|
||||||
|
uint32_t arg_list_len; /**< arguments list length */
|
||||||
|
} vm_frame_ctx_shared_args_t;
|
||||||
|
|
||||||
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
|
|
||||||
|
#define VM_FRAME_CTX_GET_FUNCTION_OBJECT(frame_ctx_p) \
|
||||||
|
(((vm_frame_ctx_shared_args_t *) (frame_ctx_p)->shared_p)->function_object_p)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared data extended with computed class fields
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vm_frame_ctx_shared_t header; /**< shared data header */
|
||||||
|
ecma_value_t *computed_class_fields_p; /**< names of the computed class fields */
|
||||||
|
} vm_frame_ctx_shared_class_fields_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the computed class field
|
||||||
|
*/
|
||||||
|
#define VM_GET_COMPUTED_CLASS_FIELDS(frame_ctx_p) \
|
||||||
|
(((vm_frame_ctx_shared_class_fields_t *) ((frame_ctx_p)->shared_p))->computed_class_fields_p)
|
||||||
|
|
||||||
|
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag bits of vm_frame_ctx_t
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VM_FRAME_CTX_DIRECT_EVAL = (1 << 1), /**< direct eval call */
|
||||||
|
VM_FRAME_CTX_IS_STRICT = (1 << 2), /**< strict mode */
|
||||||
|
} vm_frame_ctx_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context of interpreter, related to a JS stack frame
|
* Context of interpreter, related to a JS stack frame
|
||||||
*/
|
*/
|
||||||
typedef struct vm_frame_ctx_t
|
typedef struct vm_frame_ctx_t
|
||||||
{
|
{
|
||||||
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
|
vm_frame_ctx_shared_t *shared_p; /**< shared information */
|
||||||
const uint8_t *byte_code_p; /**< current byte code pointer */
|
const uint8_t *byte_code_p; /**< current byte code pointer */
|
||||||
const uint8_t *byte_code_start_p; /**< byte code start pointer */
|
const uint8_t *byte_code_start_p; /**< byte code start pointer */
|
||||||
ecma_value_t *stack_top_p; /**< stack top pointer */
|
ecma_value_t *stack_top_p; /**< stack top pointer */
|
||||||
@@ -53,7 +122,7 @@ typedef struct vm_frame_ctx_t
|
|||||||
uint32_t current_line; /**< currently executed line */
|
uint32_t current_line; /**< currently executed line */
|
||||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||||
uint16_t context_depth; /**< current context depth */
|
uint16_t context_depth; /**< current context depth */
|
||||||
uint8_t is_eval_code; /**< eval mode flag */
|
uint8_t status_flags; /**< combination of vm_frame_ctx_flags_t bits */
|
||||||
uint8_t call_operation; /**< perform a call or construct operation */
|
uint8_t call_operation; /**< perform a call or construct operation */
|
||||||
/* Registers start immediately after the frame context. */
|
/* Registers start immediately after the frame context. */
|
||||||
} vm_frame_ctx_t;
|
} vm_frame_ctx_t;
|
||||||
@@ -80,6 +149,7 @@ typedef struct vm_frame_ctx_t
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ecma_extended_object_t extended_object; /**< extended object part */
|
ecma_extended_object_t extended_object; /**< extended object part */
|
||||||
|
vm_frame_ctx_shared_t shared; /**< shared part */
|
||||||
vm_frame_ctx_t frame_ctx; /**< frame context part */
|
vm_frame_ctx_t frame_ctx; /**< frame context part */
|
||||||
} vm_executable_object_t;
|
} vm_executable_object_t;
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ vm_is_strict_mode (void)
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (JERRY_CONTEXT (vm_top_context_p) != NULL);
|
JERRY_ASSERT (JERRY_CONTEXT (vm_top_context_p) != NULL);
|
||||||
|
|
||||||
return JERRY_CONTEXT (vm_top_context_p)->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE;
|
return JERRY_CONTEXT (vm_top_context_p)->status_flags & VM_FRAME_CTX_IS_STRICT;
|
||||||
} /* vm_is_strict_mode */
|
} /* vm_is_strict_mode */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ vm_get_backtrace (uint32_t max_depth) /**< maximum backtrace depth, 0 = unlimite
|
|||||||
|
|
||||||
while (context_p != NULL)
|
while (context_p != NULL)
|
||||||
{
|
{
|
||||||
ecma_value_t resource_name = ecma_get_resource_name (context_p->bytecode_header_p);
|
ecma_value_t resource_name = ecma_get_resource_name (context_p->shared_p->bytecode_header_p);
|
||||||
ecma_string_t *str_p = ecma_get_string_from_value (resource_name);
|
ecma_string_t *str_p = ecma_get_string_from_value (resource_name);
|
||||||
ecma_stringbuilder_t builder = ecma_stringbuilder_create ();
|
ecma_stringbuilder_t builder = ecma_stringbuilder_create ();
|
||||||
|
|
||||||
|
|||||||
+109
-61
@@ -46,11 +46,6 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Special constant to represent direct eval code.
|
|
||||||
*/
|
|
||||||
#define VM_DIRECT_EVAL ((void *) 0x1)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of object[property].
|
* Get the value of object[property].
|
||||||
*
|
*
|
||||||
@@ -281,16 +276,17 @@ vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode
|
|||||||
ecma_object_t *lex_env_p) /**< pointer to the specified lexenv to run in */
|
ecma_object_t *lex_env_p) /**< pointer to the specified lexenv to run in */
|
||||||
{
|
{
|
||||||
const ecma_value_t module_init_result = ecma_module_initialize_current ();
|
const ecma_value_t module_init_result = ecma_module_initialize_current ();
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (module_init_result))
|
if (ECMA_IS_VALUE_ERROR (module_init_result))
|
||||||
{
|
{
|
||||||
return module_init_result;
|
return module_init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm_run (bytecode_p,
|
vm_frame_ctx_shared_t shared;
|
||||||
ECMA_VALUE_UNDEFINED,
|
shared.bytecode_header_p = bytecode_p;
|
||||||
lex_env_p,
|
shared.status_flags = 0;
|
||||||
NULL,
|
|
||||||
0);
|
return vm_run (&shared, ECMA_VALUE_UNDEFINED, lex_env_p);
|
||||||
} /* vm_run_module */
|
} /* vm_run_module */
|
||||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||||
|
|
||||||
@@ -337,11 +333,11 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
|
|||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||||
|
|
||||||
return vm_run (bytecode_p,
|
vm_frame_ctx_shared_t shared;
|
||||||
ecma_make_object_value (glob_obj_p),
|
shared.bytecode_header_p = bytecode_p;
|
||||||
global_scope_p,
|
shared.status_flags = 0;
|
||||||
NULL,
|
|
||||||
0);
|
return vm_run (&shared, ecma_make_object_value (glob_obj_p), global_scope_p);
|
||||||
} /* vm_run_global */
|
} /* vm_run_global */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -410,11 +406,11 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
|
|||||||
lex_env_p = lex_block_p;
|
lex_env_p = lex_block_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_value_t completion_value = vm_run (bytecode_data_p,
|
vm_frame_ctx_shared_t shared;
|
||||||
this_binding,
|
shared.bytecode_header_p = bytecode_data_p;
|
||||||
lex_env_p,
|
shared.status_flags = (parse_opts & ECMA_PARSE_DIRECT_EVAL) ? VM_FRAME_CTX_SHARED_DIRECT_EVAL : 0;
|
||||||
(parse_opts & ECMA_PARSE_DIRECT_EVAL) ? VM_DIRECT_EVAL : NULL,
|
|
||||||
0);
|
ecma_value_t completion_value = vm_run (&shared, this_binding, lex_env_p);
|
||||||
|
|
||||||
ecma_deref_object (lex_env_p);
|
ecma_deref_object (lex_env_p);
|
||||||
ecma_free_value (this_binding);
|
ecma_free_value (this_binding);
|
||||||
@@ -443,7 +439,7 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
ecma_compiled_code_t *bytecode_p;
|
ecma_compiled_code_t *bytecode_p;
|
||||||
|
|
||||||
#if ENABLED (JERRY_SNAPSHOT_EXEC)
|
#if ENABLED (JERRY_SNAPSHOT_EXEC)
|
||||||
if (JERRY_LIKELY (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
|
if (JERRY_LIKELY (!(frame_ctx_p->shared_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
|
||||||
{
|
{
|
||||||
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
||||||
bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||||
@@ -452,7 +448,7 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t *byte_p = ((uint8_t *) frame_ctx_p->bytecode_header_p) + lit_value;
|
uint8_t *byte_p = ((uint8_t *) frame_ctx_p->shared_p->bytecode_header_p) + lit_value;
|
||||||
bytecode_p = (ecma_compiled_code_t *) byte_p;
|
bytecode_p = (ecma_compiled_code_t *) byte_p;
|
||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
||||||
@@ -529,6 +525,23 @@ static const uint8_t vm_error_byte_code_p[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
#if ENABLED (JERRY_ESNEXT)
|
||||||
|
|
||||||
|
static ecma_object_t *
|
||||||
|
vm_get_class_function (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (frame_ctx_p != NULL);
|
||||||
|
|
||||||
|
if (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_NON_ARROW_FUNC)
|
||||||
|
{
|
||||||
|
return VM_FRAME_CTX_GET_FUNCTION_OBJECT (frame_ctx_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_ctx_p = frame_ctx_p->prev_context_p;
|
||||||
|
}
|
||||||
|
} /* vm_get_class_function */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'super(...)' function call handler.
|
* 'super(...)' function call handler.
|
||||||
*/
|
*/
|
||||||
@@ -612,7 +625,7 @@ vm_super_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
|
|
||||||
if (ecma_is_value_object (completion_value))
|
if (ecma_is_value_object (completion_value))
|
||||||
{
|
{
|
||||||
ecma_value_t current_function = ecma_make_object_value (JERRY_CONTEXT (current_function_obj_p));
|
ecma_value_t current_function = ecma_make_object_value (vm_get_class_function (frame_ctx_p));
|
||||||
ecma_value_t fields_value = ecma_op_init_class_fields (current_function, completion_value);
|
ecma_value_t fields_value = ecma_op_init_class_fields (current_function, completion_value);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (fields_value))
|
if (ECMA_IS_VALUE_ERROR (fields_value))
|
||||||
@@ -1008,7 +1021,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
static ecma_value_t JERRY_ATTR_NOINLINE
|
static ecma_value_t JERRY_ATTR_NOINLINE
|
||||||
vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||||
{
|
{
|
||||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->shared_p->bytecode_header_p;
|
||||||
const uint8_t *byte_code_p = frame_ctx_p->byte_code_p;
|
const uint8_t *byte_code_p = frame_ctx_p->byte_code_p;
|
||||||
ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p;
|
ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p;
|
||||||
|
|
||||||
@@ -1023,7 +1036,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
ecma_value_t left_value;
|
ecma_value_t left_value;
|
||||||
ecma_value_t right_value;
|
ecma_value_t right_value;
|
||||||
ecma_value_t result = ECMA_VALUE_EMPTY;
|
ecma_value_t result = ECMA_VALUE_EMPTY;
|
||||||
bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
|
bool is_strict = ((bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
|
||||||
|
|
||||||
/* Prepare for byte code execution. */
|
/* Prepare for byte code execution. */
|
||||||
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
|
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
|
||||||
@@ -1403,7 +1416,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) && !JERRY_NDEBUG */
|
#endif /* ENABLED (JERRY_ESNEXT) && !JERRY_NDEBUG */
|
||||||
|
|
||||||
result = vm_var_decl (lex_env_p, name_p, frame_ctx_p->is_eval_code);
|
result = vm_var_decl (lex_env_p, name_p, (frame_ctx_p->status_flags & VM_FRAME_CTX_DIRECT_EVAL) != 0);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
@@ -2040,7 +2053,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_RUN_CLASS_FIELD_INIT:
|
case VM_OC_RUN_CLASS_FIELD_INIT:
|
||||||
{
|
{
|
||||||
result = ecma_op_init_class_fields (ecma_make_object_value (JERRY_CONTEXT (current_function_obj_p)),
|
JERRY_ASSERT (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_NON_ARROW_FUNC);
|
||||||
|
result = ecma_op_init_class_fields (ecma_make_object_value (VM_FRAME_CTX_GET_FUNCTION_OBJECT (frame_ctx_p)),
|
||||||
frame_ctx_p->this_binding);
|
frame_ctx_p->this_binding);
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
@@ -2055,7 +2069,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
stack_top_p[-2] = ecma_make_integer_value (next_index);
|
stack_top_p[-2] = ecma_make_integer_value (next_index);
|
||||||
stack_top_p++;
|
stack_top_p++;
|
||||||
|
|
||||||
ecma_value_t *computed_class_fields_p = JERRY_CONTEXT (computed_class_fields_p);
|
JERRY_ASSERT (frame_ctx_p->shared_p->status_flags & VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS);
|
||||||
|
|
||||||
|
ecma_value_t *computed_class_fields_p = VM_GET_COMPUTED_CLASS_FIELDS (frame_ctx_p);
|
||||||
JERRY_ASSERT ((ecma_value_t) next_index < ECMA_COMPACT_COLLECTION_GET_SIZE (computed_class_fields_p));
|
JERRY_ASSERT ((ecma_value_t) next_index < ECMA_COMPACT_COLLECTION_GET_SIZE (computed_class_fields_p));
|
||||||
|
|
||||||
result = stack_top_p[-2];
|
result = stack_top_p[-2];
|
||||||
@@ -2065,7 +2081,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_PUSH_SUPER_CONSTRUCTOR:
|
case VM_OC_PUSH_SUPER_CONSTRUCTOR:
|
||||||
{
|
{
|
||||||
result = ecma_op_function_get_super_constructor (JERRY_CONTEXT (current_function_obj_p));
|
result = ecma_op_function_get_super_constructor (vm_get_class_function (frame_ctx_p));
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (result))
|
if (ECMA_IS_VALUE_ERROR (result))
|
||||||
{
|
{
|
||||||
@@ -2200,6 +2216,38 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
*stack_top_p++ = ECMA_VALUE_SPREAD_ELEMENT;
|
*stack_top_p++ = ECMA_VALUE_SPREAD_ELEMENT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case VM_OC_PUSH_REST_OBJECT:
|
||||||
|
{
|
||||||
|
vm_frame_ctx_shared_t *shared_p = frame_ctx_p->shared_p;
|
||||||
|
|
||||||
|
JERRY_ASSERT (shared_p->status_flags & VM_FRAME_CTX_SHARED_HAS_ARG_LIST);
|
||||||
|
|
||||||
|
const ecma_value_t *arg_list_p = ((vm_frame_ctx_shared_args_t *) shared_p)->arg_list_p;
|
||||||
|
uint32_t arg_list_len = ((vm_frame_ctx_shared_args_t *) shared_p)->arg_list_len;
|
||||||
|
uint16_t argument_end;
|
||||||
|
|
||||||
|
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
|
{
|
||||||
|
argument_end = ((cbc_uint16_arguments_t *) bytecode_header_p)->argument_end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
argument_end = ((cbc_uint8_arguments_t *) bytecode_header_p)->argument_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_list_len < argument_end)
|
||||||
|
{
|
||||||
|
arg_list_len = argument_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = ecma_op_create_array_object (arg_list_p + argument_end,
|
||||||
|
arg_list_len - argument_end,
|
||||||
|
false);
|
||||||
|
|
||||||
|
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (result));
|
||||||
|
*stack_top_p++ = result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
case VM_OC_GET_ITERATOR:
|
case VM_OC_GET_ITERATOR:
|
||||||
{
|
{
|
||||||
result = ecma_op_get_iterator (stack_top_p[-1], ECMA_VALUE_SYNC_ITERATOR, NULL);
|
result = ecma_op_get_iterator (stack_top_p[-1], ECMA_VALUE_SYNC_ITERATOR, NULL);
|
||||||
@@ -4068,7 +4116,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD
|
uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD
|
||||||
| (ECMA_AWAIT_FOR_NEXT << ECMA_AWAIT_STATE_SHIFT));
|
| (ECMA_AWAIT_FOR_NEXT << ECMA_AWAIT_STATE_SHIFT));
|
||||||
|
|
||||||
if (CBC_FUNCTION_GET_TYPE (frame_ctx_p->bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC_GENERATOR
|
if (CBC_FUNCTION_GET_TYPE (bytecode_header_p->status_flags) == CBC_FUNCTION_ASYNC_GENERATOR
|
||||||
|| frame_ctx_p->block_result != ECMA_VALUE_UNDEFINED)
|
|| frame_ctx_p->block_result != ECMA_VALUE_UNDEFINED)
|
||||||
{
|
{
|
||||||
ecma_extended_object_t *executable_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p);
|
ecma_extended_object_t *executable_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p);
|
||||||
@@ -4314,7 +4362,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
|
|
||||||
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
|
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
|
||||||
|
|
||||||
JERRY_ASSERT (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE));
|
JERRY_ASSERT (!(frame_ctx_p->shared_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE));
|
||||||
|
|
||||||
frame_ctx_p->byte_code_p = byte_code_start_p;
|
frame_ctx_p->byte_code_p = byte_code_start_p;
|
||||||
|
|
||||||
@@ -4335,7 +4383,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
|
|
||||||
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
|
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
|
||||||
|
|
||||||
JERRY_ASSERT (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE));
|
JERRY_ASSERT (!(frame_ctx_p->shared_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE));
|
||||||
|
|
||||||
frame_ctx_p->byte_code_p = byte_code_start_p;
|
frame_ctx_p->byte_code_p = byte_code_start_p;
|
||||||
|
|
||||||
@@ -4528,7 +4576,7 @@ error:
|
|||||||
| JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
|
| JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
|
||||||
|
|
||||||
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||||
&& !(frame_ctx_p->bytecode_header_p->status_flags
|
&& !(frame_ctx_p->shared_p->bytecode_header_p->status_flags
|
||||||
& (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
|
& (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
|
||||||
&& !(JERRY_CONTEXT (debugger_flags) & dont_stop))
|
&& !(JERRY_CONTEXT (debugger_flags) & dont_stop))
|
||||||
{
|
{
|
||||||
@@ -4676,6 +4724,12 @@ finish:
|
|||||||
#undef READ_LITERAL
|
#undef READ_LITERAL
|
||||||
#undef READ_LITERAL_INDEX
|
#undef READ_LITERAL_INDEX
|
||||||
|
|
||||||
|
JERRY_STATIC_ASSERT ((int) VM_FRAME_CTX_SHARED_DIRECT_EVAL == (int) VM_FRAME_CTX_DIRECT_EVAL,
|
||||||
|
vm_frame_ctx_shared_direct_eval_must_be_equal_to_frame_ctx_direct_eval);
|
||||||
|
|
||||||
|
JERRY_STATIC_ASSERT ((int) CBC_CODE_FLAGS_STRICT_MODE == (int) VM_FRAME_CTX_IS_STRICT,
|
||||||
|
cbc_code_flags_strict_mode_must_be_equal_to_vm_frame_ctx_is_strict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize code block execution
|
* Initialize code block execution
|
||||||
*
|
*
|
||||||
@@ -4683,19 +4737,20 @@ finish:
|
|||||||
* ECMA_VALUE_EMPTY - otherwise
|
* ECMA_VALUE_EMPTY - otherwise
|
||||||
*/
|
*/
|
||||||
static void JERRY_ATTR_NOINLINE
|
static void JERRY_ATTR_NOINLINE
|
||||||
vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
vm_init_exec (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||||
const ecma_value_t *arg_p, /**< arguments list */
|
|
||||||
uint32_t arg_list_len) /**< length of arguments list */
|
|
||||||
{
|
{
|
||||||
|
vm_frame_ctx_shared_t *shared_p = frame_ctx_p->shared_p;
|
||||||
|
const ecma_compiled_code_t *bytecode_header_p = shared_p->bytecode_header_p;
|
||||||
|
|
||||||
frame_ctx_p->prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
frame_ctx_p->prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||||
frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED;
|
frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED;
|
||||||
#if ENABLED (JERRY_LINE_INFO)
|
#if ENABLED (JERRY_LINE_INFO)
|
||||||
frame_ctx_p->current_line = 0;
|
frame_ctx_p->current_line = 0;
|
||||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||||
frame_ctx_p->context_depth = 0;
|
frame_ctx_p->context_depth = 0;
|
||||||
frame_ctx_p->is_eval_code = (arg_p == VM_DIRECT_EVAL);
|
frame_ctx_p->status_flags = (uint8_t) ((shared_p->status_flags & VM_FRAME_CTX_DIRECT_EVAL)
|
||||||
|
| (bytecode_header_p->status_flags & VM_FRAME_CTX_IS_STRICT));
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
|
||||||
uint16_t argument_end, register_end;
|
uint16_t argument_end, register_end;
|
||||||
ecma_value_t *literal_p;
|
ecma_value_t *literal_p;
|
||||||
|
|
||||||
@@ -4728,9 +4783,14 @@ vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
frame_ctx_p->byte_code_start_p = (uint8_t *) literal_p;
|
frame_ctx_p->byte_code_start_p = (uint8_t *) literal_p;
|
||||||
frame_ctx_p->stack_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end;
|
frame_ctx_p->stack_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end;
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
uint32_t arg_list_len = 0;
|
||||||
uint32_t function_call_argument_count = arg_list_len;
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
if (argument_end > 0)
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (shared_p->status_flags & VM_FRAME_CTX_SHARED_HAS_ARG_LIST);
|
||||||
|
|
||||||
|
const ecma_value_t *arg_list_p = ((vm_frame_ctx_shared_args_t *) shared_p)->arg_list_p;
|
||||||
|
arg_list_len = ((vm_frame_ctx_shared_args_t *) shared_p)->arg_list_len;
|
||||||
|
|
||||||
if (arg_list_len > argument_end)
|
if (arg_list_len > argument_end)
|
||||||
{
|
{
|
||||||
@@ -4739,7 +4799,8 @@ vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < arg_list_len; i++)
|
for (uint32_t i = 0; i < arg_list_len; i++)
|
||||||
{
|
{
|
||||||
VM_GET_REGISTER (frame_ctx_p, i) = ecma_fast_copy_value (arg_p[i]);
|
VM_GET_REGISTER (frame_ctx_p, i) = ecma_fast_copy_value (arg_list_p[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The arg_list_len contains the end of the copied arguments.
|
/* The arg_list_len contains the end of the copied arguments.
|
||||||
@@ -4754,18 +4815,6 @@ vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED (JERRY_ESNEXT)
|
|
||||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_REST_PARAMETER)
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (function_call_argument_count >= arg_list_len);
|
|
||||||
ecma_value_t new_array = ecma_op_create_array_object (arg_p + arg_list_len,
|
|
||||||
function_call_argument_count - arg_list_len,
|
|
||||||
false);
|
|
||||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
|
||||||
VM_GET_REGISTER (frame_ctx_p, argument_end) = new_array;
|
|
||||||
}
|
|
||||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
|
||||||
|
|
||||||
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
|
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
|
||||||
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p;
|
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p;
|
||||||
} /* vm_init_exec */
|
} /* vm_init_exec */
|
||||||
@@ -4814,7 +4863,7 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (frame_ctx_p->call_operation == VM_NO_EXEC_OP);
|
JERRY_ASSERT (frame_ctx_p->call_operation == VM_NO_EXEC_OP);
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->shared_p->bytecode_header_p;
|
||||||
uint32_t register_end;
|
uint32_t register_end;
|
||||||
|
|
||||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
@@ -4855,12 +4904,11 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
* @return ecma value
|
* @return ecma value
|
||||||
*/
|
*/
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */
|
vm_run (vm_frame_ctx_shared_t *shared_p, /**< shared data */
|
||||||
ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
|
ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
|
||||||
ecma_object_t *lex_env_p, /**< lexical environment to use */
|
ecma_object_t *lex_env_p) /**< lexical environment to use */
|
||||||
const ecma_value_t *arg_list_p, /**< arguments list */
|
|
||||||
uint32_t arg_list_len) /**< length of arguments list */
|
|
||||||
{
|
{
|
||||||
|
const ecma_compiled_code_t *bytecode_header_p = shared_p->bytecode_header_p;
|
||||||
vm_frame_ctx_t *frame_ctx_p;
|
vm_frame_ctx_t *frame_ctx_p;
|
||||||
size_t frame_size;
|
size_t frame_size;
|
||||||
|
|
||||||
@@ -4883,11 +4931,11 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
|
|||||||
|
|
||||||
frame_ctx_p = (vm_frame_ctx_t *) stack;
|
frame_ctx_p = (vm_frame_ctx_t *) stack;
|
||||||
|
|
||||||
frame_ctx_p->bytecode_header_p = bytecode_header_p;
|
frame_ctx_p->shared_p = shared_p;
|
||||||
frame_ctx_p->lex_env_p = lex_env_p;
|
frame_ctx_p->lex_env_p = lex_env_p;
|
||||||
frame_ctx_p->this_binding = this_binding_value;
|
frame_ctx_p->this_binding = this_binding_value;
|
||||||
|
|
||||||
vm_init_exec (frame_ctx_p, arg_list_p, arg_list_len);
|
vm_init_exec (frame_ctx_p);
|
||||||
return vm_execute (frame_ctx_p);
|
return vm_execute (frame_ctx_p);
|
||||||
} /* vm_run */
|
} /* vm_run */
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -271,6 +271,7 @@ typedef enum
|
|||||||
VM_OC_SET_FUNCTION_NAME, /**< set function name property */
|
VM_OC_SET_FUNCTION_NAME, /**< set function name property */
|
||||||
|
|
||||||
VM_OC_PUSH_SPREAD_ELEMENT, /**< push spread element */
|
VM_OC_PUSH_SPREAD_ELEMENT, /**< push spread element */
|
||||||
|
VM_OC_PUSH_REST_OBJECT, /**< push rest object */
|
||||||
VM_OC_GET_ITERATOR, /**< GetIterator abstract operation */
|
VM_OC_GET_ITERATOR, /**< GetIterator abstract operation */
|
||||||
VM_OC_ITERATOR_STEP, /**< IteratorStep abstract operation */
|
VM_OC_ITERATOR_STEP, /**< IteratorStep abstract operation */
|
||||||
VM_OC_ITERATOR_CLOSE, /**< IteratorClose abstract operation */
|
VM_OC_ITERATOR_CLOSE, /**< IteratorClose abstract operation */
|
||||||
@@ -352,6 +353,7 @@ typedef enum
|
|||||||
VM_OC_SET_FUNCTION_NAME = VM_OC_NONE, /**< set function name property */
|
VM_OC_SET_FUNCTION_NAME = VM_OC_NONE, /**< set function name property */
|
||||||
|
|
||||||
VM_OC_PUSH_SPREAD_ELEMENT = VM_OC_NONE, /**< push spread element */
|
VM_OC_PUSH_SPREAD_ELEMENT = VM_OC_NONE, /**< push spread element */
|
||||||
|
VM_OC_PUSH_REST_OBJECT = VM_OC_NONE, /**< push rest object */
|
||||||
VM_OC_GET_ITERATOR = VM_OC_NONE, /**< GetIterator abstract operation */
|
VM_OC_GET_ITERATOR = VM_OC_NONE, /**< GetIterator abstract operation */
|
||||||
VM_OC_ITERATOR_STEP = VM_OC_NONE, /**< IteratorStep abstract operation */
|
VM_OC_ITERATOR_STEP = VM_OC_NONE, /**< IteratorStep abstract operation */
|
||||||
VM_OC_ITERATOR_CLOSE = VM_OC_NONE, /**< IteratorClose abstract operation */
|
VM_OC_ITERATOR_CLOSE = VM_OC_NONE, /**< IteratorClose abstract operation */
|
||||||
@@ -469,8 +471,7 @@ ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_
|
|||||||
ecma_value_t vm_run_module (const ecma_compiled_code_t *bytecode_p, ecma_object_t *lex_env_p);
|
ecma_value_t vm_run_module (const ecma_compiled_code_t *bytecode_p, ecma_object_t *lex_env_p);
|
||||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||||
|
|
||||||
ecma_value_t vm_run (const ecma_compiled_code_t *bytecode_header_p, ecma_value_t this_binding_value,
|
ecma_value_t vm_run (vm_frame_ctx_shared_t *shared_p, ecma_value_t this_binding_value, ecma_object_t *lex_env_p);
|
||||||
ecma_object_t *lex_env_p, const ecma_value_t *arg_list_p, uint32_t arg_list_len);
|
|
||||||
ecma_value_t vm_execute (vm_frame_ctx_t *frame_ctx_p);
|
ecma_value_t vm_execute (vm_frame_ctx_t *frame_ctx_p);
|
||||||
|
|
||||||
bool vm_is_strict_mode (void);
|
bool vm_is_strict_mode (void);
|
||||||
|
|||||||
Reference in New Issue
Block a user