diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 3e50a17c9..9485d67a4 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -562,6 +562,21 @@ ecma_gc_mark_executable_object (ecma_object_t *object_p) /**< object */ do { + if (VM_CONTEXT_IS_VARIABLE_LENGTH (VM_GET_CONTEXT_TYPE (context_top_p[-1]))) + { + ecma_value_t *last_item_p = context_top_p - VM_GET_CONTEXT_END (context_top_p[-1]); + JERRY_ASSERT (last_item_p >= context_end_p); + context_top_p--; + + do + { + ecma_gc_set_object_visited (ecma_get_object_from_value (*(--context_top_p))); + } + while (context_top_p > last_item_p); + + continue; + } + uint32_t offsets = vm_get_context_value_offsets (context_top_p); while (VM_CONTEXT_HAS_NEXT_OFFSET (offsets)) @@ -1245,6 +1260,21 @@ ecma_gc_free_executable_object (ecma_object_t *object_p) /**< object */ { context_top_p[-1] &= (uint32_t) ~VM_CONTEXT_HAS_LEX_ENV; + if (VM_CONTEXT_IS_VARIABLE_LENGTH (VM_GET_CONTEXT_TYPE (context_top_p[-1]))) + { + ecma_value_t *last_item_p = context_top_p - VM_GET_CONTEXT_END (context_top_p[-1]); + JERRY_ASSERT (last_item_p >= context_end_p); + context_top_p--; + + do + { + ecma_free_value_if_not_object (*(--context_top_p)); + } + while (context_top_p > last_item_p); + + continue; + } + uint32_t offsets = vm_get_context_value_offsets (context_top_p); while (VM_CONTEXT_HAS_NEXT_OFFSET (offsets)) diff --git a/jerry-core/ecma/operations/ecma-iterator-object.c b/jerry-core/ecma/operations/ecma-iterator-object.c index c8c89de26..38d9e6040 100644 --- a/jerry-core/ecma/operations/ecma-iterator-object.c +++ b/jerry-core/ecma/operations/ecma-iterator-object.c @@ -175,11 +175,8 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */ ecma_value_t method, /**< provided method argument */ ecma_value_t *next_method_p) /**< [out] next method */ { - if (next_method_p != NULL) - { - /* TODO: NULL support should be removed after all functions support next method caching. */ - *next_method_p = ECMA_VALUE_UNDEFINED; - } + JERRY_ASSERT (next_method_p != NULL); + *next_method_p = ECMA_VALUE_UNDEFINED; /* 1. */ if (ECMA_IS_VALUE_ERROR (value)) @@ -215,7 +212,7 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */ } /* 3. */ - if (!ecma_is_value_object (method) || !ecma_op_is_callable (method)) + if (!ecma_op_is_callable (method)) { ecma_free_value (method); return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator is not function")); @@ -242,84 +239,28 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */ return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator is not an object")); } - if (next_method_p != NULL) + ecma_object_t *obj_p = ecma_get_object_from_value (iterator); + ecma_value_t next_method = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NEXT); + + if (ECMA_IS_VALUE_ERROR (next_method)) { - ecma_object_t *obj_p = ecma_get_object_from_value (iterator); - ecma_value_t next_method = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NEXT); + ecma_free_value (iterator); + return next_method; + } - if (ECMA_IS_VALUE_ERROR (next_method)) - { - ecma_free_value (iterator); - return next_method; - } - - if (ecma_is_value_object (next_method) && ecma_op_is_callable (next_method)) - { - *next_method_p = next_method; - } - else - { - ecma_free_value (next_method); - } + if (ecma_is_value_object (next_method) && ecma_op_is_callable (next_method)) + { + *next_method_p = next_method; + } + else + { + ecma_free_value (next_method); } /* 6. */ return iterator; } /* ecma_op_get_iterator */ -/** - * IteratorNext operation - * - * See also: ECMA-262 v6, 7.4.2 - * - * Note: - * Returned value must be freed with ecma_free_value. - * - * @return iterator result object - if success - * raised error - otherwise - */ -static ecma_value_t -ecma_op_iterator_next_old (ecma_value_t iterator, /**< iterator value */ - ecma_value_t value) /**< the routines's value argument */ -{ - JERRY_ASSERT (ecma_is_value_object (iterator)); - - /* 1 - 2. */ - ecma_object_t *obj_p = ecma_get_object_from_value (iterator); - - ecma_value_t func_next = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NEXT); - - if (ECMA_IS_VALUE_ERROR (func_next)) - { - return func_next; - } - - if (!ecma_is_value_object (func_next) || !ecma_op_is_callable (func_next)) - { - ecma_free_value (func_next); - return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'next' is not callable")); - } - - ecma_object_t *next_obj_p = ecma_get_object_from_value (func_next); - - bool has_value = !ecma_is_value_empty (value); - - ecma_value_t result; - if (has_value) - { - result = ecma_op_function_call (next_obj_p, iterator, &value, 1); - } - else - { - result = ecma_op_function_call (next_obj_p, iterator, NULL, 0); - } - - ecma_free_value (func_next); - - /* 5. */ - return result; -} /* ecma_op_iterator_next_old */ - /** * IteratorNext operation * @@ -386,7 +327,7 @@ ecma_op_iterator_return (ecma_value_t iterator, /**< iterator value */ return ecma_create_iter_result_object (value, ECMA_VALUE_TRUE); } - if (!ecma_is_value_object (func_return) || !ecma_op_is_callable (func_return)) + if (!ecma_op_is_callable (func_return)) { ecma_free_value (func_return); return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' is not callable")); @@ -582,16 +523,7 @@ ecma_op_iterator_step (ecma_value_t iterator, /**< iterator value */ ecma_value_t next_method) /**< next method */ { /* 1. */ - ecma_value_t result; - if (next_method == ECMA_VALUE_EMPTY) - { - /* TODO: EMPTY support should be removed after all functions support next method caching. */ - result = ecma_op_iterator_next_old (iterator, ECMA_VALUE_EMPTY); - } - else - { - result = ecma_op_iterator_next (iterator, next_method, ECMA_VALUE_EMPTY); - } + ecma_value_t result = ecma_op_iterator_next (iterator, next_method, ECMA_VALUE_EMPTY); /* 2. */ if (ECMA_IS_VALUE_ERROR (result)) diff --git a/jerry-core/include/jerryscript-snapshot.h b/jerry-core/include/jerryscript-snapshot.h index 831bb4922..e70144c80 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 (63u) +#define JERRY_SNAPSHOT_VERSION (64u) /** * 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 ef63c3d5b..c3700d6a6 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 == 148, +JERRY_STATIC_ASSERT (CBC_EXT_END == 147, number_of_cbc_ext_opcodes_changed); #if ENABLED (JERRY_PARSER) || ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index cc6f25779..3ca28c4ee 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -202,6 +202,12 @@ #define PARSER_WITH_CONTEXT_STACK_ALLOCATION 1 /* PARSER_BLOCK_CONTEXT_STACK_ALLOCATION must be <= 3 */ #define PARSER_BLOCK_CONTEXT_STACK_ALLOCATION 1 +/* PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION must be <= 3 */ +#define PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION 3 +/* PARSER_OBJECT_INITIALIZER_CONTEXT_STACK_ALLOCATION must be <= 2 */ +#define PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION 1 +/* PARSER_OBJECT_INITIALIZER_CONTEXT_STACK_ALLOCATION must be <= 2 */ +#define PARSER_OBJ_INIT_REST_CONTEXT_STACK_ALLOCATION 2 /** * Extra stack consumption for finally context. @@ -573,7 +579,7 @@ CBC_FORWARD_BRANCH (CBC_EXT_FINALLY, PARSER_FINALLY_CONTEXT_EXTRA_STACK_ALLOCATION, \ VM_OC_FINALLY) \ CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_PROP, CBC_NO_FLAG, 0, \ - VM_OC_INITIALIZER_PUSH_PROP | VM_OC_GET_STACK) \ + VM_OC_INITIALIZER_PUSH_PROP) \ CBC_FORWARD_BRANCH (CBC_EXT_DEFAULT_INITIALIZER, -1, \ VM_OC_DEFAULT_INITIALIZER) \ CBC_OPCODE (CBC_EXT_ERROR, CBC_NO_FLAG, 0, \ @@ -746,26 +752,24 @@ 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_CONTEXT_CREATE, CBC_NO_FLAG, PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION, \ + VM_OC_ITERATOR_CONTEXT_CREATE) \ + CBC_OPCODE (CBC_EXT_ITERATOR_CONTEXT_END, CBC_NO_FLAG, -PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION, \ + VM_OC_ITERATOR_CONTEXT_END) \ CBC_OPCODE (CBC_EXT_ITERATOR_STEP, 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) \ \ /* Object initializer related opcodes. */ \ - CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_LIST, CBC_NO_FLAG, 1, \ - VM_OC_INITIALIZER_PUSH_LIST) \ - CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_REST, CBC_NO_FLAG, 0, \ - VM_OC_INITIALIZER_PUSH_REST) \ + CBC_OPCODE (CBC_EXT_OBJ_INIT_CONTEXT_CREATE, CBC_NO_FLAG, PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION, \ + VM_OC_OBJ_INIT_CONTEXT_CREATE) \ + CBC_OPCODE (CBC_EXT_OBJ_INIT_REST_CONTEXT_CREATE, CBC_NO_FLAG, PARSER_OBJ_INIT_REST_CONTEXT_STACK_ALLOCATION, \ + VM_OC_OBJ_INIT_CONTEXT_CREATE) \ + CBC_OPCODE (CBC_EXT_OBJ_INIT_PUSH_REST, CBC_NO_FLAG, 1, \ + VM_OC_OBJ_INIT_PUSH_REST) \ + CBC_OPCODE (CBC_EXT_OBJ_INIT_CONTEXT_END, CBC_NO_FLAG, -PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION, \ + VM_OC_OBJ_INIT_CONTEXT_END) \ CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_NAME, CBC_NO_FLAG, 0, \ VM_OC_INITIALIZER_PUSH_NAME | VM_OC_GET_STACK) \ CBC_OPCODE (CBC_EXT_INITIALIZER_PUSH_NAME_LITERAL, CBC_HAS_LITERAL_ARG, 1, \ diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 7f5f9f747..5851d85a7 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -2755,7 +2755,7 @@ parser_process_unary_expression (parser_context_t *context_p, /**< context */ * * @return - pushed assignment opcode onto the parser stack */ -static uint8_t +static void parser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */ uint32_t pattern_flags) /**< pattern flags */ { @@ -2899,8 +2899,6 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**< parser_stack_push_uint8 (context_p, assign_opcode); parser_stack_push_uint8 (context_p, LEXER_ASSIGN); - - return assign_opcode; } /* parser_append_binary_single_assignment_token */ #if ENABLED (JERRY_ESNEXT) @@ -3326,13 +3324,7 @@ 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); - - 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); - + parser_append_binary_single_assignment_token (context_p, flags); parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index); if (context_p->token.type == LEXER_ASSIGN && !(flags & PARSER_PATTERN_REST_ELEMENT)) @@ -3518,19 +3510,12 @@ 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); if (!PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode) && !PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode)) { 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); @@ -3547,7 +3532,7 @@ parser_parse_array_initializer (parser_context_t *context_p, /**< context */ parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags); lexer_next_token (context_p); - parser_emit_cbc_ext (context_p, CBC_EXT_GET_ITERATOR); + parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CONTEXT_CREATE); while (context_p->token.type != LEXER_RIGHT_SQUARE) { @@ -3583,7 +3568,7 @@ parser_parse_array_initializer (parser_context_t *context_p, /**< context */ } /* close the iterator */ - parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CLOSE); + parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CONTEXT_END); parser_pattern_finalize (context_p, flags, &end_pos); } /* parser_parse_array_initializer */ @@ -3606,11 +3591,15 @@ parser_parse_object_initializer (parser_context_t *context_p, /**< context */ return; } + cbc_ext_opcode_t context_opcode = CBC_EXT_OBJ_INIT_CONTEXT_CREATE; + if (flags & PARSER_PATTERN_HAS_REST_ELEMENT) { - parser_emit_cbc_ext (context_p, CBC_EXT_INITIALIZER_PUSH_LIST); + context_opcode = CBC_EXT_OBJ_INIT_REST_CONTEXT_CREATE; } + parser_emit_cbc_ext (context_p, context_opcode); + while (true) { lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_OBJECT_PATTERN); @@ -3633,7 +3622,7 @@ parser_parse_object_initializer (parser_context_t *context_p, /**< context */ if (parser_pattern_process_assignment (context_p, flags, - CBC_EXT_INITIALIZER_PUSH_REST, + CBC_EXT_OBJ_INIT_PUSH_REST, PARSER_PATTERN_RHS_NO_LIT, LEXER_RIGHT_BRACE)) { @@ -3724,6 +3713,14 @@ parser_parse_object_initializer (parser_context_t *context_p, /**< context */ } } + if (flags & PARSER_PATTERN_HAS_REST_ELEMENT) + { + PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, (PARSER_OBJ_INIT_REST_CONTEXT_STACK_ALLOCATION + - PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION)); + } + + parser_emit_cbc_ext (context_p, CBC_EXT_OBJ_INIT_CONTEXT_END); + parser_pattern_finalize (context_p, flags, &end_pos); } /* parser_parse_object_initializer */ diff --git a/jerry-core/vm/vm-stack.c b/jerry-core/vm/vm-stack.c index 923d4e07e..851c05e95 100644 --- a/jerry-core/vm/vm-stack.c +++ b/jerry-core/vm/vm-stack.c @@ -41,6 +41,41 @@ JERRY_STATIC_ASSERT (PARSER_WITH_CONTEXT_STACK_ALLOCATION == PARSER_TRY_CONTEXT_ JERRY_STATIC_ASSERT (PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION == PARSER_FOR_AWAIT_OF_CONTEXT_STACK_ALLOCATION, for_of_context_stack_allocation_must_be_equal_to_for_await_of_context_stack_allocation); +#if ENABLED (JERRY_ESNEXT) +/** + * Abort (finalize) the current variable length stack context, and remove it. + * + * @return new stack top + */ +ecma_value_t * +vm_stack_context_abort_variable_length (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ + ecma_value_t *vm_stack_top_p, /**< current stack top */ + uint32_t context_stack_allocation) /**< 0 - if all context element + * should be released + * context stack allocation - otherwise */ +{ + JERRY_ASSERT (VM_CONTEXT_IS_VARIABLE_LENGTH (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]))); + + uint32_t context_size = VM_GET_CONTEXT_END (vm_stack_top_p[-1]); + VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, context_size); + + JERRY_ASSERT (context_size > 0); + --vm_stack_top_p; + + if (context_stack_allocation == 0) + { + context_stack_allocation = context_size; + } + + for (uint32_t i = 1; i < context_stack_allocation; i++) + { + ecma_free_value (*(--vm_stack_top_p)); + } + + return vm_stack_top_p; +} /* vm_stack_context_abort_variable_length */ +#endif /* ENABLED (JERRY_ESNEXT) */ + /** * Abort (finalize) the current stack context, and remove it. * @@ -86,6 +121,13 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ break; } #if ENABLED (JERRY_ESNEXT) + case VM_CONTEXT_ITERATOR: + case VM_CONTEXT_OBJ_INIT: + case VM_CONTEXT_OBJ_INIT_REST: + { + vm_stack_top_p = vm_stack_context_abort_variable_length (frame_ctx_p, vm_stack_top_p, 0); + break; + } case VM_CONTEXT_FOR_OF: case VM_CONTEXT_FOR_AWAIT_OF: { @@ -189,16 +231,16 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ while (frame_ctx_p->context_depth > 0) { - vm_stack_context_type_t context_type; + vm_stack_context_type_t context_type = VM_GET_CONTEXT_TYPE (stack_top_p[-1]); uint32_t context_end = VM_GET_CONTEXT_END (stack_top_p[-1]); + JERRY_ASSERT (!VM_CONTEXT_IS_VARIABLE_LENGTH (context_type) || finally_type != VM_CONTEXT_FINALLY_JUMP); - if (search_limit < context_end) + if (!VM_CONTEXT_IS_VARIABLE_LENGTH (context_type) && search_limit < context_end) { frame_ctx_p->stack_top_p = stack_top_p; return VM_CONTEXT_FOUND_EXPECTED; } - context_type = VM_GET_CONTEXT_TYPE (stack_top_p[-1]); if (context_type == VM_CONTEXT_TRY || context_type == VM_CONTEXT_CATCH) { const uint8_t *byte_code_p; @@ -314,7 +356,9 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ #if ENABLED (JERRY_ESNEXT) else if (stack_top_p[-1] & VM_CONTEXT_CLOSE_ITERATOR) { - JERRY_ASSERT (context_type == VM_CONTEXT_FOR_OF || context_type == VM_CONTEXT_FOR_AWAIT_OF); + JERRY_ASSERT (context_type == VM_CONTEXT_FOR_OF + || context_type == VM_CONTEXT_FOR_AWAIT_OF + || context_type == VM_CONTEXT_ITERATOR); JERRY_ASSERT (finally_type == VM_CONTEXT_FINALLY_THROW || !jcontext_has_pending_exception ()); ecma_value_t exception = ECMA_VALUE_UNDEFINED; @@ -323,62 +367,71 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ exception = jcontext_take_exception (); } - ecma_value_t iterator = stack_top_p[-3]; - ecma_value_t result = ecma_op_get_method_by_magic_id (iterator, LIT_MAGIC_STRING_RETURN); + ecma_value_t result; - if (!ECMA_IS_VALUE_ERROR (result) && !ecma_is_value_undefined (result)) + if (context_type == VM_CONTEXT_ITERATOR) { - if (!ecma_is_value_object (result) || !ecma_op_is_callable (result)) - { - ecma_free_value (result); - result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' is not callable")); - } - else - { - ecma_object_t *return_obj_p = ecma_get_object_from_value (result); - result = ecma_op_function_call (return_obj_p, iterator, NULL, 0); - ecma_deref_object (return_obj_p); + result = ecma_op_iterator_close (stack_top_p[-2]); + } + else + { + ecma_value_t iterator = stack_top_p[-3]; + result = ecma_op_get_method_by_magic_id (iterator, LIT_MAGIC_STRING_RETURN); - if (context_type == VM_CONTEXT_FOR_AWAIT_OF && !ECMA_IS_VALUE_ERROR (result)) + if (!ECMA_IS_VALUE_ERROR (result) && !ecma_is_value_undefined (result)) + { + if (!ecma_op_is_callable (result)) { - ecma_extended_object_t *async_generator_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p); + ecma_free_value (result); + result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' is not callable")); + } + else + { + ecma_object_t *return_obj_p = ecma_get_object_from_value (result); + result = ecma_op_function_call (return_obj_p, iterator, NULL, 0); + ecma_deref_object (return_obj_p); - result = ecma_promise_async_await (async_generator_object_p, result); + if (context_type == VM_CONTEXT_FOR_AWAIT_OF && !ECMA_IS_VALUE_ERROR (result)) + { + ecma_extended_object_t *async_generator_object_p = VM_GET_EXECUTABLE_OBJECT (frame_ctx_p); + + result = ecma_promise_async_await (async_generator_object_p, result); + + if (!ECMA_IS_VALUE_ERROR (result)) + { + uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD + | (ECMA_AWAIT_FOR_CLOSE << ECMA_AWAIT_STATE_SHIFT)); + async_generator_object_p->u.class_prop.extra_info |= extra_flags; + + stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p); + + VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FINALLY_CONTEXT_STACK_ALLOCATION); + stack_top_p += PARSER_FINALLY_CONTEXT_STACK_ALLOCATION; + + stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, context_end); + if (finally_type == VM_CONTEXT_FINALLY_THROW) + { + stack_top_p[-2] = exception; + } + + frame_ctx_p->call_operation = VM_EXEC_RETURN; + frame_ctx_p->byte_code_p = vm_stack_resume_executable_object_with_context_end; + frame_ctx_p->stack_top_p = stack_top_p; + return VM_CONTEXT_FOUND_AWAIT; + } + } if (!ECMA_IS_VALUE_ERROR (result)) { - uint16_t extra_flags = (ECMA_EXECUTABLE_OBJECT_DO_AWAIT_OR_YIELD - | (ECMA_AWAIT_FOR_CLOSE << ECMA_AWAIT_STATE_SHIFT)); - async_generator_object_p->u.class_prop.extra_info |= extra_flags; + bool is_object = ecma_is_value_object (result); - stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p); + ecma_free_value (result); + result = ECMA_VALUE_UNDEFINED; - VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FINALLY_CONTEXT_STACK_ALLOCATION); - stack_top_p += PARSER_FINALLY_CONTEXT_STACK_ALLOCATION; - - stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, context_end); - if (finally_type == VM_CONTEXT_FINALLY_THROW) + if (!is_object) { - stack_top_p[-2] = exception; + result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' result is not object")); } - - frame_ctx_p->call_operation = VM_EXEC_RETURN; - frame_ctx_p->byte_code_p = vm_stack_resume_executable_object_with_context_end; - frame_ctx_p->stack_top_p = stack_top_p; - return VM_CONTEXT_FOUND_AWAIT; - } - } - - if (!ECMA_IS_VALUE_ERROR (result)) - { - bool is_object = ecma_is_value_object (result); - - ecma_free_value (result); - result = ECMA_VALUE_UNDEFINED; - - if (!is_object) - { - result = ecma_raise_type_error (ECMA_ERR_MSG ("Iterator 'return' result is not object")); } } } @@ -487,6 +540,28 @@ vm_ref_lex_env_chain (ecma_object_t *lex_env_p, /**< top of lexical environment lex_env_p = next_lex_env_p; } + if (VM_CONTEXT_IS_VARIABLE_LENGTH (VM_GET_CONTEXT_TYPE (context_top_p[-1]))) + { + ecma_value_t *last_item_p = context_top_p - VM_GET_CONTEXT_END (context_top_p[-1]); + JERRY_ASSERT (last_item_p >= context_end_p); + context_top_p--; + + do + { + if (do_ref) + { + ecma_ref_if_object (*(--context_top_p)); + } + else + { + ecma_deref_if_object (*(--context_top_p)); + } + } + while (context_top_p > last_item_p); + + continue; + } + uint32_t offsets = vm_get_context_value_offsets (context_top_p); while (VM_CONTEXT_HAS_NEXT_OFFSET (offsets)) diff --git a/jerry-core/vm/vm-stack.h b/jerry-core/vm/vm-stack.h index 49b33ef3c..2dae2e1b0 100644 --- a/jerry-core/vm/vm-stack.h +++ b/jerry-core/vm/vm-stack.h @@ -75,6 +75,11 @@ typedef enum #if ENABLED (JERRY_ESNEXT) VM_CONTEXT_FOR_OF, /**< for-of context */ VM_CONTEXT_FOR_AWAIT_OF, /**< for-await-of context */ + + /* contexts with variable length */ + VM_CONTEXT_ITERATOR, /**< iterator context */ + VM_CONTEXT_OBJ_INIT, /**< object-initializer context */ + VM_CONTEXT_OBJ_INIT_REST, /**< object-initializer-rest context */ #endif /* ENABLED (JERRY_ESNEXT) */ } vm_stack_context_type_t; @@ -91,6 +96,21 @@ typedef enum VM_CONTEXT_FOUND_EXPECTED, /**< found the type specified in finally_type */ } vm_stack_found_type; +/** + * Checks whether the context has variable context size + * + * Layout: + * - [context descriptor] + * - [JS values belong to the context] + * - [previous JS values stored by the VM stack] + */ +#if ENABLED (JERRY_ESNEXT) +#define VM_CONTEXT_IS_VARIABLE_LENGTH(context_type) \ + ((context_type) >= VM_CONTEXT_ITERATOR) +#else /* !ENABLED (JERRY_ESNEXT) */ +#define VM_CONTEXT_IS_VARIABLE_LENGTH(context_type) false +#endif /* ENABLED (JERRY_ESNEXT) */ + /** * Checks whether the context type is a finally type. */ @@ -112,6 +132,10 @@ typedef enum */ #define VM_CONTEXT_GET_NEXT_OFFSET(offsets) (-((int32_t) ((offsets) & ((1 << VM_CONTEXT_OFFSET_SHIFT) - 1)))) +#if ENABLED (JERRY_ESNEXT) +ecma_value_t *vm_stack_context_abort_variable_length (vm_frame_ctx_t *frame_ctx_p, ecma_value_t *vm_stack_top_p, + uint32_t context_stack_allocation); +#endif /* ENABLED (JERRY_ESNEXT) */ ecma_value_t *vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, ecma_value_t *vm_stack_top_p); vm_stack_found_type vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, ecma_value_t *stack_top_p, vm_stack_context_type_t finally_type, uint32_t search_limit); diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 396264c8e..06a40becc 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1001,6 +1001,12 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; \ } +/** + * Get the end of the existing topmost context + */ +#define VM_LAST_CONTEXT_END() \ + (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth) + /** * Run generic byte code. * @@ -2307,24 +2313,39 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ *stack_top_p++ = result; continue; } - case VM_OC_GET_ITERATOR: + case VM_OC_ITERATOR_CONTEXT_CREATE: { - 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, &left_value); if (ECMA_IS_VALUE_ERROR (result)) { goto error; } - *stack_top_p++ = result; + uint32_t context_size = (uint32_t) (stack_top_p + + PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION + - VM_LAST_CONTEXT_END ()); + stack_top_p += PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION; + VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, context_size); + + stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_ITERATOR, context_size) | VM_CONTEXT_CLOSE_ITERATOR; + stack_top_p[-2] = result; + stack_top_p[-3] = left_value; + continue; } case VM_OC_ITERATOR_STEP: { - result = ecma_op_iterator_step (stack_top_p[-1], ECMA_VALUE_EMPTY); + ecma_value_t *last_context_end_p = VM_LAST_CONTEXT_END (); + + ecma_value_t iterator = last_context_end_p[-2]; + ecma_value_t next_method = last_context_end_p[-3]; + + result = ecma_op_iterator_step (iterator, next_method); if (ECMA_IS_VALUE_ERROR (result)) { + last_context_end_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; goto error; } @@ -2337,24 +2358,38 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (ECMA_IS_VALUE_ERROR (value)) { + last_context_end_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; result = value; goto error; } } + else + { + last_context_end_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; + } *stack_top_p++ = value; continue; } - case VM_OC_ITERATOR_CLOSE: + case VM_OC_ITERATOR_CONTEXT_END: { - result = ecma_op_iterator_close (left_value); + JERRY_ASSERT (VM_LAST_CONTEXT_END () == stack_top_p); - if (ECMA_IS_VALUE_ERROR (result)) + if (stack_top_p[-1] & VM_CONTEXT_CLOSE_ITERATOR) { - goto error; + stack_top_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; + result = ecma_op_iterator_close (stack_top_p[-2]); + + if (ECMA_IS_VALUE_ERROR (result)) + { + goto error; + } } - goto free_left_value; + stack_top_p = vm_stack_context_abort_variable_length (frame_ctx_p, + stack_top_p, + PARSER_ITERATOR_CONTEXT_STACK_ALLOCATION); + continue; } case VM_OC_DEFAULT_INITIALIZER: { @@ -2373,21 +2408,26 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_object_t *array_p = ecma_op_new_array_object (0); JERRY_ASSERT (ecma_op_object_is_fast_array (array_p)); - ecma_value_t iterator = stack_top_p[-1]; + + ecma_value_t *last_context_end_p = VM_LAST_CONTEXT_END (); + ecma_value_t iterator = last_context_end_p[-2]; + ecma_value_t next_method = last_context_end_p[-3]; uint32_t index = 0; while (true) { - result = ecma_op_iterator_step (iterator, ECMA_VALUE_EMPTY); + result = ecma_op_iterator_step (iterator, next_method); if (ECMA_IS_VALUE_ERROR (result)) { + last_context_end_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; ecma_deref_object (array_p); goto error; } if (ecma_is_value_false (result)) { + last_context_end_p[-1] &= (uint32_t) ~VM_CONTEXT_CLOSE_ITERATOR; break; } @@ -2409,16 +2449,51 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ *stack_top_p++ = ecma_make_object_value (array_p); continue; } - case VM_OC_INITIALIZER_PUSH_LIST: + case VM_OC_OBJ_INIT_CONTEXT_CREATE: { - stack_top_p++; - stack_top_p[-1] = stack_top_p[-2]; - stack_top_p[-2] = ecma_make_object_value (ecma_op_new_array_object (0)); + left_value = stack_top_p[-1]; + vm_stack_context_type_t context_type = VM_CONTEXT_OBJ_INIT; + uint32_t context_stack_allocation = PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION; + + if (opcode == CBC_EXT_OBJ_INIT_REST_CONTEXT_CREATE) + { + context_type = VM_CONTEXT_OBJ_INIT_REST; + context_stack_allocation = PARSER_OBJ_INIT_REST_CONTEXT_STACK_ALLOCATION; + } + + uint32_t context_size = (uint32_t) (stack_top_p + context_stack_allocation - VM_LAST_CONTEXT_END ()); + stack_top_p += context_stack_allocation; + VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, context_size); + + stack_top_p[-1] = VM_CREATE_CONTEXT (context_type, context_size); + stack_top_p[-2] = left_value; + + if (context_type == VM_CONTEXT_OBJ_INIT_REST) + { + stack_top_p[-3] = ecma_make_object_value (ecma_op_new_array_object (0)); + } continue; } - case VM_OC_INITIALIZER_PUSH_REST: + case VM_OC_OBJ_INIT_CONTEXT_END: { - if (!ecma_op_require_object_coercible (stack_top_p[-1])) + JERRY_ASSERT (stack_top_p == VM_LAST_CONTEXT_END ()); + + uint32_t context_stack_allocation = PARSER_OBJ_INIT_CONTEXT_STACK_ALLOCATION; + + if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_OBJ_INIT_REST) + { + context_stack_allocation = PARSER_OBJ_INIT_REST_CONTEXT_STACK_ALLOCATION; + } + + stack_top_p = vm_stack_context_abort_variable_length (frame_ctx_p, + stack_top_p, + context_stack_allocation); + continue; + } + case VM_OC_OBJ_INIT_PUSH_REST: + { + ecma_value_t *last_context_end_p = VM_LAST_CONTEXT_END (); + if (!ecma_op_require_object_coercible (last_context_end_p[-2])) { result = ECMA_VALUE_ERROR; goto error; @@ -2428,16 +2503,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_object_t *result_object_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL); left_value = ecma_make_object_value (result_object_p); - result = opfunc_copy_data_properties (left_value, stack_top_p[-1], stack_top_p[-2]); + result = opfunc_copy_data_properties (left_value, last_context_end_p[-2], last_context_end_p[-3]); if (ECMA_IS_VALUE_ERROR (result)) { goto error; } - ecma_free_value (stack_top_p[-2]); - stack_top_p[-2] = stack_top_p[-1]; - stack_top_p[-1] = left_value; + ecma_free_value (last_context_end_p[-3]); + last_context_end_p[-3] = last_context_end_p[-2]; + last_context_end_p[-2] = ECMA_VALUE_UNDEFINED; + + *stack_top_p++ = left_value; continue; } case VM_OC_INITIALIZER_PUSH_NAME: @@ -2456,7 +2533,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ left_value = ecma_make_string_value (property_key); } - ecma_object_t *array_obj_p = ecma_get_object_from_value (stack_top_p[-2]); + ecma_value_t *last_context_end_p = VM_LAST_CONTEXT_END (); + ecma_object_t *array_obj_p = ecma_get_object_from_value (last_context_end_p[-3]); JERRY_ASSERT (ecma_get_object_type (array_obj_p) == ECMA_OBJECT_TYPE_ARRAY); ecma_extended_object_t *ext_array_obj_p = (ecma_extended_object_t *) array_obj_p; @@ -2465,7 +2543,21 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } case VM_OC_INITIALIZER_PUSH_PROP: { - result = vm_op_get_value (stack_top_p[-1], left_value); + ecma_value_t *last_context_end_p = VM_LAST_CONTEXT_END (); + right_value = last_context_end_p[-2]; + + if (opcode == CBC_EXT_INITIALIZER_PUSH_PROP) + { + left_value = *last_context_end_p++; + while (last_context_end_p < stack_top_p) + { + last_context_end_p[-1] = *last_context_end_p; + last_context_end_p++; + } + stack_top_p--; + } + + result = vm_op_get_value (right_value, left_value); if (ECMA_IS_VALUE_ERROR (result)) { @@ -2475,21 +2567,6 @@ 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 b567789df..7cb64443e 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -275,16 +275,16 @@ typedef enum 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_ITERATOR_CONTEXT_CREATE, /**< create iterator conext */ + VM_OC_ITERATOR_CONTEXT_END, /**< finalize iterator cotnext */ VM_OC_ITERATOR_STEP, /**< IteratorStep abstract operation */ - VM_OC_ITERATOR_CLOSE, /**< IteratorClose abstract operation */ - VM_OC_INITIALIZER_PUSH_LIST, /**< push name list array */ - VM_OC_INITIALIZER_PUSH_REST, /**< push the object with the rest properties */ + VM_OC_OBJ_INIT_CONTEXT_CREATE, /**< create object initializer context */ + VM_OC_OBJ_INIT_CONTEXT_END, /**< finalize object initializer context */ + VM_OC_OBJ_INIT_PUSH_REST, /**< push the object with the rest properties */ VM_OC_INITIALIZER_PUSH_NAME, /**< append string to name list array and push the string */ 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 */ @@ -362,16 +362,16 @@ typedef enum 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_ITERATOR_CONTEXT_CREATE = VM_OC_NONE, /**< create iterator context */ VM_OC_ITERATOR_STEP = VM_OC_NONE, /**< IteratorStep abstract operation */ - VM_OC_ITERATOR_CLOSE = VM_OC_NONE, /**< IteratorClose abstract operation */ - VM_OC_INITIALIZER_PUSH_LIST = VM_OC_NONE, /**< push name list array */ - VM_OC_INITIALIZER_PUSH_REST = VM_OC_NONE, /**< push the object with the rest properties */ + VM_OC_ITERATOR_CONTEXT_END = VM_OC_NONE, /**< finalize iterator cotnext */ + VM_OC_OBJ_INIT_CONTEXT_CREATE = VM_OC_NONE, /**< create object initializer context */ + VM_OC_OBJ_INIT_CONTEXT_END = VM_OC_NONE, /**< finalize object initializer context */ + VM_OC_OBJ_INIT_PUSH_REST = VM_OC_NONE, /**< push the object with the rest properties */ VM_OC_INITIALIZER_PUSH_NAME = VM_OC_NONE, /**< append string to name list array and push the string */ 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 1f51dff25..c6765514f 100644 --- a/tests/jerry/es.next/array-pattern.js +++ b/tests/jerry/es.next/array-pattern.js @@ -38,6 +38,14 @@ function mustThrow (str) { } } +function mustNotThrow (str) { + try { + eval (str); + } catch (e) { + assert (false); + } +} + checkSyntax ("var [a]"); checkSyntax ("var [a, o.a]"); checkSyntax ("var [a, ...b,]"); @@ -329,32 +337,32 @@ function __createIterableObject (arr, methods) { assert (x.prop === "42"); }) (); -mustThrow ("var iter = __createIterableObject([], " - + "{ get 'return'() { throw new TypeError() }});" - + "var [a] = iter"); +mustThrow (`var iter = __createIterableObject([], + { get 'return'() { throw new TypeError() }}); + var [a] = iter`); -mustThrow ("var iter = __createIterableObject([], " - + "{ 'return': 5 });" - + "var [a] = iter"); +mustNotThrow (`var iter = __createIterableObject([], + { 'return': 5 }); + var [a] = iter`); -mustThrow ("var iter = __createIterableObject([], " - + "{ 'return': function() { return 5; }});" - + "var [a] = iter"); +mustNotThrow (`var iter = __createIterableObject([], + { 'return': function() { return 5; }}); + var [a] = iter`); -mustThrow ("try { throw 5 } catch (e) {" - + "var iter = __createIterableObject([], " - + "{ get 'return'() { throw new TypeError() }});" - + "var [a] = iter }"); +mustThrow (`try { throw 5 } catch (e) { + var iter = __createIterableObject([], + { get 'return'() { throw new TypeError() }}); + var [a] = iter }`); -mustThrow ("try { throw 5 } catch (e) {" - + "var iter = __createIterableObject([], " - + "{ 'return': 5 });" - + "var [a] = iter }"); +mustNotThrow (`try { throw 5 } catch (e) { + var iter = __createIterableObject([], + { 'return': 5 }); + var [a] = iter }`); -mustThrow ("try { throw 5 } catch (e) {" - + "var iter = __createIterableObject([], " - + "{ 'return': function() { return 5; }});" - + "var [a] = iter }"); +mustNotThrow (`try { throw 5 } catch (e) { + var iter = __createIterableObject([], + { 'return': function() { return 5; }}); + var [a] = iter }`); try { eval ("var a = 0; 1 + [a] = [1]"); diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 5be6bec89..863d7c479 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -203,8 +203,6 @@ - - @@ -220,34 +218,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -262,14 +232,6 @@ - - - - - - - - @@ -282,21 +244,13 @@ - - - - - - - - @@ -490,17 +444,8 @@ - - - - - - - - - @@ -523,37 +468,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -568,19 +482,12 @@ - - - - - - - @@ -598,7 +505,6 @@ - @@ -631,10 +537,8 @@ - - @@ -7282,10 +7186,6 @@ - - - - @@ -7341,10 +7241,6 @@ - - - - @@ -7810,8 +7706,6 @@ - - @@ -7837,8 +7731,6 @@ - - @@ -7880,10 +7772,6 @@ - - - -