diff --git a/jerry-core/include/jerryscript-snapshot.h b/jerry-core/include/jerryscript-snapshot.h index 6416739c8..29b6b9080 100644 --- a/jerry-core/include/jerryscript-snapshot.h +++ b/jerry-core/include/jerryscript-snapshot.h @@ -30,7 +30,7 @@ extern "C" /** * Jerry snapshot format version. */ -#define JERRY_SNAPSHOT_VERSION (19u) +#define JERRY_SNAPSHOT_VERSION (20u) /** * Flags for jerry_generate_snapshot and jerry_generate_function_snapshot. diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index ba558b03d..34dc876b2 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -590,6 +590,8 @@ VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \ CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \ VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \ + CBC_OPCODE (CBC_EXT_RESOLVE_BASE, CBC_NO_FLAG, 0, \ + VM_OC_RESOLVE_BASE_FOR_CALL) \ \ /* Class opcodes */ \ CBC_OPCODE (CBC_EXT_INHERIT_AND_SET_CONSTRUCTOR, CBC_NO_FLAG, 0, \ diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 1d8de008c..a42027b62 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -1556,6 +1556,8 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */ CBC_PUSH_IDENT_REFERENCE, context_p->last_cbc.third_literal_index); } + + parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE); } } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index c0d8e313e..3333eba86 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -476,26 +476,8 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ bool is_call_prop = ((opcode - CBC_CALL) % 6) >= 3; - ecma_value_t this_value = ECMA_VALUE_UNDEFINED; ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len; - - if (is_call_prop) - { - this_value = stack_top_p[-3]; - - if (this_value == ECMA_VALUE_REGISTER_REF) - { - /* Lexical environment cannot be 'this' value. */ - stack_top_p[-2] = ECMA_VALUE_UNDEFINED; - this_value = ECMA_VALUE_UNDEFINED; - } - else if (vm_get_implicit_this_value (&this_value)) - { - ecma_free_value (stack_top_p[-3]); - stack_top_p[-3] = this_value; - } - } - + ecma_value_t this_value = is_call_prop ? stack_top_p[-3] : ECMA_VALUE_UNDEFINED; ecma_value_t func_value = stack_top_p[-1]; ecma_value_t completion_value; @@ -1978,6 +1960,24 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ *stack_top_p++ = result; continue; } + case VM_OC_RESOLVE_BASE_FOR_CALL: + { + ecma_value_t this_value = stack_top_p[-3]; + + if (this_value == ECMA_VALUE_REGISTER_REF) + { + /* Lexical environment cannot be 'this' value. */ + stack_top_p[-2] = ECMA_VALUE_UNDEFINED; + stack_top_p[-3] = ECMA_VALUE_UNDEFINED; + } + else if (vm_get_implicit_this_value (&this_value)) + { + ecma_free_value (stack_top_p[-3]); + stack_top_p[-3] = this_value; + } + + continue; + } case VM_OC_PROP_DELETE: { result = vm_op_delete_prop (left_value, right_value, is_strict); diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 0dc8649d3..92f248c26 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -158,6 +158,7 @@ typedef enum VM_OC_EVAL, /**< eval */ VM_OC_CALL, /**< call */ VM_OC_NEW, /**< new */ + VM_OC_RESOLVE_BASE_FOR_CALL, /**< resolve base value before call */ VM_OC_JUMP, /**< jump */ VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if stric equal */ diff --git a/tests/unit-core/test-snapshot.c b/tests/unit-core/test-snapshot.c index aa9f85fe0..219d8181f 100644 --- a/tests/unit-core/test-snapshot.c +++ b/tests/unit-core/test-snapshot.c @@ -223,7 +223,7 @@ main (void) /* Check the snapshot data. Unused bytes should be filled with zeroes */ const uint8_t expected_data[] = { - 0x4A, 0x52, 0x52, 0x59, 0x13, 0x00, 0x00, 0x00, + 0x4A, 0x52, 0x52, 0x59, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,