Improve the performance of the interpreter. (#3344)
Registers are stored immediately after the frame pointer and an argument is dropped from vm_run. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
committed by
Robert Fancsik
parent
996bf76f59
commit
d006f068f4
@@ -851,7 +851,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t ret_value = vm_run (bytecode_data_p,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
ECMA_PARSE_NO_OPTS,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
@@ -914,7 +913,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t ret_value = vm_run (bytecode_data_p,
|
||||
arrow_func_p->this_binding,
|
||||
local_env_p,
|
||||
ECMA_PARSE_NO_OPTS,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
|
||||
@@ -43,13 +43,10 @@ typedef struct vm_frame_ctx_t
|
||||
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
|
||||
uint8_t *byte_code_p; /**< current byte code pointer */
|
||||
uint8_t *byte_code_start_p; /**< byte code start pointer */
|
||||
ecma_value_t *registers_p; /**< register start pointer */
|
||||
ecma_value_t *stack_top_p; /**< stack top pointer */
|
||||
ecma_value_t *literal_start_p; /**< literal list start pointer */
|
||||
ecma_object_t *lex_env_p; /**< current lexical environment */
|
||||
#if defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO)
|
||||
struct vm_frame_ctx_t *prev_context_p; /**< previous context */
|
||||
#endif /* defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO) */
|
||||
ecma_value_t this_binding; /**< this binding */
|
||||
ecma_value_t block_result; /**< block result */
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
@@ -61,8 +58,19 @@ typedef struct vm_frame_ctx_t
|
||||
uint16_t context_depth; /**< current context depth */
|
||||
uint8_t is_eval_code; /**< eval mode flag */
|
||||
uint8_t call_operation; /**< perform a call or construct operation */
|
||||
/* Registers start immediately after the frame context. */
|
||||
} vm_frame_ctx_t;
|
||||
|
||||
/**
|
||||
* Get register list corresponding to the frame context.
|
||||
*/
|
||||
#define VM_GET_REGISTERS(frame_ctx_p) ((ecma_value_t *) (frame_ctx_p + 1))
|
||||
|
||||
/**
|
||||
* Read or write a specific register.
|
||||
*/
|
||||
#define VM_GET_REGISTER(frame_ctx_p, i) (((ecma_value_t *) (frame_ctx_p + 1))[i])
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
+136
-115
@@ -43,6 +43,11 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Special constant to represent direct eval code.
|
||||
*/
|
||||
#define VM_DIRECT_EVAL ((void *) 0x1)
|
||||
|
||||
/**
|
||||
* Get the value of object[property].
|
||||
*
|
||||
@@ -260,7 +265,6 @@ vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode
|
||||
return vm_run (bytecode_p,
|
||||
ecma_make_object_value (glob_obj_p),
|
||||
lex_env_p,
|
||||
false,
|
||||
NULL,
|
||||
0);
|
||||
} /* vm_run_module */
|
||||
@@ -282,7 +286,6 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
|
||||
return vm_run (bytecode_p,
|
||||
ecma_make_object_value (glob_obj_p),
|
||||
ecma_get_global_environment (),
|
||||
false,
|
||||
NULL,
|
||||
0);
|
||||
} /* vm_run_global */
|
||||
@@ -346,8 +349,7 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
|
||||
ecma_value_t completion_value = vm_run (bytecode_data_p,
|
||||
this_binding,
|
||||
lex_env_p,
|
||||
parse_opts,
|
||||
NULL,
|
||||
(parse_opts & ECMA_PARSE_DIRECT_EVAL) ? VM_DIRECT_EVAL : NULL,
|
||||
0);
|
||||
|
||||
ecma_deref_object (lex_env_p);
|
||||
@@ -842,7 +844,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
if ((literal_index) < register_end) \
|
||||
{ \
|
||||
/* Note: There should be no specialization for arguments. */ \
|
||||
(target_value) = ecma_fast_copy_value (frame_ctx_p->registers_p[literal_index]); \
|
||||
(target_value) = ecma_fast_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@@ -973,7 +975,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
if (value_index < register_end)
|
||||
{
|
||||
/* Take (not copy) the reference. */
|
||||
lit_value = ecma_copy_value_if_not_object (frame_ctx_p->registers_p[value_index]);
|
||||
lit_value = ecma_copy_value_if_not_object (VM_GET_REGISTER (frame_ctx_p, value_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -983,8 +985,8 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (literal_index < register_end)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]);
|
||||
frame_ctx_p->registers_p[literal_index] = lit_value;
|
||||
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
VM_GET_REGISTER (frame_ctx_p, literal_index) = lit_value;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1080,8 +1082,8 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (literal_index < register_end)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]);
|
||||
frame_ctx_p->registers_p[literal_index] = lit_value;
|
||||
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
VM_GET_REGISTER (frame_ctx_p, literal_index) = lit_value;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1205,7 +1207,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_GET_STACK_LITERAL:
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
right_value = left_value;
|
||||
left_value = *(--stack_top_p);
|
||||
break;
|
||||
@@ -1226,12 +1228,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
JERRY_ASSERT (operands == VM_OC_GET_STACK
|
||||
|| operands == VM_OC_GET_STACK_STACK);
|
||||
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
left_value = *(--stack_top_p);
|
||||
|
||||
if (operands == VM_OC_GET_STACK_STACK)
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
right_value = left_value;
|
||||
left_value = *(--stack_top_p);
|
||||
}
|
||||
@@ -1295,7 +1297,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
case VM_OC_POP:
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
ecma_free_value (*(--stack_top_p));
|
||||
continue;
|
||||
}
|
||||
@@ -1651,7 +1653,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
stack_top_p[-1] = VM_CREATE_CONTEXT_WITH_ENV (VM_CONTEXT_SUPER_CLASS, branch_offset);
|
||||
|
||||
frame_ctx_p->lex_env_p = super_env_p;
|
||||
|
||||
continue;
|
||||
}
|
||||
case VM_OC_CLASS_INHERITANCE:
|
||||
@@ -1978,7 +1979,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_DEFAULT_INITIALIZER:
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
|
||||
if (stack_top_p[-1] != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
@@ -2100,7 +2101,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
*stack_top_p++ = ECMA_VALUE_REGISTER_REF;
|
||||
*stack_top_p++ = literal_index;
|
||||
*stack_top_p++ = ecma_fast_copy_value (frame_ctx_p->registers_p[literal_index]);
|
||||
*stack_top_p++ = ecma_fast_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2344,8 +2345,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
JERRY_ASSERT (literal_index < register_end);
|
||||
JERRY_ASSERT (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)));
|
||||
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]);
|
||||
frame_ctx_p->registers_p[literal_index] = left_value;
|
||||
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
VM_GET_REGISTER (frame_ctx_p, literal_index) = left_value;
|
||||
continue;
|
||||
}
|
||||
case VM_OC_ASSIGN_PROP:
|
||||
@@ -2489,7 +2490,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
ecma_value_t value = *(--stack_top_p);
|
||||
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end);
|
||||
|
||||
if (ecma_op_strict_equality_compare (value, stack_top_p[-1]))
|
||||
{
|
||||
@@ -2585,7 +2586,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (literal_index < register_end)
|
||||
{
|
||||
left_value = ecma_copy_value (frame_ctx_p->registers_p[literal_index]);
|
||||
left_value = ecma_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3194,7 +3195,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
case VM_OC_BLOCK_CREATE_CONTEXT:
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ecma_value_t *stack_context_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
ecma_value_t *stack_context_top_p;
|
||||
stack_context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
|
||||
|
||||
JERRY_ASSERT (stack_context_top_p == stack_top_p || stack_context_top_p == stack_top_p - 1);
|
||||
|
||||
if (byte_code_start_p[0] != CBC_EXT_OPCODE)
|
||||
@@ -3249,7 +3252,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
result = ecma_op_to_object (value);
|
||||
ecma_free_value (value);
|
||||
@@ -3279,7 +3282,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
ecma_value_t value = *(--stack_top_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_value_t expr_obj_value = ECMA_VALUE_UNDEFINED;
|
||||
ecma_collection_t *prop_names_p = opfunc_for_in (value, &expr_obj_value);
|
||||
@@ -3312,7 +3315,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_FOR_IN_GET_NEXT:
|
||||
{
|
||||
ecma_value_t *context_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
ecma_value_t *context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
|
||||
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_top_p[-2]);
|
||||
@@ -3328,7 +3331,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_FOR_IN_HAS_NEXT:
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, stack_top_p[-2]);
|
||||
@@ -3371,7 +3374,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
ecma_value_t value = *(--stack_top_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_value_t iterator = ecma_op_get_iterator (value, ECMA_VALUE_EMPTY);
|
||||
|
||||
@@ -3416,7 +3419,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_FOR_OF_GET_NEXT:
|
||||
{
|
||||
ecma_value_t *context_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
ecma_value_t *context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (context_top_p[-1]) == VM_CONTEXT_FOR_OF);
|
||||
|
||||
ecma_value_t next_value = ecma_op_iterator_value (context_top_p[-2]);
|
||||
@@ -3432,7 +3435,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_FOR_OF_HAS_NEXT:
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_value_t iterator_step = ecma_op_iterator_step (stack_top_p[-3]);
|
||||
|
||||
@@ -3463,7 +3466,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
/* Try opcode simply creates the try context. */
|
||||
branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p += PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
@@ -3474,7 +3477,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
case VM_OC_CATCH:
|
||||
{
|
||||
/* Catches are ignored and turned to jumps. */
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_TRY);
|
||||
|
||||
byte_code_p = byte_code_start_p + branch_offset;
|
||||
@@ -3484,7 +3487,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_TRY
|
||||
|| VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH);
|
||||
@@ -3505,7 +3508,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_CONTEXT_END:
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
ecma_value_t context_type = VM_GET_CONTEXT_TYPE (stack_top_p[-1]);
|
||||
|
||||
@@ -3513,7 +3516,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p);
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3567,12 +3570,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
byte_code_p = frame_ctx_p->byte_code_start_p + jump_target;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
continue;
|
||||
}
|
||||
case VM_OC_JUMP_AND_EXIT_CONTEXT:
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p);
|
||||
|
||||
@@ -3590,7 +3593,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
byte_code_p = frame_ctx_p->byte_code_start_p + branch_offset;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
continue;
|
||||
}
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
@@ -3711,9 +3714,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (literal_index < register_end)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]);
|
||||
|
||||
frame_ctx_p->registers_p[literal_index] = result;
|
||||
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
|
||||
VM_GET_REGISTER (frame_ctx_p, literal_index) = result;
|
||||
|
||||
if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))
|
||||
{
|
||||
@@ -3749,9 +3751,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (object == ECMA_VALUE_REGISTER_REF)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[property]);
|
||||
|
||||
frame_ctx_p->registers_p[property] = result;
|
||||
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, property));
|
||||
VM_GET_REGISTER (frame_ctx_p, property) = result;
|
||||
|
||||
if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
|
||||
{
|
||||
@@ -3805,7 +3806,7 @@ error:
|
||||
{
|
||||
ecma_value_t *vm_stack_p = stack_top_p;
|
||||
|
||||
for (vm_stack_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
for (vm_stack_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
|
||||
vm_stack_p < stack_top_p;
|
||||
vm_stack_p++)
|
||||
{
|
||||
@@ -3820,7 +3821,7 @@ error:
|
||||
}
|
||||
}
|
||||
|
||||
stack_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
stack_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
const uint32_t dont_stop = (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION
|
||||
| JERRY_DEBUGGER_VM_IGNORE
|
||||
@@ -3854,7 +3855,7 @@ error:
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
}
|
||||
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
if (frame_ctx_p->context_depth == 0)
|
||||
{
|
||||
@@ -3873,7 +3874,7 @@ error:
|
||||
0))
|
||||
{
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_RETURN);
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
byte_code_p = frame_ctx_p->byte_code_p;
|
||||
stack_top_p[-2] = result;
|
||||
@@ -3887,7 +3888,7 @@ error:
|
||||
VM_CONTEXT_FINALLY_THROW,
|
||||
0))
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (!(stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV));
|
||||
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
@@ -3914,7 +3915,7 @@ error:
|
||||
{
|
||||
do
|
||||
{
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p);
|
||||
}
|
||||
@@ -3932,19 +3933,29 @@ error:
|
||||
#undef READ_LITERAL_INDEX
|
||||
|
||||
/**
|
||||
* Execute code block.
|
||||
* Initialize code block execution
|
||||
*
|
||||
* @return ecma value
|
||||
*/
|
||||
static ecma_value_t JERRY_ATTR_NOINLINE
|
||||
vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
const ecma_value_t *arg_p, /**< arguments list */
|
||||
ecma_length_t arg_list_len) /**< length of arguments list */
|
||||
static void JERRY_ATTR_NOINLINE
|
||||
vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
const ecma_value_t *arg_p, /**< arguments list */
|
||||
ecma_length_t arg_list_len) /**< length of arguments list */
|
||||
{
|
||||
frame_ctx_p->prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED;
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
frame_ctx_p->resource_name = ECMA_VALUE_UNDEFINED;
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
#if ENABLED (JERRY_LINE_INFO)
|
||||
frame_ctx_p->current_line = 0;
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||
frame_ctx_p->context_depth = 0;
|
||||
frame_ctx_p->is_eval_code = (arg_p == VM_DIRECT_EVAL);
|
||||
|
||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
||||
ecma_value_t completion_value;
|
||||
uint16_t argument_end;
|
||||
uint16_t register_end;
|
||||
uint16_t argument_end, register_end;
|
||||
ecma_value_t *literal_p;
|
||||
|
||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
@@ -3952,6 +3963,11 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
argument_end = args_p->argument_end;
|
||||
register_end = args_p->register_end;
|
||||
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_p -= register_end;
|
||||
frame_ctx_p->literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3959,9 +3975,16 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
argument_end = args_p->argument_end;
|
||||
register_end = args_p->register_end;
|
||||
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_p -= register_end;
|
||||
frame_ctx_p->literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
}
|
||||
|
||||
frame_ctx_p->stack_top_p = frame_ctx_p->registers_p + register_end;
|
||||
frame_ctx_p->byte_code_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;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
uint32_t function_call_argument_count = arg_list_len;
|
||||
@@ -3974,14 +3997,14 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
for (uint32_t i = 0; i < arg_list_len; i++)
|
||||
{
|
||||
frame_ctx_p->registers_p[i] = ecma_fast_copy_value (arg_p[i]);
|
||||
VM_GET_REGISTER (frame_ctx_p, i) = ecma_fast_copy_value (arg_p[i]);
|
||||
}
|
||||
|
||||
/* The arg_list_len contains the end of the copied arguments.
|
||||
* Fill everything else with undefined. */
|
||||
if (register_end > arg_list_len)
|
||||
{
|
||||
ecma_value_t *stack_p = frame_ctx_p->registers_p + arg_list_len;
|
||||
ecma_value_t *stack_p = VM_GET_REGISTERS (frame_ctx_p) + arg_list_len;
|
||||
|
||||
for (uint32_t i = arg_list_len; i < register_end; i++)
|
||||
{
|
||||
@@ -3997,21 +4020,27 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
function_call_argument_count - arg_list_len,
|
||||
false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
frame_ctx_p->registers_p[argument_end] = new_array;
|
||||
arg_list_len++;
|
||||
VM_GET_REGISTER (frame_ctx_p, argument_end) = new_array;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
|
||||
|
||||
vm_frame_ctx_t *prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p;
|
||||
|
||||
vm_init_loop (frame_ctx_p);
|
||||
} /* vm_init_exec */
|
||||
|
||||
/**
|
||||
* Resume execution of a code block.
|
||||
*
|
||||
* @return ecma value
|
||||
*/
|
||||
static ecma_value_t JERRY_ATTR_NOINLINE
|
||||
vm_execute (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
completion_value = vm_loop (frame_ctx_p);
|
||||
ecma_value_t completion_value = vm_loop (frame_ctx_p);
|
||||
|
||||
switch (frame_ctx_p->call_operation)
|
||||
{
|
||||
@@ -4041,10 +4070,23 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
{
|
||||
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;
|
||||
uint32_t register_end;
|
||||
|
||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
register_end = ((cbc_uint16_arguments_t *) bytecode_header_p)->register_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
register_end = ((cbc_uint8_arguments_t *) bytecode_header_p)->register_end;
|
||||
}
|
||||
|
||||
/* Free arguments and registers */
|
||||
ecma_value_t *registers_p = VM_GET_REGISTERS (frame_ctx_p);
|
||||
for (uint32_t i = 0; i < register_end; i++)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[i]);
|
||||
ecma_fast_free_value (registers_p[i]);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
@@ -4056,7 +4098,7 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
|
||||
JERRY_CONTEXT (vm_top_context_p) = prev_context_p;
|
||||
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p->prev_context_p;
|
||||
return completion_value;
|
||||
}
|
||||
}
|
||||
@@ -4072,56 +4114,11 @@ ecma_value_t
|
||||
vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */
|
||||
ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment to use */
|
||||
uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
|
||||
const ecma_value_t *arg_list_p, /**< arguments list */
|
||||
ecma_length_t arg_list_len) /**< length of arguments list */
|
||||
{
|
||||
ecma_value_t *literal_p;
|
||||
vm_frame_ctx_t frame_ctx;
|
||||
uint32_t call_stack_size;
|
||||
|
||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint16_arguments_t));
|
||||
literal_p -= args_p->register_end;
|
||||
frame_ctx.literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
|
||||
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
|
||||
|
||||
literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint8_arguments_t));
|
||||
literal_p -= args_p->register_end;
|
||||
frame_ctx.literal_start_p = literal_p;
|
||||
literal_p += args_p->literal_end;
|
||||
}
|
||||
|
||||
frame_ctx.bytecode_header_p = bytecode_header_p;
|
||||
frame_ctx.byte_code_p = (uint8_t *) literal_p;
|
||||
frame_ctx.byte_code_start_p = (uint8_t *) literal_p;
|
||||
frame_ctx.lex_env_p = lex_env_p;
|
||||
#if defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO)
|
||||
frame_ctx.prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
#endif /* defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO) */
|
||||
frame_ctx.this_binding = this_binding_value;
|
||||
frame_ctx.block_result = ECMA_VALUE_UNDEFINED;
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
frame_ctx.resource_name = ECMA_VALUE_UNDEFINED;
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
#if ENABLED (JERRY_LINE_INFO)
|
||||
frame_ctx.current_line = 0;
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||
frame_ctx.context_depth = 0;
|
||||
frame_ctx.is_eval_code = parse_opts & ECMA_PARSE_DIRECT_EVAL;
|
||||
|
||||
/* Use JERRY_MAX() to avoid array declaration with size 0. */
|
||||
JERRY_VLA (ecma_value_t, stack, JERRY_MAX (call_stack_size, 1));
|
||||
frame_ctx.registers_p = stack;
|
||||
vm_frame_ctx_t *frame_ctx_p;
|
||||
size_t frame_size;
|
||||
|
||||
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
if (JERRY_CONTEXT (module_top_context_p) != NULL)
|
||||
@@ -4144,7 +4141,31 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
return vm_execute (&frame_ctx, arg_list_p, arg_list_len);
|
||||
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
|
||||
frame_size = (size_t) (args_p->register_end + args_p->stack_limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
|
||||
frame_size = (size_t) (args_p->register_end + args_p->stack_limit);
|
||||
}
|
||||
|
||||
frame_size = frame_size * sizeof (ecma_value_t) + sizeof (vm_frame_ctx_t);
|
||||
frame_size = (frame_size + sizeof (uintptr_t) - 1) / sizeof (uintptr_t);
|
||||
|
||||
/* Use JERRY_MAX() to avoid array declaration with size 0. */
|
||||
JERRY_VLA (uintptr_t, stack, frame_size);
|
||||
|
||||
frame_ctx_p = (vm_frame_ctx_t *) stack;
|
||||
|
||||
frame_ctx_p->bytecode_header_p = bytecode_header_p;
|
||||
frame_ctx_p->lex_env_p = lex_env_p;
|
||||
frame_ctx_p->this_binding = this_binding_value;
|
||||
|
||||
vm_init_exec (frame_ctx_p, arg_list_p, arg_list_len);
|
||||
return vm_execute (frame_ctx_p);
|
||||
} /* vm_run */
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -399,8 +399,7 @@ ecma_value_t vm_run_module (const ecma_compiled_code_t *bytecode_p, ecma_object_
|
||||
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
ecma_value_t vm_run (const ecma_compiled_code_t *bytecode_header_p, ecma_value_t this_binding_value,
|
||||
ecma_object_t *lex_env_p, uint32_t parse_opts, const ecma_value_t *arg_list_p,
|
||||
ecma_length_t arg_list_len);
|
||||
ecma_object_t *lex_env_p, const ecma_value_t *arg_list_p, ecma_length_t arg_list_len);
|
||||
|
||||
bool vm_is_strict_mode (void);
|
||||
bool vm_is_direct_eval_form_call (void);
|
||||
|
||||
Reference in New Issue
Block a user