diff --git a/jerry-core/include/jerryscript-snapshot.h b/jerry-core/include/jerryscript-snapshot.h index fde0b09ab..3c958aa2d 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 (56u) +#define JERRY_SNAPSHOT_VERSION (57u) /** * Flags for jerry_generate_snapshot and jerry_generate_function_snapshot. diff --git a/jerry-core/parser/js/byte-code.c b/jerry-core/parser/js/byte-code.c index f04e6f6f3..38b5bc205 100644 --- a/jerry-core/parser/js/byte-code.c +++ b/jerry-core/parser/js/byte-code.c @@ -27,7 +27,7 @@ JERRY_STATIC_ASSERT ((sizeof (cbc_uint16_arguments_t) % sizeof (jmem_cpointer_t) */ JERRY_STATIC_ASSERT (CBC_END == 238, number_of_cbc_opcodes_changed); -JERRY_STATIC_ASSERT (CBC_EXT_END == 136, +JERRY_STATIC_ASSERT (CBC_EXT_END == 135, number_of_cbc_ext_opcodes_changed); #if ENABLED (JERRY_PARSER) diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index 3302eb28f..ce6ff9fba 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -724,24 +724,22 @@ VM_OC_APPEND_ARRAY) \ CBC_OPCODE (CBC_EXT_REST_INITIALIZER, CBC_NO_FLAG, 1, \ VM_OC_REST_INITIALIZER) \ - CBC_OPCODE (CBC_EXT_REST_INITIALIZER_2, CBC_NO_FLAG, 1, \ - VM_OC_REST_INITIALIZER) \ - CBC_OPCODE (CBC_EXT_REST_INITIALIZER_3, CBC_NO_FLAG, 1, \ - VM_OC_REST_INITIALIZER) \ CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 1, \ VM_OC_INITIALIZER_PUSH_PROP | VM_OC_GET_LITERAL) \ CBC_OPCODE (CBC_EXT_SPREAD_NEW, CBC_HAS_POP_STACK_BYTE_ARG, 0, \ VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_STACK) \ + CBC_OPCODE (CBC_EXT_MOVE, CBC_NO_FLAG, 0, \ + VM_OC_MOVE) \ + CBC_OPCODE (CBC_EXT_MOVE_2, CBC_NO_FLAG, 0, \ + VM_OC_MOVE) \ + CBC_OPCODE (CBC_EXT_MOVE_3, CBC_NO_FLAG, 0, \ + VM_OC_MOVE) \ \ /* Iterator related opcodes. */ \ CBC_OPCODE (CBC_EXT_GET_ITERATOR, CBC_NO_FLAG, 1, \ VM_OC_GET_ITERATOR) \ CBC_OPCODE (CBC_EXT_ITERATOR_STEP, CBC_NO_FLAG, 1, \ VM_OC_ITERATOR_STEP) \ - CBC_OPCODE (CBC_EXT_ITERATOR_STEP_2, CBC_NO_FLAG, 1, \ - VM_OC_ITERATOR_STEP) \ - CBC_OPCODE (CBC_EXT_ITERATOR_STEP_3, CBC_NO_FLAG, 1, \ - VM_OC_ITERATOR_STEP) \ CBC_OPCODE (CBC_EXT_ITERATOR_CLOSE, CBC_NO_FLAG, -1, \ VM_OC_ITERATOR_CLOSE | VM_OC_GET_STACK) \ \ diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 816a1614b..55ca97d67 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -3192,13 +3192,10 @@ parser_pattern_form_assignment (parser_context_t *context_p, /**< context */ parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START); uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, flags); - if (flags & PARSER_PATTERN_ARRAY) - { - int32_t stack_adjustment = (CBC_STACK_ADJUST_BASE - (cbc_flags[assign_opcode] >> CBC_STACK_ADJUST_SHIFT)); - JERRY_ASSERT (stack_adjustment >= 1 && stack_adjustment <= 3); + int32_t stack_adjustment = (CBC_STACK_ADJUST_BASE - (cbc_flags[assign_opcode] >> CBC_STACK_ADJUST_SHIFT)); + JERRY_ASSERT (stack_adjustment >= 1 && stack_adjustment <= 3); - rhs_opcode = (uint16_t) (rhs_opcode + stack_adjustment - 1); - } + rhs_opcode = (uint16_t) (rhs_opcode + stack_adjustment - 1); parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index); @@ -3366,6 +3363,9 @@ parser_pattern_process_assignment (parser_context_t *context_p, /**< context */ } else { + /* RHS should be evaulated first */ + parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index); + parser_flush_cbc (context_p); parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_LEFT_HAND_SIDE); @@ -3373,6 +3373,9 @@ parser_pattern_process_assignment (parser_context_t *context_p, /**< context */ { parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN); } + + rhs_opcode = CBC_EXT_MOVE; + literal_index = PARSER_PATTERN_RHS_NO_LIT; } parser_pattern_form_assignment (context_p, flags, rhs_opcode, literal_index, ident_line_counter); @@ -3386,7 +3389,6 @@ parser_parse_array_initializer (parser_context_t *context_p, /**< context */ parser_pattern_flags_t flags) /**< flags */ { parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags); - flags |= PARSER_PATTERN_ARRAY; lexer_next_token (context_p); parser_emit_cbc_ext (context_p, CBC_EXT_GET_ITERATOR); diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index e6af2c21e..888370495 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -115,7 +115,6 @@ typedef enum PARSER_PATTERN_LOCAL = (1u << 6), /**< pattern is a local (catch parameter) declaration */ PARSER_PATTERN_REST_ELEMENT = (1u << 7), /**< parse rest array initializer */ PARSER_PATTERN_ARGUMENTS = (1u << 8), /**< parse arguments binding */ - PARSER_PATTERN_ARRAY = (1u << 9), /**< array pattern is being parsed */ } parser_pattern_flags_t; /** diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 73989dbaf..2499a574e 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -2142,9 +2142,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } case VM_OC_ITERATOR_STEP: { - JERRY_ASSERT (opcode >= CBC_EXT_ITERATOR_STEP && opcode <= CBC_EXT_ITERATOR_STEP_3); - const uint8_t index = (uint8_t) (1 + (opcode - CBC_EXT_ITERATOR_STEP)); - result = ecma_op_iterator_step (stack_top_p[-index], ECMA_VALUE_EMPTY); + result = ecma_op_iterator_step (stack_top_p[-1], ECMA_VALUE_EMPTY); if (ECMA_IS_VALUE_ERROR (result)) { @@ -2194,10 +2192,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } case VM_OC_REST_INITIALIZER: { - JERRY_ASSERT (opcode >= CBC_EXT_REST_INITIALIZER && opcode <= CBC_EXT_REST_INITIALIZER_3); - const uint8_t iterator_index = (uint8_t) (1 + (opcode - CBC_EXT_REST_INITIALIZER)); ecma_object_t *array_p = ecma_op_new_fast_array_object (0); - ecma_value_t iterator = stack_top_p[-iterator_index]; + ecma_value_t iterator = stack_top_p[-1]; uint32_t index = 0; while (true) @@ -2245,6 +2241,21 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ *stack_top_p++ = result; goto free_left_value; } + case VM_OC_MOVE: + { + JERRY_ASSERT (opcode >= CBC_EXT_MOVE && opcode <= CBC_EXT_MOVE_3); + const uint8_t index = (uint8_t) (1 + (opcode - CBC_EXT_MOVE)); + + ecma_value_t element = stack_top_p[-index]; + + for (int32_t i = -index; i < -1; i++) + { + stack_top_p[i] = stack_top_p[i + 1]; + } + + stack_top_p[-1] = element; + continue; + } case VM_OC_SPREAD_ARGUMENTS: { uint8_t arguments_list_len = *byte_code_p++; diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 056322ec5..5ad9e1b83 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -274,6 +274,7 @@ typedef enum VM_OC_DEFAULT_INITIALIZER, /**< default initializer inside a pattern */ VM_OC_REST_INITIALIZER, /**< create rest object inside an array pattern */ VM_OC_INITIALIZER_PUSH_PROP, /**< push property for object initializer */ + VM_OC_MOVE, /**< move element to the stack-top */ VM_OC_SPREAD_ARGUMENTS, /**< perform function call/construct with spreaded arguments */ VM_OC_CREATE_GENERATOR, /**< create a generator object */ VM_OC_YIELD, /**< yield operation */ @@ -350,6 +351,7 @@ typedef enum VM_OC_DEFAULT_INITIALIZER = VM_OC_NONE, /**< default initializer inside a pattern */ VM_OC_REST_INITIALIZER = VM_OC_NONE, /**< create rest object inside an array pattern */ VM_OC_INITIALIZER_PUSH_PROP = VM_OC_NONE, /**< push property for object initializer */ + VM_OC_MOVE = VM_OC_NONE, /**< move element to the stack-top */ VM_OC_SPREAD_ARGUMENTS = VM_OC_NONE, /**< perform function call/construct with spreaded arguments */ VM_OC_CREATE_GENERATOR = VM_OC_NONE, /**< create a generator object */ VM_OC_YIELD = VM_OC_NONE, /**< yield operation */ diff --git a/tests/jerry/es.next/array-pattern.js b/tests/jerry/es.next/array-pattern.js index 86b1969be..1f51dff25 100644 --- a/tests/jerry/es.next/array-pattern.js +++ b/tests/jerry/es.next/array-pattern.js @@ -281,6 +281,54 @@ function __createIterableObject (arr, methods) { assert (b === 2); }) (); +(function () { + var value = { y: "42" }; + var x = {}; + var assignmentResult, iterationResult, iter; + + iter = (function*() { + assignmentResult = { y: x[yield] } = value; + }()); + + iterationResult = iter.next(); + + assert (assignmentResult === undefined); + assert (iterationResult.value === undefined); + assert (iterationResult.done === false); + assert (x.prop === undefined); + + iterationResult = iter.next('prop'); + + assert (assignmentResult === value); + assert (iterationResult.value === undefined); + assert (iterationResult.done === true); + assert (x.prop === "42"); +}) (); + +(function () { + var value = { foo: "42" }; + var x = {}; + var assignmentResult, iterationResult, iter; + + iter = (function*() { + assignmentResult = { ['f' + 'o' + 'o']: x[yield] } = value; + }()); + + iterationResult = iter.next(); + + assert (assignmentResult === undefined); + assert (iterationResult.value === undefined); + assert (iterationResult.done === false); + assert (x.prop === undefined); + + iterationResult = iter.next('prop'); + + assert (assignmentResult === value); + assert (iterationResult.value === undefined); + assert (iterationResult.done === true); + assert (x.prop === "42"); +}) (); + mustThrow ("var iter = __createIterableObject([], " + "{ get 'return'() { throw new TypeError() }});" + "var [a] = iter"); diff --git a/tests/jerry/es.next/object-pattern.js b/tests/jerry/es.next/object-pattern.js index e55aae2af..e4165ec88 100644 --- a/tests/jerry/es.next/object-pattern.js +++ b/tests/jerry/es.next/object-pattern.js @@ -226,6 +226,14 @@ mustThrow ("function f ({}) {}; f();"); assert (a === 7); }) (); +(function () { + var o = {}; + + ({ a : o.c } = { get a() { return 5.2 }}) + + assert(o.c == 5.2); +}) (); + try { eval ("var a = 0; -{a} = {a:1}"); assert (false); diff --git a/tests/test262-es6-excludelist.xml b/tests/test262-es6-excludelist.xml index d01545488..716eccd0c 100644 --- a/tests/test262-es6-excludelist.xml +++ b/tests/test262-es6-excludelist.xml @@ -255,10 +255,6 @@ No longer a SyntaxError in ES11 - - - - diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 5af5acdc8..b30d68ef8 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -3047,10 +3047,6 @@ - - - - @@ -4624,10 +4620,6 @@ - - - -