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
24 /** \addtogroup parser Parser
25 * @{
26 *
27 * \addtogroup jsparser JavaScript
28 * @{
29 *
30 * \addtogroup jsparser_stmt Statement parser
31 * @{
32 */
33
34 /**
35 * Parser statement types.
36 *
37 * When a new statement is added, the following
38 * arrays must be updated as well:
39 * - statement_lengths[]
40 * - parser_statement_flags[]
41 */
42 typedef enum
43 {
44 PARSER_STATEMENT_START,
45 PARSER_STATEMENT_BLOCK,
46 #if ENABLED (JERRY_ES2015)
47 PARSER_STATEMENT_BLOCK_SCOPE,
48 PARSER_STATEMENT_PRIVATE_SCOPE,
49 PARSER_STATEMENT_BLOCK_CONTEXT,
50 PARSER_STATEMENT_PRIVATE_CONTEXT,
51 #endif /* ENABLED (JERRY_ES2015) */
52 PARSER_STATEMENT_LABEL,
53 PARSER_STATEMENT_IF,
54 PARSER_STATEMENT_ELSE,
55 PARSER_STATEMENT_SWITCH,
56 PARSER_STATEMENT_SWITCH_NO_DEFAULT,
57 PARSER_STATEMENT_DO_WHILE,
58 PARSER_STATEMENT_WHILE,
59 PARSER_STATEMENT_FOR,
60 PARSER_STATEMENT_FOR_IN,
61 #if ENABLED (JERRY_ES2015)
62 PARSER_STATEMENT_FOR_OF,
63 #endif /* ENABLED (JERRY_ES2015) */
64 PARSER_STATEMENT_WITH,
65 PARSER_STATEMENT_TRY,
66 } parser_statement_type_t;
67
68 /**
69 * Parser statement type flags.
70 */
71 typedef enum
72 {
73 PARSER_STATM_NO_OPTS = 0, /**< no options */
74 PARSER_STATM_SINGLE_STATM = (1 << 0), /**< statment can form single statement context */
75 PARSER_STATM_HAS_BLOCK = (1 << 1), /**< statement always has a code block */
76 PARSER_STATM_BREAK_TARGET = (1 << 2), /**< break target statement */
77 PARSER_STATM_CONTINUE_TARGET = (1 << 3), /**< continue target statement */
78 PARSER_STATM_CONTEXT_BREAK = (1 << 4), /**< uses another instruction form when crosses their borders */
79 } parser_statement_flags_t;
80
81 /**
82 * Parser statement attributes.
83 * Note: the order of the attributes must be keep in sync with parser_statement_type_t
84 */
85 static const uint8_t parser_statement_flags[] =
86 {
87 /* PARSER_STATEMENT_START */
88 PARSER_STATM_HAS_BLOCK,
89 /* PARSER_STATEMENT_BLOCK, */
90 PARSER_STATM_HAS_BLOCK,
91 #if ENABLED (JERRY_ES2015)
92 /* PARSER_STATEMENT_BLOCK_SCOPE, */
93 PARSER_STATM_HAS_BLOCK,
94 /* PARSER_STATEMENT_PRIVATE_SCOPE, */
95 PARSER_STATM_NO_OPTS,
96 /* PARSER_STATEMENT_BLOCK_CONTEXT, */
97 PARSER_STATM_HAS_BLOCK | PARSER_STATM_CONTEXT_BREAK,
98 /* PARSER_STATEMENT_PRIVATE_CONTEXT, */
99 PARSER_STATM_CONTEXT_BREAK,
100 #endif /* ENABLED (JERRY_ES2015) */
101 /* PARSER_STATEMENT_LABEL */
102 PARSER_STATM_SINGLE_STATM,
103 /* PARSER_STATEMENT_IF */
104 PARSER_STATM_SINGLE_STATM,
105 /* PARSER_STATEMENT_ELSE */
106 PARSER_STATM_SINGLE_STATM,
107 /* PARSER_STATEMENT_SWITCH */
108 PARSER_STATM_HAS_BLOCK | PARSER_STATM_BREAK_TARGET,
109 /* PARSER_STATEMENT_SWITCH_NO_DEFAULT */
110 PARSER_STATM_HAS_BLOCK | PARSER_STATM_BREAK_TARGET,
111 /* PARSER_STATEMENT_DO_WHILE */
112 PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM,
113 /* PARSER_STATEMENT_WHILE */
114 PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM,
115 /* PARSER_STATEMENT_FOR */
116 PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM,
117 /* PARSER_STATEMENT_FOR_IN */
118 PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM | PARSER_STATM_CONTEXT_BREAK,
119 #if ENABLED (JERRY_ES2015)
120 /* PARSER_STATEMENT_FOR_OF */
121 PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM | PARSER_STATM_CONTEXT_BREAK,
122 #endif /* ENABLED (JERRY_ES2015) */
123 /* PARSER_STATEMENT_WITH */
124 PARSER_STATM_CONTEXT_BREAK | PARSER_STATM_SINGLE_STATM,
125 /* PARSER_STATEMENT_TRY */
126 PARSER_STATM_HAS_BLOCK | PARSER_STATM_CONTEXT_BREAK
127 };
128
129 #if ENABLED (JERRY_ES2015)
130 /**
131 * Block statement.
132 */
133 typedef struct
134 {
135 uint16_t scope_stack_top; /**< preserved top of scope stack */
136 uint16_t scope_stack_reg_top; /**< preserved top register of scope stack */
137 } parser_block_statement_t;
138
139 /**
140 * Context of block statement.
141 */
142 typedef struct
143 {
144 parser_branch_t branch; /**< branch to the end */
145 } parser_block_context_t;
146
147 #endif /* !ENABLED (JERRY_ES2015) */
148
149 /**
150 * Loop statement.
151 */
152 typedef struct
153 {
154 parser_branch_node_t *branch_list_p; /**< list of breaks and continues targeting this statement */
155 } parser_loop_statement_t;
156
157 /**
158 * Label statement.
159 */
160 typedef struct
161 {
162 lexer_lit_location_t label_ident; /**< name of the label */
163 parser_branch_node_t *break_list_p; /**< list of breaks targeting this label */
164 } parser_label_statement_t;
165
166 /**
167 * If/else statement.
168 */
169 typedef struct
170 {
171 parser_branch_t branch; /**< branch to the end */
172 } parser_if_else_statement_t;
173
174 /**
175 * Switch statement.
176 */
177 typedef struct
178 {
179 parser_branch_t default_branch; /**< branch to the default case */
180 parser_branch_node_t *branch_list_p; /**< branches of case statements */
181 } parser_switch_statement_t;
182
183 /**
184 * Do-while statement.
185 */
186 typedef struct
187 {
188 uint32_t start_offset; /**< start byte code offset */
189 } parser_do_while_statement_t;
190
191 /**
192 * While statement.
193 */
194 typedef struct
195 {
196 parser_branch_t branch; /**< branch to the end */
197 scanner_location_t condition_location; /**< condition part */
198 uint32_t start_offset; /**< start byte code offset */
199 } parser_while_statement_t;
200
201 /**
202 * For statement.
203 */
204 typedef struct
205 {
206 parser_branch_t branch; /**< branch to the end */
207 scanner_location_t condition_location; /**< condition part */
208 scanner_location_t expression_location; /**< expression part */
209 uint32_t start_offset; /**< start byte code offset */
210 } parser_for_statement_t;
211
212 /**
213 * For-in statement.
214 */
215 typedef struct
216 {
217 parser_branch_t branch; /**< branch to the end */
218 uint32_t start_offset; /**< start byte code offset */
219 } parser_for_in_of_statement_t;
220
221 /**
222 * With statement.
223 */
224 typedef struct
225 {
226 parser_branch_t branch; /**< branch to the end */
227 } parser_with_statement_t;
228
229 /**
230 * Lexer token types.
231 */
232 typedef enum
233 {
234 parser_try_block, /**< try block */
235 parser_catch_block, /**< catch block */
236 parser_finally_block, /**< finally block */
237 } parser_try_block_type_t;
238
239 /**
240 * Try statement.
241 */
242 typedef struct
243 {
244 parser_try_block_type_t type; /**< current block type */
245 uint16_t scope_stack_top; /**< current top of scope stack */
246 uint16_t scope_stack_reg_top; /**< current top register of scope stack */
247 parser_branch_t branch; /**< branch to the end of the current block */
248 } parser_try_statement_t;
249
250 /**
251 * Returns the data consumed by a statement. It can be used
252 * to skip undesired frames on the stack during frame search.
253 *
254 * @return size consumed by a statement.
255 */
256 static inline size_t
parser_statement_length(uint8_t type)257 parser_statement_length (uint8_t type) /**< type of statement */
258 {
259 static const uint8_t statement_lengths[] =
260 {
261 /* PARSER_STATEMENT_BLOCK */
262 1,
263 #if ENABLED (JERRY_ES2015)
264 /* PARSER_STATEMENT_BLOCK_SCOPE */
265 (uint8_t) (sizeof (parser_block_statement_t) + 1),
266 /* PARSER_STATEMENT_PRIVATE_SCOPE */
267 (uint8_t) (sizeof (parser_block_statement_t) + 1),
268 /* PARSER_STATEMENT_BLOCK_CONTEXT */
269 (uint8_t) (sizeof (parser_block_statement_t) + sizeof (parser_block_context_t) + 1),
270 /* PARSER_STATEMENT_PRIVATE_CONTEXT */
271 (uint8_t) (sizeof (parser_block_statement_t) + sizeof (parser_block_context_t) + 1),
272 #endif /* ENABLED (JERRY_ES2015) */
273 /* PARSER_STATEMENT_LABEL */
274 (uint8_t) (sizeof (parser_label_statement_t) + 1),
275 /* PARSER_STATEMENT_IF */
276 (uint8_t) (sizeof (parser_if_else_statement_t) + 1),
277 /* PARSER_STATEMENT_ELSE */
278 (uint8_t) (sizeof (parser_if_else_statement_t) + 1),
279 /* PARSER_STATEMENT_SWITCH */
280 (uint8_t) (sizeof (parser_switch_statement_t) + sizeof (parser_loop_statement_t) + 1),
281 /* PARSER_STATEMENT_SWITCH_NO_DEFAULT */
282 (uint8_t) (sizeof (parser_switch_statement_t) + sizeof (parser_loop_statement_t) + 1),
283 /* PARSER_STATEMENT_DO_WHILE */
284 (uint8_t) (sizeof (parser_do_while_statement_t) + sizeof (parser_loop_statement_t) + 1),
285 /* PARSER_STATEMENT_WHILE */
286 (uint8_t) (sizeof (parser_while_statement_t) + sizeof (parser_loop_statement_t) + 1),
287 /* PARSER_STATEMENT_FOR */
288 (uint8_t) (sizeof (parser_for_statement_t) + sizeof (parser_loop_statement_t) + 1),
289 /* PARSER_STATEMENT_FOR_IN */
290 (uint8_t) (sizeof (parser_for_in_of_statement_t) + sizeof (parser_loop_statement_t) + 1),
291 #if ENABLED (JERRY_ES2015)
292 /* PARSER_STATEMENT_FOR_OF */
293 (uint8_t) (sizeof (parser_for_in_of_statement_t) + sizeof (parser_loop_statement_t) + 1),
294 #endif /* ENABLED (JERRY_ES2015) */
295 /* PARSER_STATEMENT_WITH */
296 (uint8_t) (sizeof (parser_with_statement_t) + 1 + 1),
297 /* PARSER_STATEMENT_TRY */
298 (uint8_t) (sizeof (parser_try_statement_t) + 1),
299 };
300
301 JERRY_ASSERT (type >= PARSER_STATEMENT_BLOCK && type <= PARSER_STATEMENT_TRY);
302
303 return statement_lengths[type - PARSER_STATEMENT_BLOCK];
304 } /* parser_statement_length */
305
306 /**
307 * Initialize stack iterator.
308 */
309 static inline void
parser_stack_iterator_init(parser_context_t * context_p,parser_stack_iterator_t * iterator)310 parser_stack_iterator_init (parser_context_t *context_p, /**< context */
311 parser_stack_iterator_t *iterator) /**< iterator */
312 {
313 iterator->current_p = context_p->stack.first_p;
314 iterator->current_position = context_p->stack.last_position;
315 } /* parser_stack_iterator_init */
316
317 /**
318 * Read the next byte from the stack.
319 *
320 * @return byte
321 */
322 static inline uint8_t
parser_stack_iterator_read_uint8(parser_stack_iterator_t * iterator)323 parser_stack_iterator_read_uint8 (parser_stack_iterator_t *iterator) /**< iterator */
324 {
325 JERRY_ASSERT (iterator->current_position > 0 && iterator->current_position <= PARSER_STACK_PAGE_SIZE);
326 return iterator->current_p->bytes[iterator->current_position - 1];
327 } /* parser_stack_iterator_read_uint8 */
328
329 /**
330 * Change last byte of the stack.
331 */
332 static inline void
parser_stack_change_last_uint8(parser_context_t * context_p,uint8_t new_value)333 parser_stack_change_last_uint8 (parser_context_t *context_p, /**< context */
334 uint8_t new_value) /**< new value */
335 {
336 parser_mem_page_t *page_p = context_p->stack.first_p;
337
338 JERRY_ASSERT (page_p != NULL
339 && context_p->stack_top_uint8 == page_p->bytes[context_p->stack.last_position - 1]);
340
341 page_p->bytes[context_p->stack.last_position - 1] = new_value;
342 context_p->stack_top_uint8 = new_value;
343 } /* parser_stack_change_last_uint8 */
344
345 /**
346 * Parse expression enclosed in parens.
347 */
348 static inline void
parser_parse_enclosed_expr(parser_context_t * context_p)349 parser_parse_enclosed_expr (parser_context_t *context_p) /**< context */
350 {
351 lexer_next_token (context_p);
352
353 if (context_p->token.type != LEXER_LEFT_PAREN)
354 {
355 parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
356 }
357
358 lexer_next_token (context_p);
359 parser_parse_expression (context_p, PARSE_EXPR);
360
361 if (context_p->token.type != LEXER_RIGHT_PAREN)
362 {
363 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
364 }
365 lexer_next_token (context_p);
366 } /* parser_parse_enclosed_expr */
367
368 #if ENABLED (JERRY_ES2015)
369
370 /**
371 * Create a block context.
372 *
373 * @return true - when a context is created, false - otherwise
374 */
375 static bool
parser_push_block_context(parser_context_t * context_p,bool is_private)376 parser_push_block_context (parser_context_t *context_p, /**< context */
377 bool is_private) /**< is private (bound to a statement) context */
378 {
379 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
380
381 parser_block_statement_t block_statement;
382 block_statement.scope_stack_top = context_p->scope_stack_top;
383 block_statement.scope_stack_reg_top = context_p->scope_stack_reg_top;
384
385 bool is_context_needed = false;
386
387 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
388 {
389 parser_block_context_t block_context;
390
391 #ifndef JERRY_NDEBUG
392 PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_BLOCK_CONTEXT_STACK_ALLOCATION);
393 #endif /* !JERRY_NDEBUG */
394
395 parser_emit_cbc_forward_branch (context_p,
396 CBC_BLOCK_CREATE_CONTEXT,
397 &block_context.branch);
398 parser_stack_push (context_p, &block_context, sizeof (parser_block_context_t));
399 is_context_needed = true;
400 }
401
402 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
403 parser_stack_push (context_p, &block_statement, sizeof (parser_block_statement_t));
404
405 uint8_t statement_type;
406
407 if (is_private)
408 {
409 statement_type = (is_context_needed ? PARSER_STATEMENT_PRIVATE_CONTEXT : PARSER_STATEMENT_PRIVATE_SCOPE);
410 }
411 else
412 {
413 statement_type = (is_context_needed ? PARSER_STATEMENT_BLOCK_CONTEXT : PARSER_STATEMENT_BLOCK_SCOPE);
414 }
415
416 parser_stack_push_uint8 (context_p, statement_type);
417
418 return is_context_needed;
419 } /* parser_push_block_context */
420
421 /**
422 * Pop block context.
423 */
424 static void
parser_pop_block_context(parser_context_t * context_p)425 parser_pop_block_context (parser_context_t *context_p) /**< context */
426 {
427 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_SCOPE
428 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
429 || context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_CONTEXT
430 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT);
431
432 uint8_t type = context_p->stack_top_uint8;
433
434 parser_block_statement_t block_statement;
435
436 parser_stack_pop_uint8 (context_p);
437 parser_stack_pop (context_p, &block_statement, sizeof (parser_block_statement_t));
438
439 context_p->scope_stack_top = block_statement.scope_stack_top;
440 context_p->scope_stack_reg_top = block_statement.scope_stack_reg_top;
441
442 if (type == PARSER_STATEMENT_BLOCK_CONTEXT || type == PARSER_STATEMENT_PRIVATE_CONTEXT)
443 {
444 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_BLOCK_CONTEXT_STACK_ALLOCATION);
445 #ifndef JERRY_NDEBUG
446 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_BLOCK_CONTEXT_STACK_ALLOCATION);
447 #endif /* !JERRY_NDEBUG */
448
449 parser_block_context_t block_context;
450 parser_stack_pop (context_p, &block_context, sizeof (parser_block_context_t));
451
452 parser_emit_cbc (context_p, CBC_CONTEXT_END);
453 parser_set_branch_to_current_position (context_p, &block_context.branch);
454 }
455
456 parser_stack_iterator_init (context_p, &context_p->last_statement);
457 } /* parser_pop_block_context */
458
459 /**
460 * Validate lexical context for a declaration.
461 */
462 static void
parser_validate_lexical_context(parser_context_t * context_p)463 parser_validate_lexical_context (parser_context_t *context_p) /**< context */
464 {
465 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_LET
466 || context_p->token.type == LEXER_KEYW_CONST
467 || context_p->token.type == LEXER_KEYW_CLASS);
468
469 if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
470 {
471 parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
472 }
473 } /* parser_validate_lexical_context */
474 #endif /* ENABLED (JERRY_ES2015) */
475
476 /**
477 * Parse var statement.
478 */
479 static void
parser_parse_var_statement(parser_context_t * context_p)480 parser_parse_var_statement (parser_context_t *context_p) /**< context */
481 {
482 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_VAR
483 || context_p->token.type == LEXER_KEYW_LET
484 || context_p->token.type == LEXER_KEYW_CONST);
485
486 #if ENABLED (JERRY_ES2015)
487 uint8_t declaration_type = context_p->token.type;
488
489 if (declaration_type != LEXER_KEYW_VAR)
490 {
491 parser_validate_lexical_context (context_p);
492 }
493 #endif /* ENABLED (JERRY_ES2015) */
494
495 while (true)
496 {
497 #if ENABLED (JERRY_ES2015)
498 if (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE))
499 {
500 parser_pattern_flags_t flags = PARSER_PATTERN_BINDING;
501
502 if (declaration_type == LEXER_KEYW_LET)
503 {
504 flags |= PARSER_PATTERN_LET;
505 }
506 else if (declaration_type == LEXER_KEYW_CONST)
507 {
508 flags |= PARSER_PATTERN_CONST;
509 }
510
511 parser_parse_initializer_by_next_char (context_p, flags);
512 }
513 else
514 {
515 #endif /* ENABLED (JERRY_ES2015) */
516 lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
517 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
518 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
519
520 #if ENABLED (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO)
521 parser_line_counter_t ident_line_counter = context_p->token.line;
522 #endif /* ENABLED (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO) */
523
524 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
525 parser_module_append_export_name (context_p);
526 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
527
528 #if ENABLED (JERRY_ES2015)
529 if (declaration_type != LEXER_KEYW_VAR
530 && context_p->token.keyword_type == LEXER_KEYW_LET)
531 {
532 parser_raise_error (context_p, PARSER_ERR_LEXICAL_LET_BINDING);
533 }
534
535 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
536 {
537 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED);
538 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
539 }
540 #endif /* ENABLED (JERRY_ES2015) */
541
542 lexer_next_token (context_p);
543
544 if (context_p->token.type == LEXER_ASSIGN)
545 {
546 #if ENABLED (JERRY_DEBUGGER)
547 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
548 && ident_line_counter != context_p->last_breakpoint_line)
549 {
550 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
551 parser_flush_cbc (context_p);
552
553 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, ident_line_counter);
554
555 context_p->last_breakpoint_line = ident_line_counter;
556 }
557 #endif /* ENABLED (JERRY_DEBUGGER) */
558
559 #if ENABLED (JERRY_LINE_INFO)
560 if (ident_line_counter != context_p->last_line_info_line)
561 {
562 parser_emit_line_info (context_p, ident_line_counter, false);
563 }
564 #endif /* ENABLED (JERRY_LINE_INFO) */
565
566 uint16_t index = context_p->lit_object.index;
567
568 lexer_next_token (context_p);
569 parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
570
571 cbc_opcode_t opcode = CBC_ASSIGN_SET_IDENT;
572
573 #if ENABLED (JERRY_ES2015)
574 if (declaration_type != LEXER_KEYW_VAR
575 && (index < PARSER_REGISTER_START))
576 {
577 opcode = CBC_INIT_LET;
578
579 if (scanner_literal_is_created (context_p, index))
580 {
581 opcode = CBC_ASSIGN_LET_CONST;
582 }
583 else if (declaration_type == LEXER_KEYW_CONST)
584 {
585 opcode = CBC_INIT_CONST;
586 }
587 }
588 #endif /* ENABLED (JERRY_ES2015) */
589
590 parser_emit_cbc_literal (context_p, (uint16_t) opcode, index);
591 }
592 #if ENABLED (JERRY_ES2015)
593 else if (declaration_type == LEXER_KEYW_LET)
594 {
595 parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED);
596
597 uint16_t index = context_p->lit_object.index;
598 cbc_opcode_t opcode = CBC_MOV_IDENT;
599
600 if (index < PARSER_REGISTER_START)
601 {
602 opcode = (scanner_literal_is_created (context_p, index) ? CBC_ASSIGN_LET_CONST
603 : CBC_INIT_LET);
604 }
605
606 parser_emit_cbc_literal (context_p, (uint16_t) opcode, index);
607 }
608 else if (declaration_type == LEXER_KEYW_CONST)
609 {
610 parser_raise_error (context_p, PARSER_ERR_MISSING_ASSIGN_AFTER_CONST);
611 }
612 }
613 #endif /* ENABLED (JERRY_ES2015) */
614
615 if (context_p->token.type != LEXER_COMMA)
616 {
617 break;
618 }
619 }
620
621 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
622 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
623 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
624 } /* parser_parse_var_statement */
625
626 /**
627 * Parse function statement.
628 */
629 static void
parser_parse_function_statement(parser_context_t * context_p)630 parser_parse_function_statement (parser_context_t *context_p) /**< context */
631 {
632 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FUNCTION);
633
634 #if ENABLED (JERRY_ES2015)
635 if (JERRY_UNLIKELY (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM))
636 {
637 if (context_p->status_flags & PARSER_IS_STRICT)
638 {
639 parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
640 }
641
642 if (context_p->stack_top_uint8 == PARSER_STATEMENT_IF
643 || context_p->stack_top_uint8 == PARSER_STATEMENT_ELSE)
644 {
645 /* There must be a parser error later if this check fails. */
646 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
647 {
648 parser_push_block_context (context_p, true);
649 }
650 }
651 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_LABEL)
652 {
653 parser_stack_iterator_t iterator;
654 parser_stack_iterator_init (context_p, &iterator);
655 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t) + 1);
656
657 while (true)
658 {
659 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
660
661 if (type == PARSER_STATEMENT_LABEL)
662 {
663 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t) + 1);
664 continue;
665 }
666
667 if (parser_statement_flags[type] & PARSER_STATM_HAS_BLOCK)
668 {
669 break;
670 }
671
672 parser_raise_error (context_p, PARSER_ERR_LABELLED_FUNC_NOT_IN_BLOCK);
673 }
674 }
675 else
676 {
677 parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
678 }
679 }
680 #endif /* ENABLED (JERRY_ES2015) */
681
682 #if ENABLED (JERRY_DEBUGGER)
683 parser_line_counter_t debugger_line = context_p->token.line;
684 parser_line_counter_t debugger_column = context_p->token.column;
685 #endif /* ENABLED (JERRY_DEBUGGER) */
686
687 #if ENABLED (JERRY_ES2015)
688 bool is_generator_function = false;
689
690 if (lexer_consume_generator (context_p))
691 {
692 is_generator_function = true;
693 }
694 #endif /* ENABLED (JERRY_ES2015) */
695
696 lexer_expect_identifier (context_p, LEXER_NEW_IDENT_LITERAL);
697 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
698 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
699
700 #if ENABLED (JERRY_ES2015)
701 if (context_p->next_scanner_info_p->source_p == context_p->source_p
702 && context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED)
703 {
704 parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED);
705 }
706 #endif /* ENABLED (JERRY_ES2015) */
707
708 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
709 parser_module_append_export_name (context_p);
710 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
711 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
712
713 uint32_t status_flags = PARSER_FUNCTION_CLOSURE;
714
715 if (context_p->token.keyword_type >= LEXER_FIRST_NON_STRICT_ARGUMENTS)
716 {
717 status_flags |= PARSER_HAS_NON_STRICT_ARG;
718 }
719
720 #if ENABLED (JERRY_ES2015)
721 if (is_generator_function)
722 {
723 status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
724 }
725
726 if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC)
727 {
728 status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
729 }
730 #endif /* ENABLED (JERRY_ES2015) */
731
732 #if ENABLED (JERRY_DEBUGGER)
733 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
734 {
735 lexer_literal_t *name_p = context_p->lit_object.literal_p;
736 jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME,
737 JERRY_DEBUGGER_NO_SUBTYPE,
738 name_p->u.char_p,
739 name_p->prop.length);
740
741 /* Reset token position for the function. */
742 context_p->token.line = debugger_line;
743 context_p->token.column = debugger_column;
744 }
745 #endif /* ENABLED (JERRY_DEBUGGER) */
746
747 JERRY_ASSERT (context_p->scope_stack_top >= 2);
748 parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top - 2;
749
750 uint16_t literal_index = context_p->lit_object.index;
751
752 while (literal_index != scope_stack_p->map_from)
753 {
754 scope_stack_p--;
755
756 JERRY_ASSERT (scope_stack_p >= context_p->scope_stack_p);
757 }
758
759 JERRY_ASSERT (scope_stack_p[1].map_from == PARSER_SCOPE_STACK_FUNC);
760
761 #if ENABLED (JERRY_ES2015)
762 if (!(context_p->status_flags & PARSER_IS_STRICT)
763 && (scope_stack_p >= context_p->scope_stack_p + context_p->scope_stack_global_end))
764 {
765 bool copy_value = true;
766
767 parser_scope_stack_t *stack_p = context_p->scope_stack_p;
768
769 while (stack_p < scope_stack_p)
770 {
771 if (literal_index == stack_p->map_from
772 && (stack_p->map_to & PARSER_SCOPE_STACK_NO_FUNCTION_COPY))
773 {
774 copy_value = false;
775 break;
776 }
777 stack_p++;
778 }
779
780 if (copy_value)
781 {
782 stack_p = context_p->scope_stack_p;
783
784 while (stack_p < scope_stack_p)
785 {
786 if (literal_index == stack_p->map_from)
787 {
788 JERRY_ASSERT (!(stack_p->map_to & PARSER_SCOPE_STACK_NO_FUNCTION_COPY));
789
790 uint16_t map_to = scanner_decode_map_to (stack_p);
791 uint16_t opcode = ((map_to >= PARSER_REGISTER_START) ? CBC_ASSIGN_LITERAL_SET_IDENT
792 : CBC_COPY_TO_GLOBAL);
793
794 parser_emit_cbc_literal_value (context_p,
795 opcode,
796 scanner_decode_map_to (scope_stack_p),
797 map_to);
798 break;
799 }
800 stack_p++;
801 }
802
803 parser_flush_cbc (context_p);
804 }
805
806 if (JERRY_UNLIKELY (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
807 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT))
808 {
809 parser_pop_block_context (context_p);
810 }
811 }
812 #endif /* ENABLED (JERRY_ES2015) */
813
814 lexer_literal_t *literal_p = PARSER_GET_LITERAL ((size_t) scope_stack_p[1].map_to);
815
816 JERRY_ASSERT ((literal_p->type == LEXER_UNUSED_LITERAL || literal_p->type == LEXER_FUNCTION_LITERAL)
817 && literal_p->status_flags == 0);
818
819 ecma_compiled_code_t *compiled_code_p = parser_parse_function (context_p, status_flags);
820
821 if (literal_p->type == LEXER_FUNCTION_LITERAL)
822 {
823 ecma_bytecode_deref (literal_p->u.bytecode_p);
824 }
825
826 literal_p->u.bytecode_p = compiled_code_p;
827 literal_p->type = LEXER_FUNCTION_LITERAL;
828
829 lexer_next_token (context_p);
830 } /* parser_parse_function_statement */
831
832 /**
833 * Parse if statement (starting part).
834 */
835 static void
parser_parse_if_statement_start(parser_context_t * context_p)836 parser_parse_if_statement_start (parser_context_t *context_p) /**< context */
837 {
838 parser_if_else_statement_t if_statement;
839
840 parser_parse_enclosed_expr (context_p);
841
842 parser_emit_cbc_forward_branch (context_p,
843 CBC_BRANCH_IF_FALSE_FORWARD,
844 &if_statement.branch);
845
846 parser_stack_push (context_p, &if_statement, sizeof (parser_if_else_statement_t));
847 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_IF);
848 parser_stack_iterator_init (context_p, &context_p->last_statement);
849 } /* parser_parse_if_statement_start */
850
851 /**
852 * Parse if statement (ending part).
853 *
854 * @return true - if parsing an 'else' statement
855 * false - otherwise
856 */
857 static bool
parser_parse_if_statement_end(parser_context_t * context_p)858 parser_parse_if_statement_end (parser_context_t *context_p) /**< context */
859 {
860 parser_if_else_statement_t if_statement;
861 parser_if_else_statement_t else_statement;
862 parser_stack_iterator_t iterator;
863
864 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_IF);
865
866 if (context_p->token.type != LEXER_KEYW_ELSE)
867 {
868 parser_stack_pop_uint8 (context_p);
869 parser_stack_pop (context_p, &if_statement, sizeof (parser_if_else_statement_t));
870 parser_stack_iterator_init (context_p, &context_p->last_statement);
871
872 parser_set_branch_to_current_position (context_p, &if_statement.branch);
873
874 return false;
875 }
876
877 parser_stack_change_last_uint8 (context_p, PARSER_STATEMENT_ELSE);
878 parser_stack_iterator_init (context_p, &iterator);
879 parser_stack_iterator_skip (&iterator, 1);
880 parser_stack_iterator_read (&iterator, &if_statement, sizeof (parser_if_else_statement_t));
881
882 parser_emit_cbc_forward_branch (context_p,
883 CBC_JUMP_FORWARD,
884 &else_statement.branch);
885
886 parser_set_branch_to_current_position (context_p, &if_statement.branch);
887
888 parser_stack_iterator_write (&iterator, &else_statement, sizeof (parser_if_else_statement_t));
889
890 lexer_next_token (context_p);
891 return true;
892 } /* parser_parse_if_statement_end */
893
894 /**
895 * Parse with statement (starting part).
896 */
897 static void
parser_parse_with_statement_start(parser_context_t * context_p)898 parser_parse_with_statement_start (parser_context_t *context_p) /**< context */
899 {
900 parser_with_statement_t with_statement;
901
902 if (context_p->status_flags & PARSER_IS_STRICT)
903 {
904 parser_raise_error (context_p, PARSER_ERR_WITH_NOT_ALLOWED);
905 }
906
907 parser_parse_enclosed_expr (context_p);
908
909 #ifndef JERRY_NDEBUG
910 PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
911 #endif /* !JERRY_NDEBUG */
912
913 uint8_t inside_with = (context_p->status_flags & PARSER_INSIDE_WITH) != 0;
914
915 context_p->status_flags |= PARSER_INSIDE_WITH;
916 parser_emit_cbc_ext_forward_branch (context_p,
917 CBC_EXT_WITH_CREATE_CONTEXT,
918 &with_statement.branch);
919
920 parser_stack_push (context_p, &with_statement, sizeof (parser_with_statement_t));
921 parser_stack_push_uint8 (context_p, inside_with);
922 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_WITH);
923 parser_stack_iterator_init (context_p, &context_p->last_statement);
924 } /* parser_parse_with_statement_start */
925
926 /**
927 * Parse with statement (ending part).
928 */
929 static void
parser_parse_with_statement_end(parser_context_t * context_p)930 parser_parse_with_statement_end (parser_context_t *context_p) /**< context */
931 {
932 parser_with_statement_t with_statement;
933
934 JERRY_ASSERT (context_p->status_flags & PARSER_INSIDE_WITH);
935
936 parser_stack_pop_uint8 (context_p);
937
938 if (!context_p->stack_top_uint8)
939 {
940 context_p->status_flags &= (uint32_t) ~PARSER_INSIDE_WITH;
941 }
942
943 parser_stack_pop_uint8 (context_p);
944 parser_stack_pop (context_p, &with_statement, sizeof (parser_with_statement_t));
945 parser_stack_iterator_init (context_p, &context_p->last_statement);
946
947 parser_flush_cbc (context_p);
948 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
949 #ifndef JERRY_NDEBUG
950 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
951 #endif /* !JERRY_NDEBUG */
952
953 parser_emit_cbc (context_p, CBC_CONTEXT_END);
954 parser_set_branch_to_current_position (context_p, &with_statement.branch);
955 } /* parser_parse_with_statement_end */
956
957 /**
958 * Parse do-while statement (ending part).
959 */
960 static void
parser_parse_do_while_statement_end(parser_context_t * context_p)961 parser_parse_do_while_statement_end (parser_context_t *context_p) /**< context */
962 {
963 parser_loop_statement_t loop;
964
965 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_DO_WHILE);
966
967 if (context_p->token.type != LEXER_KEYW_WHILE)
968 {
969 parser_raise_error (context_p, PARSER_ERR_WHILE_EXPECTED);
970 }
971
972 parser_stack_iterator_t iterator;
973 parser_stack_iterator_init (context_p, &iterator);
974
975 parser_stack_iterator_skip (&iterator, 1);
976 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
977
978 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
979
980 JERRY_ASSERT (context_p->next_scanner_info_p->source_p != context_p->source_p);
981
982 parser_parse_enclosed_expr (context_p);
983
984 if (context_p->last_cbc_opcode != CBC_PUSH_FALSE)
985 {
986 cbc_opcode_t opcode = CBC_BRANCH_IF_TRUE_BACKWARD;
987 if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
988 {
989 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
990 opcode = CBC_BRANCH_IF_FALSE_BACKWARD;
991 }
992 else if (context_p->last_cbc_opcode == CBC_PUSH_TRUE)
993 {
994 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
995 opcode = CBC_JUMP_BACKWARD;
996 }
997
998 parser_do_while_statement_t do_while_statement;
999 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
1000 parser_stack_iterator_read (&iterator, &do_while_statement, sizeof (parser_do_while_statement_t));
1001
1002 parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, do_while_statement.start_offset);
1003 }
1004 else
1005 {
1006 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1007 }
1008
1009 parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_do_while_statement_t));
1010 parser_stack_iterator_init (context_p, &context_p->last_statement);
1011
1012 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
1013 } /* parser_parse_do_while_statement_end */
1014
1015 /**
1016 * Parse while statement (starting part).
1017 */
1018 static void
parser_parse_while_statement_start(parser_context_t * context_p)1019 parser_parse_while_statement_start (parser_context_t *context_p) /**< context */
1020 {
1021 parser_while_statement_t while_statement;
1022 parser_loop_statement_t loop;
1023
1024 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_WHILE);
1025 lexer_next_token (context_p);
1026
1027 if (context_p->token.type != LEXER_LEFT_PAREN)
1028 {
1029 parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
1030 }
1031
1032 JERRY_ASSERT (context_p->next_scanner_info_p->source_p != context_p->source_p
1033 || context_p->next_scanner_info_p->type == SCANNER_TYPE_WHILE);
1034
1035 if (context_p->next_scanner_info_p->source_p != context_p->source_p)
1036 {
1037 /* The prescanner couldn't find the end of the while condition. */
1038 lexer_next_token (context_p);
1039 parser_parse_expression (context_p, PARSE_EXPR);
1040
1041 JERRY_ASSERT (context_p->token.type != LEXER_RIGHT_PAREN);
1042 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1043 }
1044
1045 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &while_statement.branch);
1046
1047 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1048
1049 while_statement.start_offset = context_p->byte_code_size;
1050 scanner_get_location (&while_statement.condition_location, context_p);
1051
1052 scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
1053 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1054 scanner_seek (context_p);
1055 lexer_next_token (context_p);
1056
1057 loop.branch_list_p = NULL;
1058
1059 parser_stack_push (context_p, &while_statement, sizeof (parser_while_statement_t));
1060 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1061 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_WHILE);
1062 parser_stack_iterator_init (context_p, &context_p->last_statement);
1063 } /* parser_parse_while_statement_start */
1064
1065 /**
1066 * Parse while statement (ending part).
1067 */
1068 static void JERRY_ATTR_NOINLINE
parser_parse_while_statement_end(parser_context_t * context_p)1069 parser_parse_while_statement_end (parser_context_t *context_p) /**< context */
1070 {
1071 parser_while_statement_t while_statement;
1072 parser_loop_statement_t loop;
1073 lexer_token_t current_token;
1074 scanner_location_t location;
1075 cbc_opcode_t opcode;
1076
1077 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_WHILE);
1078
1079 parser_stack_iterator_t iterator;
1080 parser_stack_iterator_init (context_p, &iterator);
1081
1082 parser_stack_iterator_skip (&iterator, 1);
1083 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
1084 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
1085 parser_stack_iterator_read (&iterator, &while_statement, sizeof (parser_while_statement_t));
1086
1087 scanner_get_location (&location, context_p);
1088 current_token = context_p->token;
1089
1090 parser_set_branch_to_current_position (context_p, &while_statement.branch);
1091 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
1092
1093 scanner_set_location (context_p, &while_statement.condition_location);
1094 scanner_seek (context_p);
1095 lexer_next_token (context_p);
1096
1097 parser_parse_expression (context_p, PARSE_EXPR);
1098 if (context_p->token.type != LEXER_RIGHT_PAREN)
1099 {
1100 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1101 }
1102
1103 opcode = CBC_BRANCH_IF_TRUE_BACKWARD;
1104 if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
1105 {
1106 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1107 opcode = CBC_BRANCH_IF_FALSE_BACKWARD;
1108 }
1109 else if (context_p->last_cbc_opcode == CBC_PUSH_TRUE)
1110 {
1111 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1112 opcode = CBC_JUMP_BACKWARD;
1113 }
1114
1115 parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_while_statement_t));
1116 parser_stack_iterator_init (context_p, &context_p->last_statement);
1117
1118 parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, while_statement.start_offset);
1119 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
1120
1121 /* Calling scanner_seek is unnecessary because all
1122 * info blocks inside the while statement should be processed. */
1123 scanner_set_location (context_p, &location);
1124 context_p->token = current_token;
1125 } /* parser_parse_while_statement_end */
1126
1127 /**
1128 * Check whether the opcode is a valid LeftHandSide expression
1129 * and convert it back to an assignment.
1130 *
1131 * @return the compatible assignment opcode
1132 */
1133 static uint16_t
parser_check_left_hand_side_expression(parser_context_t * context_p,uint16_t opcode)1134 parser_check_left_hand_side_expression (parser_context_t *context_p, /**< context */
1135 uint16_t opcode) /**< opcode to check */
1136 {
1137 if (opcode == CBC_PUSH_LITERAL
1138 && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
1139 {
1140 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1141 return CBC_ASSIGN_SET_IDENT;
1142 }
1143 else if (opcode == CBC_PUSH_PROP)
1144 {
1145 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1146 return CBC_ASSIGN;
1147 }
1148 else if (opcode == CBC_PUSH_PROP_LITERAL)
1149 {
1150 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1151 return CBC_ASSIGN_PROP_LITERAL;
1152 }
1153 else if (opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
1154 {
1155 context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
1156 return CBC_ASSIGN;
1157 }
1158 else if (opcode == CBC_PUSH_PROP_THIS_LITERAL)
1159 {
1160 context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
1161 return CBC_ASSIGN;
1162 }
1163 else
1164 {
1165 /* Invalid LeftHandSide expression. */
1166 parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
1167 return CBC_ASSIGN;
1168 }
1169
1170 return opcode;
1171 } /* parser_check_left_hand_side_expression */
1172
1173 /**
1174 * Parse for statement (starting part).
1175 */
1176 static void
parser_parse_for_statement_start(parser_context_t * context_p)1177 parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
1178 {
1179 parser_loop_statement_t loop;
1180
1181 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FOR);
1182 lexer_next_token (context_p);
1183
1184 if (context_p->token.type != LEXER_LEFT_PAREN)
1185 {
1186 parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
1187 }
1188
1189 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1190 {
1191 parser_for_in_of_statement_t for_in_of_statement;
1192 scanner_location_t start_location, end_location;
1193
1194 #if ENABLED (JERRY_ES2015)
1195 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR_IN
1196 || context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR_OF);
1197
1198 bool is_for_in = (context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR_IN);
1199 end_location = ((scanner_location_info_t *) context_p->next_scanner_info_p)->location;
1200
1201 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1202
1203 scanner_get_location (&start_location, context_p);
1204 lexer_next_token (context_p);
1205
1206 uint8_t token_type = LEXER_EOS;
1207 bool has_context = false;
1208
1209 if (context_p->token.type == LEXER_KEYW_VAR
1210 || context_p->token.type == LEXER_KEYW_LET
1211 || context_p->token.type == LEXER_KEYW_CONST)
1212 {
1213 token_type = context_p->token.type;
1214 has_context = context_p->next_scanner_info_p->source_p == context_p->source_p;
1215 JERRY_ASSERT (!has_context || context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
1216 scanner_get_location (&start_location, context_p);
1217
1218 /* TODO: remove this after the pre-scanner supports strict mode detection. */
1219 if (context_p->next_scanner_info_p->source_p == context_p->source_p
1220 && context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
1221 {
1222 scanner_release_next (context_p, sizeof (scanner_info_t));
1223 }
1224 }
1225 else if (context_p->token.type == LEXER_LITERAL && lexer_token_is_let (context_p))
1226 {
1227 if (context_p->next_scanner_info_p->source_p == context_p->source_p
1228 && context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
1229 {
1230 scanner_release_next (context_p, sizeof (scanner_info_t));
1231 }
1232 else
1233 {
1234 token_type = LEXER_KEYW_LET;
1235 has_context = (context_p->next_scanner_info_p->source_p == context_p->source_p);
1236 scanner_get_location (&start_location, context_p);
1237 }
1238 }
1239
1240 if (has_context)
1241 {
1242 has_context = parser_push_block_context (context_p, true);
1243 }
1244
1245 scanner_set_location (context_p, &end_location);
1246 #else /* !ENABLED (JERRY_ES2015) */
1247 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR_IN);
1248
1249 bool is_for_in = true;
1250 scanner_get_location (&start_location, context_p);
1251
1252 scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
1253 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1254 #endif /* ENABLED (JERRY_ES2015) */
1255
1256 /* The length of both 'in' and 'of' is two. */
1257 const uint8_t *source_end_p = context_p->source_p - 2;
1258
1259 scanner_seek (context_p);
1260 lexer_next_token (context_p);
1261 parser_parse_expression (context_p, PARSE_EXPR);
1262
1263 if (context_p->token.type != LEXER_RIGHT_PAREN)
1264 {
1265 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1266 }
1267
1268 #ifndef JERRY_NDEBUG
1269 PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth,
1270 is_for_in ? PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION
1271 : PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
1272 #endif /* !JERRY_NDEBUG */
1273
1274 parser_emit_cbc_ext_forward_branch (context_p,
1275 is_for_in ? CBC_EXT_FOR_IN_CREATE_CONTEXT
1276 : CBC_EXT_FOR_OF_CREATE_CONTEXT,
1277 &for_in_of_statement.branch);
1278
1279 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1280 for_in_of_statement.start_offset = context_p->byte_code_size;
1281
1282 #if ENABLED (JERRY_ES2015)
1283 if (has_context)
1284 {
1285 parser_emit_cbc_ext (context_p, CBC_EXT_CLONE_CONTEXT);
1286 }
1287 #endif /* ENABLED (JERRY_ES2015) */
1288
1289 /* The expression parser must not read the 'in' or 'of' tokens. */
1290 scanner_get_location (&end_location, context_p);
1291 scanner_set_location (context_p, &start_location);
1292
1293 const uint8_t *original_source_end_p = context_p->source_end_p;
1294 context_p->source_end_p = source_end_p;
1295 scanner_seek (context_p);
1296
1297 #if ENABLED (JERRY_ES2015)
1298 if (token_type == LEXER_EOS)
1299 {
1300 lexer_next_token (context_p);
1301 }
1302 #else /* !ENABLED (JERRY_ES2015) */
1303 lexer_next_token (context_p);
1304
1305 uint8_t token_type = context_p->token.type;
1306 #endif /* ENABLED (JERRY_ES2015) */
1307
1308 switch (token_type)
1309 {
1310 #if ENABLED (JERRY_ES2015)
1311 case LEXER_KEYW_LET:
1312 case LEXER_KEYW_CONST:
1313 #endif /* ENABLED (JERRY_ES2015) */
1314 case LEXER_KEYW_VAR:
1315 {
1316 #if ENABLED (JERRY_ES2015)
1317 if (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE))
1318 {
1319 parser_emit_cbc_ext (context_p, is_for_in ? CBC_EXT_FOR_IN_GET_NEXT
1320 : CBC_EXT_FOR_OF_GET_NEXT);
1321
1322 if (context_p->next_scanner_info_p->source_p == (context_p->source_p + 1))
1323 {
1324 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_INITIALIZER);
1325
1326 scanner_release_next (context_p, sizeof (scanner_location_info_t));
1327 }
1328
1329 parser_pattern_flags_t flags = (PARSER_PATTERN_BINDING | PARSER_PATTERN_TARGET_ON_STACK);
1330
1331 if (token_type == LEXER_KEYW_LET)
1332 {
1333 flags |= PARSER_PATTERN_LET;
1334 }
1335 else if (token_type == LEXER_KEYW_CONST)
1336 {
1337 flags |= PARSER_PATTERN_CONST;
1338 }
1339
1340 parser_parse_initializer_by_next_char (context_p, flags);
1341 break;
1342 }
1343 #endif /* ENABLED (JERRY_ES2015) */
1344
1345 lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
1346 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
1347 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
1348
1349 uint16_t literal_index = context_p->lit_object.index;
1350 lexer_next_token (context_p);
1351
1352 if (context_p->token.type == LEXER_ASSIGN)
1353 {
1354 #if ENABLED (JERRY_ES2015)
1355 if (context_p->status_flags & PARSER_IS_STRICT)
1356 {
1357 parser_raise_error (context_p, PARSER_ERR_FOR_IN_OF_DECLARATION);
1358 }
1359 #endif /* ENABLED (JERRY_ES2015) */
1360 parser_branch_t branch;
1361
1362 /* Initialiser is never executed. */
1363 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &branch);
1364 lexer_next_token (context_p);
1365 parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA);
1366 parser_set_branch_to_current_position (context_p, &branch);
1367 }
1368
1369 parser_emit_cbc_ext (context_p, is_for_in ? CBC_EXT_FOR_IN_GET_NEXT
1370 : CBC_EXT_FOR_OF_GET_NEXT);
1371 #if ENABLED (JERRY_ES2015)
1372 #ifndef JERRY_NDEBUG
1373 if (literal_index < PARSER_REGISTER_START
1374 && has_context
1375 && !scanner_literal_is_created (context_p, literal_index))
1376 {
1377 context_p->global_status_flags |= ECMA_PARSE_INTERNAL_FOR_IN_OFF_CONTEXT_ERROR;
1378 }
1379 #endif /* !JERRY_NDEBUG */
1380
1381 uint16_t opcode = (has_context ? CBC_ASSIGN_LET_CONST : CBC_ASSIGN_SET_IDENT);
1382 parser_emit_cbc_literal (context_p, opcode, literal_index);
1383 #else /* !ENABLED (JERRY_ES2015) */
1384 parser_emit_cbc_literal (context_p, CBC_ASSIGN_SET_IDENT, literal_index);
1385 #endif /* ENABLED (JERRY_ES2015) */
1386 break;
1387 }
1388 default:
1389 {
1390 uint16_t opcode;
1391
1392 parser_parse_expression (context_p, PARSE_EXPR_LEFT_HAND_SIDE);
1393
1394 opcode = context_p->last_cbc_opcode;
1395
1396 /* The CBC_EXT_FOR_IN_CREATE_CONTEXT flushed the opcode combiner. */
1397 JERRY_ASSERT (opcode != CBC_PUSH_TWO_LITERALS
1398 && opcode != CBC_PUSH_THREE_LITERALS);
1399
1400 opcode = parser_check_left_hand_side_expression (context_p, opcode);
1401
1402 parser_emit_cbc_ext (context_p, is_for_in ? CBC_EXT_FOR_IN_GET_NEXT
1403 : CBC_EXT_FOR_OF_GET_NEXT);
1404 parser_flush_cbc (context_p);
1405
1406 context_p->last_cbc_opcode = opcode;
1407 break;
1408 }
1409 }
1410
1411 if (context_p->token.type != LEXER_EOS)
1412 {
1413 #if ENABLED (JERRY_ES2015)
1414 parser_raise_error (context_p, is_for_in ? PARSER_ERR_IN_EXPECTED : PARSER_ERR_OF_EXPECTED);
1415 #else /* !ENABLED (JERRY_ES2015) */
1416 parser_raise_error (context_p, PARSER_ERR_IN_EXPECTED);
1417 #endif /* ENABLED (JERRY_ES2015) */
1418 }
1419
1420 parser_flush_cbc (context_p);
1421 scanner_set_location (context_p, &end_location);
1422 context_p->source_end_p = original_source_end_p;
1423 lexer_next_token (context_p);
1424
1425 loop.branch_list_p = NULL;
1426
1427 parser_stack_push (context_p, &for_in_of_statement, sizeof (parser_for_in_of_statement_t));
1428 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1429 #if ENABLED (JERRY_ES2015)
1430 parser_stack_push_uint8 (context_p, is_for_in ? PARSER_STATEMENT_FOR_IN
1431 : PARSER_STATEMENT_FOR_OF);
1432 #else /* !ENABLED (JERRY_ES2015) */
1433 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_FOR_IN);
1434 #endif /* ENABLED (JERRY_ES2015) */
1435 parser_stack_iterator_init (context_p, &context_p->last_statement);
1436 return;
1437 }
1438
1439 lexer_next_token (context_p);
1440
1441 if (context_p->token.type != LEXER_SEMICOLON)
1442 {
1443 #if ENABLED (JERRY_ES2015)
1444 const uint8_t *source_p = context_p->source_p;
1445 #endif /* ENABLED (JERRY_ES2015) */
1446
1447 switch (context_p->token.type)
1448 {
1449 #if ENABLED (JERRY_ES2015)
1450 case LEXER_LITERAL:
1451 {
1452 if (!lexer_token_is_let (context_p))
1453 {
1454 parser_parse_expression_statement (context_p, PARSE_EXPR);
1455 break;
1456 }
1457 /* FALLTHRU */
1458 }
1459 case LEXER_KEYW_LET:
1460 {
1461 if (context_p->next_scanner_info_p->source_p == context_p->source_p
1462 && context_p->next_scanner_info_p->type != SCANNER_TYPE_BLOCK)
1463 {
1464 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
1465 {
1466 scanner_release_next (context_p, sizeof (scanner_info_t));
1467 }
1468
1469 parser_parse_expression_statement (context_p, PARSE_EXPR);
1470 break;
1471 }
1472
1473 context_p->token.type = LEXER_KEYW_LET;
1474
1475 /* FALLTHRU */
1476 }
1477 case LEXER_KEYW_CONST:
1478 {
1479 if (context_p->next_scanner_info_p->source_p == source_p)
1480 {
1481 parser_push_block_context (context_p, true);
1482 }
1483 /* FALLTHRU */
1484 }
1485 #endif /* ENABLED (JERRY_ES2015) */
1486 case LEXER_KEYW_VAR:
1487 {
1488 parser_parse_var_statement (context_p);
1489 break;
1490 }
1491 default:
1492 {
1493 parser_parse_expression_statement (context_p, PARSE_EXPR);
1494 break;
1495 }
1496 }
1497
1498 if (context_p->token.type != LEXER_SEMICOLON)
1499 {
1500 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1501 }
1502 }
1503
1504 JERRY_ASSERT (context_p->next_scanner_info_p->source_p != context_p->source_p
1505 || context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR);
1506
1507 if (context_p->next_scanner_info_p->source_p != context_p->source_p
1508 || ((scanner_for_info_t *) context_p->next_scanner_info_p)->end_location.source_p == NULL)
1509 {
1510 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1511 {
1512 /* Even though the scanning is failed, there might be valid statements
1513 * inside the for statement which depend on scanner info blocks. */
1514 scanner_release_next (context_p, sizeof (scanner_for_info_t));
1515 }
1516
1517 /* The prescanner couldn't find the second semicolon or the closing paranthesis. */
1518 lexer_next_token (context_p);
1519 parser_parse_expression (context_p, PARSE_EXPR);
1520
1521 if (context_p->token.type != LEXER_SEMICOLON)
1522 {
1523 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1524 }
1525
1526 lexer_next_token (context_p);
1527 parser_parse_expression_statement (context_p, PARSE_EXPR);
1528
1529 JERRY_ASSERT (context_p->token.type != LEXER_RIGHT_PAREN);
1530 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1531 }
1532
1533 parser_for_statement_t for_statement;
1534 scanner_for_info_t *for_info_p = (scanner_for_info_t *) context_p->next_scanner_info_p;
1535
1536 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &for_statement.branch);
1537
1538 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1539
1540 for_statement.start_offset = context_p->byte_code_size;
1541 scanner_get_location (&for_statement.condition_location, context_p);
1542 for_statement.expression_location = for_info_p->expression_location;
1543
1544 scanner_set_location (context_p, &for_info_p->end_location);
1545 scanner_release_next (context_p, sizeof (scanner_for_info_t));
1546 scanner_seek (context_p);
1547 lexer_next_token (context_p);
1548
1549 loop.branch_list_p = NULL;
1550
1551 parser_stack_push (context_p, &for_statement, sizeof (parser_for_statement_t));
1552 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1553 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_FOR);
1554 parser_stack_iterator_init (context_p, &context_p->last_statement);
1555 } /* parser_parse_for_statement_start */
1556
1557 /**
1558 * Parse for statement (ending part).
1559 */
1560 static void JERRY_ATTR_NOINLINE
parser_parse_for_statement_end(parser_context_t * context_p)1561 parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
1562 {
1563 parser_for_statement_t for_statement;
1564 parser_loop_statement_t loop;
1565 lexer_token_t current_token;
1566 scanner_location_t location;
1567 cbc_opcode_t opcode;
1568
1569 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_FOR);
1570
1571 parser_stack_iterator_t iterator;
1572 parser_stack_iterator_init (context_p, &iterator);
1573
1574 parser_stack_iterator_skip (&iterator, 1);
1575 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
1576 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
1577 parser_stack_iterator_read (&iterator, &for_statement, sizeof (parser_for_statement_t));
1578
1579 #if ENABLED (JERRY_ES2015)
1580 bool has_block_context = false;
1581 uint8_t next_statement_type;
1582
1583 parser_stack_iterator_skip (&iterator, sizeof (parser_for_statement_t));
1584 parser_stack_iterator_read (&iterator, &next_statement_type, 1);
1585
1586 if (next_statement_type == PARSER_STATEMENT_PRIVATE_CONTEXT)
1587 {
1588 has_block_context = true;
1589 }
1590 #endif
1591
1592 scanner_get_location (&location, context_p);
1593 current_token = context_p->token;
1594
1595 scanner_set_location (context_p, &for_statement.expression_location);
1596 scanner_seek (context_p);
1597 lexer_next_token (context_p);
1598
1599 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
1600
1601 #if ENABLED (JERRY_ES2015)
1602 if (has_block_context)
1603 {
1604 parser_emit_cbc_ext (context_p, CBC_EXT_CLONE_FULL_CONTEXT);
1605 }
1606 #endif
1607
1608 if (context_p->token.type != LEXER_RIGHT_PAREN)
1609 {
1610 parser_parse_expression_statement (context_p, PARSE_EXPR);
1611
1612 if (context_p->token.type != LEXER_RIGHT_PAREN)
1613 {
1614 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1615 }
1616 }
1617
1618 parser_set_branch_to_current_position (context_p, &for_statement.branch);
1619
1620 scanner_set_location (context_p, &for_statement.condition_location);
1621 scanner_seek (context_p);
1622 lexer_next_token (context_p);
1623
1624 if (context_p->token.type != LEXER_SEMICOLON)
1625 {
1626 parser_parse_expression (context_p, PARSE_EXPR);
1627
1628 if (context_p->token.type != LEXER_SEMICOLON)
1629 {
1630 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1631 }
1632
1633 opcode = CBC_BRANCH_IF_TRUE_BACKWARD;
1634 if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
1635 {
1636 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1637 opcode = CBC_BRANCH_IF_FALSE_BACKWARD;
1638 }
1639 else if (context_p->last_cbc_opcode == CBC_PUSH_TRUE)
1640 {
1641 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1642 opcode = CBC_JUMP_BACKWARD;
1643 }
1644 }
1645 else
1646 {
1647 opcode = CBC_JUMP_BACKWARD;
1648 }
1649
1650 parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_for_statement_t));
1651 parser_stack_iterator_init (context_p, &context_p->last_statement);
1652
1653 parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, for_statement.start_offset);
1654 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
1655
1656 #if ENABLED (JERRY_ES2015)
1657 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
1658 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
1659 {
1660 parser_pop_block_context (context_p);
1661 }
1662 #endif
1663
1664 /* Calling scanner_seek is unnecessary because all
1665 * info blocks inside the for statement should be processed. */
1666 scanner_set_location (context_p, &location);
1667 context_p->token = current_token;
1668 } /* parser_parse_for_statement_end */
1669
1670 /**
1671 * Parse switch statement (starting part).
1672 */
1673 static void JERRY_ATTR_NOINLINE
parser_parse_switch_statement_start(parser_context_t * context_p)1674 parser_parse_switch_statement_start (parser_context_t *context_p) /**< context */
1675 {
1676 parser_switch_statement_t switch_statement;
1677 parser_loop_statement_t loop;
1678 parser_stack_iterator_t iterator;
1679 scanner_location_t start_location;
1680 bool switch_case_was_found;
1681 bool default_case_was_found;
1682 parser_branch_node_t *case_branches_p = NULL;
1683
1684 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_SWITCH);
1685
1686 parser_parse_enclosed_expr (context_p);
1687
1688 if (context_p->token.type != LEXER_LEFT_BRACE)
1689 {
1690 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
1691 }
1692
1693 #if ENABLED (JERRY_ES2015)
1694 if (context_p->next_scanner_info_p->source_p == context_p->source_p - 1)
1695 {
1696 parser_push_block_context (context_p, true);
1697 }
1698 #endif /* ENABLED (JERRY_ES2015) */
1699
1700 JERRY_ASSERT (context_p->next_scanner_info_p->source_p == context_p->source_p
1701 && context_p->next_scanner_info_p->type == SCANNER_TYPE_SWITCH);
1702
1703 scanner_case_info_t *case_info_p = ((scanner_switch_info_t *) context_p->next_scanner_info_p)->case_p;
1704 scanner_set_active (context_p);
1705
1706 if (case_info_p == NULL)
1707 {
1708 lexer_next_token (context_p);
1709
1710 if (context_p->token.type == LEXER_RIGHT_BRACE)
1711 {
1712 scanner_release_active (context_p, sizeof (scanner_switch_info_t));
1713
1714 parser_emit_cbc (context_p, CBC_POP);
1715 parser_flush_cbc (context_p);
1716
1717 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
1718 parser_stack_iterator_init (context_p, &context_p->last_statement);
1719 return;
1720 }
1721
1722 parser_raise_error (context_p, PARSER_ERR_INVALID_SWITCH);
1723 }
1724
1725 scanner_get_location (&start_location, context_p);
1726
1727 /* The reason of using an iterator is error management. If an error
1728 * occures, parser_free_jumps() free all data. However, the branches
1729 * created by parser_emit_cbc_forward_branch_item() would not be freed.
1730 * To free these branches, the current switch data is always stored
1731 * on the stack. If any change happens, this data is updated. Updates
1732 * are done using the iterator. */
1733
1734 switch_statement.branch_list_p = NULL;
1735 loop.branch_list_p = NULL;
1736
1737 parser_stack_push (context_p, &switch_statement, sizeof (parser_switch_statement_t));
1738 parser_stack_iterator_init (context_p, &iterator);
1739 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1740 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_SWITCH);
1741 parser_stack_iterator_init (context_p, &context_p->last_statement);
1742
1743 switch_case_was_found = false;
1744 default_case_was_found = false;
1745
1746 #if ENABLED (JERRY_LINE_INFO)
1747 uint32_t last_line_info_line = context_p->last_line_info_line;
1748 #endif /* ENABLED (JERRY_LINE_INFO) */
1749
1750 do
1751 {
1752 scanner_set_location (context_p, &case_info_p->location);
1753 scanner_seek (context_p);
1754 case_info_p = case_info_p->next_p;
1755
1756 /* The last letter of case and default is 'e' and 't' respectively. */
1757 JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LOWERCASE_E
1758 || context_p->source_p[-1] == LIT_CHAR_LOWERCASE_T);
1759
1760 bool is_default = context_p->source_p[-1] == LIT_CHAR_LOWERCASE_T;
1761 lexer_next_token (context_p);
1762
1763 if (is_default)
1764 {
1765 if (default_case_was_found)
1766 {
1767 parser_raise_error (context_p, PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED);
1768 }
1769
1770 if (context_p->token.type != LEXER_COLON)
1771 {
1772 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1773 }
1774
1775 default_case_was_found = true;
1776 continue;
1777 }
1778
1779 switch_case_was_found = true;
1780
1781 #if ENABLED (JERRY_LINE_INFO)
1782 if (context_p->token.line != context_p->last_line_info_line)
1783 {
1784 parser_emit_line_info (context_p, context_p->token.line, true);
1785 }
1786 #endif /* ENABLED (JERRY_LINE_INFO) */
1787
1788 parser_parse_expression (context_p, PARSE_EXPR);
1789
1790 if (context_p->token.type != LEXER_COLON)
1791 {
1792 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1793 }
1794
1795 uint16_t opcode = CBC_BRANCH_IF_STRICT_EQUAL;
1796
1797 if (case_info_p == NULL
1798 || (case_info_p->next_p == NULL && case_info_p->location.source_p[-1] == LIT_CHAR_LOWERCASE_T))
1799 {
1800 /* There are no more 'case' statements in the switch. */
1801 parser_emit_cbc (context_p, CBC_STRICT_EQUAL);
1802 opcode = CBC_BRANCH_IF_TRUE_FORWARD;
1803 }
1804
1805 parser_branch_node_t *new_case_p = parser_emit_cbc_forward_branch_item (context_p, opcode, NULL);
1806
1807 if (case_branches_p == NULL)
1808 {
1809 switch_statement.branch_list_p = new_case_p;
1810 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
1811 }
1812 else
1813 {
1814 case_branches_p->next_p = new_case_p;
1815 }
1816
1817 case_branches_p = new_case_p;
1818 }
1819 while (case_info_p != NULL);
1820
1821 JERRY_ASSERT (switch_case_was_found || default_case_was_found);
1822
1823 #if ENABLED (JERRY_LINE_INFO)
1824 context_p->last_line_info_line = last_line_info_line;
1825 #endif /* ENABLED (JERRY_LINE_INFO) */
1826
1827 if (!switch_case_was_found)
1828 {
1829 /* There was no case statement, so the expression result
1830 * of the switch must be popped from the stack */
1831 parser_emit_cbc (context_p, CBC_POP);
1832 }
1833
1834 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &switch_statement.default_branch);
1835 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
1836
1837 if (!default_case_was_found)
1838 {
1839 parser_stack_change_last_uint8 (context_p, PARSER_STATEMENT_SWITCH_NO_DEFAULT);
1840 }
1841
1842 scanner_release_switch_cases (((scanner_switch_info_t *) context_p->active_scanner_info_p)->case_p);
1843 scanner_release_active (context_p, sizeof (scanner_switch_info_t));
1844
1845 scanner_set_location (context_p, &start_location);
1846 scanner_seek (context_p);
1847 lexer_next_token (context_p);
1848 } /* parser_parse_switch_statement_start */
1849
1850 /**
1851 * Parse try statement (ending part).
1852 */
1853 static void
parser_parse_try_statement_end(parser_context_t * context_p)1854 parser_parse_try_statement_end (parser_context_t *context_p) /**< context */
1855 {
1856 parser_try_statement_t try_statement;
1857 parser_stack_iterator_t iterator;
1858
1859 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_TRY);
1860
1861 parser_stack_iterator_init (context_p, &iterator);
1862 parser_stack_iterator_skip (&iterator, 1);
1863 parser_stack_iterator_read (&iterator, &try_statement, sizeof (parser_try_statement_t));
1864
1865 #if ENABLED (JERRY_ES2015)
1866 context_p->scope_stack_top = try_statement.scope_stack_top;
1867 context_p->scope_stack_reg_top = try_statement.scope_stack_reg_top;
1868 #endif /* ENABLED (JERRY_ES2015) */
1869
1870 lexer_next_token (context_p);
1871
1872 if (try_statement.type == parser_finally_block)
1873 {
1874 parser_flush_cbc (context_p);
1875 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1876 #ifndef JERRY_NDEBUG
1877 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1878 #endif /* !JERRY_NDEBUG */
1879
1880 parser_emit_cbc (context_p, CBC_CONTEXT_END);
1881 parser_set_branch_to_current_position (context_p, &try_statement.branch);
1882 }
1883 else
1884 {
1885 parser_set_branch_to_current_position (context_p, &try_statement.branch);
1886
1887 if (try_statement.type == parser_catch_block)
1888 {
1889 #if !ENABLED (JERRY_ES2015)
1890 context_p->scope_stack_top = try_statement.scope_stack_top;
1891 context_p->scope_stack_reg_top = try_statement.scope_stack_reg_top;
1892 #endif /* !ENABLED (JERRY_ES2015) */
1893
1894 if (context_p->token.type != LEXER_KEYW_FINALLY)
1895 {
1896 parser_flush_cbc (context_p);
1897 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1898 #ifndef JERRY_NDEBUG
1899 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1900 #endif /* !JERRY_NDEBUG */
1901
1902 parser_emit_cbc (context_p, CBC_CONTEXT_END);
1903 parser_flush_cbc (context_p);
1904
1905 try_statement.type = parser_finally_block;
1906 }
1907 }
1908 else if (try_statement.type == parser_try_block
1909 && context_p->token.type != LEXER_KEYW_CATCH
1910 && context_p->token.type != LEXER_KEYW_FINALLY)
1911 {
1912 parser_raise_error (context_p, PARSER_ERR_CATCH_FINALLY_EXPECTED);
1913 }
1914 }
1915
1916 if (try_statement.type == parser_finally_block)
1917 {
1918 parser_stack_pop (context_p, NULL, (uint32_t) (sizeof (parser_try_statement_t) + 1));
1919 parser_stack_iterator_init (context_p, &context_p->last_statement);
1920 return;
1921 }
1922
1923 if (context_p->token.type == LEXER_KEYW_CATCH)
1924 {
1925 lexer_next_token (context_p);
1926
1927 if (context_p->token.type != LEXER_LEFT_PAREN)
1928 {
1929 parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
1930 }
1931
1932 try_statement.type = parser_catch_block;
1933 parser_emit_cbc_ext_forward_branch (context_p,
1934 CBC_EXT_CATCH,
1935 &try_statement.branch);
1936
1937 try_statement.scope_stack_top = context_p->scope_stack_top;
1938 try_statement.scope_stack_reg_top = context_p->scope_stack_reg_top;
1939
1940 #ifndef JERRY_NDEBUG
1941 bool block_found = false;
1942 #endif /* !JERRY_NDEBUG */
1943
1944 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1945 {
1946 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
1947 #ifndef JERRY_NDEBUG
1948 block_found = true;
1949 #endif /* !JERRY_NDEBUG */
1950
1951 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
1952 {
1953 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
1954 }
1955
1956 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
1957 }
1958
1959 #if ENABLED (JERRY_ES2015)
1960 if (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE))
1961 {
1962 parser_pattern_flags_t flags = (PARSER_PATTERN_BINDING
1963 | PARSER_PATTERN_TARGET_ON_STACK
1964 | PARSER_PATTERN_LET);
1965
1966 parser_parse_initializer_by_next_char (context_p, flags);
1967 }
1968 else
1969 {
1970 #endif /* ENABLED (JERRY_ES2015) */
1971 lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
1972 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
1973 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
1974
1975 #if ENABLED (JERRY_ES2015)
1976 uint16_t literal_index = context_p->lit_object.index;
1977 parser_emit_cbc_literal (context_p,
1978 (literal_index >= PARSER_REGISTER_START) ? CBC_ASSIGN_SET_IDENT : CBC_ASSIGN_LET_CONST,
1979 literal_index);
1980 #else /* !ENABLED (JERRY_ES2015) */
1981 parser_emit_cbc_literal (context_p, CBC_ASSIGN_SET_IDENT, context_p->lit_object.index);
1982 #endif /* ENABLED (JERRY_ES2015) */
1983
1984 lexer_next_token (context_p);
1985
1986 #ifndef JERRY_NDEBUG
1987 JERRY_ASSERT (block_found);
1988 #endif /* !JERRY_NDEBUG */
1989 #if ENABLED (JERRY_ES2015)
1990 }
1991 #endif /* ENABLED (JERRY_ES2015) */
1992
1993 if (context_p->token.type != LEXER_RIGHT_PAREN)
1994 {
1995 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1996 }
1997
1998 lexer_next_token (context_p);
1999
2000 if (context_p->token.type != LEXER_LEFT_BRACE)
2001 {
2002 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2003 }
2004
2005 parser_flush_cbc (context_p);
2006 }
2007 else
2008 {
2009 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FINALLY);
2010
2011 lexer_next_token (context_p);
2012
2013 if (context_p->token.type != LEXER_LEFT_BRACE)
2014 {
2015 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2016 }
2017
2018 try_statement.type = parser_finally_block;
2019 parser_emit_cbc_ext_forward_branch (context_p,
2020 CBC_EXT_FINALLY,
2021 &try_statement.branch);
2022
2023 #if ENABLED (JERRY_ES2015)
2024 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2025 {
2026 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
2027
2028 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
2029 {
2030 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
2031 }
2032
2033 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
2034 }
2035 #endif /* ENABLED (JERRY_ES2015) */
2036 }
2037
2038 lexer_next_token (context_p);
2039 parser_stack_iterator_write (&iterator, &try_statement, sizeof (parser_try_statement_t));
2040 } /* parser_parse_try_statement_end */
2041
2042 /**
2043 * Parse default statement.
2044 */
2045 static void
parser_parse_default_statement(parser_context_t * context_p)2046 parser_parse_default_statement (parser_context_t *context_p) /**< context */
2047 {
2048 parser_stack_iterator_t iterator;
2049 parser_switch_statement_t switch_statement;
2050
2051 if (context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH
2052 && context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH_NO_DEFAULT)
2053 {
2054 parser_raise_error (context_p, PARSER_ERR_DEFAULT_NOT_IN_SWITCH);
2055 }
2056
2057 lexer_next_token (context_p);
2058 /* Already checked in parser_parse_switch_statement_start. */
2059 JERRY_ASSERT (context_p->token.type == LEXER_COLON);
2060 lexer_next_token (context_p);
2061
2062 parser_stack_iterator_init (context_p, &iterator);
2063 parser_stack_iterator_skip (&iterator, 1 + sizeof (parser_loop_statement_t));
2064 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2065
2066 parser_set_branch_to_current_position (context_p, &switch_statement.default_branch);
2067 } /* parser_parse_default_statement */
2068
2069 /**
2070 * Parse case statement.
2071 */
2072 static void
parser_parse_case_statement(parser_context_t * context_p)2073 parser_parse_case_statement (parser_context_t *context_p) /**< context */
2074 {
2075 parser_stack_iterator_t iterator;
2076 parser_switch_statement_t switch_statement;
2077 parser_branch_node_t *branch_p;
2078
2079 if (context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH
2080 && context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH_NO_DEFAULT)
2081 {
2082 parser_raise_error (context_p, PARSER_ERR_CASE_NOT_IN_SWITCH);
2083 }
2084
2085 if (context_p->next_scanner_info_p->source_p != context_p->source_p)
2086 {
2087 lexer_next_token (context_p);
2088
2089 parser_parse_expression (context_p, PARSE_EXPR);
2090
2091 JERRY_ASSERT (context_p->token.type != LEXER_COLON);
2092 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
2093 }
2094
2095 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_CASE);
2096
2097 scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
2098 scanner_release_next (context_p, sizeof (scanner_location_info_t));
2099 scanner_seek (context_p);
2100 lexer_next_token (context_p);
2101
2102 parser_stack_iterator_init (context_p, &iterator);
2103 parser_stack_iterator_skip (&iterator, 1 + sizeof (parser_loop_statement_t));
2104 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2105
2106 /* Free memory after the case statement is found. */
2107
2108 branch_p = switch_statement.branch_list_p;
2109 JERRY_ASSERT (branch_p != NULL);
2110 switch_statement.branch_list_p = branch_p->next_p;
2111 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2112
2113 parser_set_branch_to_current_position (context_p, &branch_p->branch);
2114 parser_free (branch_p, sizeof (parser_branch_node_t));
2115 } /* parser_parse_case_statement */
2116
2117 /**
2118 * Parse break statement.
2119 */
2120 static void
parser_parse_break_statement(parser_context_t * context_p)2121 parser_parse_break_statement (parser_context_t *context_p) /**< context */
2122 {
2123 parser_stack_iterator_t iterator;
2124 cbc_opcode_t opcode = CBC_JUMP_FORWARD;
2125
2126 lexer_next_token (context_p);
2127 parser_stack_iterator_init (context_p, &iterator);
2128
2129 if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2130 && context_p->token.type == LEXER_LITERAL
2131 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
2132 {
2133 /* The label with the same name is searched on the stack. */
2134 while (true)
2135 {
2136 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2137 if (type == PARSER_STATEMENT_START)
2138 {
2139 parser_raise_error (context_p, PARSER_ERR_INVALID_BREAK_LABEL);
2140 }
2141
2142 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2143 {
2144 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2145 }
2146
2147 if (type == PARSER_STATEMENT_LABEL)
2148 {
2149 parser_label_statement_t label_statement;
2150
2151 parser_stack_iterator_skip (&iterator, 1);
2152 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2153
2154 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2155 {
2156 label_statement.break_list_p = parser_emit_cbc_forward_branch_item (context_p,
2157 (uint16_t) opcode,
2158 label_statement.break_list_p);
2159 parser_stack_iterator_write (&iterator, &label_statement, sizeof (parser_label_statement_t));
2160 lexer_next_token (context_p);
2161 return;
2162 }
2163 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2164 }
2165 else
2166 {
2167 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2168 }
2169 }
2170 }
2171
2172 /* The first switch or loop statement is searched. */
2173 while (true)
2174 {
2175 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2176 if (type == PARSER_STATEMENT_START)
2177 {
2178 parser_raise_error (context_p, PARSER_ERR_INVALID_BREAK);
2179 }
2180
2181 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2182 {
2183 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2184 }
2185
2186 if (parser_statement_flags[type] & PARSER_STATM_BREAK_TARGET)
2187 {
2188 parser_loop_statement_t loop;
2189
2190 parser_stack_iterator_skip (&iterator, 1);
2191 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
2192 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2193 (uint16_t) opcode,
2194 loop.branch_list_p);
2195 parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
2196 return;
2197 }
2198
2199 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2200 }
2201 } /* parser_parse_break_statement */
2202
2203 /**
2204 * Parse continue statement.
2205 */
2206 static void
parser_parse_continue_statement(parser_context_t * context_p)2207 parser_parse_continue_statement (parser_context_t *context_p) /**< context */
2208 {
2209 parser_stack_iterator_t iterator;
2210 cbc_opcode_t opcode = CBC_JUMP_FORWARD;
2211
2212 lexer_next_token (context_p);
2213 parser_stack_iterator_init (context_p, &iterator);
2214
2215 if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2216 && context_p->token.type == LEXER_LITERAL
2217 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
2218 {
2219 parser_stack_iterator_t loop_iterator;
2220
2221 loop_iterator.current_p = NULL;
2222
2223 /* The label with the same name is searched on the stack. */
2224 while (true)
2225 {
2226 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2227
2228 if (type == PARSER_STATEMENT_START)
2229 {
2230 parser_raise_error (context_p, PARSER_ERR_INVALID_CONTINUE_LABEL);
2231 }
2232
2233 /* Only those labels are checked, whose are label of a loop. */
2234 if (loop_iterator.current_p != NULL && type == PARSER_STATEMENT_LABEL)
2235 {
2236 parser_label_statement_t label_statement;
2237
2238 parser_stack_iterator_skip (&iterator, 1);
2239 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2240
2241 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2242 {
2243 parser_loop_statement_t loop;
2244
2245 parser_stack_iterator_skip (&loop_iterator, 1);
2246 parser_stack_iterator_read (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
2247 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2248 (uint16_t) opcode,
2249 loop.branch_list_p);
2250 loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
2251 parser_stack_iterator_write (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
2252 lexer_next_token (context_p);
2253 return;
2254 }
2255 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2256 continue;
2257 }
2258
2259 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2260 {
2261 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2262 }
2263
2264 if (parser_statement_flags[type] & PARSER_STATM_CONTINUE_TARGET)
2265 {
2266 loop_iterator = iterator;
2267 }
2268 else
2269 {
2270 loop_iterator.current_p = NULL;
2271 }
2272
2273 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2274 }
2275 }
2276
2277 /* The first loop statement is searched. */
2278 while (true)
2279 {
2280 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2281 if (type == PARSER_STATEMENT_START)
2282 {
2283 parser_raise_error (context_p, PARSER_ERR_INVALID_CONTINUE);
2284 }
2285
2286 if (parser_statement_flags[type] & PARSER_STATM_CONTINUE_TARGET)
2287 {
2288 parser_loop_statement_t loop;
2289
2290 parser_stack_iterator_skip (&iterator, 1);
2291 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
2292 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2293 (uint16_t) opcode,
2294 loop.branch_list_p);
2295 loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
2296 parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
2297 return;
2298 }
2299
2300 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2301 {
2302 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2303 }
2304
2305 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2306 }
2307 } /* parser_parse_continue_statement */
2308
2309 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2310 /**
2311 * Parse import statement.
2312 * Note: See 15.2.2
2313 */
2314 static void
parser_parse_import_statement(parser_context_t * context_p)2315 parser_parse_import_statement (parser_context_t *context_p) /**< parser context */
2316 {
2317 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_IMPORT);
2318
2319 parser_module_check_request_place (context_p);
2320 parser_module_context_init ();
2321
2322 context_p->module_current_node_p = parser_module_create_module_node (context_p);
2323
2324 lexer_next_token (context_p);
2325
2326 /* Check for a ModuleSpecifier*/
2327 if (context_p->token.type != LEXER_LITERAL
2328 || context_p->token.lit_location.type != LEXER_STRING_LITERAL)
2329 {
2330 if (!(context_p->token.type == LEXER_LEFT_BRACE
2331 || context_p->token.type == LEXER_MULTIPLY
2332 || (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)))
2333 {
2334 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED);
2335 }
2336
2337 if (context_p->token.type == LEXER_LITERAL)
2338 {
2339 /* Handle ImportedDefaultBinding */
2340 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2341
2342 ecma_string_t *local_name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
2343 context_p->lit_object.literal_p->prop.length);
2344
2345 if (parser_module_check_duplicate_import (context_p, local_name_p))
2346 {
2347 ecma_deref_ecma_string (local_name_p);
2348 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_IMPORT_BINDING);
2349 }
2350
2351 ecma_string_t *import_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_DEFAULT);
2352 parser_module_add_names_to_node (context_p, import_name_p, local_name_p);
2353
2354 ecma_deref_ecma_string (local_name_p);
2355 ecma_deref_ecma_string (import_name_p);
2356
2357 lexer_next_token (context_p);
2358
2359 if (context_p->token.type == LEXER_COMMA)
2360 {
2361 lexer_next_token (context_p);
2362 if (context_p->token.type != LEXER_MULTIPLY
2363 && context_p->token.type != LEXER_LEFT_BRACE)
2364 {
2365 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED);
2366 }
2367 }
2368 else if (!lexer_token_is_identifier (context_p, "from", 4))
2369 {
2370 parser_raise_error (context_p, PARSER_ERR_FROM_COMMA_EXPECTED);
2371 }
2372 }
2373
2374 if (context_p->token.type == LEXER_MULTIPLY)
2375 {
2376 /* NameSpaceImport*/
2377 lexer_next_token (context_p);
2378 if (!lexer_token_is_identifier (context_p, "as", 2))
2379 {
2380 parser_raise_error (context_p, PARSER_ERR_AS_EXPECTED);
2381 }
2382
2383 lexer_next_token (context_p);
2384 if (context_p->token.type != LEXER_LITERAL)
2385 {
2386 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
2387 }
2388
2389 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2390
2391 ecma_string_t *local_name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
2392 context_p->lit_object.literal_p->prop.length);
2393
2394 if (parser_module_check_duplicate_import (context_p, local_name_p))
2395 {
2396 ecma_deref_ecma_string (local_name_p);
2397 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_IMPORT_BINDING);
2398 }
2399
2400 ecma_string_t *import_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR);
2401
2402 parser_module_add_names_to_node (context_p, import_name_p, local_name_p);
2403 ecma_deref_ecma_string (local_name_p);
2404 ecma_deref_ecma_string (import_name_p);
2405
2406 lexer_next_token (context_p);
2407 }
2408 else if (context_p->token.type == LEXER_LEFT_BRACE)
2409 {
2410 /* Handle NamedImports */
2411 parser_module_parse_import_clause (context_p);
2412 }
2413
2414 if (!lexer_token_is_identifier (context_p, "from", 4))
2415 {
2416 parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
2417 }
2418 lexer_next_token (context_p);
2419 }
2420
2421 parser_module_handle_module_specifier (context_p);
2422 parser_module_add_import_node_to_context (context_p);
2423
2424 context_p->module_current_node_p = NULL;
2425 } /* parser_parse_import_statement */
2426
2427 /**
2428 * Parse export statement.
2429 */
2430 static void
parser_parse_export_statement(parser_context_t * context_p)2431 parser_parse_export_statement (parser_context_t *context_p) /**< context */
2432 {
2433 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_EXPORT);
2434
2435 parser_module_check_request_place (context_p);
2436 parser_module_context_init ();
2437
2438 context_p->module_current_node_p = parser_module_create_module_node (context_p);
2439
2440 lexer_next_token (context_p);
2441 switch (context_p->token.type)
2442 {
2443 case LEXER_KEYW_DEFAULT:
2444 {
2445 scanner_location_t location;
2446 scanner_get_location (&location, context_p);
2447
2448 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2449
2450 lexer_next_token (context_p);
2451 if (context_p->token.type == LEXER_KEYW_CLASS)
2452 {
2453 context_p->status_flags |= PARSER_MODULE_DEFAULT_CLASS_OR_FUNC;
2454 parser_parse_class (context_p, true);
2455 }
2456 else if (context_p->token.type == LEXER_KEYW_FUNCTION)
2457 {
2458 context_p->status_flags |= PARSER_MODULE_DEFAULT_CLASS_OR_FUNC;
2459 parser_parse_function_statement (context_p);
2460 }
2461 else
2462 {
2463 /* Assignment expression */
2464 scanner_set_location (context_p, &location);
2465
2466 /* 15.2.3.5 Use the synthetic name '*default*' as the identifier. */
2467 lexer_construct_literal_object (context_p, &lexer_default_literal, lexer_default_literal.type);
2468
2469 context_p->token.lit_location.type = LEXER_IDENT_LITERAL;
2470 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2471
2472 context_p->module_identifier_lit_p = context_p->lit_object.literal_p;
2473
2474 /* Fake an assignment to the default identifier */
2475 context_p->token.type = LEXER_ASSIGN;
2476
2477 parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
2478 }
2479
2480 ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->module_identifier_lit_p->u.char_p,
2481 context_p->module_identifier_lit_p->prop.length);
2482 ecma_string_t *export_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_DEFAULT);
2483
2484 if (parser_module_check_duplicate_export (context_p, export_name_p))
2485 {
2486 ecma_deref_ecma_string (name_p);
2487 ecma_deref_ecma_string (export_name_p);
2488 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER);
2489 }
2490
2491 parser_module_add_names_to_node (context_p,
2492 export_name_p,
2493 name_p);
2494 ecma_deref_ecma_string (name_p);
2495 ecma_deref_ecma_string (export_name_p);
2496 break;
2497 }
2498 case LEXER_MULTIPLY:
2499 {
2500 lexer_next_token (context_p);
2501 if (!lexer_token_is_identifier (context_p, "from", 4))
2502 {
2503 parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
2504 }
2505
2506 lexer_next_token (context_p);
2507 parser_module_handle_module_specifier (context_p);
2508 break;
2509 }
2510 case LEXER_KEYW_VAR:
2511 case LEXER_KEYW_LET:
2512 case LEXER_KEYW_CONST:
2513 {
2514 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2515 parser_parse_var_statement (context_p);
2516 break;
2517 }
2518 case LEXER_KEYW_CLASS:
2519 {
2520 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2521 parser_parse_class (context_p, true);
2522 break;
2523 }
2524 case LEXER_KEYW_FUNCTION:
2525 {
2526 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2527 parser_parse_function_statement (context_p);
2528 break;
2529 }
2530 case LEXER_LEFT_BRACE:
2531 {
2532 parser_module_parse_export_clause (context_p);
2533
2534 if (lexer_token_is_identifier (context_p, "from", 4))
2535 {
2536 lexer_next_token (context_p);
2537 parser_module_handle_module_specifier (context_p);
2538 }
2539 break;
2540 }
2541 default:
2542 {
2543 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED);
2544 break;
2545 }
2546 }
2547
2548 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC | PARSER_MODULE_STORE_IDENT);
2549 parser_module_add_export_node_to_context (context_p);
2550 context_p->module_current_node_p = NULL;
2551 } /* parser_parse_export_statement */
2552 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2553
2554 /**
2555 * Parse label statement.
2556 */
2557 static void
parser_parse_label(parser_context_t * context_p)2558 parser_parse_label (parser_context_t *context_p) /**< context */
2559 {
2560 parser_stack_iterator_t iterator;
2561 parser_label_statement_t label_statement;
2562
2563 parser_stack_iterator_init (context_p, &iterator);
2564
2565 while (true)
2566 {
2567 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2568 if (type == PARSER_STATEMENT_START)
2569 {
2570 break;
2571 }
2572
2573 if (type == PARSER_STATEMENT_LABEL)
2574 {
2575 parser_stack_iterator_skip (&iterator, 1);
2576 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2577 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2578
2579 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2580 {
2581 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_LABEL);
2582 }
2583 }
2584 else
2585 {
2586 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2587 }
2588 }
2589
2590 label_statement.label_ident = context_p->token.lit_location;
2591 label_statement.break_list_p = NULL;
2592 parser_stack_push (context_p, &label_statement, sizeof (parser_label_statement_t));
2593 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_LABEL);
2594 parser_stack_iterator_init (context_p, &context_p->last_statement);
2595 } /* parser_parse_label */
2596
2597 /**
2598 * Strict mode types for statement parsing.
2599 */
2600 typedef enum
2601 {
2602 PARSER_USE_STRICT_NOT_FOUND = 0, /**< 'use strict' directive is not found */
2603 PARSER_USE_STRICT_FOUND = 1, /**< 'use strict' directive is found but strict mode has already been enabled */
2604 PARSER_USE_STRICT_SET = 2, /**< strict mode is enabled after 'use strict' directive is found */
2605 } parser_strict_mode_type_t;
2606
2607 /**
2608 * Parse statements.
2609 */
2610 void
parser_parse_statements(parser_context_t * context_p)2611 parser_parse_statements (parser_context_t *context_p) /**< context */
2612 {
2613 /* Statement parsing cannot be nested. */
2614 JERRY_ASSERT (context_p->last_statement.current_p == NULL);
2615 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_START);
2616 parser_stack_iterator_init (context_p, &context_p->last_statement);
2617
2618 #if ENABLED (JERRY_DEBUGGER)
2619 /* Set lexical enviroment for the debugger. */
2620 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2621 {
2622 context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
2623 context_p->last_breakpoint_line = 0;
2624 }
2625 #endif /* ENABLED (JERRY_DEBUGGER) */
2626
2627 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2628 if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
2629 {
2630 parser_emit_cbc_ext (context_p, CBC_EXT_RESOURCE_NAME);
2631 parser_flush_cbc (context_p);
2632 }
2633 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2634 #if ENABLED (JERRY_LINE_INFO)
2635 context_p->last_line_info_line = 0;
2636 #endif /* ENABLED (JERRY_LINE_INFO) */
2637
2638 while (context_p->token.type == LEXER_LITERAL
2639 && context_p->token.lit_location.type == LEXER_STRING_LITERAL)
2640 {
2641 lexer_lit_location_t lit_location;
2642 parser_strict_mode_type_t strict_mode = PARSER_USE_STRICT_NOT_FOUND;
2643
2644 JERRY_ASSERT (context_p->stack_depth <= 1);
2645 #ifndef JERRY_NDEBUG
2646 JERRY_ASSERT (context_p->context_stack_depth == context_p->stack_depth);
2647 #endif /* !JERRY_NDEBUG */
2648
2649 if (lexer_string_is_use_strict (context_p))
2650 {
2651 strict_mode = PARSER_USE_STRICT_FOUND;
2652
2653 if (!(context_p->status_flags & PARSER_IS_STRICT))
2654 {
2655 /* The next token should be parsed in strict mode. */
2656 context_p->status_flags |= PARSER_IS_STRICT;
2657 strict_mode = PARSER_USE_STRICT_SET;
2658 }
2659 }
2660
2661 lit_location = context_p->token.lit_location;
2662 lexer_next_token (context_p);
2663
2664 if (!lexer_string_is_directive (context_p))
2665 {
2666 /* The string is part of an expression statement. */
2667 if (strict_mode == PARSER_USE_STRICT_SET)
2668 {
2669 context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
2670 }
2671
2672 #if ENABLED (JERRY_DEBUGGER)
2673 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2674 {
2675 JERRY_ASSERT (context_p->last_breakpoint_line == 0);
2676
2677 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2678 parser_flush_cbc (context_p);
2679
2680 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
2681
2682 context_p->last_breakpoint_line = context_p->token.line;
2683 }
2684 #endif /* ENABLED (JERRY_DEBUGGER) */
2685 #if ENABLED (JERRY_LINE_INFO)
2686 parser_emit_line_info (context_p, context_p->token.line, false);
2687 #endif /* ENABLED (JERRY_LINE_INFO) */
2688
2689 lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
2690 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2691 /* The extra_value is used for saving the token. */
2692 context_p->token.extra_value = context_p->token.type;
2693 context_p->token.type = LEXER_EXPRESSION_START;
2694 break;
2695 }
2696
2697 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2698 if (strict_mode == PARSER_USE_STRICT_SET && context_p->is_show_opcodes)
2699 {
2700 JERRY_DEBUG_MSG (" Note: switch to strict mode\n\n");
2701 }
2702 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2703
2704 #if ENABLED (JERRY_ES2015)
2705 if (strict_mode != PARSER_USE_STRICT_NOT_FOUND
2706 && (context_p->status_flags & PARSER_FUNCTION_HAS_NON_SIMPLE_PARAM))
2707 {
2708 parser_raise_error (context_p, PARSER_ERR_USE_STRICT_NOT_ALLOWED);
2709 }
2710 #endif /* ENABLED (JERRY_ES2015) */
2711
2712 if (context_p->token.type == LEXER_SEMICOLON)
2713 {
2714 lexer_next_token (context_p);
2715 }
2716
2717 /* The last directive prologue can be the result of the script. */
2718 if (!(context_p->status_flags & PARSER_IS_FUNCTION)
2719 && (context_p->token.type != LEXER_LITERAL
2720 || context_p->token.lit_location.type != LEXER_STRING_LITERAL))
2721 {
2722 lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
2723 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2724 parser_emit_cbc (context_p, CBC_POP_BLOCK);
2725 parser_flush_cbc (context_p);
2726 break;
2727 }
2728 }
2729
2730 CHECK_JERRY_STACK_USAGE(context_p);
2731
2732 if (context_p->status_flags & PARSER_IS_STRICT
2733 && context_p->status_flags & PARSER_HAS_NON_STRICT_ARG)
2734 {
2735 parser_raise_error (context_p, PARSER_ERR_NON_STRICT_ARG_DEFINITION);
2736 }
2737
2738 while (context_p->token.type != LEXER_EOS
2739 || context_p->stack_top_uint8 != PARSER_STATEMENT_START)
2740 {
2741 #ifndef JERRY_NDEBUG
2742 JERRY_ASSERT (context_p->stack_depth == context_p->context_stack_depth);
2743 #endif /* !JERRY_NDEBUG */
2744
2745 #if ENABLED (JERRY_ES2015)
2746 JERRY_ASSERT (context_p->stack_top_uint8 != PARSER_STATEMENT_PRIVATE_SCOPE
2747 && context_p->stack_top_uint8 != PARSER_STATEMENT_PRIVATE_CONTEXT);
2748 #endif /* ENABLED (JERRY_ES2015) */
2749
2750 #if ENABLED (JERRY_DEBUGGER)
2751 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED
2752 && context_p->token.line != context_p->last_breakpoint_line
2753 && context_p->token.type != LEXER_SEMICOLON
2754 && context_p->token.type != LEXER_LEFT_BRACE
2755 && context_p->token.type != LEXER_RIGHT_BRACE
2756 && context_p->token.type != LEXER_KEYW_VAR
2757 && context_p->token.type != LEXER_KEYW_LET
2758 && context_p->token.type != LEXER_KEYW_CONST
2759 && context_p->token.type != LEXER_KEYW_FUNCTION
2760 && context_p->token.type != LEXER_KEYW_CASE
2761 && context_p->token.type != LEXER_KEYW_DEFAULT)
2762 {
2763 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2764 parser_flush_cbc (context_p);
2765
2766 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
2767
2768 context_p->last_breakpoint_line = context_p->token.line;
2769 }
2770 #endif /* ENABLED (JERRY_DEBUGGER) */
2771
2772 #if ENABLED (JERRY_LINE_INFO)
2773 if (context_p->token.line != context_p->last_line_info_line
2774 && context_p->token.type != LEXER_SEMICOLON
2775 && context_p->token.type != LEXER_LEFT_BRACE
2776 && context_p->token.type != LEXER_RIGHT_BRACE
2777 && context_p->token.type != LEXER_KEYW_VAR
2778 && context_p->token.type != LEXER_KEYW_LET
2779 && context_p->token.type != LEXER_KEYW_CONST
2780 && context_p->token.type != LEXER_KEYW_FUNCTION
2781 && context_p->token.type != LEXER_KEYW_CASE
2782 && context_p->token.type != LEXER_KEYW_DEFAULT)
2783 {
2784 parser_emit_line_info (context_p, context_p->token.line, true);
2785 }
2786 #endif /* ENABLED (JERRY_LINE_INFO) */
2787
2788 switch (context_p->token.type)
2789 {
2790 case LEXER_SEMICOLON:
2791 {
2792 break;
2793 }
2794
2795 case LEXER_RIGHT_BRACE:
2796 {
2797 if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
2798 {
2799 parser_raise_error (context_p, PARSER_ERR_STATEMENT_EXPECTED);
2800 }
2801 break;
2802 }
2803
2804 case LEXER_LEFT_BRACE:
2805 {
2806 #if ENABLED (JERRY_ES2015)
2807 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2808 {
2809 parser_push_block_context (context_p, false);
2810 }
2811 else
2812 {
2813 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
2814 }
2815 #else /* !ENABLED (JERRY_ES2015) */
2816 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
2817 #endif /* ENABLED (JERRY_ES2015) */
2818
2819 parser_stack_iterator_init (context_p, &context_p->last_statement);
2820 lexer_next_token (context_p);
2821 continue;
2822 }
2823
2824 case LEXER_KEYW_VAR:
2825 #if ENABLED (JERRY_ES2015)
2826 case LEXER_KEYW_LET:
2827 case LEXER_KEYW_CONST:
2828 #endif /* ENABLED (JERRY_ES2015) */
2829 {
2830 parser_parse_var_statement (context_p);
2831 break;
2832 }
2833
2834 #if ENABLED (JERRY_ES2015)
2835 case LEXER_KEYW_CLASS:
2836 {
2837 parser_validate_lexical_context (context_p);
2838 parser_parse_class (context_p, true);
2839 goto consume_last_statement;
2840 }
2841 #endif /* ENABLED (JERRY_ES2015) */
2842
2843 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2844 case LEXER_KEYW_IMPORT:
2845 {
2846 parser_parse_import_statement (context_p);
2847 break;
2848 }
2849
2850 case LEXER_KEYW_EXPORT:
2851 {
2852 parser_parse_export_statement (context_p);
2853 break;
2854 }
2855 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2856
2857 case LEXER_KEYW_FUNCTION:
2858 {
2859 parser_parse_function_statement (context_p);
2860 goto consume_last_statement;
2861 }
2862
2863 case LEXER_KEYW_IF:
2864 {
2865 parser_parse_if_statement_start (context_p);
2866 continue;
2867 }
2868
2869 case LEXER_KEYW_SWITCH:
2870 {
2871 parser_parse_switch_statement_start (context_p);
2872 continue;
2873 }
2874
2875 case LEXER_KEYW_DO:
2876 {
2877 parser_do_while_statement_t do_while_statement;
2878 parser_loop_statement_t loop;
2879
2880 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
2881
2882 do_while_statement.start_offset = context_p->byte_code_size;
2883 loop.branch_list_p = NULL;
2884
2885 parser_stack_push (context_p, &do_while_statement, sizeof (parser_do_while_statement_t));
2886 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
2887 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_DO_WHILE);
2888 parser_stack_iterator_init (context_p, &context_p->last_statement);
2889 lexer_next_token (context_p);
2890 continue;
2891 }
2892
2893 case LEXER_KEYW_WHILE:
2894 {
2895 parser_parse_while_statement_start (context_p);
2896 continue;
2897 }
2898
2899 case LEXER_KEYW_FOR:
2900 {
2901 parser_parse_for_statement_start (context_p);
2902 continue;
2903 }
2904
2905 case LEXER_KEYW_WITH:
2906 {
2907 parser_parse_with_statement_start (context_p);
2908 continue;
2909 }
2910
2911 case LEXER_KEYW_TRY:
2912 {
2913 parser_try_statement_t try_statement;
2914
2915 lexer_next_token (context_p);
2916
2917 if (context_p->token.type != LEXER_LEFT_BRACE)
2918 {
2919 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2920 }
2921
2922 #ifndef JERRY_NDEBUG
2923 PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
2924 #endif /* !JERRY_NDEBUG */
2925
2926 try_statement.type = parser_try_block;
2927 parser_emit_cbc_ext_forward_branch (context_p,
2928 CBC_EXT_TRY_CREATE_CONTEXT,
2929 &try_statement.branch);
2930
2931 #if ENABLED (JERRY_ES2015)
2932 try_statement.scope_stack_top = context_p->scope_stack_top;
2933 try_statement.scope_stack_reg_top = context_p->scope_stack_reg_top;
2934
2935 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2936 {
2937 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
2938
2939 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
2940 {
2941 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
2942 }
2943
2944 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
2945 }
2946 #endif /* ENABLED (JERRY_ES2015) */
2947
2948 parser_stack_push (context_p, &try_statement, sizeof (parser_try_statement_t));
2949 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_TRY);
2950 parser_stack_iterator_init (context_p, &context_p->last_statement);
2951 lexer_next_token (context_p);
2952 continue;
2953 }
2954
2955 case LEXER_KEYW_DEFAULT:
2956 {
2957 parser_parse_default_statement (context_p);
2958 continue;
2959 }
2960
2961 case LEXER_KEYW_CASE:
2962 {
2963 parser_parse_case_statement (context_p);
2964 continue;
2965 }
2966
2967 case LEXER_KEYW_BREAK:
2968 {
2969 parser_parse_break_statement (context_p);
2970 break;
2971 }
2972
2973 case LEXER_KEYW_CONTINUE:
2974 {
2975 parser_parse_continue_statement (context_p);
2976 break;
2977 }
2978
2979 case LEXER_KEYW_THROW:
2980 {
2981 lexer_next_token (context_p);
2982 if (context_p->token.flags & LEXER_WAS_NEWLINE)
2983 {
2984 parser_raise_error (context_p, PARSER_ERR_EXPRESSION_EXPECTED);
2985 }
2986 parser_parse_expression (context_p, PARSE_EXPR);
2987 parser_emit_cbc (context_p, CBC_THROW);
2988 break;
2989 }
2990
2991 case LEXER_KEYW_RETURN:
2992 {
2993 if (!(context_p->status_flags & PARSER_IS_FUNCTION))
2994 {
2995 parser_raise_error (context_p, PARSER_ERR_INVALID_RETURN);
2996 }
2997
2998 lexer_next_token (context_p);
2999
3000 if ((context_p->token.flags & LEXER_WAS_NEWLINE)
3001 || context_p->token.type == LEXER_SEMICOLON
3002 || context_p->token.type == LEXER_EOS
3003 || context_p->token.type == LEXER_RIGHT_BRACE)
3004 {
3005 #if ENABLED (JERRY_ES2015)
3006 if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
3007 {
3008 parser_emit_cbc_ext (context_p, CBC_EXT_RETURN_PROMISE_UNDEFINED);
3009 break;
3010 }
3011 #endif /* ENABLED (JERRY_ES2015) */
3012
3013 parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK);
3014 break;
3015 }
3016
3017 parser_parse_expression (context_p, PARSE_EXPR);
3018
3019 #if ENABLED (JERRY_ES2015)
3020 if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
3021 {
3022 parser_emit_cbc_ext (context_p, CBC_EXT_RETURN_PROMISE);
3023 break;
3024 }
3025 #endif /* ENABLED (JERRY_ES2015) */
3026
3027 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
3028 {
3029 context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
3030 break;
3031 }
3032
3033 parser_emit_cbc (context_p, CBC_RETURN);
3034 break;
3035 }
3036
3037 case LEXER_KEYW_DEBUGGER:
3038 {
3039 #if ENABLED (JERRY_DEBUGGER)
3040 /* This breakpoint location is not reported to the
3041 * debugger, so it is impossible to disable it. */
3042 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
3043 {
3044 parser_emit_cbc (context_p, CBC_BREAKPOINT_ENABLED);
3045 }
3046 #endif /* ENABLED (JERRY_DEBUGGER) */
3047 lexer_next_token (context_p);
3048 break;
3049 }
3050
3051 case LEXER_LITERAL:
3052 {
3053 if (context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
3054 {
3055 if (JERRY_UNLIKELY (lexer_check_next_character (context_p, LIT_CHAR_COLON)))
3056 {
3057 parser_parse_label (context_p);
3058 lexer_consume_next_character (context_p);
3059 lexer_next_token (context_p);
3060 continue;
3061 }
3062 #if ENABLED (JERRY_ES2015)
3063 if (JERRY_UNLIKELY (lexer_token_is_let (context_p)))
3064 {
3065 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
3066 {
3067 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
3068 {
3069 scanner_release_next (context_p, sizeof (scanner_info_t));
3070 }
3071
3072 if (context_p->status_flags & PARSER_IS_FUNCTION)
3073 {
3074 parser_parse_expression_statement (context_p, PARSE_EXPR);
3075 break;
3076 }
3077
3078 parser_parse_block_expression (context_p, PARSE_EXPR);
3079 break;
3080 }
3081
3082 context_p->token.type = LEXER_KEYW_LET;
3083 parser_parse_var_statement (context_p);
3084 break;
3085 }
3086
3087 if (JERRY_UNLIKELY (lexer_token_is_async (context_p))
3088 && context_p->next_scanner_info_p->source_p == context_p->source_p)
3089 {
3090 bool is_statement = true;
3091
3092 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION)
3093 {
3094 is_statement = (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT) != 0;
3095
3096 JERRY_ASSERT (!is_statement || (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC));
3097 }
3098 else
3099 {
3100 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
3101
3102 scanner_release_next (context_p, sizeof (scanner_info_t));
3103 }
3104
3105 if (is_statement)
3106 {
3107 if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
3108 {
3109 parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
3110 }
3111
3112 lexer_next_token (context_p);
3113 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FUNCTION);
3114 continue;
3115 }
3116 }
3117 #endif /* ENABLED (JERRY_ES2015) */
3118 }
3119 /* FALLTHRU */
3120 }
3121
3122 default:
3123 {
3124 int options = PARSE_EXPR;
3125
3126 if (context_p->token.type == LEXER_EXPRESSION_START)
3127 {
3128 /* Restore the token type form the extra_value. */
3129 context_p->token.type = context_p->token.extra_value;
3130 options |= PARSE_EXPR_HAS_LITERAL;
3131 }
3132
3133 if (context_p->status_flags & PARSER_IS_FUNCTION)
3134 {
3135 parser_parse_expression_statement (context_p, options);
3136 }
3137 else
3138 {
3139 parser_parse_block_expression (context_p, options);
3140 }
3141
3142 break;
3143 }
3144 }
3145
3146 parser_flush_cbc (context_p);
3147
3148 if (context_p->token.type == LEXER_RIGHT_BRACE)
3149 {
3150 if (context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK)
3151 {
3152 parser_stack_pop_uint8 (context_p);
3153 parser_stack_iterator_init (context_p, &context_p->last_statement);
3154 lexer_next_token (context_p);
3155 }
3156 #if ENABLED (JERRY_ES2015)
3157 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_SCOPE
3158 || context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_CONTEXT)
3159 {
3160 parser_pop_block_context (context_p);
3161 lexer_next_token (context_p);
3162 }
3163 #endif /* ENABLED (JERRY_ES2015) */
3164 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH
3165 || context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH_NO_DEFAULT)
3166 {
3167 int has_default = (context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH);
3168 parser_loop_statement_t loop;
3169 parser_switch_statement_t switch_statement;
3170
3171 parser_stack_pop_uint8 (context_p);
3172 parser_stack_pop (context_p, &loop, sizeof (parser_loop_statement_t));
3173 parser_stack_pop (context_p, &switch_statement, sizeof (parser_switch_statement_t));
3174 parser_stack_iterator_init (context_p, &context_p->last_statement);
3175
3176 JERRY_ASSERT (switch_statement.branch_list_p == NULL);
3177
3178 if (!has_default)
3179 {
3180 parser_set_branch_to_current_position (context_p, &switch_statement.default_branch);
3181 }
3182
3183 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
3184 lexer_next_token (context_p);
3185
3186 #if ENABLED (JERRY_ES2015)
3187 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
3188 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
3189 {
3190 parser_pop_block_context (context_p);
3191 }
3192 #endif /* ENABLED (JERRY_ES2015) */
3193 }
3194 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_TRY)
3195 {
3196 parser_parse_try_statement_end (context_p);
3197 }
3198 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_START)
3199 {
3200 if (context_p->status_flags & PARSER_IS_CLOSURE)
3201 {
3202 parser_stack_pop_uint8 (context_p);
3203 context_p->last_statement.current_p = NULL;
3204 /* There is no lexer_next_token here, since the
3205 * next token belongs to the parent context. */
3206 return;
3207 }
3208 parser_raise_error (context_p, PARSER_ERR_INVALID_RIGHT_SQUARE);
3209 }
3210 }
3211 else if (context_p->token.type == LEXER_SEMICOLON)
3212 {
3213 lexer_next_token (context_p);
3214 }
3215 else if (context_p->token.type != LEXER_EOS
3216 && !(context_p->token.flags & LEXER_WAS_NEWLINE))
3217 {
3218 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
3219 }
3220
3221 consume_last_statement:
3222 while (true)
3223 {
3224 switch (context_p->stack_top_uint8)
3225 {
3226 case PARSER_STATEMENT_LABEL:
3227 {
3228 parser_label_statement_t label;
3229
3230 parser_stack_pop_uint8 (context_p);
3231 parser_stack_pop (context_p, &label, sizeof (parser_label_statement_t));
3232 parser_stack_iterator_init (context_p, &context_p->last_statement);
3233
3234 parser_set_breaks_to_current_position (context_p, label.break_list_p);
3235 continue;
3236 }
3237
3238 case PARSER_STATEMENT_IF:
3239 {
3240 if (parser_parse_if_statement_end (context_p))
3241 {
3242 break;
3243 }
3244 continue;
3245 }
3246
3247 case PARSER_STATEMENT_ELSE:
3248 {
3249 parser_if_else_statement_t else_statement;
3250
3251 parser_stack_pop_uint8 (context_p);
3252 parser_stack_pop (context_p, &else_statement, sizeof (parser_if_else_statement_t));
3253 parser_stack_iterator_init (context_p, &context_p->last_statement);
3254
3255 parser_set_branch_to_current_position (context_p, &else_statement.branch);
3256 continue;
3257 }
3258
3259 case PARSER_STATEMENT_DO_WHILE:
3260 {
3261 parser_parse_do_while_statement_end (context_p);
3262 if (context_p->token.type == LEXER_SEMICOLON)
3263 {
3264 lexer_next_token (context_p);
3265 }
3266 continue;
3267 }
3268
3269 case PARSER_STATEMENT_WHILE:
3270 {
3271 parser_parse_while_statement_end (context_p);
3272 continue;
3273 }
3274
3275 case PARSER_STATEMENT_FOR:
3276 {
3277 parser_parse_for_statement_end (context_p);
3278 continue;
3279 }
3280
3281 case PARSER_STATEMENT_FOR_IN:
3282 #if ENABLED (JERRY_ES2015)
3283 case PARSER_STATEMENT_FOR_OF:
3284 #endif /* ENABLED (JERRY_ES2015) */
3285 {
3286 parser_for_in_of_statement_t for_in_of_statement;
3287 parser_loop_statement_t loop;
3288
3289 #if ENABLED (JERRY_ES2015)
3290 bool is_for_in = (context_p->stack_top_uint8 == PARSER_STATEMENT_FOR_IN);
3291 #else
3292 bool is_for_in = true;
3293 #endif /* ENABLED (JERRY_ES2015) */
3294
3295 parser_stack_pop_uint8 (context_p);
3296 parser_stack_pop (context_p, &loop, sizeof (parser_loop_statement_t));
3297 parser_stack_pop (context_p, &for_in_of_statement, sizeof (parser_for_in_of_statement_t));
3298 parser_stack_iterator_init (context_p, &context_p->last_statement);
3299
3300 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
3301
3302 parser_flush_cbc (context_p);
3303 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, is_for_in ? PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION
3304 : PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
3305 #ifndef JERRY_NDEBUG
3306 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth,
3307 is_for_in ? PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION
3308 : PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
3309 #endif /* !JERRY_NDEBUG */
3310
3311 parser_emit_cbc_ext_backward_branch (context_p,
3312 is_for_in ? CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT
3313 : CBC_EXT_BRANCH_IF_FOR_OF_HAS_NEXT,
3314 for_in_of_statement.start_offset);
3315
3316 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
3317 parser_set_branch_to_current_position (context_p, &for_in_of_statement.branch);
3318
3319 #if ENABLED (JERRY_ES2015)
3320 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
3321 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
3322 {
3323 parser_pop_block_context (context_p);
3324 }
3325 #endif /* ENABLED (JERRY_ES2015) */
3326 continue;
3327 }
3328
3329 case PARSER_STATEMENT_WITH:
3330 {
3331 parser_parse_with_statement_end (context_p);
3332 continue;
3333 }
3334
3335 default:
3336 {
3337 break;
3338 }
3339 }
3340 break;
3341 }
3342 }
3343
3344 parser_stack_pop_uint8 (context_p);
3345 context_p->last_statement.current_p = NULL;
3346
3347 if (context_p->status_flags & PARSER_IS_CLOSURE)
3348 {
3349 parser_raise_error (context_p, PARSER_ERR_STATEMENT_EXPECTED);
3350 }
3351 } /* parser_parse_statements */
3352
3353 /**
3354 * Free jumps stored on the stack if a parse error is occured.
3355 */
3356 void JERRY_ATTR_NOINLINE
parser_free_jumps(parser_stack_iterator_t iterator)3357 parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
3358 {
3359 while (true)
3360 {
3361 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
3362 parser_branch_node_t *branch_list_p = NULL;
3363
3364 switch (type)
3365 {
3366 case PARSER_STATEMENT_START:
3367 {
3368 return;
3369 }
3370
3371 case PARSER_STATEMENT_LABEL:
3372 {
3373 parser_label_statement_t label;
3374
3375 parser_stack_iterator_skip (&iterator, 1);
3376 parser_stack_iterator_read (&iterator, &label, sizeof (parser_label_statement_t));
3377 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
3378 branch_list_p = label.break_list_p;
3379 break;
3380 }
3381
3382 case PARSER_STATEMENT_SWITCH:
3383 case PARSER_STATEMENT_SWITCH_NO_DEFAULT:
3384 {
3385 parser_switch_statement_t switch_statement;
3386 parser_loop_statement_t loop;
3387
3388 parser_stack_iterator_skip (&iterator, 1);
3389 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
3390 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
3391 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
3392 parser_stack_iterator_skip (&iterator, sizeof (parser_switch_statement_t));
3393
3394 branch_list_p = switch_statement.branch_list_p;
3395 while (branch_list_p != NULL)
3396 {
3397 parser_branch_node_t *next_p = branch_list_p->next_p;
3398 parser_free (branch_list_p, sizeof (parser_branch_node_t));
3399 branch_list_p = next_p;
3400 }
3401 branch_list_p = loop.branch_list_p;
3402 break;
3403 }
3404
3405 case PARSER_STATEMENT_DO_WHILE:
3406 case PARSER_STATEMENT_WHILE:
3407 case PARSER_STATEMENT_FOR:
3408 case PARSER_STATEMENT_FOR_IN:
3409 #if ENABLED (JERRY_ES2015)
3410 case PARSER_STATEMENT_FOR_OF:
3411 #endif /* ENABLED (JERRY_ES2015) */
3412 {
3413 parser_loop_statement_t loop;
3414
3415 parser_stack_iterator_skip (&iterator, 1);
3416 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
3417 parser_stack_iterator_skip (&iterator, parser_statement_length (type) - 1);
3418 branch_list_p = loop.branch_list_p;
3419 break;
3420 }
3421
3422 default:
3423 {
3424 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
3425 continue;
3426 }
3427 }
3428
3429 while (branch_list_p != NULL)
3430 {
3431 parser_branch_node_t *next_p = branch_list_p->next_p;
3432 parser_free (branch_list_p, sizeof (parser_branch_node_t));
3433 branch_list_p = next_p;
3434 }
3435 }
3436 } /* parser_free_jumps */
3437
3438 /**
3439 * @}
3440 * @}
3441 * @}
3442 */
3443
3444 #endif /* ENABLED (JERRY_PARSER) */
3445