diff --git a/jerry-core/ecma/base/ecma-gc.cpp b/jerry-core/ecma/base/ecma-gc.cpp index 5d0d36684..21c1ab083 100644 --- a/jerry-core/ecma/base/ecma-gc.cpp +++ b/jerry-core/ecma/base/ecma-gc.cpp @@ -490,9 +490,9 @@ ecma_gc_run (void) frame_iter_p != NULL; frame_iter_p = frame_iter_p->prev_frame_p) { - for (int32_t reg_index = 0; reg_index < frame_iter_p->regs_number; reg_index++) + for (uint32_t reg_index = 0; reg_index < frame_iter_p->regs_number; reg_index++) { - ecma_value_t reg_value = vm_stack_frame_get_reg_value (frame_iter_p, reg_index); + ecma_value_t reg_value = vm_stack_frame_get_reg_value (frame_iter_p, VM_REG_FIRST + reg_index); if (ecma_is_value_object (reg_value)) { diff --git a/jerry-core/parser/js/opcodes-dumper.cpp b/jerry-core/parser/js/opcodes-dumper.cpp index 0f0ee948b..9f8237b2a 100644 --- a/jerry-core/parser/js/opcodes-dumper.cpp +++ b/jerry-core/parser/js/opcodes-dumper.cpp @@ -2398,8 +2398,7 @@ void dump_reg_var_decl_for_rewrite (void) { STACK_PUSH (reg_var_decls, serializer_get_current_instr_counter ()); - dump_triple_address (VM_OP_REG_VAR_DECL, - jsp_operand_t::make_idx_const_operand (VM_REG_FIRST), + dump_double_address (VM_OP_REG_VAR_DECL, jsp_operand_t::make_unknown_operand (), jsp_operand_t::make_unknown_operand ()); } @@ -2412,17 +2411,17 @@ rewrite_reg_var_decl (void) op_meta opm = serializer_get_op_meta (reg_var_decl_oc); JERRY_ASSERT (opm.op.op_idx == VM_OP_REG_VAR_DECL); + opm.op.data.reg_var_decl.tmp_regs_num = (vm_idx_t) (jsp_reg_max_for_temps - VM_REG_GENERAL_FIRST + 1); + if (jsp_reg_max_for_local_var != VM_IDX_EMPTY) { JERRY_ASSERT (jsp_reg_max_for_local_var >= jsp_reg_max_for_temps); opm.op.data.reg_var_decl.local_var_regs_num = (vm_idx_t) (jsp_reg_max_for_local_var - jsp_reg_max_for_temps); - opm.op.data.reg_var_decl.max = jsp_reg_max_for_local_var; jsp_reg_max_for_local_var = VM_IDX_EMPTY; } else { - opm.op.data.reg_var_decl.max = jsp_reg_max_for_temps; opm.op.data.reg_var_decl.local_var_regs_num = 0; } diff --git a/jerry-core/vm/opcodes-ecma-support.h b/jerry-core/vm/opcodes-ecma-support.h index da76a3e71..733f25f30 100644 --- a/jerry-core/vm/opcodes-ecma-support.h +++ b/jerry-core/vm/opcodes-ecma-support.h @@ -34,7 +34,7 @@ #include "ecma-try-catch-macro.h" #include "serializer.h" -bool is_reg_variable (vm_frame_ctx_t *, vm_idx_t); +bool vm_is_reg_variable (vm_idx_t); ecma_completion_value_t get_variable_value (vm_frame_ctx_t *, vm_idx_t, bool); ecma_completion_value_t set_variable_value (vm_frame_ctx_t *, vm_instr_counter_t, vm_idx_t, ecma_value_t); ecma_completion_value_t vm_fill_varg_list (vm_frame_ctx_t *, ecma_length_t, ecma_collection_header_t *); diff --git a/jerry-core/vm/opcodes-helpers-variables.cpp b/jerry-core/vm/opcodes-helpers-variables.cpp index 1ffefe8af..acf0166fc 100644 --- a/jerry-core/vm/opcodes-helpers-variables.cpp +++ b/jerry-core/vm/opcodes-helpers-variables.cpp @@ -59,11 +59,10 @@ do_strict_eval_arguments_check (ecma_object_t *ref_base_lex_env_p, /**< base of * false - otherwise. */ bool -is_reg_variable (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ - vm_idx_t var_idx) /**< variable identifier */ +vm_is_reg_variable (vm_idx_t var_idx) /**< variable identifier */ { - return (var_idx >= frame_ctx_p->min_reg_idx && var_idx <= frame_ctx_p->max_reg_idx); -} /* is_reg_variable */ + return (var_idx >= VM_REG_FIRST && var_idx <= VM_REG_LAST); +} /* vm_is_reg_variable */ /** * Get variable's value. @@ -79,10 +78,9 @@ get_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - if (is_reg_variable (frame_ctx_p, var_idx)) + if (vm_is_reg_variable (var_idx)) { - ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame, - var_idx - frame_ctx_p->min_reg_idx); + ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame, var_idx); JERRY_ASSERT (!ecma_is_value_empty (reg_value)); @@ -133,12 +131,11 @@ set_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - if (is_reg_variable (frame_ctx_p, var_idx)) + if (vm_is_reg_variable (var_idx)) { ret_value = ecma_make_empty_completion_value (); - ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame, - var_idx - frame_ctx_p->min_reg_idx); + ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame, var_idx); if (ecma_is_value_number (reg_value) && ecma_is_value_number (value)) @@ -152,9 +149,7 @@ set_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ ecma_free_value (reg_value, false); } - vm_stack_frame_set_reg_value (&frame_ctx_p->stack_frame, - var_idx - frame_ctx_p->min_reg_idx, - ecma_copy_value (value, false)); + vm_stack_frame_set_reg_value (&frame_ctx_p->stack_frame, var_idx, ecma_copy_value (value, false)); } } else diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index d77f84537..eacb66d37 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -689,7 +689,7 @@ vm_helper_call_get_call_flags_and_this_arg (vm_frame_ctx_t *int_data_p, /**< int if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG) { this_arg_var_idx = next_opcode.data.meta.data_2; - JERRY_ASSERT (is_reg_variable (int_data_p, this_arg_var_idx)); + JERRY_ASSERT (vm_is_reg_variable (this_arg_var_idx)); JERRY_ASSERT ((call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) == 0); } @@ -718,7 +718,7 @@ vm_helper_call_get_call_flags_and_this_arg (vm_frame_ctx_t *int_data_p, /**< int * See also: * parse_argument_list */ - if (!is_reg_variable (int_data_p, var_idx)) + if (!vm_is_reg_variable (var_idx)) { /* * FIXME [PERF]: @@ -1050,7 +1050,7 @@ opfunc_obj_decl (vm_instr_t instr, /**< instruction */ || type == OPCODE_META_TYPE_VARG_PROP_SETTER); const vm_idx_t prop_name_var_idx = next_opcode.data.meta.data_1; - JERRY_ASSERT (is_reg_variable (frame_ctx_p, prop_name_var_idx)); + JERRY_ASSERT (vm_is_reg_variable (prop_name_var_idx)); const vm_idx_t value_for_prop_desc_var_idx = next_opcode.data.meta.data_2; @@ -1495,7 +1495,7 @@ evaluate_arg_for_typeof (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context * { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - if (is_reg_variable (frame_ctx_p, var_idx)) + if (vm_is_reg_variable (var_idx)) { // 2.b ret_value = get_variable_value (frame_ctx_p, diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index 0e3f55177..04dd91e11 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -82,16 +82,26 @@ enum : vm_idx_t */ typedef enum : vm_idx_t { - VM_REG_FIRST = VM_IDX_REG_FIRST, /** identifier of first special register */ - VM_REG_LAST = VM_IDX_REG_LAST, /**< identifier of last register */ + VM_REG_FIRST = VM_IDX_REG_FIRST, /** first register */ + VM_REG_LAST = VM_IDX_REG_LAST, /**< last register */ - VM_REG_SPECIAL_EVAL_RET = VM_REG_FIRST, /**< eval return value */ + VM_REG_SPECIAL_FIRST = VM_REG_FIRST, /**< first special register */ + + VM_REG_SPECIAL_EVAL_RET = VM_REG_SPECIAL_FIRST, /**< eval return value */ VM_REG_SPECIAL_FOR_IN_PROPERTY_NAME, /**< variable, containing property name, * at start of for-in loop body */ - VM_REG_GENERAL_FIRST, /** identifier of first non-special register */ - VM_REG_GENERAL_LAST = VM_IDX_REG_LAST /** identifier of last non-special register */ + + VM_REG_SPECIAL_LAST = VM_REG_SPECIAL_FOR_IN_PROPERTY_NAME, /**< last special register */ + + VM_REG_GENERAL_FIRST, /** first non-special register */ + VM_REG_GENERAL_LAST = VM_IDX_REG_LAST /** last non-special register */ } vm_reg_t; +/** + * Number of special VM registers + */ +#define VM_SPECIAL_REGS_NUMBER (VM_REG_SPECIAL_LAST - VM_REG_SPECIAL_FIRST + 1u) + /** * Descriptor of assignment's second argument * that specifies type of third argument. @@ -201,8 +211,6 @@ typedef struct bool is_eval_code; /**< is current code executed with eval */ bool is_call_in_direct_eval_form; /** flag, indicating if there is call of 'Direct call to eval' form in * process (see also: OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) */ - vm_idx_t min_reg_idx; /**< minimum idx used for register identification */ - vm_idx_t max_reg_idx; /**< maximum idx used for register identification */ ecma_number_t *tmp_num_p; /**< an allocated number (to reduce temporary allocations) */ vm_stack_frame_t stack_frame; /**< stack frame associated with the context */ diff --git a/jerry-core/vm/pretty-printer.cpp b/jerry-core/vm/pretty-printer.cpp index 4ca17be6d..f0330acf4 100644 --- a/jerry-core/vm/pretty-printer.cpp +++ b/jerry-core/vm/pretty-printer.cpp @@ -221,7 +221,7 @@ pp_op_meta (const bytecode_data_header_t *bytecode_data_p, PP_OP (VM_OP_PRE_INCR, "%s = ++%s;"); PP_OP (VM_OP_PRE_DECR, "%s = --%s;"); PP_OP (VM_OP_THROW_VALUE, "throw %s;"); - PP_OP (VM_OP_REG_VAR_DECL, "var %s .. %s;"); + PP_OP (VM_OP_REG_VAR_DECL, "%d tmp regs, %d local variable regs"); PP_OP (VM_OP_VAR_DECL, "var %s;"); PP_OP (VM_OP_RETVAL, "return %s;"); PP_OP (VM_OP_RET, "ret;"); diff --git a/jerry-core/vm/vm-opcodes.inc.h b/jerry-core/vm/vm-opcodes.inc.h index 33c72e1d7..a2ba40a41 100644 --- a/jerry-core/vm/vm-opcodes.inc.h +++ b/jerry-core/vm/vm-opcodes.inc.h @@ -295,9 +295,8 @@ VM_OP_3 (is_false_jmp_down, IS_FALSE_JMP_DOWN, VM_OP_1 (var_decl, VAR_DECL, variable_name, VM_OP_ARG_TYPE_STRING) -VM_OP_3 (reg_var_decl, REG_VAR_DECL, - min, VM_OP_ARG_TYPE_REGISTER, - max, VM_OP_ARG_TYPE_REGISTER, +VM_OP_2 (reg_var_decl, REG_VAR_DECL, + tmp_regs_num, VM_OP_ARG_TYPE_INTEGER_CONST, local_var_regs_num, VM_OP_ARG_TYPE_INTEGER_CONST) VM_OP_3 (meta, META, diff --git a/jerry-core/vm/vm-stack.cpp b/jerry-core/vm/vm-stack.cpp index 984079a49..f02697034 100644 --- a/jerry-core/vm/vm-stack.cpp +++ b/jerry-core/vm/vm-stack.cpp @@ -76,9 +76,9 @@ vm_stack_get_top_frame (void) void vm_stack_add_frame (vm_stack_frame_t *frame_p, /**< frame to initialize */ ecma_value_t *regs_p, /**< array of register variables' values */ - int32_t regs_num, /**< total number of register variables */ - int32_t local_vars_regs_num) /**< number of register variables, - * used for local variables */ + uint32_t regs_num, /**< total number of register variables */ + uint32_t local_vars_regs_num) /**< number of register variables, + * used for local variables */ { frame_p->prev_frame_p = vm_stack_top_frame_p; vm_stack_top_frame_p = frame_p; @@ -89,12 +89,14 @@ vm_stack_add_frame (vm_stack_frame_t *frame_p, /**< frame to initialize */ frame_p->regs_p = regs_p; frame_p->regs_number = regs_num; - for (int32_t i = 0; i < regs_num - local_vars_regs_num; i++) + JERRY_ASSERT (regs_num >= VM_SPECIAL_REGS_NUMBER); + + for (uint32_t i = 0; i < regs_num - local_vars_regs_num; i++) { regs_p[i] = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); } - for (int32_t i = regs_num - local_vars_regs_num; + for (uint32_t i = regs_num - local_vars_regs_num; i < regs_num; i++) { @@ -121,7 +123,7 @@ vm_stack_free_frame (vm_stack_frame_t *frame_p) /**< frame to initialize */ vm_stack_pop (frame_p); } - for (int32_t reg_index = 0; + for (uint32_t reg_index = 0; reg_index < frame_p->regs_number; reg_index++) { @@ -136,11 +138,11 @@ vm_stack_free_frame (vm_stack_frame_t *frame_p) /**< frame to initialize */ */ ecma_value_t vm_stack_frame_get_reg_value (vm_stack_frame_t *frame_p, /**< frame */ - int32_t reg_index) /**< index of register variable */ + uint32_t reg_index) /**< index of register variable */ { - JERRY_ASSERT (reg_index >= 0 && reg_index < frame_p->regs_number); + JERRY_ASSERT (reg_index >= VM_REG_FIRST && reg_index < VM_REG_FIRST + frame_p->regs_number); - return frame_p->regs_p[reg_index]; + return frame_p->regs_p[reg_index - VM_REG_FIRST]; } /* vm_stack_frame_get_reg_value */ /** @@ -148,12 +150,12 @@ vm_stack_frame_get_reg_value (vm_stack_frame_t *frame_p, /**< frame */ */ void vm_stack_frame_set_reg_value (vm_stack_frame_t *frame_p, /**< frame */ - int32_t reg_index, /**< index of register variable */ + uint32_t reg_index, /**< index of register variable */ ecma_value_t value) /**< ecma-value */ { - JERRY_ASSERT (reg_index >= 0 && reg_index < frame_p->regs_number); + JERRY_ASSERT (reg_index >= VM_REG_FIRST && reg_index < VM_REG_FIRST + frame_p->regs_number); - frame_p->regs_p[reg_index] = value; + frame_p->regs_p[reg_index - VM_REG_FIRST] = value; } /* vm_stack_frame_set_reg_value */ /** diff --git a/jerry-core/vm/vm-stack.h b/jerry-core/vm/vm-stack.h index 8d304c0e5..ca6ef1409 100644 --- a/jerry-core/vm/vm-stack.h +++ b/jerry-core/vm/vm-stack.h @@ -52,7 +52,7 @@ typedef struct vm_stack_frame_t ecma_value_t inlined_values[VM_STACK_FRAME_INLINED_VALUES_NUMBER]; /**< place for values inlined into stack frame * (instead of being placed on heap) */ ecma_value_t *regs_p; /**< register variables */ - int32_t regs_number; /**< number of register variables */ + uint32_t regs_number; /**< number of register variables */ } vm_stack_frame_t; extern void vm_stack_init (void); @@ -60,10 +60,10 @@ extern void vm_stack_finalize (void); extern vm_stack_frame_t * vm_stack_get_top_frame (void); extern void -vm_stack_add_frame (vm_stack_frame_t *, ecma_value_t *, int32_t, int32_t); +vm_stack_add_frame (vm_stack_frame_t *, ecma_value_t *, uint32_t, uint32_t); extern void vm_stack_free_frame (vm_stack_frame_t *); -extern ecma_value_t vm_stack_frame_get_reg_value (vm_stack_frame_t *, int32_t); -extern void vm_stack_frame_set_reg_value (vm_stack_frame_t *, int32_t, ecma_value_t); +extern ecma_value_t vm_stack_frame_get_reg_value (vm_stack_frame_t *, uint32_t); +extern void vm_stack_frame_set_reg_value (vm_stack_frame_t *, uint32_t, ecma_value_t); extern void vm_stack_push_value (vm_stack_frame_t *, ecma_value_t); extern ecma_value_t vm_stack_top_value (vm_stack_frame_t *); extern void vm_stack_pop (vm_stack_frame_t *); diff --git a/jerry-core/vm/vm.cpp b/jerry-core/vm/vm.cpp index 94aca89f3..9a10706fe 100644 --- a/jerry-core/vm/vm.cpp +++ b/jerry-core/vm/vm.cpp @@ -605,12 +605,10 @@ vm_run_from_pos (const bytecode_data_header_t *header_p, /**< byte-code data hea const vm_instr_t *curr = &instrs_p[start_pos]; JERRY_ASSERT (curr->op_idx == VM_OP_REG_VAR_DECL); - const vm_idx_t min_reg_idx = curr->data.reg_var_decl.min; - const vm_idx_t max_reg_idx = curr->data.reg_var_decl.max; - const vm_idx_t local_var_regs_num = curr->data.reg_var_decl.local_var_regs_num; - JERRY_ASSERT (max_reg_idx >= min_reg_idx); + const uint32_t tmp_regs_num = curr->data.reg_var_decl.tmp_regs_num; + const uint32_t local_var_regs_num = curr->data.reg_var_decl.local_var_regs_num; - int32_t regs_num = max_reg_idx - min_reg_idx + 1; + uint32_t regs_num = VM_SPECIAL_REGS_NUMBER + tmp_regs_num + local_var_regs_num; MEM_DEFINE_LOCAL_ARRAY (regs, regs_num, ecma_value_t); @@ -622,9 +620,8 @@ vm_run_from_pos (const bytecode_data_header_t *header_p, /**< byte-code data hea frame_ctx.is_strict = is_strict; frame_ctx.is_eval_code = is_eval_code; frame_ctx.is_call_in_direct_eval_form = false; - frame_ctx.min_reg_idx = min_reg_idx; - frame_ctx.max_reg_idx = max_reg_idx; frame_ctx.tmp_num_p = ecma_alloc_number (); + vm_stack_add_frame (&frame_ctx.stack_frame, regs, regs_num, local_var_regs_num); vm_frame_ctx_t *prev_context_p = vm_top_context_p; diff --git a/tests/unit/test-parser.cpp b/tests/unit/test-parser.cpp index e649589ae..8e4f0c6dc 100644 --- a/tests/unit/test-parser.cpp +++ b/tests/unit/test-parser.cpp @@ -121,11 +121,11 @@ main (int __attr_unused___ argc, OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER, VM_IDX_EMPTY), - getop_reg_var_decl (VM_REG_FIRST, VM_REG_GENERAL_FIRST, 0), - getop_var_decl (0), // var a; - getop_assignment (130, 1, 1), // $tmp0 = 1; - getop_assignment (0, 6, 130), // a = $tmp0; - getop_ret () // return; + getop_reg_var_decl (1u, 0u), + getop_var_decl (0), // var a; + getop_assignment (VM_REG_GENERAL_FIRST, 1, 1), // $tmp0 = 1; + getop_assignment (0, 6, VM_REG_GENERAL_FIRST), // a = $tmp0; + getop_ret () // return; }; JERRY_ASSERT (instrs_equal (bytecode_data_p->instrs_p, instrs, 5));