1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "js-parser-internal.h"
17
18 #if ENABLED (JERRY_PARSER)
19 #include "jcontext.h"
20
21 #include "ecma-helpers.h"
22 #include "lit-char-helpers.h"
23 #include "js-parser-tagged-template-literal.h"
24
25 /** \addtogroup parser Parser
26 * @{
27 *
28 * \addtogroup jsparser JavaScript
29 * @{
30 *
31 * \addtogroup jsparser_expr Expression parser
32 * @{
33 */
34
35 /**
36 * Maximum precedence for right-to-left binary operation evaluation.
37 */
38 #define PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE 6
39
40 /**
41 * Precedence for ternary operation.
42 */
43 #define PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE 4
44
45 /**
46 * Precedence for exponentiation operation.
47 */
48 #define PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION 15
49
50 /**
51 * Value of grouping level increase and decrease.
52 */
53 #define PARSER_GROUPING_LEVEL_INCREASE 2
54
55 /**
56 * Precedence of the binary tokens.
57 *
58 * See also:
59 * lexer_token_type_t
60 */
61 static const uint8_t parser_binary_precedence_table[] =
62 {
63 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
64 #if ENABLED (JERRY_ES2015)
65 3,
66 #endif /* ENABLED (JERRY_ES2015) */
67 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
68 11, 11, 11, 11, 11, 11, 12, 12, 12,
69 13, 13, 14, 14, 14,
70 #if ENABLED (JERRY_ES2015)
71 15,
72 #endif /* ENABLED (JERRY_ES2015) */
73 };
74
75 #if ENABLED (JERRY_ES2015)
76 JERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 38,
77 parser_binary_precedence_table_should_have_38_values_in_es2015);
78 #else /* !ENABLED (JERRY_ES2015) */
79 JERRY_STATIC_ASSERT (sizeof (parser_binary_precedence_table) == 36,
80 parser_binary_precedence_table_should_have_36_values_in_es51);
81 #endif /* ENABLED (JERRY_ES2015) */
82
83 /**
84 * Generate byte code for operators with lvalue.
85 */
86 static inline void
parser_push_result(parser_context_t * context_p)87 parser_push_result (parser_context_t *context_p) /**< context */
88 {
89 if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
90 {
91 JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1));
92
93 if ((context_p->last_cbc_opcode == CBC_POST_INCR
94 || context_p->last_cbc_opcode == CBC_POST_DECR)
95 && context_p->stack_depth >= context_p->stack_limit)
96 {
97 /* Stack limit is increased for CBC_POST_INCR_PUSH_RESULT
98 * and CBC_POST_DECR_PUSH_RESULT opcodes. Needed by vm.c. */
99 JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
100
101 context_p->stack_limit++;
102
103 if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
104 {
105 parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
106 }
107 }
108
109 context_p->last_cbc_opcode++;
110 parser_flush_cbc (context_p);
111 }
112 } /* parser_push_result */
113
114 /**
115 * Check for invalid assignment for "eval" and "arguments"
116 */
117 static void
parser_check_invalid_assign(parser_context_t * context_p)118 parser_check_invalid_assign (parser_context_t *context_p) /**< context */
119 {
120 JERRY_ASSERT (context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL);
121
122 if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT))
123 {
124 if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL)
125 {
126 parser_raise_error (context_p, PARSER_ERR_EVAL_CANNOT_ASSIGNED);
127 }
128 else if (context_p->last_cbc.literal_keyword_type == LEXER_KEYW_ARGUMENTS)
129 {
130 parser_raise_error (context_p, PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED);
131 }
132 }
133 } /* parser_check_invalid_assign */
134
135 #if ENABLED (JERRY_ES2015)
136
137 /**
138 * Check and throw an error if the "new.target" is invalid as a left-hand side expression.
139 */
140 static void
parser_check_invalid_new_target(parser_context_t * context_p,cbc_opcode_t opcode)141 parser_check_invalid_new_target (parser_context_t *context_p, /**< parser context */
142 cbc_opcode_t opcode) /**< current opcode under parsing */
143 {
144 /* new.target is an invalid left-hand side target */
145 if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NEW_TARGET))
146 {
147 /* Make sure that the call side is a post/pre increment or an assignment expression.
148 * There should be no other ways the "new.target" expression should be here. */
149 JERRY_ASSERT ((opcode >= CBC_PRE_INCR && opcode <= CBC_POST_DECR)
150 || (opcode == CBC_ASSIGN
151 && (context_p->token.type == LEXER_ASSIGN
152 || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type))));
153
154 parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED);
155 }
156 } /* parser_check_invalid_new_target */
157
158 #endif /* ENABLED (JERRY_ES2015) */
159
160 /**
161 * Emit identifier reference
162 */
163 static void
parser_emit_ident_reference(parser_context_t * context_p,uint16_t opcode)164 parser_emit_ident_reference (parser_context_t *context_p, /**< context */
165 uint16_t opcode) /* opcode */
166 {
167 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
168 {
169 context_p->last_cbc_opcode = opcode;
170 return;
171 }
172
173 uint16_t literal_index;
174
175 if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
176 {
177 context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
178 literal_index = context_p->last_cbc.value;
179 }
180 else if (context_p->last_cbc_opcode == CBC_PUSH_THIS_LITERAL)
181 {
182 context_p->last_cbc_opcode = CBC_PUSH_THIS;
183 literal_index = context_p->last_cbc.literal_index;
184 }
185 else
186 {
187 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
188 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
189 literal_index = context_p->last_cbc.third_literal_index;
190 }
191
192 parser_emit_cbc_literal (context_p, opcode, literal_index);
193 } /* parser_emit_ident_reference */
194
195 /**
196 * Generate byte code for operators with lvalue.
197 */
198 static void
parser_emit_unary_lvalue_opcode(parser_context_t * context_p,cbc_opcode_t opcode)199 parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
200 cbc_opcode_t opcode) /**< opcode */
201 {
202 if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
203 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
204 {
205 parser_check_invalid_assign (context_p);
206
207 uint16_t unary_opcode;
208
209 if (opcode == CBC_DELETE_PUSH_RESULT)
210 {
211 if (JERRY_UNLIKELY (context_p->status_flags & PARSER_IS_STRICT))
212 {
213 parser_raise_error (context_p, PARSER_ERR_DELETE_IDENT_NOT_ALLOWED);
214 }
215
216 unary_opcode = CBC_DELETE_IDENT_PUSH_RESULT;
217 }
218 else
219 {
220 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, opcode + CBC_UNARY_LVALUE_WITH_IDENT));
221 unary_opcode = (uint16_t) (opcode + CBC_UNARY_LVALUE_WITH_IDENT);
222 }
223
224 parser_emit_ident_reference (context_p, unary_opcode);
225
226 #if ENABLED (JERRY_ES2015)
227 if (unary_opcode != CBC_DELETE_IDENT_PUSH_RESULT
228 && scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
229 {
230 /* The current value must be read, but it cannot be changed. */
231 context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
232 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
233 }
234 #endif /* ENABLED (JERRY_ES2015) */
235 return;
236 }
237
238 if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
239 {
240 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, opcode));
241 context_p->last_cbc_opcode = (uint16_t) opcode;
242 return;
243 }
244
245 if (PARSER_IS_PUSH_PROP_LITERAL (context_p->last_cbc_opcode))
246 {
247 context_p->last_cbc_opcode = PARSER_PUSH_PROP_LITERAL_TO_PUSH_LITERAL (context_p->last_cbc_opcode);
248 }
249 else
250 {
251 /* Invalid LeftHandSide expression. */
252 if (opcode == CBC_DELETE_PUSH_RESULT)
253 {
254 #if ENABLED (JERRY_ES2015)
255 if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL)
256 || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
257 {
258 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
259 parser_emit_cbc (context_p, CBC_POP);
260 return;
261 }
262 #endif /* ENABLED (JERRY_ES2015) */
263 parser_emit_cbc (context_p, CBC_POP);
264 parser_emit_cbc (context_p, CBC_PUSH_TRUE);
265 return;
266 }
267
268 #if ENABLED (JERRY_ES2015)
269 parser_check_invalid_new_target (context_p, opcode);
270 #endif /* ENABLED (JERRY_ES2015) */
271
272 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
273 }
274
275 parser_emit_cbc (context_p, (uint16_t) opcode);
276 } /* parser_emit_unary_lvalue_opcode */
277
278 /**
279 * Parse array literal.
280 */
281 static void
parser_parse_array_literal(parser_context_t * context_p)282 parser_parse_array_literal (parser_context_t *context_p) /**< context */
283 {
284 uint32_t pushed_items = 0;
285 uint16_t opcode = (uint16_t) CBC_ARRAY_APPEND;
286
287 JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE);
288
289 parser_emit_cbc (context_p, CBC_CREATE_ARRAY);
290 lexer_next_token (context_p);
291
292 while (true)
293 {
294 if (context_p->token.type == LEXER_RIGHT_SQUARE)
295 {
296 if (pushed_items > 0)
297 {
298 parser_emit_cbc_call (context_p, opcode, pushed_items);
299 }
300 return;
301 }
302
303 pushed_items++;
304
305 if (context_p->token.type == LEXER_COMMA)
306 {
307 parser_emit_cbc (context_p, CBC_PUSH_ELISION);
308 lexer_next_token (context_p);
309 }
310 else
311 {
312 #if ENABLED (JERRY_ES2015)
313 if (context_p->token.type == LEXER_THREE_DOTS)
314 {
315 opcode = (uint16_t) (PARSER_TO_EXT_OPCODE (CBC_EXT_SPREAD_ARRAY_APPEND));
316 pushed_items++;
317 lexer_next_token (context_p);
318 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT);
319 }
320 #endif /* ENABLED (JERRY_ES2015) */
321
322 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
323
324 if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
325 {
326 parser_flush_cbc (context_p);
327 }
328
329 if (context_p->token.type == LEXER_COMMA)
330 {
331 lexer_next_token (context_p);
332 }
333 else if (context_p->token.type != LEXER_RIGHT_SQUARE)
334 {
335 parser_raise_error (context_p, PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED);
336 }
337 }
338
339 if (pushed_items >= 64)
340 {
341 parser_emit_cbc_call (context_p, opcode, pushed_items);
342 #if ENABLED (JERRY_ES2015)
343 opcode = (uint16_t) CBC_ARRAY_APPEND;
344 #endif /* ENABLED (JERRY_ES2015) */
345 pushed_items = 0;
346 }
347 }
348 } /* parser_parse_array_literal */
349
350 #if !ENABLED (JERRY_ES2015)
351 /**
352 * Object literal item types.
353 */
354 typedef enum
355 {
356 PARSER_OBJECT_PROPERTY_START, /**< marks the start of the property list */
357 PARSER_OBJECT_PROPERTY_VALUE, /**< value property */
358 PARSER_OBJECT_PROPERTY_GETTER, /**< getter property */
359 PARSER_OBJECT_PROPERTY_SETTER, /**< setter property */
360 PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS, /**< both getter and setter properties are set */
361 } parser_object_literal_item_types_t;
362
363 /**
364 * Parse object literal.
365 */
366 static void
parser_append_object_literal_item(parser_context_t * context_p,uint16_t item_index,parser_object_literal_item_types_t item_type)367 parser_append_object_literal_item (parser_context_t *context_p, /**< context */
368 uint16_t item_index, /**< index of the item name */
369 parser_object_literal_item_types_t item_type) /**< type of the item */
370 {
371 parser_stack_iterator_t iterator;
372 uint8_t *current_item_type_p;
373
374 iterator.current_p = context_p->stack.first_p;
375 iterator.current_position = context_p->stack.last_position;
376
377 while (true)
378 {
379 current_item_type_p = iterator.current_p->bytes + iterator.current_position - 1;
380
381 if (*current_item_type_p == PARSER_OBJECT_PROPERTY_START)
382 {
383 parser_stack_push_uint16 (context_p, item_index);
384 parser_stack_push_uint8 (context_p, (uint8_t) item_type);
385 return;
386 }
387
388 iterator.current_position--;
389 if (iterator.current_position == 0)
390 {
391 iterator.current_p = iterator.current_p->next_p;
392 iterator.current_position = PARSER_STACK_PAGE_SIZE;
393 }
394
395 uint32_t current_item_index = iterator.current_p->bytes[iterator.current_position - 1];
396
397 iterator.current_position--;
398 if (iterator.current_position == 0)
399 {
400 iterator.current_p = iterator.current_p->next_p;
401 iterator.current_position = PARSER_STACK_PAGE_SIZE;
402 }
403
404 current_item_index |= ((uint32_t) iterator.current_p->bytes[iterator.current_position - 1]) << 8;
405
406 iterator.current_position--;
407 if (iterator.current_position == 0)
408 {
409 iterator.current_p = iterator.current_p->next_p;
410 iterator.current_position = PARSER_STACK_PAGE_SIZE;
411 }
412
413 if (current_item_index == item_index)
414 {
415 if (item_type == PARSER_OBJECT_PROPERTY_VALUE
416 && *current_item_type_p == PARSER_OBJECT_PROPERTY_VALUE
417 && !(context_p->status_flags & PARSER_IS_STRICT))
418 {
419 return;
420 }
421
422 if (item_type == PARSER_OBJECT_PROPERTY_GETTER
423 && *current_item_type_p == PARSER_OBJECT_PROPERTY_SETTER)
424 {
425 break;
426 }
427
428 if (item_type == PARSER_OBJECT_PROPERTY_SETTER
429 && *current_item_type_p == PARSER_OBJECT_PROPERTY_GETTER)
430 {
431 break;
432 }
433
434 parser_raise_error (context_p, PARSER_ERR_OBJECT_PROPERTY_REDEFINED);
435 }
436 }
437
438 uint8_t *last_page_p = context_p->stack.first_p->bytes;
439
440 *current_item_type_p = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS;
441
442 if (current_item_type_p == (last_page_p + context_p->stack.last_position - 1))
443 {
444 context_p->stack_top_uint8 = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS;
445 }
446 } /* parser_append_object_literal_item */
447 #endif /* !ENABLED (JERRY_ES2015) */
448
449 #if ENABLED (JERRY_ES2015)
450 /** Forward definition of parse array initializer. */
451 static void
452 parser_parse_array_initializer (parser_context_t *context_p, parser_pattern_flags_t flags);
453
454 /** Forward definition of parse object initializer. */
455 static void
456 parser_parse_object_initializer (parser_context_t *context_p, parser_pattern_flags_t flags);
457
458 /**
459 * Description of "get" literal string.
460 */
461 static const lexer_lit_location_t lexer_get_literal =
462 {
463 (const uint8_t *) "get", 3, LEXER_STRING_LITERAL, false
464 };
465
466 /**
467 * Description of "set" literal string.
468 */
469 static const lexer_lit_location_t lexer_set_literal =
470 {
471 (const uint8_t *) "set", 3, LEXER_STRING_LITERAL, false
472 };
473
474 /**
475 * Class literal parsing options.
476 */
477 typedef enum
478 {
479 PARSER_CLASS_LITERAL_NO_OPTS = 0, /**< no options are provided */
480 PARSER_CLASS_LITERAL_CTOR_PRESENT = (1 << 0), /**< class constructor is present */
481 PARSER_CLASS_LITERAL_HERTIAGE_PRESENT = (1 << 1), /**< class heritage is present */
482 } parser_class_literal_opts_t;
483
484 /**
485 * Parse class literal.
486 */
487 static void
parser_parse_class_literal(parser_context_t * context_p,parser_class_literal_opts_t opts)488 parser_parse_class_literal (parser_context_t *context_p, /**< context */
489 parser_class_literal_opts_t opts) /**< class literal parsing options */
490 {
491 JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
492
493 uint32_t status_flags = PARSER_FUNCTION_CLOSURE | PARSER_ALLOW_SUPER;
494
495 lexer_literal_t *ctor_literal_p = NULL;
496
497 if (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT)
498 {
499 if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
500 {
501 parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
502 }
503
504 ctor_literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
505 ctor_literal_p->type = LEXER_UNUSED_LITERAL;
506 ctor_literal_p->status_flags = 0;
507 parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, (uint16_t) (context_p->literal_count++));
508 }
509 else if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT)
510 {
511 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE);
512 }
513 else
514 {
515 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR);
516 }
517
518 parser_emit_cbc_ext (context_p, CBC_EXT_INIT_CLASS);
519
520 bool is_static = false;
521
522 while (true)
523 {
524 if (!is_static)
525 {
526 lexer_skip_empty_statements (context_p);
527 }
528
529 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD);
530
531 if (context_p->token.type == LEXER_RIGHT_BRACE)
532 {
533 break;
534 }
535
536 bool is_computed = false;
537
538 if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
539 {
540 uint16_t literal_index, function_literal_index;
541 bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
542
543 if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
544 {
545 lexer_construct_literal_object (context_p,
546 (is_getter ? (lexer_lit_location_t *) &lexer_get_literal
547 : (lexer_lit_location_t *) &lexer_set_literal),
548 LEXER_STRING_LITERAL);
549 goto parse_class_method;
550 }
551
552 uint32_t accessor_status_flags = status_flags;
553 accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
554
555 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
556 literal_index = context_p->lit_object.index;
557
558 if (context_p->token.type == LEXER_RIGHT_SQUARE)
559 {
560 is_computed = true;
561 }
562 else if (!is_static
563 && LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)
564 && lexer_compare_literal_to_string (context_p, "constructor", 11))
565 {
566 parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR);
567 }
568
569 function_literal_index = lexer_construct_function_object (context_p, accessor_status_flags);
570
571 parser_emit_cbc_literal (context_p,
572 CBC_PUSH_LITERAL,
573 literal_index);
574
575 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
576
577 cbc_ext_opcode_t opcode;
578
579 if (is_computed)
580 {
581 context_p->last_cbc.literal_index = function_literal_index;
582
583 if (is_getter)
584 {
585 opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_GETTER : CBC_EXT_SET_COMPUTED_GETTER;
586 }
587 else
588 {
589 opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_SETTER : CBC_EXT_SET_COMPUTED_SETTER;
590 }
591 }
592 else
593 {
594 context_p->last_cbc.value = function_literal_index;
595
596 if (is_getter)
597 {
598 opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER;
599 }
600 else
601 {
602 opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER;
603 }
604 }
605
606 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
607 is_static = false;
608 continue;
609 }
610
611 if (!is_static)
612 {
613 if (context_p->token.type == LEXER_KEYW_STATIC)
614 {
615 is_static = true;
616 continue;
617 }
618
619 if (context_p->token.type == LEXER_CLASS_CONSTRUCTOR)
620 {
621 JERRY_ASSERT (opts & PARSER_CLASS_LITERAL_CTOR_PRESENT);
622 JERRY_ASSERT (ctor_literal_p != NULL);
623
624 if (ctor_literal_p->type == LEXER_FUNCTION_LITERAL)
625 {
626 /* 14.5.1 */
627 parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS);
628 }
629
630 uint32_t constructor_status_flags = (status_flags
631 | PARSER_CLASS_CONSTRUCTOR
632 | PARSER_LEXICAL_ENV_NEEDED);
633
634 if (opts & PARSER_CLASS_LITERAL_HERTIAGE_PRESENT)
635 {
636 constructor_status_flags |= PARSER_ALLOW_SUPER_CALL;
637 }
638
639 parser_flush_cbc (context_p);
640 ecma_compiled_code_t *compiled_code_p = parser_parse_function (context_p, constructor_status_flags);
641 ctor_literal_p->u.bytecode_p = compiled_code_p;
642 ctor_literal_p->type = LEXER_FUNCTION_LITERAL;
643 continue;
644 }
645 }
646
647 status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION
648 | PARSER_IS_ASYNC_FUNCTION
649 | PARSER_DISALLOW_AWAIT_YIELD);
650
651 if (context_p->token.type == LEXER_KEYW_ASYNC)
652 {
653 status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
654
655 if (!lexer_consume_generator (context_p))
656 {
657 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
658 }
659 }
660
661 if (context_p->token.type == LEXER_MULTIPLY)
662 {
663 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
664 status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
665 }
666
667 if (context_p->token.type == LEXER_RIGHT_SQUARE)
668 {
669 is_computed = true;
670 }
671 else if (LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type))
672 {
673 if (is_static)
674 {
675 if (lexer_compare_literal_to_string (context_p, "prototype", 9))
676 {
677 parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
678 }
679 }
680 else if ((status_flags & PARSER_IS_GENERATOR_FUNCTION)
681 && lexer_compare_literal_to_string (context_p, "constructor", 11))
682 {
683 parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_GENERATOR);
684 }
685 }
686
687 parse_class_method:
688 ; /* Empty statement to make compiler happy. */
689 uint16_t literal_index = context_p->lit_object.index;
690 uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
691
692 parser_emit_cbc_literal (context_p,
693 CBC_PUSH_LITERAL,
694 function_literal_index);
695
696 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
697
698 context_p->last_cbc.value = literal_index;
699
700 if (is_static)
701 {
702 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL
703 : CBC_EXT_SET_STATIC_PROPERTY_LITERAL);
704 is_static = false;
705 }
706 else
707 {
708 context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL)
709 : CBC_SET_LITERAL_PROPERTY);
710 }
711 }
712 } /* parser_parse_class_literal */
713
714 /**
715 * Parse class statement or expression.
716 */
717 void
parser_parse_class(parser_context_t * context_p,bool is_statement)718 parser_parse_class (parser_context_t *context_p, /**< context */
719 bool is_statement) /**< true - if class is parsed as a statement
720 * false - otherwise (as an expression) */
721 {
722 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS);
723
724 uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
725 uint16_t class_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
726 parser_class_literal_opts_t opts = PARSER_CLASS_LITERAL_NO_OPTS;
727
728 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
729 {
730 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR);
731 scanner_release_next (context_p, sizeof (scanner_info_t));
732 opts |= PARSER_CLASS_LITERAL_CTOR_PRESENT;
733 }
734
735 if (is_statement)
736 {
737 /* Class statement must contain an identifier. */
738 lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
739 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
740 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
741
742 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
743 {
744 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
745 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
746 }
747 class_ident_index = context_p->lit_object.index;
748
749 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
750 class_name_index = context_p->lit_object.index;
751
752 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
753 parser_module_append_export_name (context_p);
754 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
755 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
756
757 lexer_next_token (context_p);
758 }
759 else
760 {
761 lexer_next_token (context_p);
762
763 /* Class expression may contain an identifier. */
764 if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
765 {
766 /* NOTE: If 'Function.name' will be supported, the current literal object must be set to 'name' property. */
767 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
768 class_name_index = context_p->lit_object.index;
769 lexer_next_token (context_p);
770 }
771 }
772
773 if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
774 {
775 parser_emit_cbc_ext_literal (context_p, CBC_EXT_PUSH_NAMED_CLASS_ENV, class_name_index);
776 }
777 else
778 {
779 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_ANONYMOUS_CLASS_ENV);
780 }
781
782 bool is_strict = (context_p->status_flags & PARSER_IS_STRICT) != 0;
783
784 /* 14.5. A ClassBody is always strict code. */
785 context_p->status_flags |= PARSER_IS_STRICT;
786
787 if (context_p->token.type == LEXER_KEYW_EXTENDS)
788 {
789 lexer_next_token (context_p);
790 parser_parse_expression (context_p, PARSE_EXPR | PARSE_EXPR_LEFT_HAND_SIDE);
791 opts |= PARSER_CLASS_LITERAL_HERTIAGE_PRESENT;
792 }
793 else
794 {
795 /* Elisions represents that the classHeritage is not present */
796 parser_emit_cbc (context_p, CBC_PUSH_ELISION);
797 }
798
799 if (context_p->token.type != LEXER_LEFT_BRACE)
800 {
801 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
802 }
803
804 /* ClassDeclaration is parsed. Continue with class body. */
805 parser_parse_class_literal (context_p, opts);
806
807 if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
808 {
809 parser_emit_cbc_ext_literal (context_p, CBC_EXT_FINALIZE_NAMED_CLASS, class_name_index);
810 }
811 else
812 {
813 parser_emit_cbc_ext (context_p, CBC_EXT_FINALIZE_ANONYMOUS_CLASS);
814 }
815
816 if (is_statement)
817 {
818 cbc_opcode_t opcode = CBC_MOV_IDENT;
819
820 if (class_ident_index < PARSER_REGISTER_START)
821 {
822 opcode = (scanner_literal_is_created (context_p, class_ident_index) ? CBC_ASSIGN_LET_CONST
823 : CBC_INIT_LET);
824 }
825
826 parser_emit_cbc_literal (context_p, (uint16_t) opcode, class_ident_index);
827 }
828
829 parser_flush_cbc (context_p);
830
831 if (!is_strict)
832 {
833 /* Restore flag */
834 context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
835 }
836 context_p->status_flags &= (uint32_t) ~PARSER_ALLOW_SUPER;
837
838 lexer_next_token (context_p);
839 } /* parser_parse_class */
840 #endif /* ENABLED (JERRY_ES2015) */
841
842 #if ENABLED (JERRY_ES2015)
843 /**
844 * Parse object initializer method definition.
845 *
846 * See also: ES2015 14.3
847 */
848 static void
parser_parse_object_method(parser_context_t * context_p)849 parser_parse_object_method (parser_context_t *context_p) /**< context */
850 {
851 context_p->source_p--;
852 context_p->column--;
853 uint16_t function_literal_index = lexer_construct_function_object (context_p, PARSER_FUNCTION_CLOSURE);
854
855 parser_emit_cbc_literal (context_p,
856 CBC_PUSH_LITERAL,
857 function_literal_index);
858
859 lexer_next_token (context_p);
860 } /* parser_parse_object_method */
861
862 /**
863 * Reparse the current literal as a common identifier.
864 */
865 static void
parser_reparse_as_common_identifier(parser_context_t * context_p,parser_line_counter_t start_line,parser_line_counter_t start_column)866 parser_reparse_as_common_identifier (parser_context_t *context_p, /**< context */
867 parser_line_counter_t start_line, /**< start line */
868 parser_line_counter_t start_column) /**< start column */
869 {
870 /* context_p->token.lit_location.char_p is showing the character after the string start,
871 so it is not suitable for reparsing as identifier.
872 e.g.: { 'foo' } */
873 if (context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
874 {
875 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
876 }
877
878 context_p->source_p = context_p->token.lit_location.char_p;
879 context_p->line = start_line;
880 context_p->column = start_column;
881
882 lexer_next_token (context_p);
883
884 if (context_p->token.type != LEXER_LITERAL)
885 {
886 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
887 }
888
889 JERRY_ASSERT (context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
890
891 lexer_construct_literal_object (context_p,
892 &context_p->token.lit_location,
893 LEXER_IDENT_LITERAL);
894
895 } /* parser_reparse_as_common_identifier */
896 #endif /* ENABLED (JERRY_ES2015) */
897
898 /**
899 * Parse object literal.
900 */
901 static void
parser_parse_object_literal(parser_context_t * context_p)902 parser_parse_object_literal (parser_context_t *context_p) /**< context */
903 {
904 JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
905
906 parser_emit_cbc (context_p, CBC_CREATE_OBJECT);
907
908 #if !ENABLED (JERRY_ES2015)
909 parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START);
910 #endif /* !ENABLED (JERRY_ES2015) */
911
912 #if ENABLED (JERRY_ES2015)
913 bool proto_seen = false;
914 #endif /* ENABLED (JERRY_ES2015) */
915
916 while (true)
917 {
918 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
919
920 switch (context_p->token.type)
921 {
922 case LEXER_RIGHT_BRACE:
923 {
924 break;
925 }
926 case LEXER_PROPERTY_GETTER:
927 case LEXER_PROPERTY_SETTER:
928 {
929 uint32_t status_flags;
930 cbc_ext_opcode_t opcode;
931 #if !ENABLED (JERRY_ES2015)
932 parser_object_literal_item_types_t item_type;
933 #endif /* !ENABLED (JERRY_ES2015) */
934
935 if (context_p->token.type == LEXER_PROPERTY_GETTER)
936 {
937 status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_GETTER;
938 opcode = CBC_EXT_SET_GETTER;
939 #if !ENABLED (JERRY_ES2015)
940 item_type = PARSER_OBJECT_PROPERTY_GETTER;
941 #endif /* !ENABLED (JERRY_ES2015) */
942 }
943 else
944 {
945 status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_SETTER;
946 opcode = CBC_EXT_SET_SETTER;
947 #if !ENABLED (JERRY_ES2015)
948 item_type = PARSER_OBJECT_PROPERTY_SETTER;
949 #endif /* !ENABLED (JERRY_ES2015) */
950 }
951
952 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
953
954 /* This assignment is a nop for computed getters/setters. */
955 uint16_t literal_index = context_p->lit_object.index;
956
957 #if ENABLED (JERRY_ES2015)
958 if (context_p->token.type == LEXER_RIGHT_SQUARE)
959 {
960 opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
961 : CBC_EXT_SET_COMPUTED_SETTER);
962 }
963 #else /* !ENABLED (JERRY_ES2015) */
964 parser_append_object_literal_item (context_p, literal_index, item_type);
965 #endif /* ENABLED (JERRY_ES2015) */
966
967 uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
968
969 #if ENABLED (JERRY_ES2015)
970 if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
971 {
972 literal_index = function_literal_index;
973 }
974 #endif /* ENABLED (JERRY_ES2015) */
975
976 parser_emit_cbc_literal (context_p,
977 CBC_PUSH_LITERAL,
978 literal_index);
979
980 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
981 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
982 context_p->last_cbc.value = function_literal_index;
983
984 lexer_next_token (context_p);
985 break;
986 }
987 #if ENABLED (JERRY_ES2015)
988 case LEXER_RIGHT_SQUARE:
989 {
990 lexer_next_token (context_p);
991
992 if (context_p->token.type == LEXER_LEFT_PAREN)
993 {
994 parser_parse_object_method (context_p);
995
996 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
997 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
998 break;
999 }
1000
1001 if (context_p->token.type != LEXER_COLON)
1002 {
1003 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1004 }
1005
1006 lexer_next_token (context_p);
1007 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1008
1009 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1010 {
1011 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
1012 }
1013 else
1014 {
1015 parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
1016 }
1017 break;
1018 }
1019 case LEXER_KEYW_ASYNC:
1020 case LEXER_MULTIPLY:
1021 {
1022 uint32_t status_flags = PARSER_FUNCTION_CLOSURE;
1023
1024 if (context_p->token.type == LEXER_KEYW_ASYNC)
1025 {
1026 status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1027 lexer_consume_generator (context_p);
1028 }
1029
1030 if (context_p->token.type == LEXER_MULTIPLY)
1031 {
1032 status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1033 }
1034
1035 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
1036
1037 uint16_t opcode = CBC_SET_LITERAL_PROPERTY;
1038 /* This assignment is a nop for CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL. */
1039 uint16_t literal_index = context_p->lit_object.index;
1040
1041 if (context_p->token.type == LEXER_RIGHT_SQUARE)
1042 {
1043 opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
1044 }
1045
1046 uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
1047
1048 parser_emit_cbc_literal (context_p,
1049 CBC_PUSH_LITERAL,
1050 function_literal_index);
1051
1052 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
1053 context_p->last_cbc_opcode = opcode;
1054 context_p->last_cbc.value = literal_index;
1055
1056 lexer_next_token (context_p);
1057 break;
1058 }
1059 #endif /* ENABLED (JERRY_ES2015) */
1060 default:
1061 {
1062 #if ENABLED (JERRY_ES2015)
1063 const lexer_lit_location_t *literal_p = (const lexer_lit_location_t *) context_p->lit_object.literal_p;
1064 bool is_proto = ((context_p->token.lit_location.type == LEXER_IDENT_LITERAL
1065 || context_p->token.lit_location.type == LEXER_STRING_LITERAL)
1066 && lexer_compare_identifier_to_string (literal_p, (uint8_t *) "__proto__", 9)
1067 && lexer_check_next_character (context_p, LIT_CHAR_COLON));
1068 if (is_proto)
1069 {
1070 if (proto_seen)
1071 {
1072 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_PROTO);
1073 }
1074
1075 proto_seen = true;
1076 }
1077 #endif /* ENABLED (JERRY_ES2015) */
1078
1079 uint16_t literal_index = context_p->lit_object.index;
1080
1081 #if ENABLED (JERRY_ES2015)
1082 parser_line_counter_t start_line = context_p->token.line;
1083 parser_line_counter_t start_column = context_p->token.column;
1084 #else /* !ENABLED (JERRY_ES2015) */
1085 parser_append_object_literal_item (context_p,
1086 literal_index,
1087 PARSER_OBJECT_PROPERTY_VALUE);
1088 #endif /* ENABLED (JERRY_ES2015) */
1089
1090 lexer_next_token (context_p);
1091
1092 #if ENABLED (JERRY_ES2015)
1093 if (context_p->token.type == LEXER_LEFT_PAREN && !is_proto)
1094 {
1095 parser_parse_object_method (context_p);
1096
1097 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
1098 context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1099 context_p->last_cbc.value = literal_index;
1100 break;
1101 }
1102
1103 if ((context_p->token.type == LEXER_RIGHT_BRACE || context_p->token.type == LEXER_COMMA)
1104 && !is_proto)
1105 {
1106 parser_reparse_as_common_identifier (context_p, start_line, start_column);
1107 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
1108
1109 context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1110 context_p->last_cbc.value = literal_index;
1111
1112 lexer_next_token (context_p);
1113 break;
1114 }
1115 #endif /* ENABLED (JERRY_ES2015) */
1116
1117 if (context_p->token.type != LEXER_COLON)
1118 {
1119 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1120 }
1121
1122 lexer_next_token (context_p);
1123 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1124
1125 #if ENABLED (JERRY_ES2015)
1126 if (is_proto)
1127 {
1128 parser_emit_cbc_ext (context_p, CBC_EXT_SET__PROTO__);
1129 break;
1130 }
1131 #endif /* ENABLED (JERRY_ES2015) */
1132
1133 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1134 {
1135 context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
1136 context_p->last_cbc.value = literal_index;
1137 }
1138 else
1139 {
1140 parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
1141 }
1142
1143 break;
1144 }
1145 }
1146
1147 if (context_p->token.type == LEXER_RIGHT_BRACE)
1148 {
1149 break;
1150 }
1151 else if (context_p->token.type != LEXER_COMMA)
1152 {
1153 parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
1154 }
1155 }
1156
1157 #if !ENABLED (JERRY_ES2015)
1158 while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START)
1159 {
1160 parser_stack_pop (context_p, NULL, 3);
1161 }
1162
1163 parser_stack_pop_uint8 (context_p);
1164 #endif /* !ENABLED (JERRY_ES2015) */
1165 } /* parser_parse_object_literal */
1166
1167 /**
1168 * Parse function literal.
1169 */
1170 static void
parser_parse_function_expression(parser_context_t * context_p,uint32_t status_flags)1171 parser_parse_function_expression (parser_context_t *context_p, /**< context */
1172 uint32_t status_flags) /**< function status flags */
1173 {
1174 int literals = 0;
1175 uint16_t literal1 = 0;
1176 uint16_t literal2 = 0;
1177 uint16_t function_literal_index;
1178 int32_t function_name_index = -1;
1179
1180 #if !ENABLED (JERRY_ES2015)
1181 JERRY_ASSERT (status_flags & PARSER_IS_FUNC_EXPRESSION);
1182 #endif /* !ENABLED (JERRY_ES2015) */
1183
1184 #if ENABLED (JERRY_ES2015)
1185 if (status_flags & PARSER_IS_FUNC_EXPRESSION)
1186 {
1187 #endif /* !ENABLED (JERRY_ES2015) */
1188
1189 #if ENABLED (JERRY_DEBUGGER)
1190 parser_line_counter_t debugger_line = context_p->token.line;
1191 parser_line_counter_t debugger_column = context_p->token.column;
1192 #endif /* ENABLED (JERRY_DEBUGGER) */
1193
1194 #if ENABLED (JERRY_ES2015)
1195 uint32_t parent_status_flags = context_p->status_flags;
1196
1197 context_p->status_flags &= (uint32_t) ~(PARSER_IS_ASYNC_FUNCTION
1198 | PARSER_IS_GENERATOR_FUNCTION
1199 | PARSER_DISALLOW_AWAIT_YIELD);
1200
1201 if (status_flags & PARSER_IS_ASYNC_FUNCTION)
1202 {
1203 /* The name of the function cannot be await. */
1204 context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1205 }
1206
1207 if (lexer_consume_generator (context_p))
1208 {
1209 /* The name of the function cannot be yield. */
1210 context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1211 status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1212 }
1213 #endif /* ENABLED (JERRY_ES2015) */
1214
1215 if (!lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
1216 {
1217 lexer_next_token (context_p);
1218
1219 if (context_p->token.type != LEXER_LITERAL
1220 || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1221 {
1222 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
1223 }
1224
1225 parser_flush_cbc (context_p);
1226
1227 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
1228
1229 #if ENABLED (JERRY_DEBUGGER)
1230 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
1231 {
1232 jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME,
1233 JERRY_DEBUGGER_NO_SUBTYPE,
1234 context_p->lit_object.literal_p->u.char_p,
1235 context_p->lit_object.literal_p->prop.length);
1236
1237 /* Reset token position for the function. */
1238 context_p->token.line = debugger_line;
1239 context_p->token.column = debugger_column;
1240 }
1241 #endif /* ENABLED (JERRY_DEBUGGER) */
1242
1243 if (context_p->token.keyword_type >= LEXER_FIRST_NON_STRICT_ARGUMENTS)
1244 {
1245 status_flags |= PARSER_HAS_NON_STRICT_ARG;
1246 }
1247
1248 function_name_index = context_p->lit_object.index;
1249 }
1250
1251 #if ENABLED (JERRY_ES2015)
1252 context_p->status_flags = parent_status_flags;
1253 }
1254 #endif /* ENABLED (JERRY_ES2015) */
1255
1256 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1257 {
1258 literals = 1;
1259 literal1 = context_p->last_cbc.literal_index;
1260 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1261 }
1262 else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1263 {
1264 literals = 2;
1265 literal1 = context_p->last_cbc.literal_index;
1266 literal2 = context_p->last_cbc.value;
1267 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1268 }
1269
1270 function_literal_index = lexer_construct_function_object (context_p, status_flags);
1271
1272 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1273
1274 if (literals == 1)
1275 {
1276 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1277 context_p->last_cbc.literal_index = literal1;
1278 context_p->last_cbc.value = function_literal_index;
1279 }
1280 else if (literals == 2)
1281 {
1282 context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1283 context_p->last_cbc.literal_index = literal1;
1284 context_p->last_cbc.value = literal2;
1285 context_p->last_cbc.third_literal_index = function_literal_index;
1286 }
1287 else
1288 {
1289 parser_emit_cbc_literal (context_p,
1290 CBC_PUSH_LITERAL,
1291 function_literal_index);
1292
1293 if (function_name_index != -1)
1294 {
1295 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION);
1296 context_p->last_cbc.value = (uint16_t) function_name_index;
1297 }
1298 }
1299
1300 context_p->last_cbc.literal_type = LEXER_FUNCTION_LITERAL;
1301 context_p->last_cbc.literal_keyword_type = LEXER_EOS;
1302 } /* parser_parse_function_expression */
1303
1304 #if ENABLED (JERRY_ES2015)
1305
1306 /**
1307 * Parse template literal.
1308 */
1309 static void
parser_parse_template_literal(parser_context_t * context_p)1310 parser_parse_template_literal (parser_context_t *context_p) /**< context */
1311 {
1312 bool is_empty_head = true;
1313
1314 if (context_p->token.lit_location.length > 0)
1315 {
1316 is_empty_head = false;
1317
1318 lexer_construct_literal_object (context_p,
1319 &context_p->token.lit_location,
1320 context_p->token.lit_location.type);
1321
1322 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
1323 }
1324
1325 lexer_next_token (context_p);
1326 parser_parse_expression (context_p, PARSE_EXPR);
1327
1328 if (context_p->token.type != LEXER_RIGHT_BRACE)
1329 {
1330 parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1331 }
1332
1333 if (!is_empty_head)
1334 {
1335 if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1336 {
1337 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS);
1338 }
1339 else if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1340 {
1341 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1342 }
1343 else
1344 {
1345 parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT);
1346 }
1347 }
1348
1349 context_p->source_p--;
1350 context_p->column--;
1351 lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1352
1353 if (is_empty_head || context_p->token.lit_location.length > 0)
1354 {
1355 lexer_construct_literal_object (context_p,
1356 &context_p->token.lit_location,
1357 context_p->token.lit_location.type);
1358
1359 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1360 {
1361 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_TWO_LITERALS);
1362 context_p->last_cbc.value = context_p->lit_object.index;
1363 context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1364 context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1365 }
1366 else
1367 {
1368 parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1369 }
1370 }
1371
1372 while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1373 {
1374 lexer_next_token (context_p);
1375
1376 parser_parse_expression (context_p, PARSE_EXPR);
1377
1378 if (context_p->token.type != LEXER_RIGHT_BRACE)
1379 {
1380 parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1381 }
1382
1383 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1384 {
1385 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1386 }
1387 else
1388 {
1389 parser_emit_cbc_ext (context_p, CBC_EXT_STRING_CONCAT);
1390 }
1391
1392 context_p->source_p--;
1393 context_p->column--;
1394 lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1395
1396 if (context_p->token.lit_location.length > 0)
1397 {
1398 lexer_construct_literal_object (context_p,
1399 &context_p->token.lit_location,
1400 context_p->token.lit_location.type);
1401
1402 parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_STRING_CONCAT_RIGHT_LITERAL);
1403 }
1404 }
1405 } /* parser_parse_template_literal */
1406
1407 /**
1408 * Parse tagged template literal.
1409 */
1410 static size_t
parser_parse_tagged_template_literal(parser_context_t * context_p)1411 parser_parse_tagged_template_literal (parser_context_t *context_p) /**< context */
1412 {
1413 JERRY_ASSERT (context_p->token.type == LEXER_TEMPLATE_LITERAL);
1414
1415 uint32_t call_arguments = 0;
1416 ecma_collection_t *collection_p;
1417
1418 if (context_p->tagged_template_literal_cp == JMEM_CP_NULL)
1419 {
1420 collection_p = ecma_new_collection ();
1421 ECMA_SET_INTERNAL_VALUE_POINTER (context_p->tagged_template_literal_cp, collection_p);
1422 }
1423 else
1424 {
1425 collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_p->tagged_template_literal_cp);
1426 if (collection_p->item_count > CBC_MAXIMUM_BYTE_VALUE)
1427 {
1428 parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
1429 }
1430 }
1431
1432 const uint32_t tagged_id = collection_p->item_count;
1433 uint32_t prop_idx = 0;
1434 ecma_object_t *raw_strings_p;
1435 ecma_object_t *template_obj_p = parser_new_tagged_template_literal (&raw_strings_p);
1436 ecma_collection_push_back (collection_p, ecma_make_object_value (template_obj_p));
1437
1438 parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
1439
1440 call_arguments++;
1441 parser_emit_cbc_ext_call (context_p, CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, tagged_id);
1442
1443 while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1444 {
1445 JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LEFT_BRACE);
1446 lexer_next_token (context_p);
1447
1448 if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
1449 {
1450 parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
1451 }
1452
1453 parser_parse_expression (context_p, PARSE_EXPR);
1454
1455 if (context_p->token.type != LEXER_RIGHT_BRACE)
1456 {
1457 parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
1458 }
1459
1460 context_p->source_p--;
1461 context_p->column--;
1462 lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1463
1464 parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
1465 }
1466
1467 parser_tagged_template_literal_finalize (template_obj_p, raw_strings_p);
1468
1469 return call_arguments;
1470 } /* parser_parse_tagged_template_literal */
1471
1472 /**
1473 * Checks wheteher the current expression can be an assignment expression.
1474 *
1475 * @return true if the current expression can be an assignment expression, false otherwise
1476 */
1477 static inline bool JERRY_ATTR_ALWAYS_INLINE
parser_is_assignment_expr(parser_context_t * context_p)1478 parser_is_assignment_expr (parser_context_t *context_p)
1479 {
1480 return (context_p->stack_top_uint8 == LEXER_EXPRESSION_START
1481 || context_p->stack_top_uint8 == LEXER_LEFT_PAREN
1482 || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST
1483 || LEXER_IS_BINARY_LVALUE_TOKEN (context_p->stack_top_uint8));
1484 } /* parser_is_assignment_expr */
1485
1486 /**
1487 * Throws an error if the current expression is not an assignment expression.
1488 */
1489 static inline void JERRY_ATTR_ALWAYS_INLINE
parser_check_assignment_expr(parser_context_t * context_p)1490 parser_check_assignment_expr (parser_context_t *context_p)
1491 {
1492 if (!parser_is_assignment_expr (context_p))
1493 {
1494 parser_raise_error (context_p, PARSER_ERR_ASSIGNMENT_EXPECTED);
1495 }
1496 } /* parser_check_assignment_expr */
1497
1498 /**
1499 * Checks whether the next token is a valid continuation token after an AssignmentExpression.
1500 */
1501 static inline bool JERRY_ATTR_ALWAYS_INLINE
parser_abort_parsing_after_assignment_expression(parser_context_t * context_p)1502 parser_abort_parsing_after_assignment_expression (parser_context_t *context_p)
1503 {
1504 return (context_p->token.type != LEXER_RIGHT_PAREN
1505 && context_p->token.type != LEXER_COMMA);
1506 } /* parser_abort_parsing_after_assignment_expression */
1507
1508 #endif /* ENABLED (JERRY_ES2015) */
1509
1510 /**
1511 * Parse and record unary operators, and parse the primary literal.
1512 *
1513 * @return true if parsing should be aborted, true otherwise
1514 */
1515 static bool
parser_parse_unary_expression(parser_context_t * context_p,size_t * grouping_level_p)1516 parser_parse_unary_expression (parser_context_t *context_p, /**< context */
1517 size_t *grouping_level_p) /**< grouping level */
1518 {
1519 bool new_was_seen = false;
1520
1521 /* Collect unary operators. */
1522 while (true)
1523 {
1524 /* Convert plus and minus binary operators to unary operators. */
1525 switch (context_p->token.type)
1526 {
1527 case LEXER_ADD:
1528 {
1529 context_p->token.type = LEXER_PLUS;
1530 break;
1531 }
1532 case LEXER_SUBTRACT:
1533 {
1534 context_p->token.type = LEXER_NEGATE;
1535 break;
1536 }
1537 #if ENABLED (JERRY_ES2015)
1538 case LEXER_KEYW_AWAIT:
1539 {
1540 if (JERRY_UNLIKELY (context_p->token.lit_location.has_escape))
1541 {
1542 parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
1543 }
1544 break;
1545 }
1546 #endif /* ENABLED (JERRY_ES2015) */
1547 }
1548
1549 /* Bracketed expressions are primary expressions. At this
1550 * point their left paren is pushed onto the stack and
1551 * they are processed when their closing paren is reached. */
1552 if (context_p->token.type == LEXER_LEFT_PAREN)
1553 {
1554 #if ENABLED (JERRY_ES2015)
1555 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1556 {
1557 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1558 break;
1559 }
1560 #endif /* ENABLED (JERRY_ES2015) */
1561 (*grouping_level_p) += PARSER_GROUPING_LEVEL_INCREASE;
1562 new_was_seen = false;
1563 }
1564 else if (context_p->token.type == LEXER_KEYW_NEW)
1565 {
1566 /* After 'new' unary operators are not allowed. */
1567 new_was_seen = true;
1568
1569 #if ENABLED (JERRY_ES2015)
1570 /* Check if "new.target" is written here. */
1571 if (scanner_try_scan_new_target (context_p))
1572 {
1573 if (!(context_p->status_flags & PARSER_ALLOW_NEW_TARGET))
1574 {
1575 parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED);
1576 }
1577
1578 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_NEW_TARGET);
1579 lexer_next_token (context_p);
1580 /* Found "new.target" return here */
1581 return false;
1582 }
1583 #endif /* ENABLED (JERRY_ES2015) */
1584 }
1585 else if (new_was_seen
1586 || (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE)
1587 || !LEXER_IS_UNARY_OP_TOKEN (context_p->token.type))
1588 {
1589 break;
1590 }
1591
1592 parser_stack_push_uint8 (context_p, context_p->token.type);
1593 lexer_next_token (context_p);
1594 }
1595
1596 /* Parse primary expression. */
1597 switch (context_p->token.type)
1598 {
1599 #if ENABLED (JERRY_ES2015)
1600 case LEXER_TEMPLATE_LITERAL:
1601 {
1602 if (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1603 {
1604 parser_parse_template_literal (context_p);
1605 break;
1606 }
1607
1608 /* The string is a normal string literal. */
1609 /* FALLTHRU */
1610 }
1611 #endif /* ENABLED (JERRY_ES2015) */
1612 case LEXER_LITERAL:
1613 {
1614 #if ENABLED (JERRY_ES2015)
1615 if (JERRY_UNLIKELY (context_p->next_scanner_info_p->source_p == context_p->source_p))
1616 {
1617 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1618
1619 uint32_t arrow_status_flags = (PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
1620
1621 if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC)
1622 {
1623 JERRY_ASSERT (lexer_token_is_async (context_p));
1624 JERRY_ASSERT (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT));
1625
1626 uint32_t saved_status_flags = context_p->status_flags;
1627
1628 context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
1629 lexer_next_token (context_p);
1630 context_p->status_flags = saved_status_flags;
1631
1632 if (context_p->token.type == LEXER_KEYW_FUNCTION)
1633 {
1634 uint32_t status_flags = (PARSER_FUNCTION_CLOSURE
1635 | PARSER_IS_FUNC_EXPRESSION
1636 | PARSER_IS_ASYNC_FUNCTION
1637 | PARSER_DISALLOW_AWAIT_YIELD);
1638 parser_parse_function_expression (context_p, status_flags);
1639 break;
1640 }
1641
1642 arrow_status_flags = (PARSER_IS_FUNCTION
1643 | PARSER_IS_ARROW_FUNCTION
1644 | PARSER_IS_ASYNC_FUNCTION
1645 | PARSER_DISALLOW_AWAIT_YIELD);
1646 }
1647
1648 parser_check_assignment_expr (context_p);
1649 parser_parse_function_expression (context_p, arrow_status_flags);
1650 return parser_abort_parsing_after_assignment_expression (context_p);
1651 }
1652 #endif /* ENABLED (JERRY_ES2015) */
1653
1654 uint8_t type = context_p->token.lit_location.type;
1655
1656 if (type == LEXER_IDENT_LITERAL || type == LEXER_STRING_LITERAL)
1657 {
1658 lexer_construct_literal_object (context_p,
1659 &context_p->token.lit_location,
1660 context_p->token.lit_location.type);
1661
1662 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1663 if ((context_p->status_flags & PARSER_MODULE_STORE_IDENT)
1664 && type == LEXER_IDENT_LITERAL)
1665 {
1666 context_p->module_identifier_lit_p = context_p->lit_object.literal_p;
1667 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
1668 }
1669 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1670 }
1671 else if (type == LEXER_NUMBER_LITERAL)
1672 {
1673 bool is_negative_number = false;
1674
1675 if ((context_p->stack_top_uint8 == LEXER_PLUS || context_p->stack_top_uint8 == LEXER_NEGATE)
1676 && !lexer_check_post_primary_exp (context_p))
1677 {
1678 do
1679 {
1680 if (context_p->stack_top_uint8 == LEXER_NEGATE)
1681 {
1682 is_negative_number = !is_negative_number;
1683 }
1684 parser_stack_pop_uint8 (context_p);
1685 }
1686 while (context_p->stack_top_uint8 == LEXER_PLUS
1687 || context_p->stack_top_uint8 == LEXER_NEGATE);
1688 }
1689
1690 if (lexer_construct_number_object (context_p, true, is_negative_number))
1691 {
1692 JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
1693
1694 parser_emit_cbc_push_number (context_p, is_negative_number);
1695 break;
1696 }
1697 }
1698
1699 cbc_opcode_t opcode = CBC_PUSH_LITERAL;
1700
1701 if (context_p->token.keyword_type != LEXER_KEYW_EVAL)
1702 {
1703 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1704 {
1705 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1706 context_p->last_cbc.value = context_p->lit_object.index;
1707 context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1708 context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1709 break;
1710 }
1711
1712 if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1713 {
1714 context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1715 context_p->last_cbc.third_literal_index = context_p->lit_object.index;
1716 context_p->last_cbc.literal_type = context_p->token.lit_location.type;
1717 context_p->last_cbc.literal_keyword_type = context_p->token.keyword_type;
1718 break;
1719 }
1720
1721 if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
1722 {
1723 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1724 opcode = CBC_PUSH_THIS_LITERAL;
1725 }
1726 }
1727
1728 parser_emit_cbc_literal_from_token (context_p, (uint16_t) opcode);
1729 break;
1730 }
1731 case LEXER_KEYW_FUNCTION:
1732 {
1733 parser_parse_function_expression (context_p, PARSER_FUNCTION_CLOSURE | PARSER_IS_FUNC_EXPRESSION);
1734 break;
1735 }
1736 case LEXER_LEFT_BRACE:
1737 {
1738 #if ENABLED (JERRY_ES2015)
1739 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1740 {
1741 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
1742
1743 if (parser_is_assignment_expr (context_p))
1744 {
1745 parser_parse_object_initializer (context_p, PARSER_PATTERN_NO_OPTS);
1746 return parser_abort_parsing_after_assignment_expression (context_p);
1747 }
1748
1749 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1750 }
1751 #endif /* ENABLED (JERRY_ES2015) */
1752
1753 parser_parse_object_literal (context_p);
1754 break;
1755 }
1756 case LEXER_LEFT_SQUARE:
1757 {
1758 #if ENABLED (JERRY_ES2015)
1759 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1760 {
1761 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
1762
1763 if (parser_is_assignment_expr (context_p))
1764 {
1765 parser_parse_array_initializer (context_p, PARSER_PATTERN_NO_OPTS);
1766 return parser_abort_parsing_after_assignment_expression (context_p);
1767 }
1768
1769 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1770 }
1771 #endif /* ENABLED (JERRY_ES2015) */
1772
1773 parser_parse_array_literal (context_p);
1774 break;
1775 }
1776 case LEXER_DIVIDE:
1777 case LEXER_ASSIGN_DIVIDE:
1778 {
1779 lexer_construct_regexp_object (context_p, false);
1780
1781 uint16_t literal_index = (uint16_t) (context_p->literal_count - 1);
1782
1783 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1784 {
1785 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1786 context_p->last_cbc.value = literal_index;
1787 }
1788 else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
1789 {
1790 context_p->last_cbc_opcode = CBC_PUSH_THREE_LITERALS;
1791 context_p->last_cbc.third_literal_index = literal_index;
1792 }
1793 else
1794 {
1795 parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, literal_index);
1796 }
1797
1798 context_p->last_cbc.literal_type = LEXER_REGEXP_LITERAL;
1799 context_p->last_cbc.literal_keyword_type = LEXER_EOS;
1800 break;
1801 }
1802 case LEXER_KEYW_THIS:
1803 {
1804 #if ENABLED (JERRY_ES2015)
1805 if (context_p->status_flags & PARSER_ALLOW_SUPER_CALL)
1806 {
1807 parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_LEXICAL_THIS);
1808 }
1809 else
1810 {
1811 #endif /* ENABLED (JERRY_ES2015) */
1812 parser_emit_cbc (context_p, CBC_PUSH_THIS);
1813 #if ENABLED (JERRY_ES2015)
1814 }
1815 #endif /* ENABLED (JERRY_ES2015) */
1816 break;
1817 }
1818 case LEXER_LIT_TRUE:
1819 {
1820 parser_emit_cbc (context_p, CBC_PUSH_TRUE);
1821 break;
1822 }
1823 case LEXER_LIT_FALSE:
1824 {
1825 parser_emit_cbc (context_p, CBC_PUSH_FALSE);
1826 break;
1827 }
1828 case LEXER_LIT_NULL:
1829 {
1830 parser_emit_cbc (context_p, CBC_PUSH_NULL);
1831 break;
1832 }
1833 #if ENABLED (JERRY_ES2015)
1834 case LEXER_KEYW_CLASS:
1835 {
1836 parser_parse_class (context_p, false);
1837 return false;
1838 }
1839 case LEXER_KEYW_SUPER:
1840 {
1841 if (context_p->status_flags & PARSER_ALLOW_SUPER)
1842 {
1843 if (lexer_check_next_characters (context_p, LIT_CHAR_DOT, LIT_CHAR_LEFT_SQUARE))
1844 {
1845 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER);
1846 break;
1847 }
1848
1849 if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)
1850 && (context_p->status_flags & PARSER_ALLOW_SUPER_CALL))
1851 {
1852 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_CONSTRUCTOR);
1853 break;
1854 }
1855 }
1856
1857 parser_raise_error (context_p, PARSER_ERR_UNEXPECTED_SUPER_KEYWORD);
1858 }
1859 case LEXER_LEFT_PAREN:
1860 {
1861 JERRY_ASSERT (context_p->next_scanner_info_p->source_p == context_p->source_p
1862 && context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
1863
1864 parser_check_assignment_expr (context_p);
1865
1866 parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
1867 return parser_abort_parsing_after_assignment_expression (context_p);
1868 }
1869 case LEXER_KEYW_YIELD:
1870 {
1871 JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
1872 && !(context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD));
1873
1874 if (context_p->token.lit_location.has_escape)
1875 {
1876 parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
1877 }
1878
1879 parser_check_assignment_expr (context_p);
1880 lexer_next_token (context_p);
1881
1882 cbc_ext_opcode_t opcode = CBC_EXT_YIELD;
1883
1884 if (!lexer_check_yield_no_arg (context_p))
1885 {
1886 if (context_p->token.type == LEXER_MULTIPLY)
1887 {
1888 lexer_next_token (context_p);
1889 opcode = CBC_EXT_YIELD_ITERATOR;
1890 }
1891
1892 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
1893 }
1894 else
1895 {
1896 parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED);
1897 }
1898
1899 parser_emit_cbc_ext (context_p, opcode);
1900
1901 return (context_p->token.type != LEXER_RIGHT_PAREN
1902 && context_p->token.type != LEXER_COMMA);
1903 }
1904 #endif /* ENABLED (JERRY_ES2015) */
1905 default:
1906 {
1907 bool is_left_hand_side = (*grouping_level_p == PARSE_EXPR_LEFT_HAND_SIDE);
1908 parser_raise_error (context_p, (is_left_hand_side ? PARSER_ERR_LEFT_HAND_SIDE_EXP_EXPECTED
1909 : PARSER_ERR_PRIMARY_EXP_EXPECTED));
1910 break;
1911 }
1912 }
1913 lexer_next_token (context_p);
1914 return false;
1915 } /* parser_parse_unary_expression */
1916
1917 /**
1918 * Parse the postfix part of unary operators, and
1919 * generate byte code for the whole expression.
1920 */
1921 static void
parser_process_unary_expression(parser_context_t * context_p,size_t grouping_level)1922 parser_process_unary_expression (parser_context_t *context_p, /**< context */
1923 size_t grouping_level) /**< grouping level */
1924 {
1925 /* Parse postfix part of a primary expression. */
1926 while (true)
1927 {
1928 /* Since break would only break the switch, we use
1929 * continue to continue this loop. Without continue,
1930 * the code abandons the loop. */
1931 switch (context_p->token.type)
1932 {
1933 case LEXER_DOT:
1934 {
1935 parser_push_result (context_p);
1936
1937 lexer_expect_identifier (context_p, LEXER_STRING_LITERAL);
1938 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
1939 && context_p->lit_object.literal_p->type == LEXER_STRING_LITERAL);
1940 context_p->token.lit_location.type = LEXER_STRING_LITERAL;
1941
1942 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
1943 {
1944 JERRY_ASSERT (CBC_ARGS_EQ (CBC_PUSH_PROP_LITERAL_LITERAL,
1945 CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
1946 context_p->last_cbc_opcode = CBC_PUSH_PROP_LITERAL_LITERAL;
1947 context_p->last_cbc.value = context_p->lit_object.index;
1948 }
1949 else if (context_p->last_cbc_opcode == CBC_PUSH_THIS)
1950 {
1951 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1952 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_THIS_LITERAL);
1953 }
1954 #if ENABLED (JERRY_ES2015)
1955 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1956 {
1957 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL);
1958 context_p->last_cbc.literal_index = context_p->lit_object.index;
1959 }
1960 #endif /* ENABLED (JERRY_ES2015) */
1961 else
1962 {
1963 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_PROP_LITERAL);
1964 }
1965 lexer_next_token (context_p);
1966 continue;
1967 }
1968
1969 case LEXER_LEFT_SQUARE:
1970 {
1971 parser_push_result (context_p);
1972
1973 #if ENABLED (JERRY_ES2015)
1974 uint16_t last_cbc_opcode = context_p->last_cbc_opcode;
1975
1976 if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1977 {
1978 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1979 }
1980 #endif /* ENABLED (JERRY_ES2015) */
1981
1982 lexer_next_token (context_p);
1983 parser_parse_expression (context_p, PARSE_EXPR);
1984 if (context_p->token.type != LEXER_RIGHT_SQUARE)
1985 {
1986 parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED);
1987 }
1988 lexer_next_token (context_p);
1989
1990 #if ENABLED (JERRY_ES2015)
1991 if (last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER))
1992 {
1993 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SUPER_PROP);
1994 continue;
1995 }
1996 #endif /* ENABLED (JERRY_ES2015) */
1997
1998 if (PARSER_IS_MUTABLE_PUSH_LITERAL (context_p->last_cbc_opcode))
1999 {
2000 context_p->last_cbc_opcode = PARSER_PUSH_LITERAL_TO_PUSH_PROP_LITERAL (context_p->last_cbc_opcode);
2001 }
2002 else
2003 {
2004 parser_emit_cbc (context_p, CBC_PUSH_PROP);
2005 }
2006 continue;
2007 }
2008
2009 #if ENABLED (JERRY_ES2015)
2010 case LEXER_TEMPLATE_LITERAL:
2011 #endif /* ENABLED (JERRY_ES2015) */
2012 case LEXER_LEFT_PAREN:
2013 {
2014 size_t call_arguments = 0;
2015 uint16_t opcode = CBC_CALL;
2016 bool is_eval = false;
2017
2018 parser_push_result (context_p);
2019
2020 if (context_p->stack_top_uint8 == LEXER_KEYW_NEW)
2021 {
2022 parser_stack_pop_uint8 (context_p);
2023 opcode = CBC_NEW;
2024 }
2025 else
2026 {
2027 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
2028 && context_p->last_cbc.literal_keyword_type == LEXER_KEYW_EVAL
2029 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2030 {
2031 is_eval = true;
2032 }
2033
2034 if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2035 {
2036 opcode = CBC_CALL_PROP;
2037 context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
2038 }
2039 #if ENABLED (JERRY_ES2015)
2040 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_CONSTRUCTOR))
2041 {
2042 opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL);
2043 }
2044 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
2045 {
2046 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE);
2047 opcode = CBC_CALL_PROP;
2048 }
2049 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
2050 {
2051 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE);
2052 opcode = CBC_CALL_PROP;
2053 }
2054 #endif /* ENABLED (JERRY_ES2015) */
2055 else if (JERRY_UNLIKELY (context_p->status_flags & PARSER_INSIDE_WITH)
2056 && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2057 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2058 {
2059 opcode = CBC_CALL_PROP;
2060 parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
2061 parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
2062 }
2063 }
2064
2065 #if ENABLED (JERRY_ES2015)
2066 bool has_spread_element = false;
2067
2068 if (context_p->token.type == LEXER_TEMPLATE_LITERAL)
2069 {
2070 call_arguments = parser_parse_tagged_template_literal (context_p);
2071 }
2072 else
2073 {
2074 lexer_next_token (context_p);
2075
2076 while (context_p->token.type != LEXER_RIGHT_PAREN)
2077 {
2078 if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
2079 {
2080 parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
2081 }
2082
2083 if (context_p->token.type == LEXER_THREE_DOTS)
2084 {
2085 has_spread_element = true;
2086 call_arguments++;
2087 parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_SPREAD_ELEMENT);
2088 lexer_next_token (context_p);
2089 }
2090
2091 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2092
2093 if (context_p->token.type == LEXER_COMMA)
2094 {
2095 lexer_next_token (context_p);
2096 continue;
2097 }
2098
2099 if (context_p->token.type != LEXER_RIGHT_PAREN)
2100 {
2101 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
2102 }
2103
2104 break;
2105 }
2106 }
2107 #else /* !ENABLED (JERRY_ES2015) */
2108 lexer_next_token (context_p);
2109
2110 if (context_p->token.type != LEXER_RIGHT_PAREN)
2111 {
2112 while (true)
2113 {
2114 if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
2115 {
2116 parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
2117 }
2118
2119 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2120
2121 if (context_p->token.type != LEXER_COMMA)
2122 {
2123 break;
2124 }
2125 lexer_next_token (context_p);
2126 }
2127
2128 if (context_p->token.type != LEXER_RIGHT_PAREN)
2129 {
2130 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
2131 }
2132 }
2133 #endif /* ENABLED (JERRY_ES2015) */
2134
2135 lexer_next_token (context_p);
2136
2137 if (is_eval)
2138 {
2139 context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
2140
2141 #if ENABLED (JERRY_ES2015)
2142 uint16_t eval_flags = PARSER_SAVE_STATUS_FLAGS (context_p->status_flags);
2143 const uint32_t required_flags = PARSER_IS_FUNCTION | PARSER_LEXICAL_BLOCK_NEEDED;
2144
2145 if (context_p->status_flags & PARSER_FUNCTION_IS_PARSING_ARGS)
2146 {
2147 context_p->status_flags |= PARSER_LEXICAL_BLOCK_NEEDED;
2148 }
2149 else if (((context_p->status_flags & (required_flags | PARSER_IS_STRICT)) == required_flags)
2150 || ((context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT)
2151 && !(context_p->status_flags & PARSER_IS_FUNCTION)))
2152 {
2153 eval_flags |= PARSER_GET_EVAL_FLAG (ECMA_PARSE_FUNCTION_CONTEXT);
2154 }
2155
2156 if (eval_flags != 0)
2157 {
2158 parser_emit_cbc_ext_call (context_p, CBC_EXT_LOCAL_EVAL, eval_flags);
2159 }
2160 else
2161 {
2162 #endif /* ENABLED (JERRY_ES2015) */
2163 parser_emit_cbc (context_p, CBC_EVAL);
2164 #if ENABLED (JERRY_ES2015)
2165 }
2166 #endif /* ENABLED (JERRY_ES2015) */
2167 }
2168
2169 #if ENABLED (JERRY_ES2015)
2170 if (has_spread_element)
2171 {
2172 uint16_t spread_opcode;
2173
2174 if (opcode == CBC_CALL)
2175 {
2176 spread_opcode = CBC_EXT_SPREAD_CALL;
2177 }
2178 else if (opcode == CBC_CALL_PROP)
2179 {
2180 spread_opcode = CBC_EXT_SPREAD_CALL_PROP;
2181 }
2182 else if (opcode == CBC_NEW)
2183 {
2184 spread_opcode = CBC_EXT_SPREAD_NEW;
2185 }
2186 else
2187 {
2188 /* opcode is unchanged */
2189 JERRY_ASSERT (opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL));
2190 spread_opcode = CBC_EXT_SPREAD_SUPER_CALL;
2191 }
2192
2193 parser_emit_cbc_ext_call (context_p, spread_opcode, call_arguments);
2194 continue;
2195 }
2196 #endif /* ENABLED (JERRY_ES2015) */
2197
2198 if (call_arguments <= 1)
2199 {
2200 if (opcode == CBC_CALL)
2201 {
2202 parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0 + (call_arguments * 6)));
2203 continue;
2204 }
2205 if (opcode == CBC_CALL_PROP)
2206 {
2207 parser_emit_cbc (context_p, (uint16_t) (CBC_CALL0_PROP + (call_arguments * 6)));
2208 continue;
2209 }
2210 if (opcode == CBC_NEW)
2211 {
2212 parser_emit_cbc (context_p, (uint16_t) (CBC_NEW0 + call_arguments));
2213 continue;
2214 }
2215 }
2216
2217 if (call_arguments == 2)
2218 {
2219 if (opcode == CBC_CALL)
2220 {
2221 parser_emit_cbc (context_p, CBC_CALL2);
2222 continue;
2223 }
2224 if (opcode == CBC_CALL_PROP)
2225 {
2226 parser_flush_cbc (context_p);
2227 /* Manually adjusting stack usage. */
2228 JERRY_ASSERT (context_p->stack_depth > 0);
2229 context_p->stack_depth--;
2230 parser_emit_cbc (context_p, CBC_CALL2_PROP);
2231 continue;
2232 }
2233 }
2234
2235 parser_emit_cbc_call (context_p, opcode, call_arguments);
2236 continue;
2237 }
2238
2239 default:
2240 {
2241 if (context_p->stack_top_uint8 == LEXER_KEYW_NEW)
2242 {
2243 parser_push_result (context_p);
2244 parser_emit_cbc (context_p, CBC_NEW0);
2245 parser_stack_pop_uint8 (context_p);
2246 continue;
2247 }
2248
2249 if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2250 && (context_p->token.type == LEXER_INCREASE || context_p->token.type == LEXER_DECREASE)
2251 && grouping_level != PARSE_EXPR_LEFT_HAND_SIDE)
2252 {
2253 cbc_opcode_t opcode = (context_p->token.type == LEXER_INCREASE) ? CBC_POST_INCR : CBC_POST_DECR;
2254 parser_push_result (context_p);
2255 parser_emit_unary_lvalue_opcode (context_p, opcode);
2256 lexer_next_token (context_p);
2257 }
2258 break;
2259 }
2260 }
2261 break;
2262 }
2263
2264 #if ENABLED (JERRY_ES2015)
2265 uint8_t last_unary_token = LEXER_INCREASE;
2266 #endif /* ENABLED (JERRY_ES2015) */
2267
2268 /* Generate byte code for the unary operators. */
2269 while (true)
2270 {
2271 uint8_t token = context_p->stack_top_uint8;
2272 if (!LEXER_IS_UNARY_OP_TOKEN (token))
2273 {
2274 #if ENABLED (JERRY_ES2015)
2275 if (context_p->token.type == LEXER_EXPONENTIATION
2276 && last_unary_token != LEXER_INCREASE
2277 && last_unary_token != LEXER_DECREASE)
2278 {
2279 parser_raise_error (context_p, PARSER_ERR_INVALID_EXPONENTIATION);
2280 }
2281 #endif /* ENABLED (JERRY_ES2015) */
2282 break;
2283 }
2284
2285 #if ENABLED (JERRY_ES2015)
2286 last_unary_token = token;
2287 #endif /* ENABLED (JERRY_ES2015) */
2288
2289 parser_push_result (context_p);
2290 parser_stack_pop_uint8 (context_p);
2291
2292 if (LEXER_IS_UNARY_LVALUE_OP_TOKEN (token))
2293 {
2294 if (token == LEXER_KEYW_DELETE)
2295 {
2296 token = CBC_DELETE_PUSH_RESULT;
2297 }
2298 else
2299 {
2300 token = (uint8_t) (LEXER_UNARY_LVALUE_OP_TOKEN_TO_OPCODE (token));
2301 }
2302 parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token);
2303 }
2304 #if ENABLED (JERRY_ES2015)
2305 else if (JERRY_UNLIKELY (token == LEXER_KEYW_AWAIT))
2306 {
2307 parser_emit_cbc_ext (context_p, CBC_EXT_AWAIT);
2308 }
2309 #endif /* ENABLED (JERRY_ES2015) */
2310 else
2311 {
2312 token = (uint8_t) (LEXER_UNARY_OP_TOKEN_TO_OPCODE (token));
2313
2314 if (token == CBC_TYPEOF)
2315 {
2316 if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2317 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2318 {
2319 parser_emit_ident_reference (context_p, CBC_TYPEOF_IDENT);
2320 }
2321 else
2322 {
2323 parser_emit_cbc (context_p, token);
2324 }
2325 }
2326 else
2327 {
2328 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
2329 {
2330 /* It is not worth to combine with push multiple literals
2331 * since the byte code size will not decrease. */
2332 JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, token + 1));
2333 context_p->last_cbc_opcode = (uint16_t) (token + 1);
2334 }
2335 else
2336 {
2337 parser_emit_cbc (context_p, token);
2338 }
2339 }
2340 }
2341 }
2342 } /* parser_process_unary_expression */
2343
2344 /**
2345 * Append a binary '=' token.
2346 *
2347 * @return - pushed assignment opcode onto the parser stack
2348 */
2349 static uint8_t
parser_append_binary_single_assignment_token(parser_context_t * context_p,uint32_t pattern_flags)2350 parser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */
2351 uint32_t pattern_flags) /**< pattern flags */
2352 {
2353 JERRY_UNUSED (pattern_flags);
2354
2355 /* Unlike other tokens, the whole byte code is saved for binary
2356 * assignment, since it has multiple forms depending on the
2357 * previous instruction. */
2358
2359 uint8_t assign_opcode = CBC_ASSIGN;
2360
2361 if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2362 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2363 {
2364 parser_check_invalid_assign (context_p);
2365
2366 uint16_t literal_index;
2367
2368 switch (context_p->last_cbc_opcode)
2369 {
2370 case CBC_PUSH_LITERAL:
2371 {
2372 literal_index = context_p->last_cbc.literal_index;
2373 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2374 break;
2375 }
2376 case CBC_PUSH_TWO_LITERALS:
2377 {
2378 literal_index = context_p->last_cbc.value;
2379 context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
2380 break;
2381 }
2382 case CBC_PUSH_THIS_LITERAL:
2383 {
2384 literal_index = context_p->last_cbc.literal_index;
2385 context_p->last_cbc_opcode = CBC_PUSH_THIS;
2386 parser_flush_cbc (context_p);
2387 break;
2388 }
2389 default:
2390 {
2391 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
2392 literal_index = context_p->last_cbc.third_literal_index;
2393 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
2394 break;
2395 }
2396 }
2397
2398 assign_opcode = CBC_ASSIGN_SET_IDENT;
2399
2400 #if ENABLED (JERRY_ES2015)
2401 if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL)))
2402 {
2403 if (scanner_literal_is_const_reg (context_p, literal_index))
2404 {
2405 parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
2406 }
2407 }
2408 else if (literal_index < PARSER_REGISTER_START)
2409 {
2410 assign_opcode = CBC_INIT_LET;
2411
2412 if (scanner_literal_is_created (context_p, literal_index))
2413 {
2414 assign_opcode = CBC_ASSIGN_LET_CONST;
2415 }
2416 else if (pattern_flags & PARSER_PATTERN_CONST)
2417 {
2418 assign_opcode = CBC_INIT_CONST;
2419 }
2420 else if (pattern_flags & PARSER_PATTERN_LOCAL)
2421 {
2422 assign_opcode = CBC_INIT_ARG_OR_CATCH;
2423 }
2424 }
2425 #endif /* ENABLED (JERRY_ES2015) */
2426
2427 parser_stack_push_uint16 (context_p, literal_index);
2428 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode));
2429 }
2430 else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
2431 {
2432 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_ASSIGN));
2433 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2434 }
2435 else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
2436 {
2437 if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
2438 {
2439 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_ASSIGN_PROP_LITERAL));
2440 parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
2441 assign_opcode = CBC_ASSIGN_PROP_LITERAL;
2442 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2443 }
2444 else
2445 {
2446 context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
2447 }
2448 }
2449 else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
2450 {
2451 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS));
2452 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
2453 }
2454 else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
2455 {
2456 if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
2457 {
2458 JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_ASSIGN_PROP_THIS_LITERAL));
2459 parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
2460 assign_opcode = CBC_ASSIGN_PROP_THIS_LITERAL;
2461 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
2462 }
2463 else
2464 {
2465 context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
2466 }
2467 }
2468 #if ENABLED (JERRY_ES2015)
2469 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
2470 {
2471 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
2472 assign_opcode = CBC_ASSIGN_SUPER;
2473 }
2474 else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
2475 {
2476 context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
2477 assign_opcode = CBC_ASSIGN_SUPER;
2478 }
2479 #endif /* ENABLED (JERRY_ES2015) */
2480 else
2481 {
2482 /* Invalid LeftHandSide expression. */
2483 #if ENABLED (JERRY_ES2015)
2484 parser_check_invalid_new_target (context_p, CBC_ASSIGN);
2485 #endif /* ENABLED (JERRY_ES2015) */
2486
2487 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
2488 }
2489
2490 parser_stack_push_uint8 (context_p, assign_opcode);
2491 parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
2492
2493 return assign_opcode;
2494 } /* parser_append_binary_single_assignment_token */
2495
2496 /**
2497 * Append a binary token.
2498 */
2499 static void
parser_append_binary_token(parser_context_t * context_p)2500 parser_append_binary_token (parser_context_t *context_p) /**< context */
2501 {
2502 JERRY_ASSERT (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type));
2503
2504 parser_push_result (context_p);
2505
2506 if (context_p->token.type == LEXER_ASSIGN)
2507 {
2508 parser_append_binary_single_assignment_token (context_p, 0);
2509 return;
2510 }
2511
2512 if (LEXER_IS_BINARY_LVALUE_TOKEN (context_p->token.type))
2513 {
2514 if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
2515 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
2516 {
2517 parser_check_invalid_assign (context_p);
2518
2519 parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
2520
2521 #if ENABLED (JERRY_ES2015)
2522 if (scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
2523 {
2524 parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
2525 }
2526 #endif /* ENABLED (JERRY_ES2015) */
2527 }
2528 else if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2529 {
2530 context_p->last_cbc_opcode = PARSER_PUSH_PROP_TO_PUSH_PROP_REFERENCE (context_p->last_cbc_opcode);
2531 }
2532 else
2533 {
2534 /* Invalid LeftHandSide expression. */
2535 #if ENABLED (JERRY_ES2015)
2536 parser_check_invalid_new_target (context_p, CBC_ASSIGN);
2537 #endif /* ENABLED (JERRY_ES2015) */
2538
2539 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
2540 parser_emit_cbc (context_p, CBC_PUSH_PROP_REFERENCE);
2541 }
2542 }
2543 else if (context_p->token.type == LEXER_LOGICAL_OR
2544 || context_p->token.type == LEXER_LOGICAL_AND)
2545 {
2546 parser_branch_t branch;
2547 uint16_t opcode = CBC_BRANCH_IF_LOGICAL_TRUE;
2548
2549 if (context_p->token.type == LEXER_LOGICAL_AND)
2550 {
2551 opcode = CBC_BRANCH_IF_LOGICAL_FALSE;
2552 }
2553
2554 parser_emit_cbc_forward_branch (context_p, opcode, &branch);
2555 parser_stack_push (context_p, &branch, sizeof (parser_branch_t));
2556 }
2557
2558 parser_stack_push_uint8 (context_p, context_p->token.type);
2559 } /* parser_append_binary_token */
2560
2561 /**
2562 * Emit opcode for binary computations.
2563 */
2564 static void
parser_process_binary_opcodes(parser_context_t * context_p,uint8_t min_prec_treshold)2565 parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
2566 uint8_t min_prec_treshold) /**< minimal precedence of tokens */
2567 {
2568 while (true)
2569 {
2570 uint8_t token = context_p->stack_top_uint8;
2571 cbc_opcode_t opcode;
2572
2573 /* For left-to-right operators (all binary operators except assignment
2574 * and logical operators), the byte code is flushed if the precedence
2575 * of the next operator is less or equal than the current operator. For
2576 * assignment and logical operators, we add 1 to the min precendence to
2577 * force right-to-left evaluation order. */
2578
2579 if (!LEXER_IS_BINARY_OP_TOKEN (token)
2580 || parser_binary_precedence_table[token - LEXER_FIRST_BINARY_OP] < min_prec_treshold)
2581 {
2582 return;
2583 }
2584
2585 parser_push_result (context_p);
2586 parser_stack_pop_uint8 (context_p);
2587
2588 if (token == LEXER_ASSIGN)
2589 {
2590 opcode = (cbc_opcode_t) context_p->stack_top_uint8;
2591 parser_stack_pop_uint8 (context_p);
2592
2593 int32_t index = -1;
2594 if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
2595 {
2596 JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
2597 || opcode == CBC_ASSIGN_PROP_LITERAL
2598 || opcode == CBC_ASSIGN_PROP_THIS_LITERAL
2599 || opcode == CBC_ASSIGN_LET_CONST
2600 || opcode == CBC_INIT_ARG_OR_CATCH
2601 || opcode == CBC_INIT_LET
2602 || opcode == CBC_INIT_CONST);
2603
2604 index = parser_stack_pop_uint16 (context_p);
2605 }
2606
2607 #if ENABLED (JERRY_ES2015)
2608 if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_CONST))
2609 {
2610 parser_stack_pop_uint8 (context_p);
2611 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
2612 }
2613 #endif /* ENABLED (JERRY_ES2015) */
2614
2615 if (index >= 0)
2616 {
2617 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
2618 && opcode == CBC_ASSIGN_SET_IDENT)
2619 {
2620 JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
2621 CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
2622
2623 context_p->last_cbc.value = (uint16_t) index;
2624 context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
2625 continue;
2626 }
2627
2628 parser_emit_cbc_literal (context_p, (uint16_t) opcode, (uint16_t) index);
2629
2630 if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL
2631 && (context_p->stack_depth >= context_p->stack_limit))
2632 {
2633 /* Stack limit is increased for VM_OC_ASSIGN_PROP_THIS. Needed by vm.c. */
2634 JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
2635
2636 context_p->stack_limit++;
2637
2638 if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
2639 {
2640 parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
2641 }
2642 }
2643 continue;
2644 }
2645 }
2646 else if (LEXER_IS_BINARY_LVALUE_TOKEN (token))
2647 {
2648 parser_stack_push_uint8 (context_p, CBC_ASSIGN);
2649 parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
2650 parser_stack_push_uint8 (context_p, lexer_convert_binary_lvalue_token_to_binary (token));
2651 continue;
2652 }
2653 else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND)
2654 {
2655 parser_branch_t branch;
2656 parser_stack_pop (context_p, &branch, sizeof (parser_branch_t));
2657 parser_set_branch_to_current_position (context_p, &branch);
2658 continue;
2659 }
2660 else
2661 {
2662 opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token);
2663
2664 if (PARSER_IS_PUSH_NUMBER (context_p->last_cbc_opcode))
2665 {
2666 lexer_convert_push_number_to_push_literal (context_p);
2667 }
2668
2669 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
2670 {
2671 JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL));
2672 context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_LITERAL);
2673 continue;
2674 }
2675 else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
2676 {
2677 JERRY_ASSERT (CBC_ARGS_EQ (opcode + CBC_BINARY_WITH_TWO_LITERALS,
2678 CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
2679 context_p->last_cbc_opcode = (uint16_t) (opcode + CBC_BINARY_WITH_TWO_LITERALS);
2680 continue;
2681 }
2682 }
2683 parser_emit_cbc (context_p, (uint16_t) opcode);
2684 }
2685 } /* parser_process_binary_opcodes */
2686
2687 #if ENABLED (JERRY_ES2015)
2688 /**
2689 * End position marker of a pattern.
2690 */
2691 typedef struct
2692 {
2693 scanner_location_t location; /**< end position of the pattern */
2694 lexer_token_t token; /**< token at the end position */
2695 } parser_pattern_end_marker_t;
2696
2697 /**
2698 * Literal index should not be emitted while processing rhs target value
2699 */
2700 #define PARSER_PATTERN_RHS_NO_LIT UINT16_MAX
2701
2702 /**
2703 * Process the target of an initializer pattern.
2704 */
2705 static parser_pattern_end_marker_t
parser_pattern_get_target(parser_context_t * context_p,parser_pattern_flags_t flags)2706 parser_pattern_get_target (parser_context_t *context_p, /**< context */
2707 parser_pattern_flags_t flags) /**< flags */
2708 {
2709 parser_pattern_end_marker_t end_marker;
2710 end_marker.token.type = LEXER_INVALID_PATTERN;
2711 parser_branch_t skip_init;
2712
2713 if (flags & PARSER_PATTERN_TARGET_DEFAULT)
2714 {
2715 JERRY_ASSERT (flags & PARSER_PATTERN_TARGET_ON_STACK);
2716
2717 parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init);
2718 }
2719
2720 if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK)
2721 {
2722 scanner_location_t start_location;
2723
2724 if (context_p->next_scanner_info_p->source_p != context_p->source_p
2725 || context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
2726 || (flags & PARSER_PATTERN_REST_ELEMENT))
2727 {
2728 /* Found invalid pattern, push null value to fake the rhs target. */
2729 parser_emit_cbc (context_p, CBC_PUSH_NULL);
2730 }
2731 else
2732 {
2733 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
2734 scanner_get_location (&start_location, context_p);
2735
2736 scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
2737 scanner_release_next (context_p, sizeof (scanner_location_info_t));
2738 scanner_seek (context_p);
2739 lexer_next_token (context_p);
2740
2741 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2742 scanner_get_location (&(end_marker.location), context_p);
2743 end_marker.token = context_p->token;
2744
2745 scanner_set_location (context_p, &start_location);
2746 scanner_seek (context_p);
2747 parser_flush_cbc (context_p);
2748 }
2749 }
2750
2751 if (flags & PARSER_PATTERN_TARGET_DEFAULT)
2752 {
2753 parser_set_branch_to_current_position (context_p, &skip_init);
2754 }
2755
2756 return end_marker;
2757 } /* parser_pattern_get_target */
2758
2759 /**
2760 * Finalize an assignment/binding pattern.
2761 */
2762 static void
parser_pattern_finalize(parser_context_t * context_p,parser_pattern_flags_t flags,parser_pattern_end_marker_t * end_marker_p)2763 parser_pattern_finalize (parser_context_t *context_p, /**< context */
2764 parser_pattern_flags_t flags, /**< flags */
2765 parser_pattern_end_marker_t *end_marker_p) /**< pattern end position */
2766 {
2767 if ((flags & (PARSER_PATTERN_TARGET_ON_STACK | PARSER_PATTERN_TARGET_DEFAULT)) != PARSER_PATTERN_TARGET_ON_STACK)
2768 {
2769 if (end_marker_p->token.type == LEXER_INVALID_PATTERN)
2770 {
2771 parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
2772 }
2773
2774 scanner_set_location (context_p, &(end_marker_p->location));
2775 context_p->token = end_marker_p->token;
2776 }
2777 else
2778 {
2779 JERRY_ASSERT (!(flags & PARSER_PATTERN_TARGET_DEFAULT));
2780 lexer_next_token (context_p);
2781 }
2782
2783 if ((flags & (PARSER_PATTERN_BINDING | PARSER_PATTERN_NESTED_PATTERN)) == PARSER_PATTERN_BINDING)
2784 {
2785 /* Pop the result of the expression. */
2786 parser_emit_cbc (context_p, CBC_POP);
2787 }
2788
2789 parser_flush_cbc (context_p);
2790 } /* parser_pattern_finalize */
2791
2792 /**
2793 * Emit right-hand-side target value.
2794 */
2795 static void
parser_pattern_emit_rhs(parser_context_t * context_p,uint16_t rhs_opcode,uint16_t literal_index)2796 parser_pattern_emit_rhs (parser_context_t *context_p, /**< context */
2797 uint16_t rhs_opcode, /**< opcode to process the rhs value */
2798 uint16_t literal_index) /**< literal index for object pattern */
2799 {
2800 if (literal_index != PARSER_PATTERN_RHS_NO_LIT)
2801 {
2802 parser_emit_cbc_ext_literal (context_p, rhs_opcode, literal_index);
2803 }
2804 else
2805 {
2806 parser_emit_cbc_ext (context_p, rhs_opcode);
2807 }
2808 } /* parser_pattern_emit_rhs */
2809
2810 /**
2811 * Form an assignment from a pattern.
2812 */
2813 static void
parser_pattern_form_assignment(parser_context_t * context_p,parser_pattern_flags_t flags,uint16_t rhs_opcode,uint16_t literal_index,parser_line_counter_t ident_line_counter)2814 parser_pattern_form_assignment (parser_context_t *context_p, /**< context */
2815 parser_pattern_flags_t flags, /**< flags */
2816 uint16_t rhs_opcode, /**< opcode to process the rhs value */
2817 uint16_t literal_index, /**< literal index for object pattern */
2818 parser_line_counter_t ident_line_counter) /**< identifier line counter */
2819 {
2820 JERRY_UNUSED (ident_line_counter);
2821
2822 parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
2823 uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, flags);
2824
2825 if (flags & PARSER_PATTERN_ARRAY)
2826 {
2827 int32_t stack_adjustment = (CBC_STACK_ADJUST_BASE - (cbc_flags[assign_opcode] >> CBC_STACK_ADJUST_SHIFT));
2828 JERRY_ASSERT (stack_adjustment >= 1 && stack_adjustment <= 3);
2829
2830 rhs_opcode = (uint16_t) (rhs_opcode + stack_adjustment - 1);
2831 }
2832
2833 parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index);
2834
2835 if (context_p->token.type == LEXER_ASSIGN)
2836 {
2837 parser_branch_t skip_init;
2838 lexer_next_token (context_p);
2839 parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init);
2840
2841 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
2842 parser_set_branch_to_current_position (context_p, &skip_init);
2843 }
2844
2845 parser_process_binary_opcodes (context_p, 0);
2846
2847 JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
2848 parser_stack_pop_uint8 (context_p);
2849
2850 #if ENABLED (JERRY_DEBUGGER)
2851 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2852 && ident_line_counter != context_p->last_breakpoint_line)
2853 {
2854 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2855 parser_flush_cbc (context_p);
2856
2857 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, ident_line_counter);
2858
2859 context_p->last_breakpoint_line = ident_line_counter;
2860 }
2861 #endif /* ENABLED (JERRY_DEBUGGER) */
2862
2863 #if ENABLED (JERRY_LINE_INFO)
2864 if (ident_line_counter != context_p->last_line_info_line)
2865 {
2866 parser_emit_line_info (context_p, ident_line_counter, false);
2867 }
2868 #endif /* ENABLED (JERRY_LINE_INFO) */
2869 } /* parser_pattern_form_assignment */
2870
2871 /**
2872 * Parse pattern inside a pattern.
2873 */
2874 static void
parser_pattern_process_nested_pattern(parser_context_t * context_p,parser_pattern_flags_t flags,uint16_t rhs_opcode,uint16_t literal_index)2875 parser_pattern_process_nested_pattern (parser_context_t *context_p, /**< context */
2876 parser_pattern_flags_t flags, /**< flags */
2877 uint16_t rhs_opcode, /**< opcode to process the rhs value */
2878 uint16_t literal_index) /**< literal index for object pattern */
2879 {
2880 JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE);
2881
2882 parser_pattern_flags_t options = (PARSER_PATTERN_NESTED_PATTERN
2883 | PARSER_PATTERN_TARGET_ON_STACK
2884 | (flags & (PARSER_PATTERN_BINDING
2885 | PARSER_PATTERN_LET
2886 | PARSER_PATTERN_CONST
2887 | PARSER_PATTERN_LOCAL
2888 | PARSER_PATTERN_REST_ELEMENT
2889 | PARSER_PATTERN_ARGUMENTS)));
2890
2891 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2892 {
2893 options |= PARSER_PATTERN_TARGET_DEFAULT;
2894 }
2895
2896 parser_pattern_emit_rhs (context_p, rhs_opcode, literal_index);
2897
2898 if (context_p->token.type == LEXER_LEFT_BRACE)
2899 {
2900 parser_parse_object_initializer (context_p, options);
2901 }
2902 else
2903 {
2904 parser_parse_array_initializer (context_p, options);
2905 }
2906
2907 parser_emit_cbc (context_p, CBC_POP);
2908 } /* parser_pattern_process_nested_pattern */
2909
2910 /**
2911 * Process the current {Binding, Assignment}Property
2912 */
2913 static void
parser_pattern_process_assignment(parser_context_t * context_p,parser_pattern_flags_t flags,uint16_t rhs_opcode,uint16_t literal_index,lexer_token_type_t end_type)2914 parser_pattern_process_assignment (parser_context_t *context_p, /**< context */
2915 parser_pattern_flags_t flags, /**< flags */
2916 uint16_t rhs_opcode, /**< opcode to process the rhs value */
2917 uint16_t literal_index, /**< literal index for object pattern */
2918 lexer_token_type_t end_type) /**< end type token */
2919 {
2920 if (context_p->token.type == LEXER_LEFT_BRACE || context_p->token.type == LEXER_LEFT_SQUARE)
2921 {
2922 parser_pattern_process_nested_pattern (context_p, flags, rhs_opcode, literal_index);
2923 return;
2924 }
2925
2926 parser_line_counter_t ident_line_counter = context_p->token.line;
2927
2928 if (flags & PARSER_PATTERN_BINDING)
2929 {
2930 if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
2931 {
2932 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
2933 }
2934
2935 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2936
2937 if (flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST)
2938 && context_p->token.keyword_type == LEXER_KEYW_LET)
2939 {
2940 parser_raise_error (context_p, PARSER_ERR_LEXICAL_LET_BINDING);
2941 }
2942
2943 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2944 {
2945 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
2946 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
2947 }
2948
2949 if (flags & PARSER_PATTERN_ARGUMENTS)
2950 {
2951 if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
2952 {
2953 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
2954 }
2955 context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT;
2956 }
2957 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2958 parser_module_append_export_name (context_p);
2959 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2960
2961 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2962 lexer_next_token (context_p);
2963
2964 if (context_p->token.type != end_type
2965 && context_p->token.type != LEXER_ASSIGN
2966 && context_p->token.type != LEXER_COMMA)
2967 {
2968 parser_raise_error (context_p, PARSER_ERR_ILLEGAL_PROPERTY_IN_DECLARATION);
2969 }
2970 }
2971 else
2972 {
2973 parser_flush_cbc (context_p);
2974 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_LEFT_HAND_SIDE);
2975
2976 if (!PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode) && !PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
2977 {
2978 parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
2979 }
2980 }
2981
2982 parser_pattern_form_assignment (context_p, flags, rhs_opcode, literal_index, ident_line_counter);
2983 } /* parser_pattern_process_assignment */
2984
2985 /**
2986 * Parse array initializer.
2987 */
2988 static void
parser_parse_array_initializer(parser_context_t * context_p,parser_pattern_flags_t flags)2989 parser_parse_array_initializer (parser_context_t *context_p, /**< context */
2990 parser_pattern_flags_t flags) /**< flags */
2991 {
2992 parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags);
2993 flags |= PARSER_PATTERN_ARRAY;
2994
2995 lexer_next_token (context_p);
2996 parser_emit_cbc_ext (context_p, CBC_EXT_GET_ITERATOR);
2997
2998 while (context_p->token.type != LEXER_RIGHT_SQUARE)
2999 {
3000 uint16_t rhs_opcode = CBC_EXT_ITERATOR_STEP;
3001
3002 if (context_p->token.type == LEXER_COMMA)
3003 {
3004 parser_emit_cbc_ext (context_p, rhs_opcode);
3005 parser_emit_cbc (context_p, CBC_POP);
3006 lexer_next_token (context_p);
3007 continue;
3008 }
3009
3010 parser_pattern_flags_t options = flags;
3011
3012 if (context_p->token.type == LEXER_THREE_DOTS)
3013 {
3014 lexer_next_token (context_p);
3015 rhs_opcode = CBC_EXT_REST_INITIALIZER;
3016 options |= PARSER_PATTERN_REST_ELEMENT;
3017 }
3018
3019 parser_pattern_process_assignment (context_p, options, rhs_opcode, PARSER_PATTERN_RHS_NO_LIT, LEXER_RIGHT_SQUARE);
3020
3021 if (context_p->token.type == LEXER_COMMA && rhs_opcode != CBC_EXT_REST_INITIALIZER)
3022 {
3023 lexer_next_token (context_p);
3024 }
3025 else if (context_p->token.type != LEXER_RIGHT_SQUARE)
3026 {
3027 parser_raise_error (context_p, PARSER_ERR_INVALID_DESTRUCTURING_PATTERN);
3028 }
3029 }
3030
3031 /* close the iterator */
3032 parser_emit_cbc_ext (context_p, CBC_EXT_ITERATOR_CLOSE);
3033
3034 parser_pattern_finalize (context_p, flags, &end_pos);
3035 } /* parser_parse_array_initializer */
3036
3037 /**
3038 * Parse object initializer.
3039 */
3040 static void
parser_parse_object_initializer(parser_context_t * context_p,parser_pattern_flags_t flags)3041 parser_parse_object_initializer (parser_context_t *context_p, /**< context */
3042 parser_pattern_flags_t flags) /**< flags */
3043 {
3044 parser_pattern_end_marker_t end_pos = parser_pattern_get_target (context_p, flags);
3045
3046 /* 12.14.5.2: ObjectAssignmentPattern : { } */
3047 if (lexer_check_next_character (context_p, LIT_CHAR_RIGHT_BRACE))
3048 {
3049 parser_emit_cbc_ext (context_p, CBC_EXT_REQUIRE_OBJECT_COERCIBLE);
3050 lexer_consume_next_character (context_p);
3051 parser_pattern_finalize (context_p, flags, &end_pos);
3052 return;
3053 }
3054
3055 while (true)
3056 {
3057 lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_OBJECT_PATTERN);
3058
3059 uint16_t prop_index = context_p->lit_object.index;
3060 parser_line_counter_t start_line = context_p->token.line;
3061 parser_line_counter_t start_column = context_p->token.column;
3062 uint16_t push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP_LITERAL;
3063
3064 if (context_p->token.type == LEXER_RIGHT_BRACE)
3065 {
3066 break;
3067 }
3068 else if (context_p->token.type == LEXER_RIGHT_SQUARE)
3069 {
3070 prop_index = PARSER_PATTERN_RHS_NO_LIT;
3071 push_prop_opcode = CBC_EXT_INITIALIZER_PUSH_PROP;
3072 }
3073
3074 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
3075 {
3076 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
3077 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
3078 }
3079
3080 lexer_next_token (context_p);
3081
3082 if (context_p->token.type == LEXER_COLON)
3083 {
3084 lexer_next_token (context_p);
3085 parser_pattern_process_assignment (context_p, flags, push_prop_opcode, prop_index, LEXER_RIGHT_BRACE);
3086 }
3087 else
3088 {
3089 if (push_prop_opcode == CBC_EXT_INITIALIZER_PUSH_PROP)
3090 {
3091 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
3092 }
3093
3094 if (context_p->token.type != LEXER_RIGHT_BRACE
3095 && context_p->token.type != LEXER_ASSIGN
3096 && context_p->token.type != LEXER_COMMA)
3097 {
3098 parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
3099 }
3100
3101 parser_reparse_as_common_identifier (context_p, start_line, start_column);
3102 lexer_next_token (context_p);
3103
3104 JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE
3105 || context_p->token.type == LEXER_ASSIGN
3106 || context_p->token.type == LEXER_COMMA);
3107
3108 if (flags & PARSER_PATTERN_ARGUMENTS)
3109 {
3110 if (context_p->lit_object.literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
3111 {
3112 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
3113 }
3114 context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_FUNCTION_ARGUMENT;
3115 }
3116
3117 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3118 parser_module_append_export_name (context_p);
3119 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3120
3121 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
3122 parser_pattern_form_assignment (context_p, flags, push_prop_opcode, prop_index, start_line);
3123 }
3124
3125 if (context_p->token.type == LEXER_RIGHT_BRACE)
3126 {
3127 break;
3128 }
3129 else if (context_p->token.type != LEXER_COMMA)
3130 {
3131 parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
3132 }
3133 }
3134
3135 parser_pattern_finalize (context_p, flags, &end_pos);
3136 } /* parser_parse_object_initializer */
3137
3138 /**
3139 * Parse an initializer.
3140 */
3141 void
parser_parse_initializer(parser_context_t * context_p,parser_pattern_flags_t flags)3142 parser_parse_initializer (parser_context_t *context_p, /**< context */
3143 parser_pattern_flags_t flags) /**< flags */
3144 {
3145 if (context_p->token.type == LEXER_LEFT_BRACE)
3146 {
3147 parser_parse_object_initializer (context_p, flags);
3148 }
3149 else
3150 {
3151 JERRY_ASSERT (context_p->token.type == LEXER_LEFT_SQUARE);
3152 parser_parse_array_initializer (context_p, flags);
3153 }
3154 } /* parser_parse_initializer */
3155
3156 /**
3157 * Parse an initializer using the next character.
3158 */
3159 void
parser_parse_initializer_by_next_char(parser_context_t * context_p,parser_pattern_flags_t flags)3160 parser_parse_initializer_by_next_char (parser_context_t *context_p, /**< context */
3161 parser_pattern_flags_t flags) /**< flags */
3162 {
3163 JERRY_ASSERT (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE));
3164
3165 if (lexer_consume_next_character (context_p) == LIT_CHAR_LEFT_BRACE)
3166 {
3167 parser_parse_object_initializer (context_p, flags);
3168 }
3169 else
3170 {
3171 parser_parse_array_initializer (context_p, flags);
3172 }
3173 } /* parser_parse_initializer_by_next_char */
3174
3175 #endif /* ENABLED (JERRY_ES2015) */
3176
3177 /**
3178 * Process ternary expression.
3179 */
3180 static void
parser_process_ternary_expression(parser_context_t * context_p)3181 parser_process_ternary_expression (parser_context_t *context_p) /**< context */
3182 {
3183 JERRY_ASSERT (context_p->token.type == LEXER_QUESTION_MARK);
3184
3185 cbc_opcode_t opcode = CBC_BRANCH_IF_FALSE_FORWARD;
3186 parser_branch_t cond_branch;
3187 parser_branch_t uncond_branch;
3188
3189 parser_push_result (context_p);
3190
3191 if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
3192 {
3193 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
3194 opcode = CBC_BRANCH_IF_TRUE_FORWARD;
3195 }
3196
3197 parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch);
3198
3199 lexer_next_token (context_p);
3200 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
3201 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &uncond_branch);
3202 parser_set_branch_to_current_position (context_p, &cond_branch);
3203
3204 /* Although byte code is constructed for two branches,
3205 * only one of them will be executed. To reflect this
3206 * the stack is manually adjusted. */
3207 JERRY_ASSERT (context_p->stack_depth > 0);
3208 context_p->stack_depth--;
3209
3210 if (context_p->token.type != LEXER_COLON)
3211 {
3212 parser_raise_error (context_p, PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED);
3213 }
3214
3215 lexer_next_token (context_p);
3216
3217 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
3218 parser_set_branch_to_current_position (context_p, &uncond_branch);
3219
3220 /* Last opcode rewrite is not allowed because
3221 * the result may come from the first branch. */
3222 parser_flush_cbc (context_p);
3223
3224 parser_process_binary_opcodes (context_p, 0);
3225 } /* parser_process_ternary_expression */
3226
3227 /**
3228 * Process expression sequence.
3229 */
3230 static void
parser_process_expression_sequence(parser_context_t * context_p)3231 parser_process_expression_sequence (parser_context_t *context_p) /**< context */
3232 {
3233 if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3234 {
3235 parser_emit_cbc (context_p, CBC_POP);
3236 }
3237
3238 if (context_p->stack_top_uint8 == LEXER_LEFT_PAREN)
3239 {
3240 parser_mem_page_t *page_p = context_p->stack.first_p;
3241
3242 JERRY_ASSERT (page_p != NULL);
3243
3244 page_p->bytes[context_p->stack.last_position - 1] = LEXER_COMMA_SEP_LIST;
3245 context_p->stack_top_uint8 = LEXER_COMMA_SEP_LIST;
3246 }
3247
3248 lexer_next_token (context_p);
3249 } /* parser_process_expression_sequence */
3250
3251 /**
3252 * Process group expression.
3253 */
3254 static void
parser_process_group_expression(parser_context_t * context_p,size_t * grouping_level_p)3255 parser_process_group_expression (parser_context_t *context_p, /**< context */
3256 size_t *grouping_level_p) /**< grouping level */
3257 {
3258 JERRY_ASSERT (*grouping_level_p >= PARSER_GROUPING_LEVEL_INCREASE);
3259 (*grouping_level_p) -= PARSER_GROUPING_LEVEL_INCREASE;
3260
3261 if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
3262 {
3263 parser_push_result (context_p);
3264 parser_flush_cbc (context_p);
3265 }
3266
3267 parser_stack_pop_uint8 (context_p);
3268 lexer_next_token (context_p);
3269
3270 #if ENABLED (JERRY_ES2015)
3271 /* Lookahead for anonymous function declaration after '=' token when the assignment base is LHS expression
3272 with a single indentifier in it. e.g.: (a) = function () {} */
3273 if (JERRY_UNLIKELY (context_p->token.type == LEXER_ASSIGN
3274 && PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
3275 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL
3276 && parser_is_assignment_expr (context_p)))
3277 {
3278 parser_stack_push_uint8 (context_p, LEXER_ASSIGN_GROUP_EXPR);
3279 }
3280 #endif /* ENABLED (JERRY_ES2015) */
3281
3282 } /* parser_process_group_expression */
3283
3284 /**
3285 * Parse block expression.
3286 */
3287 void
parser_parse_block_expression(parser_context_t * context_p,int options)3288 parser_parse_block_expression (parser_context_t *context_p, /**< context */
3289 int options) /**< option flags */
3290 {
3291 parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
3292
3293 if (CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3294 {
3295 JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 2));
3296 PARSER_PLUS_EQUAL_U16 (context_p->last_cbc_opcode, 2);
3297 parser_flush_cbc (context_p);
3298 }
3299 else
3300 {
3301 parser_emit_cbc (context_p, CBC_POP_BLOCK);
3302 }
3303 } /* parser_parse_block_expression */
3304
3305 /**
3306 * Parse expression statement.
3307 */
3308 void
parser_parse_expression_statement(parser_context_t * context_p,int options)3309 parser_parse_expression_statement (parser_context_t *context_p, /**< context */
3310 int options) /**< option flags */
3311 {
3312 parser_parse_expression (context_p, options | PARSE_EXPR_NO_PUSH_RESULT);
3313
3314 if (!CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode))
3315 {
3316 parser_emit_cbc (context_p, CBC_POP);
3317 }
3318 } /* parser_parse_expression_statement */
3319
3320 JERRY_STATIC_ASSERT (PARSE_EXPR_LEFT_HAND_SIDE == 0x1,
3321 value_of_parse_expr_left_hand_side_must_be_1);
3322
3323 /**
3324 * Parse expression.
3325 */
3326 void
parser_parse_expression(parser_context_t * context_p,int options)3327 parser_parse_expression (parser_context_t *context_p, /**< context */
3328 int options) /**< option flags */
3329 {
3330 size_t grouping_level = (options & PARSE_EXPR_LEFT_HAND_SIDE);
3331
3332 parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
3333
3334 if (options & PARSE_EXPR_HAS_LITERAL)
3335 {
3336 JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
3337 goto process_unary_expression;
3338 }
3339
3340 while (true)
3341 {
3342 if (parser_parse_unary_expression (context_p, &grouping_level))
3343 {
3344 parser_process_binary_opcodes (context_p, 0);
3345 break;
3346 }
3347
3348 while (true)
3349 {
3350 process_unary_expression:
3351 parser_process_unary_expression (context_p, grouping_level);
3352
3353 if (JERRY_LIKELY (grouping_level != PARSE_EXPR_LEFT_HAND_SIDE))
3354 {
3355 uint8_t min_prec_treshold = 0;
3356
3357 if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
3358 {
3359 min_prec_treshold = parser_binary_precedence_table[context_p->token.type - LEXER_FIRST_BINARY_OP];
3360
3361 #if ENABLED (JERRY_ES2015)
3362 /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND + LEXER_EXPONENTIATION */
3363 if ((min_prec_treshold == PARSER_RIGHT_TO_LEFT_ORDER_EXPONENTIATION)
3364 || (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE
3365 && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE))
3366 {
3367 /* Right-to-left evaluation order. */
3368 min_prec_treshold++;
3369 }
3370 #else /* !ENABLED (JERRY_ES2015) */
3371 /* Check for BINARY_LVALUE tokens + LEXER_LOGICAL_OR + LEXER_LOGICAL_AND */
3372 if (min_prec_treshold <= PARSER_RIGHT_TO_LEFT_ORDER_MAX_PRECEDENCE
3373 && min_prec_treshold != PARSER_RIGHT_TO_LEFT_ORDER_TERNARY_PRECEDENCE)
3374 {
3375 /* Right-to-left evaluation order. */
3376 min_prec_treshold++;
3377 }
3378 #endif /* ENABLED (JERRY_ES2015) */
3379 }
3380
3381 parser_process_binary_opcodes (context_p, min_prec_treshold);
3382 }
3383
3384 if (context_p->token.type == LEXER_RIGHT_PAREN
3385 && (context_p->stack_top_uint8 == LEXER_LEFT_PAREN
3386 || context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST))
3387 {
3388 parser_process_group_expression (context_p, &grouping_level);
3389 continue;
3390 }
3391
3392 break;
3393 }
3394
3395 if (grouping_level == PARSE_EXPR_LEFT_HAND_SIDE)
3396 {
3397 break;
3398 }
3399
3400 if (JERRY_UNLIKELY (context_p->token.type == LEXER_QUESTION_MARK))
3401 {
3402 parser_process_ternary_expression (context_p);
3403
3404 if (context_p->token.type == LEXER_RIGHT_PAREN)
3405 {
3406 goto process_unary_expression;
3407 }
3408 }
3409 else if (LEXER_IS_BINARY_OP_TOKEN (context_p->token.type))
3410 {
3411 parser_append_binary_token (context_p);
3412 lexer_next_token (context_p);
3413 continue;
3414 }
3415
3416 if (JERRY_UNLIKELY (context_p->token.type == LEXER_COMMA)
3417 && (!(options & PARSE_EXPR_NO_COMMA) || grouping_level >= PARSER_GROUPING_LEVEL_INCREASE))
3418 {
3419 parser_process_expression_sequence (context_p);
3420 continue;
3421 }
3422
3423 break;
3424 }
3425
3426 if (grouping_level >= PARSER_GROUPING_LEVEL_INCREASE)
3427 {
3428 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
3429 }
3430
3431 JERRY_ASSERT (context_p->stack_top_uint8 == LEXER_EXPRESSION_START);
3432 parser_stack_pop_uint8 (context_p);
3433
3434 if (!(options & PARSE_EXPR_NO_PUSH_RESULT))
3435 {
3436 parser_push_result (context_p);
3437 }
3438 } /* parser_parse_expression */
3439
3440 /**
3441 * @}
3442 * @}
3443 * @}
3444 */
3445
3446 #endif /* ENABLED (JERRY_PARSER) */
3447