Improve destructuring patterns (#4527)

- Fix evaluation order of the operands
- Implement proper iterator closing of array destructuring
- Support next method caching

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2021-02-04 13:11:11 +01:00
committed by GitHub
parent 3bb67397a0
commit e7d11eaf9e
12 changed files with 389 additions and 354 deletions
+1 -1
View File
@@ -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)
+19 -15
View File
@@ -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, \
+18 -21
View File
@@ -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 */