1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "js-parser-internal.h" 17425bb815Sopenharmony_ci 18425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER) 19425bb815Sopenharmony_ci#include "jcontext.h" 20425bb815Sopenharmony_ci 21425bb815Sopenharmony_ci#include "ecma-helpers.h" 22425bb815Sopenharmony_ci#include "lit-char-helpers.h" 23425bb815Sopenharmony_ci#include "js-parser-tagged-template-literal.h" 24425bb815Sopenharmony_ci 25425bb815Sopenharmony_ci/** \addtogroup parser Parser 26425bb815Sopenharmony_ci * @{ 27425bb815Sopenharmony_ci * 28425bb815Sopenharmony_ci * \addtogroup jsparser JavaScript 29425bb815Sopenharmony_ci * @{ 30425bb815Sopenharmony_ci * 31425bb815Sopenharmony_ci * \addtogroup jsparser_expr Expression parser 32425bb815Sopenharmony_ci * @{ 33425bb815Sopenharmony_ci */ 34425bb815Sopenharmony_ci 35425bb815Sopenharmony_ci/** 36425bb815Sopenharmony_ci * Maximum precedence for right-to-left binary operation evaluation. 37425bb815Sopenharmony_ci */ 38425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 6 39425bb815Sopenharmony_ci 40425bb815Sopenharmony_ci/** 41425bb815Sopenharmony_ci * Precedence for ternary operation. 42425bb815Sopenharmony_ci */ 43425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE 4 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ci/** 46425bb815Sopenharmony_ci * Precedence for exponentiation operation. 47425bb815Sopenharmony_ci */ 48425bb815Sopenharmony_ci#define PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION 15 49425bb815Sopenharmony_ci 50425bb815Sopenharmony_ci/** 51425bb815Sopenharmony_ci * Value of grouping level increase and decrease. 52425bb815Sopenharmony_ci */ 53425bb815Sopenharmony_ci#define PARSER_GROUPING_LEVEL_INCREASE 2 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_ci/** 56425bb815Sopenharmony_ci * Precedence of the binary tokens. 57425bb815Sopenharmony_ci * 58425bb815Sopenharmony_ci * See also: 59425bb815Sopenharmony_ci * lexer_token_type_t 60425bb815Sopenharmony_ci */ 61425bb815Sopenharmony_cistatic const uint8_t parser_binary_precedence_table[] = 62425bb815Sopenharmony_ci{ 63425bb815Sopenharmony_ci 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 64425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 65425bb815Sopenharmony_ci 3, 66425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 67425bb815Sopenharmony_ci 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 68425bb815Sopenharmony_ci 11, 11, 11, 11, 11, 11, 12, 12, 12, 69425bb815Sopenharmony_ci 13, 13, 14, 14, 14, 70425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 71425bb815Sopenharmony_ci 15, 72425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 73425bb815Sopenharmony_ci}; 74425bb815Sopenharmony_ci 75425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 76425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 38, 77425bb815Sopenharmony_ci parser_binary_precedence_table_should_have_38_values_in_es2015); 78425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 79425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 36, 80425bb815Sopenharmony_ci parser_binary_precedence_table_should_have_36_values_in_es51); 81425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 82425bb815Sopenharmony_ci 83425bb815Sopenharmony_ci/** 84425bb815Sopenharmony_ci * Generate byte code for operators with lvalue. 85425bb815Sopenharmony_ci */ 86425bb815Sopenharmony_cistatic inline void 87425bb815Sopenharmony_ciparser_push_result (parser_context_t *context_p) /**< context */ 88425bb815Sopenharmony_ci{ 89425bb815Sopenharmony_ci if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) 90425bb815Sopenharmony_ci { 91425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1)); 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci if ((context_p->last_cbc_opcode == CBC_POST_INCR 94425bb815Sopenharmony_ci || context_p->last_cbc_opcode == CBC_POST_DECR) 95425bb815Sopenharmony_ci && context_p->stack_depth >= context_p->stack_limit) 96425bb815Sopenharmony_ci { 97425bb815Sopenharmony_ci /* Stack limit is increased for CBC_POST_INCR_PUSH_RESULT 98425bb815Sopenharmony_ci * and CBC_POST_DECR_PUSH_RESULT opcodes. Needed by vm.c. */ 99425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit); 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci context_p->stack_limit++; 102425bb815Sopenharmony_ci 103425bb815Sopenharmony_ci if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT) 104425bb815Sopenharmony_ci { 105425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED); 106425bb815Sopenharmony_ci } 107425bb815Sopenharmony_ci } 108425bb815Sopenharmony_ci 109425bb815Sopenharmony_ci context_p->last_cbc_opcode++; 110425bb815Sopenharmony_ci parser_flush_cbc (context_p); 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci} /* parser_push_result */ 113425bb815Sopenharmony_ci 114425bb815Sopenharmony_ci/** 115425bb815Sopenharmony_ci * Check for invalid assignment for "eval" and "arguments" 116425bb815Sopenharmony_ci */ 117425bb815Sopenharmony_cistatic void 118425bb815Sopenharmony_ciparser_check_invalid_assign (parser_context_t *context_p) /**< context */ 119425bb815Sopenharmony_ci{ 120425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL); 121425bb815Sopenharmony_ci 122425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT)) 123425bb815Sopenharmony_ci { 124425bb815Sopenharmony_ci if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL) 125425bb815Sopenharmony_ci { 126425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_EVAL_CANNOT_ASSIGNED); 127425bb815Sopenharmony_ci } 128425bb815Sopenharmony_ci else if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_ARGUMENTS) 129425bb815Sopenharmony_ci { 130425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED); 131425bb815Sopenharmony_ci } 132425bb815Sopenharmony_ci } 133425bb815Sopenharmony_ci} /* parser_check_invalid_assign */ 134425bb815Sopenharmony_ci 135425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 136425bb815Sopenharmony_ci 137425bb815Sopenharmony_ci/** 138425bb815Sopenharmony_ci * Check and throw an error if the "new.target" is invalid as a left-hand side expression. 139425bb815Sopenharmony_ci */ 140425bb815Sopenharmony_cistatic void 141425bb815Sopenharmony_ciparser_check_invalid_new_target (parser_context_t *context_p, /**< parser context */ 142425bb815Sopenharmony_ci cbc_opcode_t opcode) /**< current opcode under parsing */ 143425bb815Sopenharmony_ci{ 144425bb815Sopenharmony_ci /* new.target is an invalid left-hand side target */ 145425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NEW_TARGET)) 146425bb815Sopenharmony_ci { 147425bb815Sopenharmony_ci /* Make sure that the call side is a post/pre increment or an assignment expression. 148425bb815Sopenharmony_ci * There should be no other ways the "new.target" expression should be here. */ 149425bb815Sopenharmony_ci JERRY_ASSERT ((opcode >= CBC_PRE_INCR && opcode <= CBC_POST_DECR) 150425bb815Sopenharmony_ci || (opcode == CBC_ASSIGN 151425bb815Sopenharmony_ci && (context_p->token.type == LEXER_ASSIGN 152425bb815Sopenharmony_ci || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type)))); 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED); 155425bb815Sopenharmony_ci } 156425bb815Sopenharmony_ci} /* parser_check_invalid_new_target */ 157425bb815Sopenharmony_ci 158425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_ci/** 161425bb815Sopenharmony_ci * Emit identifier reference 162425bb815Sopenharmony_ci */ 163425bb815Sopenharmony_cistatic void 164425bb815Sopenharmony_ciparser_emit_ident_reference (parser_context_t *context_p, /**< context */ 165425bb815Sopenharmony_ci uint16_t opcode) /* opcode */ 166425bb815Sopenharmony_ci{ 167425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 168425bb815Sopenharmony_ci { 169425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 170425bb815Sopenharmony_ci return; 171425bb815Sopenharmony_ci } 172425bb815Sopenharmony_ci 173425bb815Sopenharmony_ci uint16_t literal_index; 174425bb815Sopenharmony_ci 175425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 176425bb815Sopenharmony_ci { 177425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_LITERAL; 178425bb815Sopenharmony_ci literal_index = context_p->last_cbc.value; 179425bb815Sopenharmony_ci } 180425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL) 181425bb815Sopenharmony_ci { 182425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THIS; 183425bb815Sopenharmony_ci literal_index = context_p->last_cbc.literal_index; 184425bb815Sopenharmony_ci } 185425bb815Sopenharmony_ci else 186425bb815Sopenharmony_ci { 187425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS); 188425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 189425bb815Sopenharmony_ci literal_index = context_p->last_cbc.third_literal_index; 190425bb815Sopenharmony_ci } 191425bb815Sopenharmony_ci 192425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, opcode, literal_index); 193425bb815Sopenharmony_ci} /* parser_emit_ident_reference */ 194425bb815Sopenharmony_ci 195425bb815Sopenharmony_ci/** 196425bb815Sopenharmony_ci * Generate byte code for operators with lvalue. 197425bb815Sopenharmony_ci */ 198425bb815Sopenharmony_cistatic void 199425bb815Sopenharmony_ciparser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */ 200425bb815Sopenharmony_ci cbc_opcode_t opcode) /**< opcode */ 201425bb815Sopenharmony_ci{ 202425bb815Sopenharmony_ci if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 203425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 204425bb815Sopenharmony_ci { 205425bb815Sopenharmony_ci parser_check_invalid_assign (context_p); 206425bb815Sopenharmony_ci 207425bb815Sopenharmony_ci uint16_t unary_opcode; 208425bb815Sopenharmony_ci 209425bb815Sopenharmony_ci if (opcode == CBC_DELETE_PUSH_RESULT) 210425bb815Sopenharmony_ci { 211425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT)) 212425bb815Sopenharmony_ci { 213425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED); 214425bb815Sopenharmony_ci } 215425bb815Sopenharmony_ci 216425bb815Sopenharmony_ci unary_opcode = CBC_DELETE_IDENT_PUSH_RESULT; 217425bb815Sopenharmony_ci } 218425bb815Sopenharmony_ci else 219425bb815Sopenharmony_ci { 220425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT)); 221425bb815Sopenharmony_ci unary_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT); 222425bb815Sopenharmony_ci } 223425bb815Sopenharmony_ci 224425bb815Sopenharmony_ci parser_emit_ident_reference (context_p, unary_opcode); 225425bb815Sopenharmony_ci 226425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 227425bb815Sopenharmony_ci if (unary_opcode != CBC_DELETE_IDENT_PUSH_RESULT 228425bb815Sopenharmony_ci && scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index)) 229425bb815Sopenharmony_ci { 230425bb815Sopenharmony_ci /* The current value must be read, but it cannot be changed. */ 231425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_LITERAL; 232425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR); 233425bb815Sopenharmony_ci } 234425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 235425bb815Sopenharmony_ci return; 236425bb815Sopenharmony_ci } 237425bb815Sopenharmony_ci 238425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_PROP) 239425bb815Sopenharmony_ci { 240425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, opcode)); 241425bb815Sopenharmony_ci context_p->last_cbc_opcode = (uint16_t) opcode; 242425bb815Sopenharmony_ci return; 243425bb815Sopenharmony_ci } 244425bb815Sopenharmony_ci 245425bb815Sopenharmony_ci if (PARSER_IS_PUSH_PROP_LITERAL (context_p->last_cbc_opcode)) 246425bb815Sopenharmony_ci { 247425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_PUSH_PROP_LITERAL_TO_PUSH_LITERAL (context_p->last_cbc_opcode); 248425bb815Sopenharmony_ci } 249425bb815Sopenharmony_ci else 250425bb815Sopenharmony_ci { 251425bb815Sopenharmony_ci /* Invalid LeftHandSide expression. */ 252425bb815Sopenharmony_ci if (opcode == CBC_DELETE_PUSH_RESULT) 253425bb815Sopenharmony_ci { 254425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 255425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL) 256425bb815Sopenharmony_ci || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP)) 257425bb815Sopenharmony_ci { 258425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR); 259425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 260425bb815Sopenharmony_ci return; 261425bb815Sopenharmony_ci } 262425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 263425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 264425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_TRUE); 265425bb815Sopenharmony_ci return; 266425bb815Sopenharmony_ci } 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 269425bb815Sopenharmony_ci parser_check_invalid_new_target (context_p, opcode); 270425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 271425bb815Sopenharmony_ci 272425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR); 273425bb815Sopenharmony_ci } 274425bb815Sopenharmony_ci 275425bb815Sopenharmony_ci parser_emit_cbc (context_p, (uint16_t) opcode); 276425bb815Sopenharmony_ci} /* parser_emit_unary_lvalue_opcode */ 277425bb815Sopenharmony_ci 278425bb815Sopenharmony_ci/** 279425bb815Sopenharmony_ci * Parse array literal. 280425bb815Sopenharmony_ci */ 281425bb815Sopenharmony_cistatic void 282425bb815Sopenharmony_ciparser_parse_array_literal (parser_context_t *context_p) /**< context */ 283425bb815Sopenharmony_ci{ 284425bb815Sopenharmony_ci uint32_t pushed_items = 0; 285425bb815Sopenharmony_ci uint16_t opcode = (uint16_t) CBC_ARRAY_APPEND; 286425bb815Sopenharmony_ci 287425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE); 288425bb815Sopenharmony_ci 289425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_CREATE_ARRAY); 290425bb815Sopenharmony_ci lexer_next_token (context_p); 291425bb815Sopenharmony_ci 292425bb815Sopenharmony_ci while (true) 293425bb815Sopenharmony_ci { 294425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_SQUARE) 295425bb815Sopenharmony_ci { 296425bb815Sopenharmony_ci if (pushed_items > 0) 297425bb815Sopenharmony_ci { 298425bb815Sopenharmony_ci parser_emit_cbc_call (context_p, opcode, pushed_items); 299425bb815Sopenharmony_ci } 300425bb815Sopenharmony_ci return; 301425bb815Sopenharmony_ci } 302425bb815Sopenharmony_ci 303425bb815Sopenharmony_ci pushed_items++; 304425bb815Sopenharmony_ci 305425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COMMA) 306425bb815Sopenharmony_ci { 307425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_ELISION); 308425bb815Sopenharmony_ci lexer_next_token (context_p); 309425bb815Sopenharmony_ci } 310425bb815Sopenharmony_ci else 311425bb815Sopenharmony_ci { 312425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 313425bb815Sopenharmony_ci if (context_p->token.type == LEXER_THREE_DOTS) 314425bb815Sopenharmony_ci { 315425bb815Sopenharmony_ci opcode = (uint16_t) (PARSER_TO_EXT_OPCODE (CBC_EXT_SPREAD_ARRAY_APPEND)); 316425bb815Sopenharmony_ci pushed_items++; 317425bb815Sopenharmony_ci lexer_next_token (context_p); 318425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT); 319425bb815Sopenharmony_ci } 320425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 321425bb815Sopenharmony_ci 322425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 323425bb815Sopenharmony_ci 324425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_THIS) 325425bb815Sopenharmony_ci { 326425bb815Sopenharmony_ci parser_flush_cbc (context_p); 327425bb815Sopenharmony_ci } 328425bb815Sopenharmony_ci 329425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COMMA) 330425bb815Sopenharmony_ci { 331425bb815Sopenharmony_ci lexer_next_token (context_p); 332425bb815Sopenharmony_ci } 333425bb815Sopenharmony_ci else if (context_p->token.type != LEXER_RIGHT_SQUARE) 334425bb815Sopenharmony_ci { 335425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED); 336425bb815Sopenharmony_ci } 337425bb815Sopenharmony_ci } 338425bb815Sopenharmony_ci 339425bb815Sopenharmony_ci if (pushed_items >= 64) 340425bb815Sopenharmony_ci { 341425bb815Sopenharmony_ci parser_emit_cbc_call (context_p, opcode, pushed_items); 342425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 343425bb815Sopenharmony_ci opcode = (uint16_t) CBC_ARRAY_APPEND; 344425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 345425bb815Sopenharmony_ci pushed_items = 0; 346425bb815Sopenharmony_ci } 347425bb815Sopenharmony_ci } 348425bb815Sopenharmony_ci} /* parser_parse_array_literal */ 349425bb815Sopenharmony_ci 350425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 351425bb815Sopenharmony_ci/** 352425bb815Sopenharmony_ci * Object literal item types. 353425bb815Sopenharmony_ci */ 354425bb815Sopenharmony_citypedef enum 355425bb815Sopenharmony_ci{ 356425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_START, /**< marks the start of the property list */ 357425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_VALUE, /**< value property */ 358425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_GETTER, /**< getter property */ 359425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_SETTER, /**< setter property */ 360425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS, /**< both getter and setter properties are set */ 361425bb815Sopenharmony_ci} parser_object_literal_item_types_t; 362425bb815Sopenharmony_ci 363425bb815Sopenharmony_ci/** 364425bb815Sopenharmony_ci * Parse object literal. 365425bb815Sopenharmony_ci */ 366425bb815Sopenharmony_cistatic void 367425bb815Sopenharmony_ciparser_append_object_literal_item (parser_context_t *context_p, /**< context */ 368425bb815Sopenharmony_ci uint16_t item_index, /**< index of the item name */ 369425bb815Sopenharmony_ci parser_object_literal_item_types_t item_type) /**< type of the item */ 370425bb815Sopenharmony_ci{ 371425bb815Sopenharmony_ci parser_stack_iterator_t iterator; 372425bb815Sopenharmony_ci uint8_t *current_item_type_p; 373425bb815Sopenharmony_ci 374425bb815Sopenharmony_ci iterator.current_p = context_p->stack.first_p; 375425bb815Sopenharmony_ci iterator.current_position = context_p->stack.last_position; 376425bb815Sopenharmony_ci 377425bb815Sopenharmony_ci while (true) 378425bb815Sopenharmony_ci { 379425bb815Sopenharmony_ci current_item_type_p = iterator.current_p->bytes + iterator.current_position - 1; 380425bb815Sopenharmony_ci 381425bb815Sopenharmony_ci if (*current_item_type_p == PARSER_OBJECT_PROPERTY_START) 382425bb815Sopenharmony_ci { 383425bb815Sopenharmony_ci parser_stack_push_uint16 (context_p, item_index); 384425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, (uint8_t) item_type); 385425bb815Sopenharmony_ci return; 386425bb815Sopenharmony_ci } 387425bb815Sopenharmony_ci 388425bb815Sopenharmony_ci iterator.current_position--; 389425bb815Sopenharmony_ci if (iterator.current_position == 0) 390425bb815Sopenharmony_ci { 391425bb815Sopenharmony_ci iterator.current_p = iterator.current_p->next_p; 392425bb815Sopenharmony_ci iterator.current_position = PARSER_STACK_PAGE_SIZE; 393425bb815Sopenharmony_ci } 394425bb815Sopenharmony_ci 395425bb815Sopenharmony_ci uint32_t current_item_index = iterator.current_p->bytes[iterator.current_position - 1]; 396425bb815Sopenharmony_ci 397425bb815Sopenharmony_ci iterator.current_position--; 398425bb815Sopenharmony_ci if (iterator.current_position == 0) 399425bb815Sopenharmony_ci { 400425bb815Sopenharmony_ci iterator.current_p = iterator.current_p->next_p; 401425bb815Sopenharmony_ci iterator.current_position = PARSER_STACK_PAGE_SIZE; 402425bb815Sopenharmony_ci } 403425bb815Sopenharmony_ci 404425bb815Sopenharmony_ci current_item_index |= ((uint32_t) iterator.current_p->bytes[iterator.current_position - 1]) << 8; 405425bb815Sopenharmony_ci 406425bb815Sopenharmony_ci iterator.current_position--; 407425bb815Sopenharmony_ci if (iterator.current_position == 0) 408425bb815Sopenharmony_ci { 409425bb815Sopenharmony_ci iterator.current_p = iterator.current_p->next_p; 410425bb815Sopenharmony_ci iterator.current_position = PARSER_STACK_PAGE_SIZE; 411425bb815Sopenharmony_ci } 412425bb815Sopenharmony_ci 413425bb815Sopenharmony_ci if (current_item_index == item_index) 414425bb815Sopenharmony_ci { 415425bb815Sopenharmony_ci if (item_type == PARSER_OBJECT_PROPERTY_VALUE 416425bb815Sopenharmony_ci && *current_item_type_p == PARSER_OBJECT_PROPERTY_VALUE 417425bb815Sopenharmony_ci && !(context_p->status_flags & PARSER_IS_STRICT)) 418425bb815Sopenharmony_ci { 419425bb815Sopenharmony_ci return; 420425bb815Sopenharmony_ci } 421425bb815Sopenharmony_ci 422425bb815Sopenharmony_ci if (item_type == PARSER_OBJECT_PROPERTY_GETTER 423425bb815Sopenharmony_ci && *current_item_type_p == PARSER_OBJECT_PROPERTY_SETTER) 424425bb815Sopenharmony_ci { 425425bb815Sopenharmony_ci break; 426425bb815Sopenharmony_ci } 427425bb815Sopenharmony_ci 428425bb815Sopenharmony_ci if (item_type == PARSER_OBJECT_PROPERTY_SETTER 429425bb815Sopenharmony_ci && *current_item_type_p == PARSER_OBJECT_PROPERTY_GETTER) 430425bb815Sopenharmony_ci { 431425bb815Sopenharmony_ci break; 432425bb815Sopenharmony_ci } 433425bb815Sopenharmony_ci 434425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OBJECT_PROPERTY_REDEFINED); 435425bb815Sopenharmony_ci } 436425bb815Sopenharmony_ci } 437425bb815Sopenharmony_ci 438425bb815Sopenharmony_ci uint8_t *last_page_p = context_p->stack.first_p->bytes; 439425bb815Sopenharmony_ci 440425bb815Sopenharmony_ci *current_item_type_p = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS; 441425bb815Sopenharmony_ci 442425bb815Sopenharmony_ci if (current_item_type_p == (last_page_p + context_p->stack.last_position - 1)) 443425bb815Sopenharmony_ci { 444425bb815Sopenharmony_ci context_p->stack_top_uint8 = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS; 445425bb815Sopenharmony_ci } 446425bb815Sopenharmony_ci} /* parser_append_object_literal_item */ 447425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 448425bb815Sopenharmony_ci 449425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 450425bb815Sopenharmony_ci/** Forward definition of parse array initializer. */ 451425bb815Sopenharmony_cistatic void 452425bb815Sopenharmony_ciparser_parse_array_initializer (parser_context_t *context_p, parser_pattern_flags_t flags); 453425bb815Sopenharmony_ci 454425bb815Sopenharmony_ci/** Forward definition of parse object initializer. */ 455425bb815Sopenharmony_cistatic void 456425bb815Sopenharmony_ciparser_parse_object_initializer (parser_context_t *context_p, parser_pattern_flags_t flags); 457425bb815Sopenharmony_ci 458425bb815Sopenharmony_ci/** 459425bb815Sopenharmony_ci * Description of "get" literal string. 460425bb815Sopenharmony_ci */ 461425bb815Sopenharmony_cistatic const lexer_lit_location_t lexer_get_literal = 462425bb815Sopenharmony_ci{ 463425bb815Sopenharmony_ci (const uint8_t *) "get", 3, LEXER_STRING_LITERAL, false 464425bb815Sopenharmony_ci}; 465425bb815Sopenharmony_ci 466425bb815Sopenharmony_ci/** 467425bb815Sopenharmony_ci * Description of "set" literal string. 468425bb815Sopenharmony_ci */ 469425bb815Sopenharmony_cistatic const lexer_lit_location_t lexer_set_literal = 470425bb815Sopenharmony_ci{ 471425bb815Sopenharmony_ci (const uint8_t *) "set", 3, LEXER_STRING_LITERAL, false 472425bb815Sopenharmony_ci}; 473425bb815Sopenharmony_ci 474425bb815Sopenharmony_ci/** 475425bb815Sopenharmony_ci * Class literal parsing options. 476425bb815Sopenharmony_ci */ 477425bb815Sopenharmony_citypedef enum 478425bb815Sopenharmony_ci{ 479425bb815Sopenharmony_ci PARSER_CLASS_LITERAL_NO_OPTS = 0, /**< no options are provided */ 480425bb815Sopenharmony_ci PARSER_CLASS_LITERAL_CTOR_PRESENT = (1 << 0), /**< class constructor is present */ 481425bb815Sopenharmony_ci PARSER_CLASS_LITERAL_HERTIAGE_PRESENT = (1 << 1), /**< class heritage is present */ 482425bb815Sopenharmony_ci} parser_class_literal_opts_t; 483425bb815Sopenharmony_ci 484425bb815Sopenharmony_ci/** 485425bb815Sopenharmony_ci * Parse class literal. 486425bb815Sopenharmony_ci */ 487425bb815Sopenharmony_cistatic void 488425bb815Sopenharmony_ciparser_parse_class_literal (parser_context_t *context_p, /**< context */ 489425bb815Sopenharmony_ci parser_class_literal_opts_t opts) /**< class literal parsing options */ 490425bb815Sopenharmony_ci{ 491425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE); 492425bb815Sopenharmony_ci 493425bb815Sopenharmony_ci uint32_t status_flags = PARSER_FUNCTION_CLOSURE | PARSER_ALLOW_SUPER; 494425bb815Sopenharmony_ci 495425bb815Sopenharmony_ci lexer_literal_t *ctor_literal_p = NULL; 496425bb815Sopenharmony_ci 497425bb815Sopenharmony_ci if (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT) 498425bb815Sopenharmony_ci { 499425bb815Sopenharmony_ci if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 500425bb815Sopenharmony_ci { 501425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 502425bb815Sopenharmony_ci } 503425bb815Sopenharmony_ci 504425bb815Sopenharmony_ci ctor_literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 505425bb815Sopenharmony_ci ctor_literal_p->type = LEXER_UNUSED_LITERAL; 506425bb815Sopenharmony_ci ctor_literal_p->status_flags = 0; 507425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, (uint16_t) (context_p->literal_count++)); 508425bb815Sopenharmony_ci } 509425bb815Sopenharmony_ci else if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT) 510425bb815Sopenharmony_ci { 511425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE); 512425bb815Sopenharmony_ci } 513425bb815Sopenharmony_ci else 514425bb815Sopenharmony_ci { 515425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR); 516425bb815Sopenharmony_ci } 517425bb815Sopenharmony_ci 518425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_INIT_CLASS); 519425bb815Sopenharmony_ci 520425bb815Sopenharmony_ci bool is_static = false; 521425bb815Sopenharmony_ci 522425bb815Sopenharmony_ci while (true) 523425bb815Sopenharmony_ci { 524425bb815Sopenharmony_ci if (!is_static) 525425bb815Sopenharmony_ci { 526425bb815Sopenharmony_ci lexer_skip_empty_statements (context_p); 527425bb815Sopenharmony_ci } 528425bb815Sopenharmony_ci 529425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD); 530425bb815Sopenharmony_ci 531425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 532425bb815Sopenharmony_ci { 533425bb815Sopenharmony_ci break; 534425bb815Sopenharmony_ci } 535425bb815Sopenharmony_ci 536425bb815Sopenharmony_ci bool is_computed = false; 537425bb815Sopenharmony_ci 538425bb815Sopenharmony_ci if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER) 539425bb815Sopenharmony_ci { 540425bb815Sopenharmony_ci uint16_t literal_index, function_literal_index; 541425bb815Sopenharmony_ci bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER); 542425bb815Sopenharmony_ci 543425bb815Sopenharmony_ci if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)) 544425bb815Sopenharmony_ci { 545425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 546425bb815Sopenharmony_ci (is_getter ? (lexer_lit_location_t *) &lexer_get_literal 547425bb815Sopenharmony_ci : (lexer_lit_location_t *) &lexer_set_literal), 548425bb815Sopenharmony_ci LEXER_STRING_LITERAL); 549425bb815Sopenharmony_ci goto parse_class_method; 550425bb815Sopenharmony_ci } 551425bb815Sopenharmony_ci 552425bb815Sopenharmony_ci uint32_t accessor_status_flags = status_flags; 553425bb815Sopenharmony_ci accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER); 554425bb815Sopenharmony_ci 555425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); 556425bb815Sopenharmony_ci literal_index = context_p->lit_object.index; 557425bb815Sopenharmony_ci 558425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_SQUARE) 559425bb815Sopenharmony_ci { 560425bb815Sopenharmony_ci is_computed = true; 561425bb815Sopenharmony_ci } 562425bb815Sopenharmony_ci else if (!is_static 563425bb815Sopenharmony_ci && LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type) 564425bb815Sopenharmony_ci && lexer_compare_literal_to_string (context_p, "constructor", 11)) 565425bb815Sopenharmony_ci { 566425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR); 567425bb815Sopenharmony_ci } 568425bb815Sopenharmony_ci 569425bb815Sopenharmony_ci function_literal_index = lexer_construct_function_object (context_p, accessor_status_flags); 570425bb815Sopenharmony_ci 571425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 572425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 573425bb815Sopenharmony_ci literal_index); 574425bb815Sopenharmony_ci 575425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 576425bb815Sopenharmony_ci 577425bb815Sopenharmony_ci cbc_ext_opcode_t opcode; 578425bb815Sopenharmony_ci 579425bb815Sopenharmony_ci if (is_computed) 580425bb815Sopenharmony_ci { 581425bb815Sopenharmony_ci context_p->last_cbc.literal_index = function_literal_index; 582425bb815Sopenharmony_ci 583425bb815Sopenharmony_ci if (is_getter) 584425bb815Sopenharmony_ci { 585425bb815Sopenharmony_ci opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_GETTER : CBC_EXT_SET_COMPUTED_GETTER; 586425bb815Sopenharmony_ci } 587425bb815Sopenharmony_ci else 588425bb815Sopenharmony_ci { 589425bb815Sopenharmony_ci opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_SETTER : CBC_EXT_SET_COMPUTED_SETTER; 590425bb815Sopenharmony_ci } 591425bb815Sopenharmony_ci } 592425bb815Sopenharmony_ci else 593425bb815Sopenharmony_ci { 594425bb815Sopenharmony_ci context_p->last_cbc.value = function_literal_index; 595425bb815Sopenharmony_ci 596425bb815Sopenharmony_ci if (is_getter) 597425bb815Sopenharmony_ci { 598425bb815Sopenharmony_ci opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER; 599425bb815Sopenharmony_ci } 600425bb815Sopenharmony_ci else 601425bb815Sopenharmony_ci { 602425bb815Sopenharmony_ci opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER; 603425bb815Sopenharmony_ci } 604425bb815Sopenharmony_ci } 605425bb815Sopenharmony_ci 606425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode); 607425bb815Sopenharmony_ci is_static = false; 608425bb815Sopenharmony_ci continue; 609425bb815Sopenharmony_ci } 610425bb815Sopenharmony_ci 611425bb815Sopenharmony_ci if (!is_static) 612425bb815Sopenharmony_ci { 613425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_STATIC) 614425bb815Sopenharmony_ci { 615425bb815Sopenharmony_ci is_static = true; 616425bb815Sopenharmony_ci continue; 617425bb815Sopenharmony_ci } 618425bb815Sopenharmony_ci 619425bb815Sopenharmony_ci if (context_p->token.type == LEXER_CLASS_CONSTRUCTOR) 620425bb815Sopenharmony_ci { 621425bb815Sopenharmony_ci JERRY_ASSERT (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT); 622425bb815Sopenharmony_ci JERRY_ASSERT (ctor_literal_p != NULL); 623425bb815Sopenharmony_ci 624425bb815Sopenharmony_ci if (ctor_literal_p->type == LEXER_FUNCTION_LITERAL) 625425bb815Sopenharmony_ci { 626425bb815Sopenharmony_ci /* 14.5.1 */ 627425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS); 628425bb815Sopenharmony_ci } 629425bb815Sopenharmony_ci 630425bb815Sopenharmony_ci uint32_t constructor_status_flags = (status_flags 631425bb815Sopenharmony_ci | PARSER_CLASS_CONSTRUCTOR 632425bb815Sopenharmony_ci | PARSER_LEXICAL_ENV_NEEDED); 633425bb815Sopenharmony_ci 634425bb815Sopenharmony_ci if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT) 635425bb815Sopenharmony_ci { 636425bb815Sopenharmony_ci constructor_status_flags |= PARSER_ALLOW_SUPER_CALL; 637425bb815Sopenharmony_ci } 638425bb815Sopenharmony_ci 639425bb815Sopenharmony_ci parser_flush_cbc (context_p); 640425bb815Sopenharmony_ci ecma_compiled_code_t *compiled_code_p = parser_parse_function (context_p, constructor_status_flags); 641425bb815Sopenharmony_ci ctor_literal_p->u.bytecode_p = compiled_code_p; 642425bb815Sopenharmony_ci ctor_literal_p->type = LEXER_FUNCTION_LITERAL; 643425bb815Sopenharmony_ci continue; 644425bb815Sopenharmony_ci } 645425bb815Sopenharmony_ci } 646425bb815Sopenharmony_ci 647425bb815Sopenharmony_ci status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION 648425bb815Sopenharmony_ci | PARSER_IS_ASYNC_FUNCTION 649425bb815Sopenharmony_ci | PARSER_DISALLOW_AWAIT_YIELD); 650425bb815Sopenharmony_ci 651425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_ASYNC) 652425bb815Sopenharmony_ci { 653425bb815Sopenharmony_ci status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 654425bb815Sopenharmony_ci 655425bb815Sopenharmony_ci if (!lexer_consume_generator (context_p)) 656425bb815Sopenharmony_ci { 657425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); 658425bb815Sopenharmony_ci } 659425bb815Sopenharmony_ci } 660425bb815Sopenharmony_ci 661425bb815Sopenharmony_ci if (context_p->token.type == LEXER_MULTIPLY) 662425bb815Sopenharmony_ci { 663425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); 664425bb815Sopenharmony_ci status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 665425bb815Sopenharmony_ci } 666425bb815Sopenharmony_ci 667425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_SQUARE) 668425bb815Sopenharmony_ci { 669425bb815Sopenharmony_ci is_computed = true; 670425bb815Sopenharmony_ci } 671425bb815Sopenharmony_ci else if (LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)) 672425bb815Sopenharmony_ci { 673425bb815Sopenharmony_ci if (is_static) 674425bb815Sopenharmony_ci { 675425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "prototype", 9)) 676425bb815Sopenharmony_ci { 677425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE); 678425bb815Sopenharmony_ci } 679425bb815Sopenharmony_ci } 680425bb815Sopenharmony_ci else if ((status_flags & PARSER_IS_GENERATOR_FUNCTION) 681425bb815Sopenharmony_ci && lexer_compare_literal_to_string (context_p, "constructor", 11)) 682425bb815Sopenharmony_ci { 683425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_GENERATOR); 684425bb815Sopenharmony_ci } 685425bb815Sopenharmony_ci } 686425bb815Sopenharmony_ci 687425bb815Sopenharmony_ciparse_class_method: 688425bb815Sopenharmony_ci ; /* Empty statement to make compiler happy. */ 689425bb815Sopenharmony_ci uint16_t literal_index = context_p->lit_object.index; 690425bb815Sopenharmony_ci uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags); 691425bb815Sopenharmony_ci 692425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 693425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 694425bb815Sopenharmony_ci function_literal_index); 695425bb815Sopenharmony_ci 696425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 697425bb815Sopenharmony_ci 698425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 699425bb815Sopenharmony_ci 700425bb815Sopenharmony_ci if (is_static) 701425bb815Sopenharmony_ci { 702425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL 703425bb815Sopenharmony_ci : CBC_EXT_SET_STATIC_PROPERTY_LITERAL); 704425bb815Sopenharmony_ci is_static = false; 705425bb815Sopenharmony_ci } 706425bb815Sopenharmony_ci else 707425bb815Sopenharmony_ci { 708425bb815Sopenharmony_ci context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL) 709425bb815Sopenharmony_ci : CBC_SET_LITERAL_PROPERTY); 710425bb815Sopenharmony_ci } 711425bb815Sopenharmony_ci } 712425bb815Sopenharmony_ci} /* parser_parse_class_literal */ 713425bb815Sopenharmony_ci 714425bb815Sopenharmony_ci/** 715425bb815Sopenharmony_ci * Parse class statement or expression. 716425bb815Sopenharmony_ci */ 717425bb815Sopenharmony_civoid 718425bb815Sopenharmony_ciparser_parse_class (parser_context_t *context_p, /**< context */ 719425bb815Sopenharmony_ci bool is_statement) /**< true - if class is parsed as a statement 720425bb815Sopenharmony_ci * false - otherwise (as an expression) */ 721425bb815Sopenharmony_ci{ 722425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS); 723425bb815Sopenharmony_ci 724425bb815Sopenharmony_ci uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; 725425bb815Sopenharmony_ci uint16_t class_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; 726425bb815Sopenharmony_ci parser_class_literal_opts_t opts = PARSER_CLASS_LITERAL_NO_OPTS; 727425bb815Sopenharmony_ci 728425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 729425bb815Sopenharmony_ci { 730425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR); 731425bb815Sopenharmony_ci scanner_release_next (context_p, sizeof (scanner_info_t)); 732425bb815Sopenharmony_ci opts |= PARSER_CLASS_LITERAL_CTOR_PRESENT; 733425bb815Sopenharmony_ci } 734425bb815Sopenharmony_ci 735425bb815Sopenharmony_ci if (is_statement) 736425bb815Sopenharmony_ci { 737425bb815Sopenharmony_ci /* Class statement must contain an identifier. */ 738425bb815Sopenharmony_ci lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL); 739425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 740425bb815Sopenharmony_ci && context_p->token.lit_location.type == LEXER_IDENT_LITERAL); 741425bb815Sopenharmony_ci 742425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 743425bb815Sopenharmony_ci { 744425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); 745425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 746425bb815Sopenharmony_ci } 747425bb815Sopenharmony_ci class_ident_index = context_p->lit_object.index; 748425bb815Sopenharmony_ci 749425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL); 750425bb815Sopenharmony_ci class_name_index = context_p->lit_object.index; 751425bb815Sopenharmony_ci 752425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 753425bb815Sopenharmony_ci parser_module_append_export_name (context_p); 754425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT); 755425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 756425bb815Sopenharmony_ci 757425bb815Sopenharmony_ci lexer_next_token (context_p); 758425bb815Sopenharmony_ci } 759425bb815Sopenharmony_ci else 760425bb815Sopenharmony_ci { 761425bb815Sopenharmony_ci lexer_next_token (context_p); 762425bb815Sopenharmony_ci 763425bb815Sopenharmony_ci /* Class expression may contain an identifier. */ 764425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL) 765425bb815Sopenharmony_ci { 766425bb815Sopenharmony_ci /* NOTE: If 'Function.name' will be supported, the current literal object must be set to 'name' property. */ 767425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL); 768425bb815Sopenharmony_ci class_name_index = context_p->lit_object.index; 769425bb815Sopenharmony_ci lexer_next_token (context_p); 770425bb815Sopenharmony_ci } 771425bb815Sopenharmony_ci } 772425bb815Sopenharmony_ci 773425bb815Sopenharmony_ci if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS) 774425bb815Sopenharmony_ci { 775425bb815Sopenharmony_ci parser_emit_cbc_ext_literal (context_p, CBC_EXT_PUSH_NAMED_CLASS_ENV, class_name_index); 776425bb815Sopenharmony_ci } 777425bb815Sopenharmony_ci else 778425bb815Sopenharmony_ci { 779425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_ANONYMOUS_CLASS_ENV); 780425bb815Sopenharmony_ci } 781425bb815Sopenharmony_ci 782425bb815Sopenharmony_ci bool is_strict = (context_p->status_flags & PARSER_IS_STRICT) != 0; 783425bb815Sopenharmony_ci 784425bb815Sopenharmony_ci /* 14.5. A ClassBody is always strict code. */ 785425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_STRICT; 786425bb815Sopenharmony_ci 787425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_EXTENDS) 788425bb815Sopenharmony_ci { 789425bb815Sopenharmony_ci lexer_next_token (context_p); 790425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR | PARSE_EXPR_LEFT_HAND_SIDE); 791425bb815Sopenharmony_ci opts |= PARSER_CLASS_LITERAL_HERTIAGE_PRESENT; 792425bb815Sopenharmony_ci } 793425bb815Sopenharmony_ci else 794425bb815Sopenharmony_ci { 795425bb815Sopenharmony_ci /* Elisions represents that the classHeritage is not present */ 796425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_ELISION); 797425bb815Sopenharmony_ci } 798425bb815Sopenharmony_ci 799425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LEFT_BRACE) 800425bb815Sopenharmony_ci { 801425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED); 802425bb815Sopenharmony_ci } 803425bb815Sopenharmony_ci 804425bb815Sopenharmony_ci /* ClassDeclaration is parsed. Continue with class body. */ 805425bb815Sopenharmony_ci parser_parse_class_literal (context_p, opts); 806425bb815Sopenharmony_ci 807425bb815Sopenharmony_ci if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS) 808425bb815Sopenharmony_ci { 809425bb815Sopenharmony_ci parser_emit_cbc_ext_literal (context_p, CBC_EXT_FINALIZE_NAMED_CLASS, class_name_index); 810425bb815Sopenharmony_ci } 811425bb815Sopenharmony_ci else 812425bb815Sopenharmony_ci { 813425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_FINALIZE_ANONYMOUS_CLASS); 814425bb815Sopenharmony_ci } 815425bb815Sopenharmony_ci 816425bb815Sopenharmony_ci if (is_statement) 817425bb815Sopenharmony_ci { 818425bb815Sopenharmony_ci cbc_opcode_t opcode = CBC_MOV_IDENT; 819425bb815Sopenharmony_ci 820425bb815Sopenharmony_ci if (class_ident_index < PARSER_REGISTER_START) 821425bb815Sopenharmony_ci { 822425bb815Sopenharmony_ci opcode = (scanner_literal_is_created (context_p, class_ident_index) ? CBC_ASSIGN_LET_CONST 823425bb815Sopenharmony_ci : CBC_INIT_LET); 824425bb815Sopenharmony_ci } 825425bb815Sopenharmony_ci 826425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, (uint16_t) opcode, class_ident_index); 827425bb815Sopenharmony_ci } 828425bb815Sopenharmony_ci 829425bb815Sopenharmony_ci parser_flush_cbc (context_p); 830425bb815Sopenharmony_ci 831425bb815Sopenharmony_ci if (!is_strict) 832425bb815Sopenharmony_ci { 833425bb815Sopenharmony_ci /* Restore flag */ 834425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT; 835425bb815Sopenharmony_ci } 836425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_ALLOW_SUPER; 837425bb815Sopenharmony_ci 838425bb815Sopenharmony_ci lexer_next_token (context_p); 839425bb815Sopenharmony_ci} /* parser_parse_class */ 840425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 841425bb815Sopenharmony_ci 842425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 843425bb815Sopenharmony_ci/** 844425bb815Sopenharmony_ci * Parse object initializer method definition. 845425bb815Sopenharmony_ci * 846425bb815Sopenharmony_ci * See also: ES2015 14.3 847425bb815Sopenharmony_ci */ 848425bb815Sopenharmony_cistatic void 849425bb815Sopenharmony_ciparser_parse_object_method (parser_context_t *context_p) /**< context */ 850425bb815Sopenharmony_ci{ 851425bb815Sopenharmony_ci context_p->source_p--; 852425bb815Sopenharmony_ci context_p->column--; 853425bb815Sopenharmony_ci uint16_t function_literal_index = lexer_construct_function_object (context_p, PARSER_FUNCTION_CLOSURE); 854425bb815Sopenharmony_ci 855425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 856425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 857425bb815Sopenharmony_ci function_literal_index); 858425bb815Sopenharmony_ci 859425bb815Sopenharmony_ci lexer_next_token (context_p); 860425bb815Sopenharmony_ci} /* parser_parse_object_method */ 861425bb815Sopenharmony_ci 862425bb815Sopenharmony_ci/** 863425bb815Sopenharmony_ci * Reparse the current literal as a common identifier. 864425bb815Sopenharmony_ci */ 865425bb815Sopenharmony_cistatic void 866425bb815Sopenharmony_ciparser_reparse_as_common_identifier (parser_context_t *context_p, /**< context */ 867425bb815Sopenharmony_ci parser_line_counter_t start_line, /**< start line */ 868425bb815Sopenharmony_ci parser_line_counter_t start_column) /**< start column */ 869425bb815Sopenharmony_ci{ 870425bb815Sopenharmony_ci /* context_p->token.lit_location.char_p is showing the character after the string start, 871425bb815Sopenharmony_ci so it is not suitable for reparsing as identifier. 872425bb815Sopenharmony_ci e.g.: { 'foo' } */ 873425bb815Sopenharmony_ci if (context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 874425bb815Sopenharmony_ci { 875425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 876425bb815Sopenharmony_ci } 877425bb815Sopenharmony_ci 878425bb815Sopenharmony_ci context_p->source_p = context_p->token.lit_location.char_p; 879425bb815Sopenharmony_ci context_p->line = start_line; 880425bb815Sopenharmony_ci context_p->column = start_column; 881425bb815Sopenharmony_ci 882425bb815Sopenharmony_ci lexer_next_token (context_p); 883425bb815Sopenharmony_ci 884425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL) 885425bb815Sopenharmony_ci { 886425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 887425bb815Sopenharmony_ci } 888425bb815Sopenharmony_ci 889425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.lit_location.type == LEXER_IDENT_LITERAL); 890425bb815Sopenharmony_ci 891425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 892425bb815Sopenharmony_ci &context_p->token.lit_location, 893425bb815Sopenharmony_ci LEXER_IDENT_LITERAL); 894425bb815Sopenharmony_ci 895425bb815Sopenharmony_ci} /* parser_reparse_as_common_identifier */ 896425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 897425bb815Sopenharmony_ci 898425bb815Sopenharmony_ci/** 899425bb815Sopenharmony_ci * Parse object literal. 900425bb815Sopenharmony_ci */ 901425bb815Sopenharmony_cistatic void 902425bb815Sopenharmony_ciparser_parse_object_literal (parser_context_t *context_p) /**< context */ 903425bb815Sopenharmony_ci{ 904425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE); 905425bb815Sopenharmony_ci 906425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_CREATE_OBJECT); 907425bb815Sopenharmony_ci 908425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 909425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START); 910425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 911425bb815Sopenharmony_ci 912425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 913425bb815Sopenharmony_ci bool proto_seen = false; 914425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 915425bb815Sopenharmony_ci 916425bb815Sopenharmony_ci while (true) 917425bb815Sopenharmony_ci { 918425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS); 919425bb815Sopenharmony_ci 920425bb815Sopenharmony_ci switch (context_p->token.type) 921425bb815Sopenharmony_ci { 922425bb815Sopenharmony_ci case LEXER_RIGHT_BRACE: 923425bb815Sopenharmony_ci { 924425bb815Sopenharmony_ci break; 925425bb815Sopenharmony_ci } 926425bb815Sopenharmony_ci case LEXER_PROPERTY_GETTER: 927425bb815Sopenharmony_ci case LEXER_PROPERTY_SETTER: 928425bb815Sopenharmony_ci { 929425bb815Sopenharmony_ci uint32_t status_flags; 930425bb815Sopenharmony_ci cbc_ext_opcode_t opcode; 931425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 932425bb815Sopenharmony_ci parser_object_literal_item_types_t item_type; 933425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 934425bb815Sopenharmony_ci 935425bb815Sopenharmony_ci if (context_p->token.type == LEXER_PROPERTY_GETTER) 936425bb815Sopenharmony_ci { 937425bb815Sopenharmony_ci status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_GETTER; 938425bb815Sopenharmony_ci opcode = CBC_EXT_SET_GETTER; 939425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 940425bb815Sopenharmony_ci item_type = PARSER_OBJECT_PROPERTY_GETTER; 941425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 942425bb815Sopenharmony_ci } 943425bb815Sopenharmony_ci else 944425bb815Sopenharmony_ci { 945425bb815Sopenharmony_ci status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_SETTER; 946425bb815Sopenharmony_ci opcode = CBC_EXT_SET_SETTER; 947425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 948425bb815Sopenharmony_ci item_type = PARSER_OBJECT_PROPERTY_SETTER; 949425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 950425bb815Sopenharmony_ci } 951425bb815Sopenharmony_ci 952425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); 953425bb815Sopenharmony_ci 954425bb815Sopenharmony_ci /* This assignment is a nop for computed getters/setters. */ 955425bb815Sopenharmony_ci uint16_t literal_index = context_p->lit_object.index; 956425bb815Sopenharmony_ci 957425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 958425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_SQUARE) 959425bb815Sopenharmony_ci { 960425bb815Sopenharmony_ci opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER 961425bb815Sopenharmony_ci : CBC_EXT_SET_COMPUTED_SETTER); 962425bb815Sopenharmony_ci } 963425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 964425bb815Sopenharmony_ci parser_append_object_literal_item (context_p, literal_index, item_type); 965425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 966425bb815Sopenharmony_ci 967425bb815Sopenharmony_ci uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags); 968425bb815Sopenharmony_ci 969425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 970425bb815Sopenharmony_ci if (opcode >= CBC_EXT_SET_COMPUTED_GETTER) 971425bb815Sopenharmony_ci { 972425bb815Sopenharmony_ci literal_index = function_literal_index; 973425bb815Sopenharmony_ci } 974425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 975425bb815Sopenharmony_ci 976425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 977425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 978425bb815Sopenharmony_ci literal_index); 979425bb815Sopenharmony_ci 980425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 981425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode); 982425bb815Sopenharmony_ci context_p->last_cbc.value = function_literal_index; 983425bb815Sopenharmony_ci 984425bb815Sopenharmony_ci lexer_next_token (context_p); 985425bb815Sopenharmony_ci break; 986425bb815Sopenharmony_ci } 987425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 988425bb815Sopenharmony_ci case LEXER_RIGHT_SQUARE: 989425bb815Sopenharmony_ci { 990425bb815Sopenharmony_ci lexer_next_token (context_p); 991425bb815Sopenharmony_ci 992425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_PAREN) 993425bb815Sopenharmony_ci { 994425bb815Sopenharmony_ci parser_parse_object_method (context_p); 995425bb815Sopenharmony_ci 996425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 997425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL); 998425bb815Sopenharmony_ci break; 999425bb815Sopenharmony_ci } 1000425bb815Sopenharmony_ci 1001425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COLON) 1002425bb815Sopenharmony_ci { 1003425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED); 1004425bb815Sopenharmony_ci } 1005425bb815Sopenharmony_ci 1006425bb815Sopenharmony_ci lexer_next_token (context_p); 1007425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 1008425bb815Sopenharmony_ci 1009425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1010425bb815Sopenharmony_ci { 1011425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL); 1012425bb815Sopenharmony_ci } 1013425bb815Sopenharmony_ci else 1014425bb815Sopenharmony_ci { 1015425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY); 1016425bb815Sopenharmony_ci } 1017425bb815Sopenharmony_ci break; 1018425bb815Sopenharmony_ci } 1019425bb815Sopenharmony_ci case LEXER_KEYW_ASYNC: 1020425bb815Sopenharmony_ci case LEXER_MULTIPLY: 1021425bb815Sopenharmony_ci { 1022425bb815Sopenharmony_ci uint32_t status_flags = PARSER_FUNCTION_CLOSURE; 1023425bb815Sopenharmony_ci 1024425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_ASYNC) 1025425bb815Sopenharmony_ci { 1026425bb815Sopenharmony_ci status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1027425bb815Sopenharmony_ci lexer_consume_generator (context_p); 1028425bb815Sopenharmony_ci } 1029425bb815Sopenharmony_ci 1030425bb815Sopenharmony_ci if (context_p->token.type == LEXER_MULTIPLY) 1031425bb815Sopenharmony_ci { 1032425bb815Sopenharmony_ci status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1033425bb815Sopenharmony_ci } 1034425bb815Sopenharmony_ci 1035425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); 1036425bb815Sopenharmony_ci 1037425bb815Sopenharmony_ci uint16_t opcode = CBC_SET_LITERAL_PROPERTY; 1038425bb815Sopenharmony_ci /* This assignment is a nop for CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL. */ 1039425bb815Sopenharmony_ci uint16_t literal_index = context_p->lit_object.index; 1040425bb815Sopenharmony_ci 1041425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_SQUARE) 1042425bb815Sopenharmony_ci { 1043425bb815Sopenharmony_ci opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL); 1044425bb815Sopenharmony_ci } 1045425bb815Sopenharmony_ci 1046425bb815Sopenharmony_ci uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags); 1047425bb815Sopenharmony_ci 1048425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 1049425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 1050425bb815Sopenharmony_ci function_literal_index); 1051425bb815Sopenharmony_ci 1052425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 1053425bb815Sopenharmony_ci context_p->last_cbc_opcode = opcode; 1054425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 1055425bb815Sopenharmony_ci 1056425bb815Sopenharmony_ci lexer_next_token (context_p); 1057425bb815Sopenharmony_ci break; 1058425bb815Sopenharmony_ci } 1059425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1060425bb815Sopenharmony_ci default: 1061425bb815Sopenharmony_ci { 1062425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1063425bb815Sopenharmony_ci const lexer_lit_location_t *literal_p = (const lexer_lit_location_t *) context_p->lit_object.literal_p; 1064425bb815Sopenharmony_ci bool is_proto = ((context_p->token.lit_location.type == LEXER_IDENT_LITERAL 1065425bb815Sopenharmony_ci || context_p->token.lit_location.type == LEXER_STRING_LITERAL) 1066425bb815Sopenharmony_ci && lexer_compare_identifier_to_string (literal_p, (uint8_t *) "__proto__", 9) 1067425bb815Sopenharmony_ci && lexer_check_next_character (context_p, LIT_CHAR_COLON)); 1068425bb815Sopenharmony_ci if (is_proto) 1069425bb815Sopenharmony_ci { 1070425bb815Sopenharmony_ci if (proto_seen) 1071425bb815Sopenharmony_ci { 1072425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DUPLICATED_PROTO); 1073425bb815Sopenharmony_ci } 1074425bb815Sopenharmony_ci 1075425bb815Sopenharmony_ci proto_seen = true; 1076425bb815Sopenharmony_ci } 1077425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1078425bb815Sopenharmony_ci 1079425bb815Sopenharmony_ci uint16_t literal_index = context_p->lit_object.index; 1080425bb815Sopenharmony_ci 1081425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1082425bb815Sopenharmony_ci parser_line_counter_t start_line = context_p->token.line; 1083425bb815Sopenharmony_ci parser_line_counter_t start_column = context_p->token.column; 1084425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1085425bb815Sopenharmony_ci parser_append_object_literal_item (context_p, 1086425bb815Sopenharmony_ci literal_index, 1087425bb815Sopenharmony_ci PARSER_OBJECT_PROPERTY_VALUE); 1088425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1089425bb815Sopenharmony_ci 1090425bb815Sopenharmony_ci lexer_next_token (context_p); 1091425bb815Sopenharmony_ci 1092425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1093425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_PAREN && !is_proto) 1094425bb815Sopenharmony_ci { 1095425bb815Sopenharmony_ci parser_parse_object_method (context_p); 1096425bb815Sopenharmony_ci 1097425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 1098425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY; 1099425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 1100425bb815Sopenharmony_ci break; 1101425bb815Sopenharmony_ci } 1102425bb815Sopenharmony_ci 1103425bb815Sopenharmony_ci if ((context_p->token.type == LEXER_RIGHT_BRACE || context_p->token.type == LEXER_COMMA) 1104425bb815Sopenharmony_ci && !is_proto) 1105425bb815Sopenharmony_ci { 1106425bb815Sopenharmony_ci parser_reparse_as_common_identifier (context_p, start_line, start_column); 1107425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL); 1108425bb815Sopenharmony_ci 1109425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY; 1110425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 1111425bb815Sopenharmony_ci 1112425bb815Sopenharmony_ci lexer_next_token (context_p); 1113425bb815Sopenharmony_ci break; 1114425bb815Sopenharmony_ci } 1115425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1116425bb815Sopenharmony_ci 1117425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COLON) 1118425bb815Sopenharmony_ci { 1119425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED); 1120425bb815Sopenharmony_ci } 1121425bb815Sopenharmony_ci 1122425bb815Sopenharmony_ci lexer_next_token (context_p); 1123425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 1124425bb815Sopenharmony_ci 1125425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1126425bb815Sopenharmony_ci if (is_proto) 1127425bb815Sopenharmony_ci { 1128425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_SET__PROTO__); 1129425bb815Sopenharmony_ci break; 1130425bb815Sopenharmony_ci } 1131425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1132425bb815Sopenharmony_ci 1133425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1134425bb815Sopenharmony_ci { 1135425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY; 1136425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 1137425bb815Sopenharmony_ci } 1138425bb815Sopenharmony_ci else 1139425bb815Sopenharmony_ci { 1140425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index); 1141425bb815Sopenharmony_ci } 1142425bb815Sopenharmony_ci 1143425bb815Sopenharmony_ci break; 1144425bb815Sopenharmony_ci } 1145425bb815Sopenharmony_ci } 1146425bb815Sopenharmony_ci 1147425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 1148425bb815Sopenharmony_ci { 1149425bb815Sopenharmony_ci break; 1150425bb815Sopenharmony_ci } 1151425bb815Sopenharmony_ci else if (context_p->token.type != LEXER_COMMA) 1152425bb815Sopenharmony_ci { 1153425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED); 1154425bb815Sopenharmony_ci } 1155425bb815Sopenharmony_ci } 1156425bb815Sopenharmony_ci 1157425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 1158425bb815Sopenharmony_ci while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START) 1159425bb815Sopenharmony_ci { 1160425bb815Sopenharmony_ci parser_stack_pop (context_p, NULL, 3); 1161425bb815Sopenharmony_ci } 1162425bb815Sopenharmony_ci 1163425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 1164425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 1165425bb815Sopenharmony_ci} /* parser_parse_object_literal */ 1166425bb815Sopenharmony_ci 1167425bb815Sopenharmony_ci/** 1168425bb815Sopenharmony_ci * Parse function literal. 1169425bb815Sopenharmony_ci */ 1170425bb815Sopenharmony_cistatic void 1171425bb815Sopenharmony_ciparser_parse_function_expression (parser_context_t *context_p, /**< context */ 1172425bb815Sopenharmony_ci uint32_t status_flags) /**< function status flags */ 1173425bb815Sopenharmony_ci{ 1174425bb815Sopenharmony_ci int literals = 0; 1175425bb815Sopenharmony_ci uint16_t literal1 = 0; 1176425bb815Sopenharmony_ci uint16_t literal2 = 0; 1177425bb815Sopenharmony_ci uint16_t function_literal_index; 1178425bb815Sopenharmony_ci int32_t function_name_index = -1; 1179425bb815Sopenharmony_ci 1180425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 1181425bb815Sopenharmony_ci JERRY_ASSERT (status_flags & PARSER_IS_FUNC_EXPRESSION); 1182425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 1183425bb815Sopenharmony_ci 1184425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1185425bb815Sopenharmony_ci if (status_flags & PARSER_IS_FUNC_EXPRESSION) 1186425bb815Sopenharmony_ci { 1187425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 1188425bb815Sopenharmony_ci 1189425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 1190425bb815Sopenharmony_ci parser_line_counter_t debugger_line = context_p->token.line; 1191425bb815Sopenharmony_ci parser_line_counter_t debugger_column = context_p->token.column; 1192425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 1193425bb815Sopenharmony_ci 1194425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1195425bb815Sopenharmony_ci uint32_t parent_status_flags = context_p->status_flags; 1196425bb815Sopenharmony_ci 1197425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~(PARSER_IS_ASYNC_FUNCTION 1198425bb815Sopenharmony_ci | PARSER_IS_GENERATOR_FUNCTION 1199425bb815Sopenharmony_ci | PARSER_DISALLOW_AWAIT_YIELD); 1200425bb815Sopenharmony_ci 1201425bb815Sopenharmony_ci if (status_flags & PARSER_IS_ASYNC_FUNCTION) 1202425bb815Sopenharmony_ci { 1203425bb815Sopenharmony_ci /* The name of the function cannot be await. */ 1204425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1205425bb815Sopenharmony_ci } 1206425bb815Sopenharmony_ci 1207425bb815Sopenharmony_ci if (lexer_consume_generator (context_p)) 1208425bb815Sopenharmony_ci { 1209425bb815Sopenharmony_ci /* The name of the function cannot be yield. */ 1210425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1211425bb815Sopenharmony_ci status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1212425bb815Sopenharmony_ci } 1213425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1214425bb815Sopenharmony_ci 1215425bb815Sopenharmony_ci if (!lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)) 1216425bb815Sopenharmony_ci { 1217425bb815Sopenharmony_ci lexer_next_token (context_p); 1218425bb815Sopenharmony_ci 1219425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 1220425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 1221425bb815Sopenharmony_ci { 1222425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 1223425bb815Sopenharmony_ci } 1224425bb815Sopenharmony_ci 1225425bb815Sopenharmony_ci parser_flush_cbc (context_p); 1226425bb815Sopenharmony_ci 1227425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL); 1228425bb815Sopenharmony_ci 1229425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 1230425bb815Sopenharmony_ci if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 1231425bb815Sopenharmony_ci { 1232425bb815Sopenharmony_ci jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME, 1233425bb815Sopenharmony_ci JERRY_DEBUGGER_NO_SUBTYPE, 1234425bb815Sopenharmony_ci context_p->lit_object.literal_p->u.char_p, 1235425bb815Sopenharmony_ci context_p->lit_object.literal_p->prop.length); 1236425bb815Sopenharmony_ci 1237425bb815Sopenharmony_ci /* Reset token position for the function. */ 1238425bb815Sopenharmony_ci context_p->token.line = debugger_line; 1239425bb815Sopenharmony_ci context_p->token.column = debugger_column; 1240425bb815Sopenharmony_ci } 1241425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 1242425bb815Sopenharmony_ci 1243425bb815Sopenharmony_ci if (context_p->token.keyword_type >= LEXER_FIRST_NON_STRICT_ARGUMENTS) 1244425bb815Sopenharmony_ci { 1245425bb815Sopenharmony_ci status_flags |= PARSER_HAS_NON_STRICT_ARG; 1246425bb815Sopenharmony_ci } 1247425bb815Sopenharmony_ci 1248425bb815Sopenharmony_ci function_name_index = context_p->lit_object.index; 1249425bb815Sopenharmony_ci } 1250425bb815Sopenharmony_ci 1251425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1252425bb815Sopenharmony_ci context_p->status_flags = parent_status_flags; 1253425bb815Sopenharmony_ci } 1254425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1255425bb815Sopenharmony_ci 1256425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1257425bb815Sopenharmony_ci { 1258425bb815Sopenharmony_ci literals = 1; 1259425bb815Sopenharmony_ci literal1 = context_p->last_cbc.literal_index; 1260425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 1261425bb815Sopenharmony_ci } 1262425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 1263425bb815Sopenharmony_ci { 1264425bb815Sopenharmony_ci literals = 2; 1265425bb815Sopenharmony_ci literal1 = context_p->last_cbc.literal_index; 1266425bb815Sopenharmony_ci literal2 = context_p->last_cbc.value; 1267425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 1268425bb815Sopenharmony_ci } 1269425bb815Sopenharmony_ci 1270425bb815Sopenharmony_ci function_literal_index = lexer_construct_function_object (context_p, status_flags); 1271425bb815Sopenharmony_ci 1272425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE); 1273425bb815Sopenharmony_ci 1274425bb815Sopenharmony_ci if (literals == 1) 1275425bb815Sopenharmony_ci { 1276425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 1277425bb815Sopenharmony_ci context_p->last_cbc.literal_index = literal1; 1278425bb815Sopenharmony_ci context_p->last_cbc.value = function_literal_index; 1279425bb815Sopenharmony_ci } 1280425bb815Sopenharmony_ci else if (literals == 2) 1281425bb815Sopenharmony_ci { 1282425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS; 1283425bb815Sopenharmony_ci context_p->last_cbc.literal_index = literal1; 1284425bb815Sopenharmony_ci context_p->last_cbc.value = literal2; 1285425bb815Sopenharmony_ci context_p->last_cbc.third_literal_index = function_literal_index; 1286425bb815Sopenharmony_ci } 1287425bb815Sopenharmony_ci else 1288425bb815Sopenharmony_ci { 1289425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, 1290425bb815Sopenharmony_ci CBC_PUSH_LITERAL, 1291425bb815Sopenharmony_ci function_literal_index); 1292425bb815Sopenharmony_ci 1293425bb815Sopenharmony_ci if (function_name_index != -1) 1294425bb815Sopenharmony_ci { 1295425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION); 1296425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) function_name_index; 1297425bb815Sopenharmony_ci } 1298425bb815Sopenharmony_ci } 1299425bb815Sopenharmony_ci 1300425bb815Sopenharmony_ci context_p->last_cbc.literal_type = LEXER_FUNCTION_LITERAL; 1301425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = LEXER_EOS; 1302425bb815Sopenharmony_ci} /* parser_parse_function_expression */ 1303425bb815Sopenharmony_ci 1304425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1305425bb815Sopenharmony_ci 1306425bb815Sopenharmony_ci/** 1307425bb815Sopenharmony_ci * Parse template literal. 1308425bb815Sopenharmony_ci */ 1309425bb815Sopenharmony_cistatic void 1310425bb815Sopenharmony_ciparser_parse_template_literal (parser_context_t *context_p) /**< context */ 1311425bb815Sopenharmony_ci{ 1312425bb815Sopenharmony_ci bool is_empty_head = true; 1313425bb815Sopenharmony_ci 1314425bb815Sopenharmony_ci if (context_p->token.lit_location.length > 0) 1315425bb815Sopenharmony_ci { 1316425bb815Sopenharmony_ci is_empty_head = false; 1317425bb815Sopenharmony_ci 1318425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 1319425bb815Sopenharmony_ci &context_p->token.lit_location, 1320425bb815Sopenharmony_ci context_p->token.lit_location.type); 1321425bb815Sopenharmony_ci 1322425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL); 1323425bb815Sopenharmony_ci } 1324425bb815Sopenharmony_ci 1325425bb815Sopenharmony_ci lexer_next_token (context_p); 1326425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR); 1327425bb815Sopenharmony_ci 1328425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_BRACE) 1329425bb815Sopenharmony_ci { 1330425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED); 1331425bb815Sopenharmony_ci } 1332425bb815Sopenharmony_ci 1333425bb815Sopenharmony_ci if (!is_empty_head) 1334425bb815Sopenharmony_ci { 1335425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 1336425bb815Sopenharmony_ci { 1337425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS); 1338425bb815Sopenharmony_ci } 1339425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1340425bb815Sopenharmony_ci { 1341425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL); 1342425bb815Sopenharmony_ci } 1343425bb815Sopenharmony_ci else 1344425bb815Sopenharmony_ci { 1345425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT); 1346425bb815Sopenharmony_ci } 1347425bb815Sopenharmony_ci } 1348425bb815Sopenharmony_ci 1349425bb815Sopenharmony_ci context_p->source_p--; 1350425bb815Sopenharmony_ci context_p->column--; 1351425bb815Sopenharmony_ci lexer_parse_string (context_p, LEXER_STRING_NO_OPTS); 1352425bb815Sopenharmony_ci 1353425bb815Sopenharmony_ci if (is_empty_head || context_p->token.lit_location.length > 0) 1354425bb815Sopenharmony_ci { 1355425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 1356425bb815Sopenharmony_ci &context_p->token.lit_location, 1357425bb815Sopenharmony_ci context_p->token.lit_location.type); 1358425bb815Sopenharmony_ci 1359425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1360425bb815Sopenharmony_ci { 1361425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS); 1362425bb815Sopenharmony_ci context_p->last_cbc.value = context_p->lit_object.index; 1363425bb815Sopenharmony_ci context_p->last_cbc.literal_type = context_p->token.lit_location.type; 1364425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type; 1365425bb815Sopenharmony_ci } 1366425bb815Sopenharmony_ci else 1367425bb815Sopenharmony_ci { 1368425bb815Sopenharmony_ci parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL); 1369425bb815Sopenharmony_ci } 1370425bb815Sopenharmony_ci } 1371425bb815Sopenharmony_ci 1372425bb815Sopenharmony_ci while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT) 1373425bb815Sopenharmony_ci { 1374425bb815Sopenharmony_ci lexer_next_token (context_p); 1375425bb815Sopenharmony_ci 1376425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR); 1377425bb815Sopenharmony_ci 1378425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_BRACE) 1379425bb815Sopenharmony_ci { 1380425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED); 1381425bb815Sopenharmony_ci } 1382425bb815Sopenharmony_ci 1383425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1384425bb815Sopenharmony_ci { 1385425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL); 1386425bb815Sopenharmony_ci } 1387425bb815Sopenharmony_ci else 1388425bb815Sopenharmony_ci { 1389425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT); 1390425bb815Sopenharmony_ci } 1391425bb815Sopenharmony_ci 1392425bb815Sopenharmony_ci context_p->source_p--; 1393425bb815Sopenharmony_ci context_p->column--; 1394425bb815Sopenharmony_ci lexer_parse_string (context_p, LEXER_STRING_NO_OPTS); 1395425bb815Sopenharmony_ci 1396425bb815Sopenharmony_ci if (context_p->token.lit_location.length > 0) 1397425bb815Sopenharmony_ci { 1398425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 1399425bb815Sopenharmony_ci &context_p->token.lit_location, 1400425bb815Sopenharmony_ci context_p->token.lit_location.type); 1401425bb815Sopenharmony_ci 1402425bb815Sopenharmony_ci parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL); 1403425bb815Sopenharmony_ci } 1404425bb815Sopenharmony_ci } 1405425bb815Sopenharmony_ci} /* parser_parse_template_literal */ 1406425bb815Sopenharmony_ci 1407425bb815Sopenharmony_ci/** 1408425bb815Sopenharmony_ci * Parse tagged template literal. 1409425bb815Sopenharmony_ci */ 1410425bb815Sopenharmony_cistatic size_t 1411425bb815Sopenharmony_ciparser_parse_tagged_template_literal (parser_context_t *context_p) /**< context */ 1412425bb815Sopenharmony_ci{ 1413425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_TEMPLATE_LITERAL); 1414425bb815Sopenharmony_ci 1415425bb815Sopenharmony_ci uint32_t call_arguments = 0; 1416425bb815Sopenharmony_ci ecma_collection_t *collection_p; 1417425bb815Sopenharmony_ci 1418425bb815Sopenharmony_ci if (context_p->tagged_template_literal_cp == JMEM_CP_NULL) 1419425bb815Sopenharmony_ci { 1420425bb815Sopenharmony_ci collection_p = ecma_new_collection (); 1421425bb815Sopenharmony_ci ECMA_SET_INTERNAL_VALUE_POINTER (context_p->tagged_template_literal_cp, collection_p); 1422425bb815Sopenharmony_ci } 1423425bb815Sopenharmony_ci else 1424425bb815Sopenharmony_ci { 1425425bb815Sopenharmony_ci collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_p->tagged_template_literal_cp); 1426425bb815Sopenharmony_ci if (collection_p->item_count > CBC_MAXIMUM_BYTE_VALUE) 1427425bb815Sopenharmony_ci { 1428425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED); 1429425bb815Sopenharmony_ci } 1430425bb815Sopenharmony_ci } 1431425bb815Sopenharmony_ci 1432425bb815Sopenharmony_ci const uint32_t tagged_id = collection_p->item_count; 1433425bb815Sopenharmony_ci uint32_t prop_idx = 0; 1434425bb815Sopenharmony_ci ecma_object_t *raw_strings_p; 1435425bb815Sopenharmony_ci ecma_object_t *template_obj_p = parser_new_tagged_template_literal (&raw_strings_p); 1436425bb815Sopenharmony_ci ecma_collection_push_back (collection_p, ecma_make_object_value (template_obj_p)); 1437425bb815Sopenharmony_ci 1438425bb815Sopenharmony_ci parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++); 1439425bb815Sopenharmony_ci 1440425bb815Sopenharmony_ci call_arguments++; 1441425bb815Sopenharmony_ci parser_emit_cbc_ext_call (context_p, CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, tagged_id); 1442425bb815Sopenharmony_ci 1443425bb815Sopenharmony_ci while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT) 1444425bb815Sopenharmony_ci { 1445425bb815Sopenharmony_ci JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LEFT_BRACE); 1446425bb815Sopenharmony_ci lexer_next_token (context_p); 1447425bb815Sopenharmony_ci 1448425bb815Sopenharmony_ci if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE) 1449425bb815Sopenharmony_ci { 1450425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED); 1451425bb815Sopenharmony_ci } 1452425bb815Sopenharmony_ci 1453425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR); 1454425bb815Sopenharmony_ci 1455425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_BRACE) 1456425bb815Sopenharmony_ci { 1457425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED); 1458425bb815Sopenharmony_ci } 1459425bb815Sopenharmony_ci 1460425bb815Sopenharmony_ci context_p->source_p--; 1461425bb815Sopenharmony_ci context_p->column--; 1462425bb815Sopenharmony_ci lexer_parse_string (context_p, LEXER_STRING_NO_OPTS); 1463425bb815Sopenharmony_ci 1464425bb815Sopenharmony_ci parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++); 1465425bb815Sopenharmony_ci } 1466425bb815Sopenharmony_ci 1467425bb815Sopenharmony_ci parser_tagged_template_literal_finalize (template_obj_p, raw_strings_p); 1468425bb815Sopenharmony_ci 1469425bb815Sopenharmony_ci return call_arguments; 1470425bb815Sopenharmony_ci} /* parser_parse_tagged_template_literal */ 1471425bb815Sopenharmony_ci 1472425bb815Sopenharmony_ci/** 1473425bb815Sopenharmony_ci * Checks wheteher the current expression can be an assignment expression. 1474425bb815Sopenharmony_ci * 1475425bb815Sopenharmony_ci * @return true if the current expression can be an assignment expression, false otherwise 1476425bb815Sopenharmony_ci */ 1477425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE 1478425bb815Sopenharmony_ciparser_is_assignment_expr (parser_context_t *context_p) 1479425bb815Sopenharmony_ci{ 1480425bb815Sopenharmony_ci return (context_p->stack_top_uint8 == LEXER_EXPRESSION_START 1481425bb815Sopenharmony_ci || context_p->stack_top_uint8 == LEXER_LEFT_PAREN 1482425bb815Sopenharmony_ci || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST 1483425bb815Sopenharmony_ci || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->stack_top_uint8)); 1484425bb815Sopenharmony_ci} /* parser_is_assignment_expr */ 1485425bb815Sopenharmony_ci 1486425bb815Sopenharmony_ci/** 1487425bb815Sopenharmony_ci * Throws an error if the current expression is not an assignment expression. 1488425bb815Sopenharmony_ci */ 1489425bb815Sopenharmony_cistatic inline void JERRY_ATTR_ALWAYS_INLINE 1490425bb815Sopenharmony_ciparser_check_assignment_expr (parser_context_t *context_p) 1491425bb815Sopenharmony_ci{ 1492425bb815Sopenharmony_ci if (!parser_is_assignment_expr (context_p)) 1493425bb815Sopenharmony_ci { 1494425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ASSIGNMENT_EXPECTED); 1495425bb815Sopenharmony_ci } 1496425bb815Sopenharmony_ci} /* parser_check_assignment_expr */ 1497425bb815Sopenharmony_ci 1498425bb815Sopenharmony_ci/** 1499425bb815Sopenharmony_ci * Checks whether the next token is a valid continuation token after an AssignmentExpression. 1500425bb815Sopenharmony_ci */ 1501425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE 1502425bb815Sopenharmony_ciparser_abort_parsing_after_assignment_expression (parser_context_t *context_p) 1503425bb815Sopenharmony_ci{ 1504425bb815Sopenharmony_ci return (context_p->token.type != LEXER_RIGHT_PAREN 1505425bb815Sopenharmony_ci && context_p->token.type != LEXER_COMMA); 1506425bb815Sopenharmony_ci} /* parser_abort_parsing_after_assignment_expression */ 1507425bb815Sopenharmony_ci 1508425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1509425bb815Sopenharmony_ci 1510425bb815Sopenharmony_ci/** 1511425bb815Sopenharmony_ci * Parse and record unary operators, and parse the primary literal. 1512425bb815Sopenharmony_ci * 1513425bb815Sopenharmony_ci * @return true if parsing should be aborted, true otherwise 1514425bb815Sopenharmony_ci */ 1515425bb815Sopenharmony_cistatic bool 1516425bb815Sopenharmony_ciparser_parse_unary_expression (parser_context_t *context_p, /**< context */ 1517425bb815Sopenharmony_ci size_t *grouping_level_p) /**< grouping level */ 1518425bb815Sopenharmony_ci{ 1519425bb815Sopenharmony_ci bool new_was_seen = false; 1520425bb815Sopenharmony_ci 1521425bb815Sopenharmony_ci /* Collect unary operators. */ 1522425bb815Sopenharmony_ci while (true) 1523425bb815Sopenharmony_ci { 1524425bb815Sopenharmony_ci /* Convert plus and minus binary operators to unary operators. */ 1525425bb815Sopenharmony_ci switch (context_p->token.type) 1526425bb815Sopenharmony_ci { 1527425bb815Sopenharmony_ci case LEXER_ADD: 1528425bb815Sopenharmony_ci { 1529425bb815Sopenharmony_ci context_p->token.type = LEXER_PLUS; 1530425bb815Sopenharmony_ci break; 1531425bb815Sopenharmony_ci } 1532425bb815Sopenharmony_ci case LEXER_SUBTRACT: 1533425bb815Sopenharmony_ci { 1534425bb815Sopenharmony_ci context_p->token.type = LEXER_NEGATE; 1535425bb815Sopenharmony_ci break; 1536425bb815Sopenharmony_ci } 1537425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1538425bb815Sopenharmony_ci case LEXER_KEYW_AWAIT: 1539425bb815Sopenharmony_ci { 1540425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->token.lit_location.has_escape)) 1541425bb815Sopenharmony_ci { 1542425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 1543425bb815Sopenharmony_ci } 1544425bb815Sopenharmony_ci break; 1545425bb815Sopenharmony_ci } 1546425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1547425bb815Sopenharmony_ci } 1548425bb815Sopenharmony_ci 1549425bb815Sopenharmony_ci /* Bracketed expressions are primary expressions. At this 1550425bb815Sopenharmony_ci * point their left paren is pushed onto the stack and 1551425bb815Sopenharmony_ci * they are processed when their closing paren is reached. */ 1552425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_PAREN) 1553425bb815Sopenharmony_ci { 1554425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1555425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 1556425bb815Sopenharmony_ci { 1557425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION); 1558425bb815Sopenharmony_ci break; 1559425bb815Sopenharmony_ci } 1560425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1561425bb815Sopenharmony_ci (*grouping_level_p) += PARSER_GROUPING_LEVEL_INCREASE; 1562425bb815Sopenharmony_ci new_was_seen = false; 1563425bb815Sopenharmony_ci } 1564425bb815Sopenharmony_ci else if (context_p->token.type == LEXER_KEYW_NEW) 1565425bb815Sopenharmony_ci { 1566425bb815Sopenharmony_ci /* After 'new' unary operators are not allowed. */ 1567425bb815Sopenharmony_ci new_was_seen = true; 1568425bb815Sopenharmony_ci 1569425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1570425bb815Sopenharmony_ci /* Check if "new.target" is written here. */ 1571425bb815Sopenharmony_ci if (scanner_try_scan_new_target (context_p)) 1572425bb815Sopenharmony_ci { 1573425bb815Sopenharmony_ci if (!(context_p->status_flags & PARSER_ALLOW_NEW_TARGET)) 1574425bb815Sopenharmony_ci { 1575425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED); 1576425bb815Sopenharmony_ci } 1577425bb815Sopenharmony_ci 1578425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_NEW_TARGET); 1579425bb815Sopenharmony_ci lexer_next_token (context_p); 1580425bb815Sopenharmony_ci /* Found "new.target" return here */ 1581425bb815Sopenharmony_ci return false; 1582425bb815Sopenharmony_ci } 1583425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1584425bb815Sopenharmony_ci } 1585425bb815Sopenharmony_ci else if (new_was_seen 1586425bb815Sopenharmony_ci || (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE) 1587425bb815Sopenharmony_ci || !LEXER_IS_UNARY_OP_TOKEN (context_p->token.type)) 1588425bb815Sopenharmony_ci { 1589425bb815Sopenharmony_ci break; 1590425bb815Sopenharmony_ci } 1591425bb815Sopenharmony_ci 1592425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, context_p->token.type); 1593425bb815Sopenharmony_ci lexer_next_token (context_p); 1594425bb815Sopenharmony_ci } 1595425bb815Sopenharmony_ci 1596425bb815Sopenharmony_ci /* Parse primary expression. */ 1597425bb815Sopenharmony_ci switch (context_p->token.type) 1598425bb815Sopenharmony_ci { 1599425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1600425bb815Sopenharmony_ci case LEXER_TEMPLATE_LITERAL: 1601425bb815Sopenharmony_ci { 1602425bb815Sopenharmony_ci if (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT) 1603425bb815Sopenharmony_ci { 1604425bb815Sopenharmony_ci parser_parse_template_literal (context_p); 1605425bb815Sopenharmony_ci break; 1606425bb815Sopenharmony_ci } 1607425bb815Sopenharmony_ci 1608425bb815Sopenharmony_ci /* The string is a normal string literal. */ 1609425bb815Sopenharmony_ci /* FALLTHRU */ 1610425bb815Sopenharmony_ci } 1611425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1612425bb815Sopenharmony_ci case LEXER_LITERAL: 1613425bb815Sopenharmony_ci { 1614425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1615425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->next_scanner_info_p->source_p == context_p->source_p)) 1616425bb815Sopenharmony_ci { 1617425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION); 1618425bb815Sopenharmony_ci 1619425bb815Sopenharmony_ci uint32_t arrow_status_flags = (PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION); 1620425bb815Sopenharmony_ci 1621425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC) 1622425bb815Sopenharmony_ci { 1623425bb815Sopenharmony_ci JERRY_ASSERT (lexer_token_is_async (context_p)); 1624425bb815Sopenharmony_ci JERRY_ASSERT (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT)); 1625425bb815Sopenharmony_ci 1626425bb815Sopenharmony_ci uint32_t saved_status_flags = context_p->status_flags; 1627425bb815Sopenharmony_ci 1628425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD; 1629425bb815Sopenharmony_ci lexer_next_token (context_p); 1630425bb815Sopenharmony_ci context_p->status_flags = saved_status_flags; 1631425bb815Sopenharmony_ci 1632425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_FUNCTION) 1633425bb815Sopenharmony_ci { 1634425bb815Sopenharmony_ci uint32_t status_flags = (PARSER_FUNCTION_CLOSURE 1635425bb815Sopenharmony_ci | PARSER_IS_FUNC_EXPRESSION 1636425bb815Sopenharmony_ci | PARSER_IS_ASYNC_FUNCTION 1637425bb815Sopenharmony_ci | PARSER_DISALLOW_AWAIT_YIELD); 1638425bb815Sopenharmony_ci parser_parse_function_expression (context_p, status_flags); 1639425bb815Sopenharmony_ci break; 1640425bb815Sopenharmony_ci } 1641425bb815Sopenharmony_ci 1642425bb815Sopenharmony_ci arrow_status_flags = (PARSER_IS_FUNCTION 1643425bb815Sopenharmony_ci | PARSER_IS_ARROW_FUNCTION 1644425bb815Sopenharmony_ci | PARSER_IS_ASYNC_FUNCTION 1645425bb815Sopenharmony_ci | PARSER_DISALLOW_AWAIT_YIELD); 1646425bb815Sopenharmony_ci } 1647425bb815Sopenharmony_ci 1648425bb815Sopenharmony_ci parser_check_assignment_expr (context_p); 1649425bb815Sopenharmony_ci parser_parse_function_expression (context_p, arrow_status_flags); 1650425bb815Sopenharmony_ci return parser_abort_parsing_after_assignment_expression (context_p); 1651425bb815Sopenharmony_ci } 1652425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1653425bb815Sopenharmony_ci 1654425bb815Sopenharmony_ci uint8_t type = context_p->token.lit_location.type; 1655425bb815Sopenharmony_ci 1656425bb815Sopenharmony_ci if (type == LEXER_IDENT_LITERAL || type == LEXER_STRING_LITERAL) 1657425bb815Sopenharmony_ci { 1658425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 1659425bb815Sopenharmony_ci &context_p->token.lit_location, 1660425bb815Sopenharmony_ci context_p->token.lit_location.type); 1661425bb815Sopenharmony_ci 1662425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 1663425bb815Sopenharmony_ci if ((context_p->status_flags & PARSER_MODULE_STORE_IDENT) 1664425bb815Sopenharmony_ci && type == LEXER_IDENT_LITERAL) 1665425bb815Sopenharmony_ci { 1666425bb815Sopenharmony_ci context_p->module_identifier_lit_p = context_p->lit_object.literal_p; 1667425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT); 1668425bb815Sopenharmony_ci } 1669425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 1670425bb815Sopenharmony_ci } 1671425bb815Sopenharmony_ci else if (type == LEXER_NUMBER_LITERAL) 1672425bb815Sopenharmony_ci { 1673425bb815Sopenharmony_ci bool is_negative_number = false; 1674425bb815Sopenharmony_ci 1675425bb815Sopenharmony_ci if ((context_p->stack_top_uint8 == LEXER_PLUS || context_p->stack_top_uint8 == LEXER_NEGATE) 1676425bb815Sopenharmony_ci && !lexer_check_post_primary_exp (context_p)) 1677425bb815Sopenharmony_ci { 1678425bb815Sopenharmony_ci do 1679425bb815Sopenharmony_ci { 1680425bb815Sopenharmony_ci if (context_p->stack_top_uint8 == LEXER_NEGATE) 1681425bb815Sopenharmony_ci { 1682425bb815Sopenharmony_ci is_negative_number = !is_negative_number; 1683425bb815Sopenharmony_ci } 1684425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 1685425bb815Sopenharmony_ci } 1686425bb815Sopenharmony_ci while (context_p->stack_top_uint8 == LEXER_PLUS 1687425bb815Sopenharmony_ci || context_p->stack_top_uint8 == LEXER_NEGATE); 1688425bb815Sopenharmony_ci } 1689425bb815Sopenharmony_ci 1690425bb815Sopenharmony_ci if (lexer_construct_number_object (context_p, true, is_negative_number)) 1691425bb815Sopenharmony_ci { 1692425bb815Sopenharmony_ci JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END); 1693425bb815Sopenharmony_ci 1694425bb815Sopenharmony_ci parser_emit_cbc_push_number (context_p, is_negative_number); 1695425bb815Sopenharmony_ci break; 1696425bb815Sopenharmony_ci } 1697425bb815Sopenharmony_ci } 1698425bb815Sopenharmony_ci 1699425bb815Sopenharmony_ci cbc_opcode_t opcode = CBC_PUSH_LITERAL; 1700425bb815Sopenharmony_ci 1701425bb815Sopenharmony_ci if (context_p->token.keyword_type != LEXER_KEYW_EVAL) 1702425bb815Sopenharmony_ci { 1703425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1704425bb815Sopenharmony_ci { 1705425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 1706425bb815Sopenharmony_ci context_p->last_cbc.value = context_p->lit_object.index; 1707425bb815Sopenharmony_ci context_p->last_cbc.literal_type = context_p->token.lit_location.type; 1708425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type; 1709425bb815Sopenharmony_ci break; 1710425bb815Sopenharmony_ci } 1711425bb815Sopenharmony_ci 1712425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 1713425bb815Sopenharmony_ci { 1714425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS; 1715425bb815Sopenharmony_ci context_p->last_cbc.third_literal_index = context_p->lit_object.index; 1716425bb815Sopenharmony_ci context_p->last_cbc.literal_type = context_p->token.lit_location.type; 1717425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type; 1718425bb815Sopenharmony_ci break; 1719425bb815Sopenharmony_ci } 1720425bb815Sopenharmony_ci 1721425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_THIS) 1722425bb815Sopenharmony_ci { 1723425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 1724425bb815Sopenharmony_ci opcode = CBC_PUSH_THIS_LITERAL; 1725425bb815Sopenharmony_ci } 1726425bb815Sopenharmony_ci } 1727425bb815Sopenharmony_ci 1728425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, (uint16_t) opcode); 1729425bb815Sopenharmony_ci break; 1730425bb815Sopenharmony_ci } 1731425bb815Sopenharmony_ci case LEXER_KEYW_FUNCTION: 1732425bb815Sopenharmony_ci { 1733425bb815Sopenharmony_ci parser_parse_function_expression (context_p, PARSER_FUNCTION_CLOSURE | PARSER_IS_FUNC_EXPRESSION); 1734425bb815Sopenharmony_ci break; 1735425bb815Sopenharmony_ci } 1736425bb815Sopenharmony_ci case LEXER_LEFT_BRACE: 1737425bb815Sopenharmony_ci { 1738425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1739425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 1740425bb815Sopenharmony_ci { 1741425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER); 1742425bb815Sopenharmony_ci 1743425bb815Sopenharmony_ci if (parser_is_assignment_expr (context_p)) 1744425bb815Sopenharmony_ci { 1745425bb815Sopenharmony_ci parser_parse_object_initializer (context_p, PARSER_PATTERN_NO_OPTS); 1746425bb815Sopenharmony_ci return parser_abort_parsing_after_assignment_expression (context_p); 1747425bb815Sopenharmony_ci } 1748425bb815Sopenharmony_ci 1749425bb815Sopenharmony_ci scanner_release_next (context_p, sizeof (scanner_location_info_t)); 1750425bb815Sopenharmony_ci } 1751425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1752425bb815Sopenharmony_ci 1753425bb815Sopenharmony_ci parser_parse_object_literal (context_p); 1754425bb815Sopenharmony_ci break; 1755425bb815Sopenharmony_ci } 1756425bb815Sopenharmony_ci case LEXER_LEFT_SQUARE: 1757425bb815Sopenharmony_ci { 1758425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1759425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 1760425bb815Sopenharmony_ci { 1761425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER); 1762425bb815Sopenharmony_ci 1763425bb815Sopenharmony_ci if (parser_is_assignment_expr (context_p)) 1764425bb815Sopenharmony_ci { 1765425bb815Sopenharmony_ci parser_parse_array_initializer (context_p, PARSER_PATTERN_NO_OPTS); 1766425bb815Sopenharmony_ci return parser_abort_parsing_after_assignment_expression (context_p); 1767425bb815Sopenharmony_ci } 1768425bb815Sopenharmony_ci 1769425bb815Sopenharmony_ci scanner_release_next (context_p, sizeof (scanner_location_info_t)); 1770425bb815Sopenharmony_ci } 1771425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1772425bb815Sopenharmony_ci 1773425bb815Sopenharmony_ci parser_parse_array_literal (context_p); 1774425bb815Sopenharmony_ci break; 1775425bb815Sopenharmony_ci } 1776425bb815Sopenharmony_ci case LEXER_DIVIDE: 1777425bb815Sopenharmony_ci case LEXER_ASSIGN_DIVIDE: 1778425bb815Sopenharmony_ci { 1779425bb815Sopenharmony_ci lexer_construct_regexp_object (context_p, false); 1780425bb815Sopenharmony_ci 1781425bb815Sopenharmony_ci uint16_t literal_index = (uint16_t) (context_p->literal_count - 1); 1782425bb815Sopenharmony_ci 1783425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1784425bb815Sopenharmony_ci { 1785425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 1786425bb815Sopenharmony_ci context_p->last_cbc.value = literal_index; 1787425bb815Sopenharmony_ci } 1788425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 1789425bb815Sopenharmony_ci { 1790425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS; 1791425bb815Sopenharmony_ci context_p->last_cbc.third_literal_index = literal_index; 1792425bb815Sopenharmony_ci } 1793425bb815Sopenharmony_ci else 1794425bb815Sopenharmony_ci { 1795425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, literal_index); 1796425bb815Sopenharmony_ci } 1797425bb815Sopenharmony_ci 1798425bb815Sopenharmony_ci context_p->last_cbc.literal_type = LEXER_REGEXP_LITERAL; 1799425bb815Sopenharmony_ci context_p->last_cbc.literal_keyword_type = LEXER_EOS; 1800425bb815Sopenharmony_ci break; 1801425bb815Sopenharmony_ci } 1802425bb815Sopenharmony_ci case LEXER_KEYW_THIS: 1803425bb815Sopenharmony_ci { 1804425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1805425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_ALLOW_SUPER_CALL) 1806425bb815Sopenharmony_ci { 1807425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_LEXICAL_THIS); 1808425bb815Sopenharmony_ci } 1809425bb815Sopenharmony_ci else 1810425bb815Sopenharmony_ci { 1811425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1812425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_THIS); 1813425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1814425bb815Sopenharmony_ci } 1815425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1816425bb815Sopenharmony_ci break; 1817425bb815Sopenharmony_ci } 1818425bb815Sopenharmony_ci case LEXER_LIT_TRUE: 1819425bb815Sopenharmony_ci { 1820425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_TRUE); 1821425bb815Sopenharmony_ci break; 1822425bb815Sopenharmony_ci } 1823425bb815Sopenharmony_ci case LEXER_LIT_FALSE: 1824425bb815Sopenharmony_ci { 1825425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_FALSE); 1826425bb815Sopenharmony_ci break; 1827425bb815Sopenharmony_ci } 1828425bb815Sopenharmony_ci case LEXER_LIT_NULL: 1829425bb815Sopenharmony_ci { 1830425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_NULL); 1831425bb815Sopenharmony_ci break; 1832425bb815Sopenharmony_ci } 1833425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1834425bb815Sopenharmony_ci case LEXER_KEYW_CLASS: 1835425bb815Sopenharmony_ci { 1836425bb815Sopenharmony_ci parser_parse_class (context_p, false); 1837425bb815Sopenharmony_ci return false; 1838425bb815Sopenharmony_ci } 1839425bb815Sopenharmony_ci case LEXER_KEYW_SUPER: 1840425bb815Sopenharmony_ci { 1841425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_ALLOW_SUPER) 1842425bb815Sopenharmony_ci { 1843425bb815Sopenharmony_ci if (lexer_check_next_characters (context_p, LIT_CHAR_DOT, LIT_CHAR_LEFT_SQUARE)) 1844425bb815Sopenharmony_ci { 1845425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER); 1846425bb815Sopenharmony_ci break; 1847425bb815Sopenharmony_ci } 1848425bb815Sopenharmony_ci 1849425bb815Sopenharmony_ci if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN) 1850425bb815Sopenharmony_ci && (context_p->status_flags & PARSER_ALLOW_SUPER_CALL)) 1851425bb815Sopenharmony_ci { 1852425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_CONSTRUCTOR); 1853425bb815Sopenharmony_ci break; 1854425bb815Sopenharmony_ci } 1855425bb815Sopenharmony_ci } 1856425bb815Sopenharmony_ci 1857425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNEXPECTED_SUPER_KEYWORD); 1858425bb815Sopenharmony_ci } 1859425bb815Sopenharmony_ci case LEXER_LEFT_PAREN: 1860425bb815Sopenharmony_ci { 1861425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->source_p == context_p->source_p 1862425bb815Sopenharmony_ci && context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION); 1863425bb815Sopenharmony_ci 1864425bb815Sopenharmony_ci parser_check_assignment_expr (context_p); 1865425bb815Sopenharmony_ci 1866425bb815Sopenharmony_ci parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION); 1867425bb815Sopenharmony_ci return parser_abort_parsing_after_assignment_expression (context_p); 1868425bb815Sopenharmony_ci } 1869425bb815Sopenharmony_ci case LEXER_KEYW_YIELD: 1870425bb815Sopenharmony_ci { 1871425bb815Sopenharmony_ci JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION) 1872425bb815Sopenharmony_ci && !(context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD)); 1873425bb815Sopenharmony_ci 1874425bb815Sopenharmony_ci if (context_p->token.lit_location.has_escape) 1875425bb815Sopenharmony_ci { 1876425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 1877425bb815Sopenharmony_ci } 1878425bb815Sopenharmony_ci 1879425bb815Sopenharmony_ci parser_check_assignment_expr (context_p); 1880425bb815Sopenharmony_ci lexer_next_token (context_p); 1881425bb815Sopenharmony_ci 1882425bb815Sopenharmony_ci cbc_ext_opcode_t opcode = CBC_EXT_YIELD; 1883425bb815Sopenharmony_ci 1884425bb815Sopenharmony_ci if (!lexer_check_yield_no_arg (context_p)) 1885425bb815Sopenharmony_ci { 1886425bb815Sopenharmony_ci if (context_p->token.type == LEXER_MULTIPLY) 1887425bb815Sopenharmony_ci { 1888425bb815Sopenharmony_ci lexer_next_token (context_p); 1889425bb815Sopenharmony_ci opcode = CBC_EXT_YIELD_ITERATOR; 1890425bb815Sopenharmony_ci } 1891425bb815Sopenharmony_ci 1892425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 1893425bb815Sopenharmony_ci } 1894425bb815Sopenharmony_ci else 1895425bb815Sopenharmony_ci { 1896425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED); 1897425bb815Sopenharmony_ci } 1898425bb815Sopenharmony_ci 1899425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, opcode); 1900425bb815Sopenharmony_ci 1901425bb815Sopenharmony_ci return (context_p->token.type != LEXER_RIGHT_PAREN 1902425bb815Sopenharmony_ci && context_p->token.type != LEXER_COMMA); 1903425bb815Sopenharmony_ci } 1904425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1905425bb815Sopenharmony_ci default: 1906425bb815Sopenharmony_ci { 1907425bb815Sopenharmony_ci bool is_left_hand_side = (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE); 1908425bb815Sopenharmony_ci parser_raise_error (context_p, (is_left_hand_side ? PARSER_ERR_LEFT_HAND_SIDE_EXP_EXPECTED 1909425bb815Sopenharmony_ci : PARSER_ERR_PRIMARY_EXP_EXPECTED)); 1910425bb815Sopenharmony_ci break; 1911425bb815Sopenharmony_ci } 1912425bb815Sopenharmony_ci } 1913425bb815Sopenharmony_ci lexer_next_token (context_p); 1914425bb815Sopenharmony_ci return false; 1915425bb815Sopenharmony_ci} /* parser_parse_unary_expression */ 1916425bb815Sopenharmony_ci 1917425bb815Sopenharmony_ci/** 1918425bb815Sopenharmony_ci * Parse the postfix part of unary operators, and 1919425bb815Sopenharmony_ci * generate byte code for the whole expression. 1920425bb815Sopenharmony_ci */ 1921425bb815Sopenharmony_cistatic void 1922425bb815Sopenharmony_ciparser_process_unary_expression (parser_context_t *context_p, /**< context */ 1923425bb815Sopenharmony_ci size_t grouping_level) /**< grouping level */ 1924425bb815Sopenharmony_ci{ 1925425bb815Sopenharmony_ci /* Parse postfix part of a primary expression. */ 1926425bb815Sopenharmony_ci while (true) 1927425bb815Sopenharmony_ci { 1928425bb815Sopenharmony_ci /* Since break would only break the switch, we use 1929425bb815Sopenharmony_ci * continue to continue this loop. Without continue, 1930425bb815Sopenharmony_ci * the code abandons the loop. */ 1931425bb815Sopenharmony_ci switch (context_p->token.type) 1932425bb815Sopenharmony_ci { 1933425bb815Sopenharmony_ci case LEXER_DOT: 1934425bb815Sopenharmony_ci { 1935425bb815Sopenharmony_ci parser_push_result (context_p); 1936425bb815Sopenharmony_ci 1937425bb815Sopenharmony_ci lexer_expect_identifier (context_p, LEXER_STRING_LITERAL); 1938425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 1939425bb815Sopenharmony_ci && context_p->lit_object.literal_p->type == LEXER_STRING_LITERAL); 1940425bb815Sopenharmony_ci context_p->token.lit_location.type = LEXER_STRING_LITERAL; 1941425bb815Sopenharmony_ci 1942425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 1943425bb815Sopenharmony_ci { 1944425bb815Sopenharmony_ci JERRY_ASSERT (CBC_ARGS_EQ (CBC_PUSH_PROP_LITERAL_LITERAL, 1945425bb815Sopenharmony_ci CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)); 1946425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL; 1947425bb815Sopenharmony_ci context_p->last_cbc.value = context_p->lit_object.index; 1948425bb815Sopenharmony_ci } 1949425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_THIS) 1950425bb815Sopenharmony_ci { 1951425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 1952425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_THIS_LITERAL); 1953425bb815Sopenharmony_ci } 1954425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1955425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER)) 1956425bb815Sopenharmony_ci { 1957425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL); 1958425bb815Sopenharmony_ci context_p->last_cbc.literal_index = context_p->lit_object.index; 1959425bb815Sopenharmony_ci } 1960425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1961425bb815Sopenharmony_ci else 1962425bb815Sopenharmony_ci { 1963425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_LITERAL); 1964425bb815Sopenharmony_ci } 1965425bb815Sopenharmony_ci lexer_next_token (context_p); 1966425bb815Sopenharmony_ci continue; 1967425bb815Sopenharmony_ci } 1968425bb815Sopenharmony_ci 1969425bb815Sopenharmony_ci case LEXER_LEFT_SQUARE: 1970425bb815Sopenharmony_ci { 1971425bb815Sopenharmony_ci parser_push_result (context_p); 1972425bb815Sopenharmony_ci 1973425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1974425bb815Sopenharmony_ci uint16_t last_cbc_opcode = context_p->last_cbc_opcode; 1975425bb815Sopenharmony_ci 1976425bb815Sopenharmony_ci if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER)) 1977425bb815Sopenharmony_ci { 1978425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 1979425bb815Sopenharmony_ci } 1980425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1981425bb815Sopenharmony_ci 1982425bb815Sopenharmony_ci lexer_next_token (context_p); 1983425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR); 1984425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_SQUARE) 1985425bb815Sopenharmony_ci { 1986425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED); 1987425bb815Sopenharmony_ci } 1988425bb815Sopenharmony_ci lexer_next_token (context_p); 1989425bb815Sopenharmony_ci 1990425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1991425bb815Sopenharmony_ci if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER)) 1992425bb815Sopenharmony_ci { 1993425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_PROP); 1994425bb815Sopenharmony_ci continue; 1995425bb815Sopenharmony_ci } 1996425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1997425bb815Sopenharmony_ci 1998425bb815Sopenharmony_ci if (PARSER_IS_MUTABLE_PUSH_LITERAL (context_p->last_cbc_opcode)) 1999425bb815Sopenharmony_ci { 2000425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_PUSH_LITERAL_TO_PUSH_PROP_LITERAL (context_p->last_cbc_opcode); 2001425bb815Sopenharmony_ci } 2002425bb815Sopenharmony_ci else 2003425bb815Sopenharmony_ci { 2004425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_PROP); 2005425bb815Sopenharmony_ci } 2006425bb815Sopenharmony_ci continue; 2007425bb815Sopenharmony_ci } 2008425bb815Sopenharmony_ci 2009425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2010425bb815Sopenharmony_ci case LEXER_TEMPLATE_LITERAL: 2011425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2012425bb815Sopenharmony_ci case LEXER_LEFT_PAREN: 2013425bb815Sopenharmony_ci { 2014425bb815Sopenharmony_ci size_t call_arguments = 0; 2015425bb815Sopenharmony_ci uint16_t opcode = CBC_CALL; 2016425bb815Sopenharmony_ci bool is_eval = false; 2017425bb815Sopenharmony_ci 2018425bb815Sopenharmony_ci parser_push_result (context_p); 2019425bb815Sopenharmony_ci 2020425bb815Sopenharmony_ci if (context_p->stack_top_uint8 == LEXER_KEYW_NEW) 2021425bb815Sopenharmony_ci { 2022425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2023425bb815Sopenharmony_ci opcode = CBC_NEW; 2024425bb815Sopenharmony_ci } 2025425bb815Sopenharmony_ci else 2026425bb815Sopenharmony_ci { 2027425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL 2028425bb815Sopenharmony_ci && context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL 2029425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 2030425bb815Sopenharmony_ci { 2031425bb815Sopenharmony_ci is_eval = true; 2032425bb815Sopenharmony_ci } 2033425bb815Sopenharmony_ci 2034425bb815Sopenharmony_ci if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode)) 2035425bb815Sopenharmony_ci { 2036425bb815Sopenharmony_ci opcode = CBC_CALL_PROP; 2037425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode); 2038425bb815Sopenharmony_ci } 2039425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2040425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_CONSTRUCTOR)) 2041425bb815Sopenharmony_ci { 2042425bb815Sopenharmony_ci opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL); 2043425bb815Sopenharmony_ci } 2044425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL)) 2045425bb815Sopenharmony_ci { 2046425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE); 2047425bb815Sopenharmony_ci opcode = CBC_CALL_PROP; 2048425bb815Sopenharmony_ci } 2049425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP)) 2050425bb815Sopenharmony_ci { 2051425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE); 2052425bb815Sopenharmony_ci opcode = CBC_CALL_PROP; 2053425bb815Sopenharmony_ci } 2054425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2055425bb815Sopenharmony_ci else if (JERRY_UNLIKELY (context_p->status_flags & PARSER_INSIDE_WITH) 2056425bb815Sopenharmony_ci && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 2057425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 2058425bb815Sopenharmony_ci { 2059425bb815Sopenharmony_ci opcode = CBC_CALL_PROP; 2060425bb815Sopenharmony_ci parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE); 2061425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE); 2062425bb815Sopenharmony_ci } 2063425bb815Sopenharmony_ci } 2064425bb815Sopenharmony_ci 2065425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2066425bb815Sopenharmony_ci bool has_spread_element = false; 2067425bb815Sopenharmony_ci 2068425bb815Sopenharmony_ci if (context_p->token.type == LEXER_TEMPLATE_LITERAL) 2069425bb815Sopenharmony_ci { 2070425bb815Sopenharmony_ci call_arguments = parser_parse_tagged_template_literal (context_p); 2071425bb815Sopenharmony_ci } 2072425bb815Sopenharmony_ci else 2073425bb815Sopenharmony_ci { 2074425bb815Sopenharmony_ci lexer_next_token (context_p); 2075425bb815Sopenharmony_ci 2076425bb815Sopenharmony_ci while (context_p->token.type != LEXER_RIGHT_PAREN) 2077425bb815Sopenharmony_ci { 2078425bb815Sopenharmony_ci if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE) 2079425bb815Sopenharmony_ci { 2080425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED); 2081425bb815Sopenharmony_ci } 2082425bb815Sopenharmony_ci 2083425bb815Sopenharmony_ci if (context_p->token.type == LEXER_THREE_DOTS) 2084425bb815Sopenharmony_ci { 2085425bb815Sopenharmony_ci has_spread_element = true; 2086425bb815Sopenharmony_ci call_arguments++; 2087425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT); 2088425bb815Sopenharmony_ci lexer_next_token (context_p); 2089425bb815Sopenharmony_ci } 2090425bb815Sopenharmony_ci 2091425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 2092425bb815Sopenharmony_ci 2093425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COMMA) 2094425bb815Sopenharmony_ci { 2095425bb815Sopenharmony_ci lexer_next_token (context_p); 2096425bb815Sopenharmony_ci continue; 2097425bb815Sopenharmony_ci } 2098425bb815Sopenharmony_ci 2099425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_PAREN) 2100425bb815Sopenharmony_ci { 2101425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED); 2102425bb815Sopenharmony_ci } 2103425bb815Sopenharmony_ci 2104425bb815Sopenharmony_ci break; 2105425bb815Sopenharmony_ci } 2106425bb815Sopenharmony_ci } 2107425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2108425bb815Sopenharmony_ci lexer_next_token (context_p); 2109425bb815Sopenharmony_ci 2110425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_PAREN) 2111425bb815Sopenharmony_ci { 2112425bb815Sopenharmony_ci while (true) 2113425bb815Sopenharmony_ci { 2114425bb815Sopenharmony_ci if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE) 2115425bb815Sopenharmony_ci { 2116425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED); 2117425bb815Sopenharmony_ci } 2118425bb815Sopenharmony_ci 2119425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 2120425bb815Sopenharmony_ci 2121425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COMMA) 2122425bb815Sopenharmony_ci { 2123425bb815Sopenharmony_ci break; 2124425bb815Sopenharmony_ci } 2125425bb815Sopenharmony_ci lexer_next_token (context_p); 2126425bb815Sopenharmony_ci } 2127425bb815Sopenharmony_ci 2128425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_PAREN) 2129425bb815Sopenharmony_ci { 2130425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED); 2131425bb815Sopenharmony_ci } 2132425bb815Sopenharmony_ci } 2133425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2134425bb815Sopenharmony_ci 2135425bb815Sopenharmony_ci lexer_next_token (context_p); 2136425bb815Sopenharmony_ci 2137425bb815Sopenharmony_ci if (is_eval) 2138425bb815Sopenharmony_ci { 2139425bb815Sopenharmony_ci context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED; 2140425bb815Sopenharmony_ci 2141425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2142425bb815Sopenharmony_ci uint16_t eval_flags = PARSER_SAVE_STATUS_FLAGS (context_p->status_flags); 2143425bb815Sopenharmony_ci const uint32_t required_flags = PARSER_IS_FUNCTION | PARSER_LEXICAL_BLOCK_NEEDED; 2144425bb815Sopenharmony_ci 2145425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_FUNCTION_IS_PARSING_ARGS) 2146425bb815Sopenharmony_ci { 2147425bb815Sopenharmony_ci context_p->status_flags |= PARSER_LEXICAL_BLOCK_NEEDED; 2148425bb815Sopenharmony_ci } 2149425bb815Sopenharmony_ci else if (((context_p->status_flags & (required_flags | PARSER_IS_STRICT)) == required_flags) 2150425bb815Sopenharmony_ci || ((context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT) 2151425bb815Sopenharmony_ci && !(context_p->status_flags & PARSER_IS_FUNCTION))) 2152425bb815Sopenharmony_ci { 2153425bb815Sopenharmony_ci eval_flags |= PARSER_GET_EVAL_FLAG (ECMA_PARSE_FUNCTION_CONTEXT); 2154425bb815Sopenharmony_ci } 2155425bb815Sopenharmony_ci 2156425bb815Sopenharmony_ci if (eval_flags != 0) 2157425bb815Sopenharmony_ci { 2158425bb815Sopenharmony_ci parser_emit_cbc_ext_call (context_p, CBC_EXT_LOCAL_EVAL, eval_flags); 2159425bb815Sopenharmony_ci } 2160425bb815Sopenharmony_ci else 2161425bb815Sopenharmony_ci { 2162425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2163425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_EVAL); 2164425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2165425bb815Sopenharmony_ci } 2166425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2167425bb815Sopenharmony_ci } 2168425bb815Sopenharmony_ci 2169425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2170425bb815Sopenharmony_ci if (has_spread_element) 2171425bb815Sopenharmony_ci { 2172425bb815Sopenharmony_ci uint16_t spread_opcode; 2173425bb815Sopenharmony_ci 2174425bb815Sopenharmony_ci if (opcode == CBC_CALL) 2175425bb815Sopenharmony_ci { 2176425bb815Sopenharmony_ci spread_opcode = CBC_EXT_SPREAD_CALL; 2177425bb815Sopenharmony_ci } 2178425bb815Sopenharmony_ci else if (opcode == CBC_CALL_PROP) 2179425bb815Sopenharmony_ci { 2180425bb815Sopenharmony_ci spread_opcode = CBC_EXT_SPREAD_CALL_PROP; 2181425bb815Sopenharmony_ci } 2182425bb815Sopenharmony_ci else if (opcode == CBC_NEW) 2183425bb815Sopenharmony_ci { 2184425bb815Sopenharmony_ci spread_opcode = CBC_EXT_SPREAD_NEW; 2185425bb815Sopenharmony_ci } 2186425bb815Sopenharmony_ci else 2187425bb815Sopenharmony_ci { 2188425bb815Sopenharmony_ci /* opcode is unchanged */ 2189425bb815Sopenharmony_ci JERRY_ASSERT (opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL)); 2190425bb815Sopenharmony_ci spread_opcode = CBC_EXT_SPREAD_SUPER_CALL; 2191425bb815Sopenharmony_ci } 2192425bb815Sopenharmony_ci 2193425bb815Sopenharmony_ci parser_emit_cbc_ext_call (context_p, spread_opcode, call_arguments); 2194425bb815Sopenharmony_ci continue; 2195425bb815Sopenharmony_ci } 2196425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2197425bb815Sopenharmony_ci 2198425bb815Sopenharmony_ci if (call_arguments <= 1) 2199425bb815Sopenharmony_ci { 2200425bb815Sopenharmony_ci if (opcode == CBC_CALL) 2201425bb815Sopenharmony_ci { 2202425bb815Sopenharmony_ci parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0 + (call_arguments * 6))); 2203425bb815Sopenharmony_ci continue; 2204425bb815Sopenharmony_ci } 2205425bb815Sopenharmony_ci if (opcode == CBC_CALL_PROP) 2206425bb815Sopenharmony_ci { 2207425bb815Sopenharmony_ci parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0_PROP + (call_arguments * 6))); 2208425bb815Sopenharmony_ci continue; 2209425bb815Sopenharmony_ci } 2210425bb815Sopenharmony_ci if (opcode == CBC_NEW) 2211425bb815Sopenharmony_ci { 2212425bb815Sopenharmony_ci parser_emit_cbc (context_p, (uint16_t) (CBC_NEW0 + call_arguments)); 2213425bb815Sopenharmony_ci continue; 2214425bb815Sopenharmony_ci } 2215425bb815Sopenharmony_ci } 2216425bb815Sopenharmony_ci 2217425bb815Sopenharmony_ci if (call_arguments == 2) 2218425bb815Sopenharmony_ci { 2219425bb815Sopenharmony_ci if (opcode == CBC_CALL) 2220425bb815Sopenharmony_ci { 2221425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_CALL2); 2222425bb815Sopenharmony_ci continue; 2223425bb815Sopenharmony_ci } 2224425bb815Sopenharmony_ci if (opcode == CBC_CALL_PROP) 2225425bb815Sopenharmony_ci { 2226425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2227425bb815Sopenharmony_ci /* Manually adjusting stack usage. */ 2228425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_depth > 0); 2229425bb815Sopenharmony_ci context_p->stack_depth--; 2230425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_CALL2_PROP); 2231425bb815Sopenharmony_ci continue; 2232425bb815Sopenharmony_ci } 2233425bb815Sopenharmony_ci } 2234425bb815Sopenharmony_ci 2235425bb815Sopenharmony_ci parser_emit_cbc_call (context_p, opcode, call_arguments); 2236425bb815Sopenharmony_ci continue; 2237425bb815Sopenharmony_ci } 2238425bb815Sopenharmony_ci 2239425bb815Sopenharmony_ci default: 2240425bb815Sopenharmony_ci { 2241425bb815Sopenharmony_ci if (context_p->stack_top_uint8 == LEXER_KEYW_NEW) 2242425bb815Sopenharmony_ci { 2243425bb815Sopenharmony_ci parser_push_result (context_p); 2244425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_NEW0); 2245425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2246425bb815Sopenharmony_ci continue; 2247425bb815Sopenharmony_ci } 2248425bb815Sopenharmony_ci 2249425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_WAS_NEWLINE) 2250425bb815Sopenharmony_ci && (context_p->token.type == LEXER_INCREASE || context_p->token.type == LEXER_DECREASE) 2251425bb815Sopenharmony_ci && grouping_level != PARSE_EXPR_LEFT_HAND_SIDE) 2252425bb815Sopenharmony_ci { 2253425bb815Sopenharmony_ci cbc_opcode_t opcode = (context_p->token.type == LEXER_INCREASE) ? CBC_POST_INCR : CBC_POST_DECR; 2254425bb815Sopenharmony_ci parser_push_result (context_p); 2255425bb815Sopenharmony_ci parser_emit_unary_lvalue_opcode (context_p, opcode); 2256425bb815Sopenharmony_ci lexer_next_token (context_p); 2257425bb815Sopenharmony_ci } 2258425bb815Sopenharmony_ci break; 2259425bb815Sopenharmony_ci } 2260425bb815Sopenharmony_ci } 2261425bb815Sopenharmony_ci break; 2262425bb815Sopenharmony_ci } 2263425bb815Sopenharmony_ci 2264425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2265425bb815Sopenharmony_ci uint8_t last_unary_token = LEXER_INCREASE; 2266425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2267425bb815Sopenharmony_ci 2268425bb815Sopenharmony_ci /* Generate byte code for the unary operators. */ 2269425bb815Sopenharmony_ci while (true) 2270425bb815Sopenharmony_ci { 2271425bb815Sopenharmony_ci uint8_t token = context_p->stack_top_uint8; 2272425bb815Sopenharmony_ci if (!LEXER_IS_UNARY_OP_TOKEN (token)) 2273425bb815Sopenharmony_ci { 2274425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2275425bb815Sopenharmony_ci if (context_p->token.type == LEXER_EXPONENTIATION 2276425bb815Sopenharmony_ci && last_unary_token != LEXER_INCREASE 2277425bb815Sopenharmony_ci && last_unary_token != LEXER_DECREASE) 2278425bb815Sopenharmony_ci { 2279425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_EXPONENTIATION); 2280425bb815Sopenharmony_ci } 2281425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2282425bb815Sopenharmony_ci break; 2283425bb815Sopenharmony_ci } 2284425bb815Sopenharmony_ci 2285425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2286425bb815Sopenharmony_ci last_unary_token = token; 2287425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2288425bb815Sopenharmony_ci 2289425bb815Sopenharmony_ci parser_push_result (context_p); 2290425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2291425bb815Sopenharmony_ci 2292425bb815Sopenharmony_ci if (LEXER_IS_UNARY_LVALUE_OP_TOKEN (token)) 2293425bb815Sopenharmony_ci { 2294425bb815Sopenharmony_ci if (token == LEXER_KEYW_DELETE) 2295425bb815Sopenharmony_ci { 2296425bb815Sopenharmony_ci token = CBC_DELETE_PUSH_RESULT; 2297425bb815Sopenharmony_ci } 2298425bb815Sopenharmony_ci else 2299425bb815Sopenharmony_ci { 2300425bb815Sopenharmony_ci token = (uint8_t) (LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE (token)); 2301425bb815Sopenharmony_ci } 2302425bb815Sopenharmony_ci parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token); 2303425bb815Sopenharmony_ci } 2304425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2305425bb815Sopenharmony_ci else if (JERRY_UNLIKELY (token == LEXER_KEYW_AWAIT)) 2306425bb815Sopenharmony_ci { 2307425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_AWAIT); 2308425bb815Sopenharmony_ci } 2309425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2310425bb815Sopenharmony_ci else 2311425bb815Sopenharmony_ci { 2312425bb815Sopenharmony_ci token = (uint8_t) (LEXER_UNARY_OP_TOKEN_TO_OPCODE (token)); 2313425bb815Sopenharmony_ci 2314425bb815Sopenharmony_ci if (token == CBC_TYPEOF) 2315425bb815Sopenharmony_ci { 2316425bb815Sopenharmony_ci if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 2317425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 2318425bb815Sopenharmony_ci { 2319425bb815Sopenharmony_ci parser_emit_ident_reference (context_p, CBC_TYPEOF_IDENT); 2320425bb815Sopenharmony_ci } 2321425bb815Sopenharmony_ci else 2322425bb815Sopenharmony_ci { 2323425bb815Sopenharmony_ci parser_emit_cbc (context_p, token); 2324425bb815Sopenharmony_ci } 2325425bb815Sopenharmony_ci } 2326425bb815Sopenharmony_ci else 2327425bb815Sopenharmony_ci { 2328425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 2329425bb815Sopenharmony_ci { 2330425bb815Sopenharmony_ci /* It is not worth to combine with push multiple literals 2331425bb815Sopenharmony_ci * since the byte code size will not decrease. */ 2332425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, token + 1)); 2333425bb815Sopenharmony_ci context_p->last_cbc_opcode = (uint16_t) (token + 1); 2334425bb815Sopenharmony_ci } 2335425bb815Sopenharmony_ci else 2336425bb815Sopenharmony_ci { 2337425bb815Sopenharmony_ci parser_emit_cbc (context_p, token); 2338425bb815Sopenharmony_ci } 2339425bb815Sopenharmony_ci } 2340425bb815Sopenharmony_ci } 2341425bb815Sopenharmony_ci } 2342425bb815Sopenharmony_ci} /* parser_process_unary_expression */ 2343425bb815Sopenharmony_ci 2344425bb815Sopenharmony_ci/** 2345425bb815Sopenharmony_ci * Append a binary '=' token. 2346425bb815Sopenharmony_ci * 2347425bb815Sopenharmony_ci * @return - pushed assignment opcode onto the parser stack 2348425bb815Sopenharmony_ci */ 2349425bb815Sopenharmony_cistatic uint8_t 2350425bb815Sopenharmony_ciparser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */ 2351425bb815Sopenharmony_ci uint32_t pattern_flags) /**< pattern flags */ 2352425bb815Sopenharmony_ci{ 2353425bb815Sopenharmony_ci JERRY_UNUSED (pattern_flags); 2354425bb815Sopenharmony_ci 2355425bb815Sopenharmony_ci /* Unlike other tokens, the whole byte code is saved for binary 2356425bb815Sopenharmony_ci * assignment, since it has multiple forms depending on the 2357425bb815Sopenharmony_ci * previous instruction. */ 2358425bb815Sopenharmony_ci 2359425bb815Sopenharmony_ci uint8_t assign_opcode = CBC_ASSIGN; 2360425bb815Sopenharmony_ci 2361425bb815Sopenharmony_ci if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 2362425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 2363425bb815Sopenharmony_ci { 2364425bb815Sopenharmony_ci parser_check_invalid_assign (context_p); 2365425bb815Sopenharmony_ci 2366425bb815Sopenharmony_ci uint16_t literal_index; 2367425bb815Sopenharmony_ci 2368425bb815Sopenharmony_ci switch (context_p->last_cbc_opcode) 2369425bb815Sopenharmony_ci { 2370425bb815Sopenharmony_ci case CBC_PUSH_LITERAL: 2371425bb815Sopenharmony_ci { 2372425bb815Sopenharmony_ci literal_index = context_p->last_cbc.literal_index; 2373425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 2374425bb815Sopenharmony_ci break; 2375425bb815Sopenharmony_ci } 2376425bb815Sopenharmony_ci case CBC_PUSH_TWO_LITERALS: 2377425bb815Sopenharmony_ci { 2378425bb815Sopenharmony_ci literal_index = context_p->last_cbc.value; 2379425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_LITERAL; 2380425bb815Sopenharmony_ci break; 2381425bb815Sopenharmony_ci } 2382425bb815Sopenharmony_ci case CBC_PUSH_THIS_LITERAL: 2383425bb815Sopenharmony_ci { 2384425bb815Sopenharmony_ci literal_index = context_p->last_cbc.literal_index; 2385425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THIS; 2386425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2387425bb815Sopenharmony_ci break; 2388425bb815Sopenharmony_ci } 2389425bb815Sopenharmony_ci default: 2390425bb815Sopenharmony_ci { 2391425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS); 2392425bb815Sopenharmony_ci literal_index = context_p->last_cbc.third_literal_index; 2393425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 2394425bb815Sopenharmony_ci break; 2395425bb815Sopenharmony_ci } 2396425bb815Sopenharmony_ci } 2397425bb815Sopenharmony_ci 2398425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_SET_IDENT; 2399425bb815Sopenharmony_ci 2400425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2401425bb815Sopenharmony_ci if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL))) 2402425bb815Sopenharmony_ci { 2403425bb815Sopenharmony_ci if (scanner_literal_is_const_reg (context_p, literal_index)) 2404425bb815Sopenharmony_ci { 2405425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST); 2406425bb815Sopenharmony_ci } 2407425bb815Sopenharmony_ci } 2408425bb815Sopenharmony_ci else if (literal_index < PARSER_REGISTER_START) 2409425bb815Sopenharmony_ci { 2410425bb815Sopenharmony_ci assign_opcode = CBC_INIT_LET; 2411425bb815Sopenharmony_ci 2412425bb815Sopenharmony_ci if (scanner_literal_is_created (context_p, literal_index)) 2413425bb815Sopenharmony_ci { 2414425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_LET_CONST; 2415425bb815Sopenharmony_ci } 2416425bb815Sopenharmony_ci else if (pattern_flags & PARSER_PATTERN_CONST) 2417425bb815Sopenharmony_ci { 2418425bb815Sopenharmony_ci assign_opcode = CBC_INIT_CONST; 2419425bb815Sopenharmony_ci } 2420425bb815Sopenharmony_ci else if (pattern_flags & PARSER_PATTERN_LOCAL) 2421425bb815Sopenharmony_ci { 2422425bb815Sopenharmony_ci assign_opcode = CBC_INIT_ARG_OR_CATCH; 2423425bb815Sopenharmony_ci } 2424425bb815Sopenharmony_ci } 2425425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2426425bb815Sopenharmony_ci 2427425bb815Sopenharmony_ci parser_stack_push_uint16 (context_p, literal_index); 2428425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode)); 2429425bb815Sopenharmony_ci } 2430425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_PROP) 2431425bb815Sopenharmony_ci { 2432425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_ASSIGN)); 2433425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 2434425bb815Sopenharmony_ci } 2435425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL) 2436425bb815Sopenharmony_ci { 2437425bb815Sopenharmony_ci if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL) 2438425bb815Sopenharmony_ci { 2439425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_ASSIGN_PROP_LITERAL)); 2440425bb815Sopenharmony_ci parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index); 2441425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_PROP_LITERAL; 2442425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 2443425bb815Sopenharmony_ci } 2444425bb815Sopenharmony_ci else 2445425bb815Sopenharmony_ci { 2446425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_LITERAL; 2447425bb815Sopenharmony_ci } 2448425bb815Sopenharmony_ci } 2449425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL) 2450425bb815Sopenharmony_ci { 2451425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS)); 2452425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS; 2453425bb815Sopenharmony_ci } 2454425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL) 2455425bb815Sopenharmony_ci { 2456425bb815Sopenharmony_ci if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL) 2457425bb815Sopenharmony_ci { 2458425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_ASSIGN_PROP_THIS_LITERAL)); 2459425bb815Sopenharmony_ci parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index); 2460425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_PROP_THIS_LITERAL; 2461425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 2462425bb815Sopenharmony_ci } 2463425bb815Sopenharmony_ci else 2464425bb815Sopenharmony_ci { 2465425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL; 2466425bb815Sopenharmony_ci } 2467425bb815Sopenharmony_ci } 2468425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2469425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL)) 2470425bb815Sopenharmony_ci { 2471425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE); 2472425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_SUPER; 2473425bb815Sopenharmony_ci } 2474425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP)) 2475425bb815Sopenharmony_ci { 2476425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE); 2477425bb815Sopenharmony_ci assign_opcode = CBC_ASSIGN_SUPER; 2478425bb815Sopenharmony_ci } 2479425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2480425bb815Sopenharmony_ci else 2481425bb815Sopenharmony_ci { 2482425bb815Sopenharmony_ci /* Invalid LeftHandSide expression. */ 2483425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2484425bb815Sopenharmony_ci parser_check_invalid_new_target (context_p, CBC_ASSIGN); 2485425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2486425bb815Sopenharmony_ci 2487425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR); 2488425bb815Sopenharmony_ci } 2489425bb815Sopenharmony_ci 2490425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, assign_opcode); 2491425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_ASSIGN); 2492425bb815Sopenharmony_ci 2493425bb815Sopenharmony_ci return assign_opcode; 2494425bb815Sopenharmony_ci} /* parser_append_binary_single_assignment_token */ 2495425bb815Sopenharmony_ci 2496425bb815Sopenharmony_ci/** 2497425bb815Sopenharmony_ci * Append a binary token. 2498425bb815Sopenharmony_ci */ 2499425bb815Sopenharmony_cistatic void 2500425bb815Sopenharmony_ciparser_append_binary_token (parser_context_t *context_p) /**< context */ 2501425bb815Sopenharmony_ci{ 2502425bb815Sopenharmony_ci JERRY_ASSERT (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type)); 2503425bb815Sopenharmony_ci 2504425bb815Sopenharmony_ci parser_push_result (context_p); 2505425bb815Sopenharmony_ci 2506425bb815Sopenharmony_ci if (context_p->token.type == LEXER_ASSIGN) 2507425bb815Sopenharmony_ci { 2508425bb815Sopenharmony_ci parser_append_binary_single_assignment_token (context_p, 0); 2509425bb815Sopenharmony_ci return; 2510425bb815Sopenharmony_ci } 2511425bb815Sopenharmony_ci 2512425bb815Sopenharmony_ci if (LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type)) 2513425bb815Sopenharmony_ci { 2514425bb815Sopenharmony_ci if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 2515425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL) 2516425bb815Sopenharmony_ci { 2517425bb815Sopenharmony_ci parser_check_invalid_assign (context_p); 2518425bb815Sopenharmony_ci 2519425bb815Sopenharmony_ci parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE); 2520425bb815Sopenharmony_ci 2521425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2522425bb815Sopenharmony_ci if (scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index)) 2523425bb815Sopenharmony_ci { 2524425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST); 2525425bb815Sopenharmony_ci } 2526425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2527425bb815Sopenharmony_ci } 2528425bb815Sopenharmony_ci else if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode)) 2529425bb815Sopenharmony_ci { 2530425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode); 2531425bb815Sopenharmony_ci } 2532425bb815Sopenharmony_ci else 2533425bb815Sopenharmony_ci { 2534425bb815Sopenharmony_ci /* Invalid LeftHandSide expression. */ 2535425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2536425bb815Sopenharmony_ci parser_check_invalid_new_target (context_p, CBC_ASSIGN); 2537425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2538425bb815Sopenharmony_ci 2539425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR); 2540425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_PROP_REFERENCE); 2541425bb815Sopenharmony_ci } 2542425bb815Sopenharmony_ci } 2543425bb815Sopenharmony_ci else if (context_p->token.type == LEXER_LOGICAL_OR 2544425bb815Sopenharmony_ci || context_p->token.type == LEXER_LOGICAL_AND) 2545425bb815Sopenharmony_ci { 2546425bb815Sopenharmony_ci parser_branch_t branch; 2547425bb815Sopenharmony_ci uint16_t opcode = CBC_BRANCH_IF_LOGICAL_TRUE; 2548425bb815Sopenharmony_ci 2549425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LOGICAL_AND) 2550425bb815Sopenharmony_ci { 2551425bb815Sopenharmony_ci opcode = CBC_BRANCH_IF_LOGICAL_FALSE; 2552425bb815Sopenharmony_ci } 2553425bb815Sopenharmony_ci 2554425bb815Sopenharmony_ci parser_emit_cbc_forward_branch (context_p, opcode, &branch); 2555425bb815Sopenharmony_ci parser_stack_push (context_p, &branch, sizeof (parser_branch_t)); 2556425bb815Sopenharmony_ci } 2557425bb815Sopenharmony_ci 2558425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, context_p->token.type); 2559425bb815Sopenharmony_ci} /* parser_append_binary_token */ 2560425bb815Sopenharmony_ci 2561425bb815Sopenharmony_ci/** 2562425bb815Sopenharmony_ci * Emit opcode for binary computations. 2563425bb815Sopenharmony_ci */ 2564425bb815Sopenharmony_cistatic void 2565425bb815Sopenharmony_ciparser_process_binary_opcodes (parser_context_t *context_p, /**< context */ 2566425bb815Sopenharmony_ci uint8_t min_prec_treshold) /**< minimal precedence of tokens */ 2567425bb815Sopenharmony_ci{ 2568425bb815Sopenharmony_ci while (true) 2569425bb815Sopenharmony_ci { 2570425bb815Sopenharmony_ci uint8_t token = context_p->stack_top_uint8; 2571425bb815Sopenharmony_ci cbc_opcode_t opcode; 2572425bb815Sopenharmony_ci 2573425bb815Sopenharmony_ci /* For left-to-right operators (all binary operators except assignment 2574425bb815Sopenharmony_ci * and logical operators), the byte code is flushed if the precedence 2575425bb815Sopenharmony_ci * of the next operator is less or equal than the current operator. For 2576425bb815Sopenharmony_ci * assignment and logical operators, we add 1 to the min precendence to 2577425bb815Sopenharmony_ci * force right-to-left evaluation order. */ 2578425bb815Sopenharmony_ci 2579425bb815Sopenharmony_ci if (!LEXER_IS_BINARY_OP_TOKEN (token) 2580425bb815Sopenharmony_ci || parser_binary_precedence_table[token - LEXER_FIRST_BINARY_OP] < min_prec_treshold) 2581425bb815Sopenharmony_ci { 2582425bb815Sopenharmony_ci return; 2583425bb815Sopenharmony_ci } 2584425bb815Sopenharmony_ci 2585425bb815Sopenharmony_ci parser_push_result (context_p); 2586425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2587425bb815Sopenharmony_ci 2588425bb815Sopenharmony_ci if (token == LEXER_ASSIGN) 2589425bb815Sopenharmony_ci { 2590425bb815Sopenharmony_ci opcode = (cbc_opcode_t) context_p->stack_top_uint8; 2591425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2592425bb815Sopenharmony_ci 2593425bb815Sopenharmony_ci int32_t index = -1; 2594425bb815Sopenharmony_ci if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG) 2595425bb815Sopenharmony_ci { 2596425bb815Sopenharmony_ci JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT 2597425bb815Sopenharmony_ci || opcode == CBC_ASSIGN_PROP_LITERAL 2598425bb815Sopenharmony_ci || opcode == CBC_ASSIGN_PROP_THIS_LITERAL 2599425bb815Sopenharmony_ci || opcode == CBC_ASSIGN_LET_CONST 2600425bb815Sopenharmony_ci || opcode == CBC_INIT_ARG_OR_CATCH 2601425bb815Sopenharmony_ci || opcode == CBC_INIT_LET 2602425bb815Sopenharmony_ci || opcode == CBC_INIT_CONST); 2603425bb815Sopenharmony_ci 2604425bb815Sopenharmony_ci index = parser_stack_pop_uint16 (context_p); 2605425bb815Sopenharmony_ci } 2606425bb815Sopenharmony_ci 2607425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2608425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_CONST)) 2609425bb815Sopenharmony_ci { 2610425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2611425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR); 2612425bb815Sopenharmony_ci } 2613425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2614425bb815Sopenharmony_ci 2615425bb815Sopenharmony_ci if (index >= 0) 2616425bb815Sopenharmony_ci { 2617425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL 2618425bb815Sopenharmony_ci && opcode == CBC_ASSIGN_SET_IDENT) 2619425bb815Sopenharmony_ci { 2620425bb815Sopenharmony_ci JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT, 2621425bb815Sopenharmony_ci CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)); 2622425bb815Sopenharmony_ci 2623425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) index; 2624425bb815Sopenharmony_ci context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT; 2625425bb815Sopenharmony_ci continue; 2626425bb815Sopenharmony_ci } 2627425bb815Sopenharmony_ci 2628425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, (uint16_t) opcode, (uint16_t) index); 2629425bb815Sopenharmony_ci 2630425bb815Sopenharmony_ci if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL 2631425bb815Sopenharmony_ci && (context_p->stack_depth >= context_p->stack_limit)) 2632425bb815Sopenharmony_ci { 2633425bb815Sopenharmony_ci /* Stack limit is increased for VM_OC_ASSIGN_PROP_THIS. Needed by vm.c. */ 2634425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit); 2635425bb815Sopenharmony_ci 2636425bb815Sopenharmony_ci context_p->stack_limit++; 2637425bb815Sopenharmony_ci 2638425bb815Sopenharmony_ci if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT) 2639425bb815Sopenharmony_ci { 2640425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED); 2641425bb815Sopenharmony_ci } 2642425bb815Sopenharmony_ci } 2643425bb815Sopenharmony_ci continue; 2644425bb815Sopenharmony_ci } 2645425bb815Sopenharmony_ci } 2646425bb815Sopenharmony_ci else if (LEXER_IS_BINARY_LVALUE_TOKEN (token)) 2647425bb815Sopenharmony_ci { 2648425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, CBC_ASSIGN); 2649425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_ASSIGN); 2650425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, lexer_convert_binary_lvalue_token_to_binary (token)); 2651425bb815Sopenharmony_ci continue; 2652425bb815Sopenharmony_ci } 2653425bb815Sopenharmony_ci else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND) 2654425bb815Sopenharmony_ci { 2655425bb815Sopenharmony_ci parser_branch_t branch; 2656425bb815Sopenharmony_ci parser_stack_pop (context_p, &branch, sizeof (parser_branch_t)); 2657425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, &branch); 2658425bb815Sopenharmony_ci continue; 2659425bb815Sopenharmony_ci } 2660425bb815Sopenharmony_ci else 2661425bb815Sopenharmony_ci { 2662425bb815Sopenharmony_ci opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token); 2663425bb815Sopenharmony_ci 2664425bb815Sopenharmony_ci if (PARSER_IS_PUSH_NUMBER (context_p->last_cbc_opcode)) 2665425bb815Sopenharmony_ci { 2666425bb815Sopenharmony_ci lexer_convert_push_number_to_push_literal (context_p); 2667425bb815Sopenharmony_ci } 2668425bb815Sopenharmony_ci 2669425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) 2670425bb815Sopenharmony_ci { 2671425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL)); 2672425bb815Sopenharmony_ci context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_LITERAL); 2673425bb815Sopenharmony_ci continue; 2674425bb815Sopenharmony_ci } 2675425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS) 2676425bb815Sopenharmony_ci { 2677425bb815Sopenharmony_ci JERRY_ASSERT (CBC_ARGS_EQ (opcode + CBC_BINARY_WITH_TWO_LITERALS, 2678425bb815Sopenharmony_ci CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2)); 2679425bb815Sopenharmony_ci context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_TWO_LITERALS); 2680425bb815Sopenharmony_ci continue; 2681425bb815Sopenharmony_ci } 2682425bb815Sopenharmony_ci } 2683425bb815Sopenharmony_ci parser_emit_cbc (context_p, (uint16_t) opcode); 2684425bb815Sopenharmony_ci } 2685425bb815Sopenharmony_ci} /* parser_process_binary_opcodes */ 2686425bb815Sopenharmony_ci 2687425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2688425bb815Sopenharmony_ci/** 2689425bb815Sopenharmony_ci * End position marker of a pattern. 2690425bb815Sopenharmony_ci */ 2691425bb815Sopenharmony_citypedef struct 2692425bb815Sopenharmony_ci{ 2693425bb815Sopenharmony_ci scanner_location_t location; /**< end position of the pattern */ 2694425bb815Sopenharmony_ci lexer_token_t token; /**< token at the end position */ 2695425bb815Sopenharmony_ci} parser_pattern_end_marker_t; 2696425bb815Sopenharmony_ci 2697425bb815Sopenharmony_ci/** 2698425bb815Sopenharmony_ci * Literal index should not be emitted while processing rhs target value 2699425bb815Sopenharmony_ci */ 2700425bb815Sopenharmony_ci#define PARSER_PATTERN_RHS_NO_LIT UINT16_MAX 2701425bb815Sopenharmony_ci 2702425bb815Sopenharmony_ci/** 2703425bb815Sopenharmony_ci * Process the target of an initializer pattern. 2704425bb815Sopenharmony_ci */ 2705425bb815Sopenharmony_cistatic parser_pattern_end_marker_t 2706425bb815Sopenharmony_ciparser_pattern_get_target (parser_context_t *context_p, /**< context */ 2707425bb815Sopenharmony_ci parser_pattern_flags_t flags) /**< flags */ 2708425bb815Sopenharmony_ci{ 2709425bb815Sopenharmony_ci parser_pattern_end_marker_t end_marker; 2710425bb815Sopenharmony_ci end_marker.token.type = LEXER_INVALID_PATTERN; 2711425bb815Sopenharmony_ci parser_branch_t skip_init; 2712425bb815Sopenharmony_ci 2713425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_TARGET_DEFAULT) 2714425bb815Sopenharmony_ci { 2715425bb815Sopenharmony_ci JERRY_ASSERT (flags & PARSER_PATTERN_TARGET_ON_STACK); 2716425bb815Sopenharmony_ci 2717425bb815Sopenharmony_ci parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init); 2718425bb815Sopenharmony_ci } 2719425bb815Sopenharmony_ci 2720425bb815Sopenharmony_ci if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK) 2721425bb815Sopenharmony_ci { 2722425bb815Sopenharmony_ci scanner_location_t start_location; 2723425bb815Sopenharmony_ci 2724425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p != context_p->source_p 2725425bb815Sopenharmony_ci || context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED 2726425bb815Sopenharmony_ci || (flags & PARSER_PATTERN_REST_ELEMENT)) 2727425bb815Sopenharmony_ci { 2728425bb815Sopenharmony_ci /* Found invalid pattern, push null value to fake the rhs target. */ 2729425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_PUSH_NULL); 2730425bb815Sopenharmony_ci } 2731425bb815Sopenharmony_ci else 2732425bb815Sopenharmony_ci { 2733425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER); 2734425bb815Sopenharmony_ci scanner_get_location (&start_location, context_p); 2735425bb815Sopenharmony_ci 2736425bb815Sopenharmony_ci scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location); 2737425bb815Sopenharmony_ci scanner_release_next (context_p, sizeof (scanner_location_info_t)); 2738425bb815Sopenharmony_ci scanner_seek (context_p); 2739425bb815Sopenharmony_ci lexer_next_token (context_p); 2740425bb815Sopenharmony_ci 2741425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 2742425bb815Sopenharmony_ci scanner_get_location (&(end_marker.location), context_p); 2743425bb815Sopenharmony_ci end_marker.token = context_p->token; 2744425bb815Sopenharmony_ci 2745425bb815Sopenharmony_ci scanner_set_location (context_p, &start_location); 2746425bb815Sopenharmony_ci scanner_seek (context_p); 2747425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2748425bb815Sopenharmony_ci } 2749425bb815Sopenharmony_ci } 2750425bb815Sopenharmony_ci 2751425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_TARGET_DEFAULT) 2752425bb815Sopenharmony_ci { 2753425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, &skip_init); 2754425bb815Sopenharmony_ci } 2755425bb815Sopenharmony_ci 2756425bb815Sopenharmony_ci return end_marker; 2757425bb815Sopenharmony_ci} /* parser_pattern_get_target */ 2758425bb815Sopenharmony_ci 2759425bb815Sopenharmony_ci/** 2760425bb815Sopenharmony_ci * Finalize an assignment/binding pattern. 2761425bb815Sopenharmony_ci */ 2762425bb815Sopenharmony_cistatic void 2763425bb815Sopenharmony_ciparser_pattern_finalize (parser_context_t *context_p, /**< context */ 2764425bb815Sopenharmony_ci parser_pattern_flags_t flags, /**< flags */ 2765425bb815Sopenharmony_ci parser_pattern_end_marker_t *end_marker_p) /**< pattern end position */ 2766425bb815Sopenharmony_ci{ 2767425bb815Sopenharmony_ci if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK) 2768425bb815Sopenharmony_ci { 2769425bb815Sopenharmony_ci if (end_marker_p->token.type == LEXER_INVALID_PATTERN) 2770425bb815Sopenharmony_ci { 2771425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN); 2772425bb815Sopenharmony_ci } 2773425bb815Sopenharmony_ci 2774425bb815Sopenharmony_ci scanner_set_location (context_p, &(end_marker_p->location)); 2775425bb815Sopenharmony_ci context_p->token = end_marker_p->token; 2776425bb815Sopenharmony_ci } 2777425bb815Sopenharmony_ci else 2778425bb815Sopenharmony_ci { 2779425bb815Sopenharmony_ci JERRY_ASSERT (!(flags & PARSER_PATTERN_TARGET_DEFAULT)); 2780425bb815Sopenharmony_ci lexer_next_token (context_p); 2781425bb815Sopenharmony_ci } 2782425bb815Sopenharmony_ci 2783425bb815Sopenharmony_ci if ((flags & (PARSER_PATTERN_BINDING | PARSER_PATTERN_NESTED_PATTERN)) == PARSER_PATTERN_BINDING) 2784425bb815Sopenharmony_ci { 2785425bb815Sopenharmony_ci /* Pop the result of the expression. */ 2786425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 2787425bb815Sopenharmony_ci } 2788425bb815Sopenharmony_ci 2789425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2790425bb815Sopenharmony_ci} /* parser_pattern_finalize */ 2791425bb815Sopenharmony_ci 2792425bb815Sopenharmony_ci/** 2793425bb815Sopenharmony_ci * Emit right-hand-side target value. 2794425bb815Sopenharmony_ci */ 2795425bb815Sopenharmony_cistatic void 2796425bb815Sopenharmony_ciparser_pattern_emit_rhs (parser_context_t *context_p, /**< context */ 2797425bb815Sopenharmony_ci uint16_t rhs_opcode, /**< opcode to process the rhs value */ 2798425bb815Sopenharmony_ci uint16_t literal_index) /**< literal index for object pattern */ 2799425bb815Sopenharmony_ci{ 2800425bb815Sopenharmony_ci if (literal_index != PARSER_PATTERN_RHS_NO_LIT) 2801425bb815Sopenharmony_ci { 2802425bb815Sopenharmony_ci parser_emit_cbc_ext_literal (context_p, rhs_opcode, literal_index); 2803425bb815Sopenharmony_ci } 2804425bb815Sopenharmony_ci else 2805425bb815Sopenharmony_ci { 2806425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, rhs_opcode); 2807425bb815Sopenharmony_ci } 2808425bb815Sopenharmony_ci} /* parser_pattern_emit_rhs */ 2809425bb815Sopenharmony_ci 2810425bb815Sopenharmony_ci/** 2811425bb815Sopenharmony_ci * Form an assignment from a pattern. 2812425bb815Sopenharmony_ci */ 2813425bb815Sopenharmony_cistatic void 2814425bb815Sopenharmony_ciparser_pattern_form_assignment (parser_context_t *context_p, /**< context */ 2815425bb815Sopenharmony_ci parser_pattern_flags_t flags, /**< flags */ 2816425bb815Sopenharmony_ci uint16_t rhs_opcode, /**< opcode to process the rhs value */ 2817425bb815Sopenharmony_ci uint16_t literal_index, /**< literal index for object pattern */ 2818425bb815Sopenharmony_ci parser_line_counter_t ident_line_counter) /**< identifier line counter */ 2819425bb815Sopenharmony_ci{ 2820425bb815Sopenharmony_ci JERRY_UNUSED (ident_line_counter); 2821425bb815Sopenharmony_ci 2822425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START); 2823425bb815Sopenharmony_ci uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, flags); 2824425bb815Sopenharmony_ci 2825425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_ARRAY) 2826425bb815Sopenharmony_ci { 2827425bb815Sopenharmony_ci int32_t stack_adjustment = (CBC_STACK_ADJUST_BASE - (cbc_flags[assign_opcode] >> CBC_STACK_ADJUST_SHIFT)); 2828425bb815Sopenharmony_ci JERRY_ASSERT (stack_adjustment >= 1 && stack_adjustment <= 3); 2829425bb815Sopenharmony_ci 2830425bb815Sopenharmony_ci rhs_opcode = (uint16_t) (rhs_opcode + stack_adjustment - 1); 2831425bb815Sopenharmony_ci } 2832425bb815Sopenharmony_ci 2833425bb815Sopenharmony_ci parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index); 2834425bb815Sopenharmony_ci 2835425bb815Sopenharmony_ci if (context_p->token.type == LEXER_ASSIGN) 2836425bb815Sopenharmony_ci { 2837425bb815Sopenharmony_ci parser_branch_t skip_init; 2838425bb815Sopenharmony_ci lexer_next_token (context_p); 2839425bb815Sopenharmony_ci parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init); 2840425bb815Sopenharmony_ci 2841425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 2842425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, &skip_init); 2843425bb815Sopenharmony_ci } 2844425bb815Sopenharmony_ci 2845425bb815Sopenharmony_ci parser_process_binary_opcodes (context_p, 0); 2846425bb815Sopenharmony_ci 2847425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START); 2848425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 2849425bb815Sopenharmony_ci 2850425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 2851425bb815Sopenharmony_ci if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 2852425bb815Sopenharmony_ci && ident_line_counter != context_p->last_breakpoint_line) 2853425bb815Sopenharmony_ci { 2854425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED); 2855425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2856425bb815Sopenharmony_ci 2857425bb815Sopenharmony_ci parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, ident_line_counter); 2858425bb815Sopenharmony_ci 2859425bb815Sopenharmony_ci context_p->last_breakpoint_line = ident_line_counter; 2860425bb815Sopenharmony_ci } 2861425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 2862425bb815Sopenharmony_ci 2863425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) 2864425bb815Sopenharmony_ci if (ident_line_counter != context_p->last_line_info_line) 2865425bb815Sopenharmony_ci { 2866425bb815Sopenharmony_ci parser_emit_line_info (context_p, ident_line_counter, false); 2867425bb815Sopenharmony_ci } 2868425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) */ 2869425bb815Sopenharmony_ci} /* parser_pattern_form_assignment */ 2870425bb815Sopenharmony_ci 2871425bb815Sopenharmony_ci/** 2872425bb815Sopenharmony_ci * Parse pattern inside a pattern. 2873425bb815Sopenharmony_ci */ 2874425bb815Sopenharmony_cistatic void 2875425bb815Sopenharmony_ciparser_pattern_process_nested_pattern (parser_context_t *context_p, /**< context */ 2876425bb815Sopenharmony_ci parser_pattern_flags_t flags, /**< flags */ 2877425bb815Sopenharmony_ci uint16_t rhs_opcode, /**< opcode to process the rhs value */ 2878425bb815Sopenharmony_ci uint16_t literal_index) /**< literal index for object pattern */ 2879425bb815Sopenharmony_ci{ 2880425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE); 2881425bb815Sopenharmony_ci 2882425bb815Sopenharmony_ci parser_pattern_flags_t options = (PARSER_PATTERN_NESTED_PATTERN 2883425bb815Sopenharmony_ci | PARSER_PATTERN_TARGET_ON_STACK 2884425bb815Sopenharmony_ci | (flags & (PARSER_PATTERN_BINDING 2885425bb815Sopenharmony_ci | PARSER_PATTERN_LET 2886425bb815Sopenharmony_ci | PARSER_PATTERN_CONST 2887425bb815Sopenharmony_ci | PARSER_PATTERN_LOCAL 2888425bb815Sopenharmony_ci | PARSER_PATTERN_REST_ELEMENT 2889425bb815Sopenharmony_ci | PARSER_PATTERN_ARGUMENTS))); 2890425bb815Sopenharmony_ci 2891425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 2892425bb815Sopenharmony_ci { 2893425bb815Sopenharmony_ci options |= PARSER_PATTERN_TARGET_DEFAULT; 2894425bb815Sopenharmony_ci } 2895425bb815Sopenharmony_ci 2896425bb815Sopenharmony_ci parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index); 2897425bb815Sopenharmony_ci 2898425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_BRACE) 2899425bb815Sopenharmony_ci { 2900425bb815Sopenharmony_ci parser_parse_object_initializer (context_p, options); 2901425bb815Sopenharmony_ci } 2902425bb815Sopenharmony_ci else 2903425bb815Sopenharmony_ci { 2904425bb815Sopenharmony_ci parser_parse_array_initializer (context_p, options); 2905425bb815Sopenharmony_ci } 2906425bb815Sopenharmony_ci 2907425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 2908425bb815Sopenharmony_ci} /* parser_pattern_process_nested_pattern */ 2909425bb815Sopenharmony_ci 2910425bb815Sopenharmony_ci/** 2911425bb815Sopenharmony_ci * Process the current {Binding, Assignment}Property 2912425bb815Sopenharmony_ci */ 2913425bb815Sopenharmony_cistatic void 2914425bb815Sopenharmony_ciparser_pattern_process_assignment (parser_context_t *context_p, /**< context */ 2915425bb815Sopenharmony_ci parser_pattern_flags_t flags, /**< flags */ 2916425bb815Sopenharmony_ci uint16_t rhs_opcode, /**< opcode to process the rhs value */ 2917425bb815Sopenharmony_ci uint16_t literal_index, /**< literal index for object pattern */ 2918425bb815Sopenharmony_ci lexer_token_type_t end_type) /**< end type token */ 2919425bb815Sopenharmony_ci{ 2920425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE) 2921425bb815Sopenharmony_ci { 2922425bb815Sopenharmony_ci parser_pattern_process_nested_pattern (context_p, flags, rhs_opcode, literal_index); 2923425bb815Sopenharmony_ci return; 2924425bb815Sopenharmony_ci } 2925425bb815Sopenharmony_ci 2926425bb815Sopenharmony_ci parser_line_counter_t ident_line_counter = context_p->token.line; 2927425bb815Sopenharmony_ci 2928425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_BINDING) 2929425bb815Sopenharmony_ci { 2930425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 2931425bb815Sopenharmony_ci { 2932425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 2933425bb815Sopenharmony_ci } 2934425bb815Sopenharmony_ci 2935425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL); 2936425bb815Sopenharmony_ci 2937425bb815Sopenharmony_ci if (flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST) 2938425bb815Sopenharmony_ci && context_p->token.keyword_type == LEXER_KEYW_LET) 2939425bb815Sopenharmony_ci { 2940425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LEXICAL_LET_BINDING); 2941425bb815Sopenharmony_ci } 2942425bb815Sopenharmony_ci 2943425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 2944425bb815Sopenharmony_ci { 2945425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); 2946425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 2947425bb815Sopenharmony_ci } 2948425bb815Sopenharmony_ci 2949425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_ARGUMENTS) 2950425bb815Sopenharmony_ci { 2951425bb815Sopenharmony_ci if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT) 2952425bb815Sopenharmony_ci { 2953425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 2954425bb815Sopenharmony_ci } 2955425bb815Sopenharmony_ci context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT; 2956425bb815Sopenharmony_ci } 2957425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 2958425bb815Sopenharmony_ci parser_module_append_export_name (context_p); 2959425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 2960425bb815Sopenharmony_ci 2961425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL); 2962425bb815Sopenharmony_ci lexer_next_token (context_p); 2963425bb815Sopenharmony_ci 2964425bb815Sopenharmony_ci if (context_p->token.type != end_type 2965425bb815Sopenharmony_ci && context_p->token.type != LEXER_ASSIGN 2966425bb815Sopenharmony_ci && context_p->token.type != LEXER_COMMA) 2967425bb815Sopenharmony_ci { 2968425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ILLEGAL_PROPERTY_IN_DECLARATION); 2969425bb815Sopenharmony_ci } 2970425bb815Sopenharmony_ci } 2971425bb815Sopenharmony_ci else 2972425bb815Sopenharmony_ci { 2973425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2974425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_LEFT_HAND_SIDE); 2975425bb815Sopenharmony_ci 2976425bb815Sopenharmony_ci if (!PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode) && !PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode)) 2977425bb815Sopenharmony_ci { 2978425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN); 2979425bb815Sopenharmony_ci } 2980425bb815Sopenharmony_ci } 2981425bb815Sopenharmony_ci 2982425bb815Sopenharmony_ci parser_pattern_form_assignment (context_p, flags, rhs_opcode, literal_index, ident_line_counter); 2983425bb815Sopenharmony_ci} /* parser_pattern_process_assignment */ 2984425bb815Sopenharmony_ci 2985425bb815Sopenharmony_ci/** 2986425bb815Sopenharmony_ci * Parse array initializer. 2987425bb815Sopenharmony_ci */ 2988425bb815Sopenharmony_cistatic void 2989425bb815Sopenharmony_ciparser_parse_array_initializer (parser_context_t *context_p, /**< context */ 2990425bb815Sopenharmony_ci parser_pattern_flags_t flags) /**< flags */ 2991425bb815Sopenharmony_ci{ 2992425bb815Sopenharmony_ci parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags); 2993425bb815Sopenharmony_ci flags |= PARSER_PATTERN_ARRAY; 2994425bb815Sopenharmony_ci 2995425bb815Sopenharmony_ci lexer_next_token (context_p); 2996425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_GET_ITERATOR); 2997425bb815Sopenharmony_ci 2998425bb815Sopenharmony_ci while (context_p->token.type != LEXER_RIGHT_SQUARE) 2999425bb815Sopenharmony_ci { 3000425bb815Sopenharmony_ci uint16_t rhs_opcode = CBC_EXT_ITERATOR_STEP; 3001425bb815Sopenharmony_ci 3002425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COMMA) 3003425bb815Sopenharmony_ci { 3004425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, rhs_opcode); 3005425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 3006425bb815Sopenharmony_ci lexer_next_token (context_p); 3007425bb815Sopenharmony_ci continue; 3008425bb815Sopenharmony_ci } 3009425bb815Sopenharmony_ci 3010425bb815Sopenharmony_ci parser_pattern_flags_t options = flags; 3011425bb815Sopenharmony_ci 3012425bb815Sopenharmony_ci if (context_p->token.type == LEXER_THREE_DOTS) 3013425bb815Sopenharmony_ci { 3014425bb815Sopenharmony_ci lexer_next_token (context_p); 3015425bb815Sopenharmony_ci rhs_opcode = CBC_EXT_REST_INITIALIZER; 3016425bb815Sopenharmony_ci options |= PARSER_PATTERN_REST_ELEMENT; 3017425bb815Sopenharmony_ci } 3018425bb815Sopenharmony_ci 3019425bb815Sopenharmony_ci parser_pattern_process_assignment (context_p, options, rhs_opcode, PARSER_PATTERN_RHS_NO_LIT, LEXER_RIGHT_SQUARE); 3020425bb815Sopenharmony_ci 3021425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COMMA && rhs_opcode != CBC_EXT_REST_INITIALIZER) 3022425bb815Sopenharmony_ci { 3023425bb815Sopenharmony_ci lexer_next_token (context_p); 3024425bb815Sopenharmony_ci } 3025425bb815Sopenharmony_ci else if (context_p->token.type != LEXER_RIGHT_SQUARE) 3026425bb815Sopenharmony_ci { 3027425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN); 3028425bb815Sopenharmony_ci } 3029425bb815Sopenharmony_ci } 3030425bb815Sopenharmony_ci 3031425bb815Sopenharmony_ci /* close the iterator */ 3032425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CLOSE); 3033425bb815Sopenharmony_ci 3034425bb815Sopenharmony_ci parser_pattern_finalize (context_p, flags, &end_pos); 3035425bb815Sopenharmony_ci} /* parser_parse_array_initializer */ 3036425bb815Sopenharmony_ci 3037425bb815Sopenharmony_ci/** 3038425bb815Sopenharmony_ci * Parse object initializer. 3039425bb815Sopenharmony_ci */ 3040425bb815Sopenharmony_cistatic void 3041425bb815Sopenharmony_ciparser_parse_object_initializer (parser_context_t *context_p, /**< context */ 3042425bb815Sopenharmony_ci parser_pattern_flags_t flags) /**< flags */ 3043425bb815Sopenharmony_ci{ 3044425bb815Sopenharmony_ci parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags); 3045425bb815Sopenharmony_ci 3046425bb815Sopenharmony_ci /* 12.14.5.2: ObjectAssignmentPattern : { } */ 3047425bb815Sopenharmony_ci if (lexer_check_next_character (context_p, LIT_CHAR_RIGHT_BRACE)) 3048425bb815Sopenharmony_ci { 3049425bb815Sopenharmony_ci parser_emit_cbc_ext (context_p, CBC_EXT_REQUIRE_OBJECT_COERCIBLE); 3050425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 3051425bb815Sopenharmony_ci parser_pattern_finalize (context_p, flags, &end_pos); 3052425bb815Sopenharmony_ci return; 3053425bb815Sopenharmony_ci } 3054425bb815Sopenharmony_ci 3055425bb815Sopenharmony_ci while (true) 3056425bb815Sopenharmony_ci { 3057425bb815Sopenharmony_ci lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_OBJECT_PATTERN); 3058425bb815Sopenharmony_ci 3059425bb815Sopenharmony_ci uint16_t prop_index = context_p->lit_object.index; 3060425bb815Sopenharmony_ci parser_line_counter_t start_line = context_p->token.line; 3061425bb815Sopenharmony_ci parser_line_counter_t start_column = context_p->token.column; 3062425bb815Sopenharmony_ci uint16_t push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP_LITERAL; 3063425bb815Sopenharmony_ci 3064425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 3065425bb815Sopenharmony_ci { 3066425bb815Sopenharmony_ci break; 3067425bb815Sopenharmony_ci } 3068425bb815Sopenharmony_ci else if (context_p->token.type == LEXER_RIGHT_SQUARE) 3069425bb815Sopenharmony_ci { 3070425bb815Sopenharmony_ci prop_index = PARSER_PATTERN_RHS_NO_LIT; 3071425bb815Sopenharmony_ci push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP; 3072425bb815Sopenharmony_ci } 3073425bb815Sopenharmony_ci 3074425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 3075425bb815Sopenharmony_ci { 3076425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); 3077425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 3078425bb815Sopenharmony_ci } 3079425bb815Sopenharmony_ci 3080425bb815Sopenharmony_ci lexer_next_token (context_p); 3081425bb815Sopenharmony_ci 3082425bb815Sopenharmony_ci if (context_p->token.type == LEXER_COLON) 3083425bb815Sopenharmony_ci { 3084425bb815Sopenharmony_ci lexer_next_token (context_p); 3085425bb815Sopenharmony_ci parser_pattern_process_assignment (context_p, flags, push_prop_opcode, prop_index, LEXER_RIGHT_BRACE); 3086425bb815Sopenharmony_ci } 3087425bb815Sopenharmony_ci else 3088425bb815Sopenharmony_ci { 3089425bb815Sopenharmony_ci if (push_prop_opcode == CBC_EXT_INITIALIZER_PUSH_PROP) 3090425bb815Sopenharmony_ci { 3091425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED); 3092425bb815Sopenharmony_ci } 3093425bb815Sopenharmony_ci 3094425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_BRACE 3095425bb815Sopenharmony_ci && context_p->token.type != LEXER_ASSIGN 3096425bb815Sopenharmony_ci && context_p->token.type != LEXER_COMMA) 3097425bb815Sopenharmony_ci { 3098425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED); 3099425bb815Sopenharmony_ci } 3100425bb815Sopenharmony_ci 3101425bb815Sopenharmony_ci parser_reparse_as_common_identifier (context_p, start_line, start_column); 3102425bb815Sopenharmony_ci lexer_next_token (context_p); 3103425bb815Sopenharmony_ci 3104425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE 3105425bb815Sopenharmony_ci || context_p->token.type == LEXER_ASSIGN 3106425bb815Sopenharmony_ci || context_p->token.type == LEXER_COMMA); 3107425bb815Sopenharmony_ci 3108425bb815Sopenharmony_ci if (flags & PARSER_PATTERN_ARGUMENTS) 3109425bb815Sopenharmony_ci { 3110425bb815Sopenharmony_ci if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT) 3111425bb815Sopenharmony_ci { 3112425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 3113425bb815Sopenharmony_ci } 3114425bb815Sopenharmony_ci context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT; 3115425bb815Sopenharmony_ci } 3116425bb815Sopenharmony_ci 3117425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 3118425bb815Sopenharmony_ci parser_module_append_export_name (context_p); 3119425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 3120425bb815Sopenharmony_ci 3121425bb815Sopenharmony_ci parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL); 3122425bb815Sopenharmony_ci parser_pattern_form_assignment (context_p, flags, push_prop_opcode, prop_index, start_line); 3123425bb815Sopenharmony_ci } 3124425bb815Sopenharmony_ci 3125425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 3126425bb815Sopenharmony_ci { 3127425bb815Sopenharmony_ci break; 3128425bb815Sopenharmony_ci } 3129425bb815Sopenharmony_ci else if (context_p->token.type != LEXER_COMMA) 3130425bb815Sopenharmony_ci { 3131425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED); 3132425bb815Sopenharmony_ci } 3133425bb815Sopenharmony_ci } 3134425bb815Sopenharmony_ci 3135425bb815Sopenharmony_ci parser_pattern_finalize (context_p, flags, &end_pos); 3136425bb815Sopenharmony_ci} /* parser_parse_object_initializer */ 3137425bb815Sopenharmony_ci 3138425bb815Sopenharmony_ci/** 3139425bb815Sopenharmony_ci * Parse an initializer. 3140425bb815Sopenharmony_ci */ 3141425bb815Sopenharmony_civoid 3142425bb815Sopenharmony_ciparser_parse_initializer (parser_context_t *context_p, /**< context */ 3143425bb815Sopenharmony_ci parser_pattern_flags_t flags) /**< flags */ 3144425bb815Sopenharmony_ci{ 3145425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LEFT_BRACE) 3146425bb815Sopenharmony_ci { 3147425bb815Sopenharmony_ci parser_parse_object_initializer (context_p, flags); 3148425bb815Sopenharmony_ci } 3149425bb815Sopenharmony_ci else 3150425bb815Sopenharmony_ci { 3151425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE); 3152425bb815Sopenharmony_ci parser_parse_array_initializer (context_p, flags); 3153425bb815Sopenharmony_ci } 3154425bb815Sopenharmony_ci} /* parser_parse_initializer */ 3155425bb815Sopenharmony_ci 3156425bb815Sopenharmony_ci/** 3157425bb815Sopenharmony_ci * Parse an initializer using the next character. 3158425bb815Sopenharmony_ci */ 3159425bb815Sopenharmony_civoid 3160425bb815Sopenharmony_ciparser_parse_initializer_by_next_char (parser_context_t *context_p, /**< context */ 3161425bb815Sopenharmony_ci parser_pattern_flags_t flags) /**< flags */ 3162425bb815Sopenharmony_ci{ 3163425bb815Sopenharmony_ci JERRY_ASSERT (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE)); 3164425bb815Sopenharmony_ci 3165425bb815Sopenharmony_ci if (lexer_consume_next_character (context_p) == LIT_CHAR_LEFT_BRACE) 3166425bb815Sopenharmony_ci { 3167425bb815Sopenharmony_ci parser_parse_object_initializer (context_p, flags); 3168425bb815Sopenharmony_ci } 3169425bb815Sopenharmony_ci else 3170425bb815Sopenharmony_ci { 3171425bb815Sopenharmony_ci parser_parse_array_initializer (context_p, flags); 3172425bb815Sopenharmony_ci } 3173425bb815Sopenharmony_ci} /* parser_parse_initializer_by_next_char */ 3174425bb815Sopenharmony_ci 3175425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3176425bb815Sopenharmony_ci 3177425bb815Sopenharmony_ci/** 3178425bb815Sopenharmony_ci * Process ternary expression. 3179425bb815Sopenharmony_ci */ 3180425bb815Sopenharmony_cistatic void 3181425bb815Sopenharmony_ciparser_process_ternary_expression (parser_context_t *context_p) /**< context */ 3182425bb815Sopenharmony_ci{ 3183425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_QUESTION_MARK); 3184425bb815Sopenharmony_ci 3185425bb815Sopenharmony_ci cbc_opcode_t opcode = CBC_BRANCH_IF_FALSE_FORWARD; 3186425bb815Sopenharmony_ci parser_branch_t cond_branch; 3187425bb815Sopenharmony_ci parser_branch_t uncond_branch; 3188425bb815Sopenharmony_ci 3189425bb815Sopenharmony_ci parser_push_result (context_p); 3190425bb815Sopenharmony_ci 3191425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT) 3192425bb815Sopenharmony_ci { 3193425bb815Sopenharmony_ci context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; 3194425bb815Sopenharmony_ci opcode = CBC_BRANCH_IF_TRUE_FORWARD; 3195425bb815Sopenharmony_ci } 3196425bb815Sopenharmony_ci 3197425bb815Sopenharmony_ci parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch); 3198425bb815Sopenharmony_ci 3199425bb815Sopenharmony_ci lexer_next_token (context_p); 3200425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 3201425bb815Sopenharmony_ci parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &uncond_branch); 3202425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, &cond_branch); 3203425bb815Sopenharmony_ci 3204425bb815Sopenharmony_ci /* Although byte code is constructed for two branches, 3205425bb815Sopenharmony_ci * only one of them will be executed. To reflect this 3206425bb815Sopenharmony_ci * the stack is manually adjusted. */ 3207425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_depth > 0); 3208425bb815Sopenharmony_ci context_p->stack_depth--; 3209425bb815Sopenharmony_ci 3210425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COLON) 3211425bb815Sopenharmony_ci { 3212425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED); 3213425bb815Sopenharmony_ci } 3214425bb815Sopenharmony_ci 3215425bb815Sopenharmony_ci lexer_next_token (context_p); 3216425bb815Sopenharmony_ci 3217425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 3218425bb815Sopenharmony_ci parser_set_branch_to_current_position (context_p, &uncond_branch); 3219425bb815Sopenharmony_ci 3220425bb815Sopenharmony_ci /* Last opcode rewrite is not allowed because 3221425bb815Sopenharmony_ci * the result may come from the first branch. */ 3222425bb815Sopenharmony_ci parser_flush_cbc (context_p); 3223425bb815Sopenharmony_ci 3224425bb815Sopenharmony_ci parser_process_binary_opcodes (context_p, 0); 3225425bb815Sopenharmony_ci} /* parser_process_ternary_expression */ 3226425bb815Sopenharmony_ci 3227425bb815Sopenharmony_ci/** 3228425bb815Sopenharmony_ci * Process expression sequence. 3229425bb815Sopenharmony_ci */ 3230425bb815Sopenharmony_cistatic void 3231425bb815Sopenharmony_ciparser_process_expression_sequence (parser_context_t *context_p) /**< context */ 3232425bb815Sopenharmony_ci{ 3233425bb815Sopenharmony_ci if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) 3234425bb815Sopenharmony_ci { 3235425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 3236425bb815Sopenharmony_ci } 3237425bb815Sopenharmony_ci 3238425bb815Sopenharmony_ci if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN) 3239425bb815Sopenharmony_ci { 3240425bb815Sopenharmony_ci parser_mem_page_t *page_p = context_p->stack.first_p; 3241425bb815Sopenharmony_ci 3242425bb815Sopenharmony_ci JERRY_ASSERT (page_p != NULL); 3243425bb815Sopenharmony_ci 3244425bb815Sopenharmony_ci page_p->bytes[context_p->stack.last_position - 1] = LEXER_COMMA_SEP_LIST; 3245425bb815Sopenharmony_ci context_p->stack_top_uint8 = LEXER_COMMA_SEP_LIST; 3246425bb815Sopenharmony_ci } 3247425bb815Sopenharmony_ci 3248425bb815Sopenharmony_ci lexer_next_token (context_p); 3249425bb815Sopenharmony_ci} /* parser_process_expression_sequence */ 3250425bb815Sopenharmony_ci 3251425bb815Sopenharmony_ci/** 3252425bb815Sopenharmony_ci * Process group expression. 3253425bb815Sopenharmony_ci */ 3254425bb815Sopenharmony_cistatic void 3255425bb815Sopenharmony_ciparser_process_group_expression (parser_context_t *context_p, /**< context */ 3256425bb815Sopenharmony_ci size_t *grouping_level_p) /**< grouping level */ 3257425bb815Sopenharmony_ci{ 3258425bb815Sopenharmony_ci JERRY_ASSERT (*grouping_level_p >= PARSER_GROUPING_LEVEL_INCREASE); 3259425bb815Sopenharmony_ci (*grouping_level_p) -= PARSER_GROUPING_LEVEL_INCREASE; 3260425bb815Sopenharmony_ci 3261425bb815Sopenharmony_ci if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST) 3262425bb815Sopenharmony_ci { 3263425bb815Sopenharmony_ci parser_push_result (context_p); 3264425bb815Sopenharmony_ci parser_flush_cbc (context_p); 3265425bb815Sopenharmony_ci } 3266425bb815Sopenharmony_ci 3267425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 3268425bb815Sopenharmony_ci lexer_next_token (context_p); 3269425bb815Sopenharmony_ci 3270425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3271425bb815Sopenharmony_ci /* Lookahead for anonymous function declaration after '=' token when the assignment base is LHS expression 3272425bb815Sopenharmony_ci with a single indentifier in it. e.g.: (a) = function () {} */ 3273425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->token.type == LEXER_ASSIGN 3274425bb815Sopenharmony_ci && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode) 3275425bb815Sopenharmony_ci && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL 3276425bb815Sopenharmony_ci && parser_is_assignment_expr (context_p))) 3277425bb815Sopenharmony_ci { 3278425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_ASSIGN_GROUP_EXPR); 3279425bb815Sopenharmony_ci } 3280425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3281425bb815Sopenharmony_ci 3282425bb815Sopenharmony_ci} /* parser_process_group_expression */ 3283425bb815Sopenharmony_ci 3284425bb815Sopenharmony_ci/** 3285425bb815Sopenharmony_ci * Parse block expression. 3286425bb815Sopenharmony_ci */ 3287425bb815Sopenharmony_civoid 3288425bb815Sopenharmony_ciparser_parse_block_expression (parser_context_t *context_p, /**< context */ 3289425bb815Sopenharmony_ci int options) /**< option flags */ 3290425bb815Sopenharmony_ci{ 3291425bb815Sopenharmony_ci parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT); 3292425bb815Sopenharmony_ci 3293425bb815Sopenharmony_ci if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) 3294425bb815Sopenharmony_ci { 3295425bb815Sopenharmony_ci JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 2)); 3296425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_U16 (context_p->last_cbc_opcode, 2); 3297425bb815Sopenharmony_ci parser_flush_cbc (context_p); 3298425bb815Sopenharmony_ci } 3299425bb815Sopenharmony_ci else 3300425bb815Sopenharmony_ci { 3301425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP_BLOCK); 3302425bb815Sopenharmony_ci } 3303425bb815Sopenharmony_ci} /* parser_parse_block_expression */ 3304425bb815Sopenharmony_ci 3305425bb815Sopenharmony_ci/** 3306425bb815Sopenharmony_ci * Parse expression statement. 3307425bb815Sopenharmony_ci */ 3308425bb815Sopenharmony_civoid 3309425bb815Sopenharmony_ciparser_parse_expression_statement (parser_context_t *context_p, /**< context */ 3310425bb815Sopenharmony_ci int options) /**< option flags */ 3311425bb815Sopenharmony_ci{ 3312425bb815Sopenharmony_ci parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT); 3313425bb815Sopenharmony_ci 3314425bb815Sopenharmony_ci if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)) 3315425bb815Sopenharmony_ci { 3316425bb815Sopenharmony_ci parser_emit_cbc (context_p, CBC_POP); 3317425bb815Sopenharmony_ci } 3318425bb815Sopenharmony_ci} /* parser_parse_expression_statement */ 3319425bb815Sopenharmony_ci 3320425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSE_EXPR_LEFT_HAND_SIDE == 0x1, 3321425bb815Sopenharmony_ci value_of_parse_expr_left_hand_side_must_be_1); 3322425bb815Sopenharmony_ci 3323425bb815Sopenharmony_ci/** 3324425bb815Sopenharmony_ci * Parse expression. 3325425bb815Sopenharmony_ci */ 3326425bb815Sopenharmony_civoid 3327425bb815Sopenharmony_ciparser_parse_expression (parser_context_t *context_p, /**< context */ 3328425bb815Sopenharmony_ci int options) /**< option flags */ 3329425bb815Sopenharmony_ci{ 3330425bb815Sopenharmony_ci size_t grouping_level = (options & PARSE_EXPR_LEFT_HAND_SIDE); 3331425bb815Sopenharmony_ci 3332425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START); 3333425bb815Sopenharmony_ci 3334425bb815Sopenharmony_ci if (options & PARSE_EXPR_HAS_LITERAL) 3335425bb815Sopenharmony_ci { 3336425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); 3337425bb815Sopenharmony_ci goto process_unary_expression; 3338425bb815Sopenharmony_ci } 3339425bb815Sopenharmony_ci 3340425bb815Sopenharmony_ci while (true) 3341425bb815Sopenharmony_ci { 3342425bb815Sopenharmony_ci if (parser_parse_unary_expression (context_p, &grouping_level)) 3343425bb815Sopenharmony_ci { 3344425bb815Sopenharmony_ci parser_process_binary_opcodes (context_p, 0); 3345425bb815Sopenharmony_ci break; 3346425bb815Sopenharmony_ci } 3347425bb815Sopenharmony_ci 3348425bb815Sopenharmony_ci while (true) 3349425bb815Sopenharmony_ci { 3350425bb815Sopenharmony_ciprocess_unary_expression: 3351425bb815Sopenharmony_ci parser_process_unary_expression (context_p, grouping_level); 3352425bb815Sopenharmony_ci 3353425bb815Sopenharmony_ci if (JERRY_LIKELY (grouping_level != PARSE_EXPR_LEFT_HAND_SIDE)) 3354425bb815Sopenharmony_ci { 3355425bb815Sopenharmony_ci uint8_t min_prec_treshold = 0; 3356425bb815Sopenharmony_ci 3357425bb815Sopenharmony_ci if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type)) 3358425bb815Sopenharmony_ci { 3359425bb815Sopenharmony_ci min_prec_treshold = parser_binary_precedence_table[context_p->token.type - LEXER_FIRST_BINARY_OP]; 3360425bb815Sopenharmony_ci 3361425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3362425bb815Sopenharmony_ci /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND + LEXER_EXPONENTIATION */ 3363425bb815Sopenharmony_ci if ((min_prec_treshold == PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION) 3364425bb815Sopenharmony_ci || (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 3365425bb815Sopenharmony_ci && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE)) 3366425bb815Sopenharmony_ci { 3367425bb815Sopenharmony_ci /* Right-to-left evaluation order. */ 3368425bb815Sopenharmony_ci min_prec_treshold++; 3369425bb815Sopenharmony_ci } 3370425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 3371425bb815Sopenharmony_ci /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND */ 3372425bb815Sopenharmony_ci if (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 3373425bb815Sopenharmony_ci && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE) 3374425bb815Sopenharmony_ci { 3375425bb815Sopenharmony_ci /* Right-to-left evaluation order. */ 3376425bb815Sopenharmony_ci min_prec_treshold++; 3377425bb815Sopenharmony_ci } 3378425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3379425bb815Sopenharmony_ci } 3380425bb815Sopenharmony_ci 3381425bb815Sopenharmony_ci parser_process_binary_opcodes (context_p, min_prec_treshold); 3382425bb815Sopenharmony_ci } 3383425bb815Sopenharmony_ci 3384425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_PAREN 3385425bb815Sopenharmony_ci && (context_p->stack_top_uint8 == LEXER_LEFT_PAREN 3386425bb815Sopenharmony_ci || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)) 3387425bb815Sopenharmony_ci { 3388425bb815Sopenharmony_ci parser_process_group_expression (context_p, &grouping_level); 3389425bb815Sopenharmony_ci continue; 3390425bb815Sopenharmony_ci } 3391425bb815Sopenharmony_ci 3392425bb815Sopenharmony_ci break; 3393425bb815Sopenharmony_ci } 3394425bb815Sopenharmony_ci 3395425bb815Sopenharmony_ci if (grouping_level == PARSE_EXPR_LEFT_HAND_SIDE) 3396425bb815Sopenharmony_ci { 3397425bb815Sopenharmony_ci break; 3398425bb815Sopenharmony_ci } 3399425bb815Sopenharmony_ci 3400425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->token.type == LEXER_QUESTION_MARK)) 3401425bb815Sopenharmony_ci { 3402425bb815Sopenharmony_ci parser_process_ternary_expression (context_p); 3403425bb815Sopenharmony_ci 3404425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_PAREN) 3405425bb815Sopenharmony_ci { 3406425bb815Sopenharmony_ci goto process_unary_expression; 3407425bb815Sopenharmony_ci } 3408425bb815Sopenharmony_ci } 3409425bb815Sopenharmony_ci else if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type)) 3410425bb815Sopenharmony_ci { 3411425bb815Sopenharmony_ci parser_append_binary_token (context_p); 3412425bb815Sopenharmony_ci lexer_next_token (context_p); 3413425bb815Sopenharmony_ci continue; 3414425bb815Sopenharmony_ci } 3415425bb815Sopenharmony_ci 3416425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->token.type == LEXER_COMMA) 3417425bb815Sopenharmony_ci && (!(options & PARSE_EXPR_NO_COMMA) || grouping_level >= PARSER_GROUPING_LEVEL_INCREASE)) 3418425bb815Sopenharmony_ci { 3419425bb815Sopenharmony_ci parser_process_expression_sequence (context_p); 3420425bb815Sopenharmony_ci continue; 3421425bb815Sopenharmony_ci } 3422425bb815Sopenharmony_ci 3423425bb815Sopenharmony_ci break; 3424425bb815Sopenharmony_ci } 3425425bb815Sopenharmony_ci 3426425bb815Sopenharmony_ci if (grouping_level >= PARSER_GROUPING_LEVEL_INCREASE) 3427425bb815Sopenharmony_ci { 3428425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED); 3429425bb815Sopenharmony_ci } 3430425bb815Sopenharmony_ci 3431425bb815Sopenharmony_ci JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START); 3432425bb815Sopenharmony_ci parser_stack_pop_uint8 (context_p); 3433425bb815Sopenharmony_ci 3434425bb815Sopenharmony_ci if (!(options & PARSE_EXPR_NO_PUSH_RESULT)) 3435425bb815Sopenharmony_ci { 3436425bb815Sopenharmony_ci parser_push_result (context_p); 3437425bb815Sopenharmony_ci } 3438425bb815Sopenharmony_ci} /* parser_parse_expression */ 3439425bb815Sopenharmony_ci 3440425bb815Sopenharmony_ci/** 3441425bb815Sopenharmony_ci * @} 3442425bb815Sopenharmony_ci * @} 3443425bb815Sopenharmony_ci * @} 3444425bb815Sopenharmony_ci */ 3445425bb815Sopenharmony_ci 3446425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER) */ 3447