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
1458 if (context_p->next_scanner_info_p->source_p == context_p->source_p
1459 && context_p->next_scanner_info_p->type != SCANNER_TYPE_BLOCK)
1460 {
1461 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
1462 {
1463 scanner_release_next (context_p, sizeof (scanner_info_t));
1464 }
1465
1466 parser_parse_expression_statement (context_p, PARSE_EXPR);
1467 break;
1468 }
1469
1470 context_p->token.type = LEXER_KEYW_LET;
1471 /* FALLTHRU */
1472 }
1473 case LEXER_KEYW_LET:
1474 case LEXER_KEYW_CONST:
1475 {
1476 if (context_p->next_scanner_info_p->source_p == source_p)
1477 {
1478 parser_push_block_context (context_p, true);
1479 }
1480 /* FALLTHRU */
1481 }
1482 #endif /* ENABLED (JERRY_ES2015) */
1483 case LEXER_KEYW_VAR:
1484 {
1485 parser_parse_var_statement (context_p);
1486 break;
1487 }
1488 default:
1489 {
1490 parser_parse_expression_statement (context_p, PARSE_EXPR);
1491 break;
1492 }
1493 }
1494
1495 if (context_p->token.type != LEXER_SEMICOLON)
1496 {
1497 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1498 }
1499 }
1500
1501 JERRY_ASSERT (context_p->next_scanner_info_p->source_p != context_p->source_p
1502 || context_p->next_scanner_info_p->type == SCANNER_TYPE_FOR);
1503
1504 if (context_p->next_scanner_info_p->source_p != context_p->source_p
1505 || ((scanner_for_info_t *) context_p->next_scanner_info_p)->end_location.source_p == NULL)
1506 {
1507 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1508 {
1509 /* Even though the scanning is failed, there might be valid statements
1510 * inside the for statement which depend on scanner info blocks. */
1511 scanner_release_next (context_p, sizeof (scanner_for_info_t));
1512 }
1513
1514 /* The prescanner couldn't find the second semicolon or the closing paranthesis. */
1515 lexer_next_token (context_p);
1516 parser_parse_expression (context_p, PARSE_EXPR);
1517
1518 if (context_p->token.type != LEXER_SEMICOLON)
1519 {
1520 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1521 }
1522
1523 lexer_next_token (context_p);
1524 parser_parse_expression_statement (context_p, PARSE_EXPR);
1525
1526 JERRY_ASSERT (context_p->token.type != LEXER_RIGHT_PAREN);
1527 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1528 }
1529
1530 parser_for_statement_t for_statement;
1531 scanner_for_info_t *for_info_p = (scanner_for_info_t *) context_p->next_scanner_info_p;
1532
1533 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &for_statement.branch);
1534
1535 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
1536
1537 for_statement.start_offset = context_p->byte_code_size;
1538 scanner_get_location (&for_statement.condition_location, context_p);
1539 for_statement.expression_location = for_info_p->expression_location;
1540
1541 scanner_set_location (context_p, &for_info_p->end_location);
1542 scanner_release_next (context_p, sizeof (scanner_for_info_t));
1543 scanner_seek (context_p);
1544 lexer_next_token (context_p);
1545
1546 loop.branch_list_p = NULL;
1547
1548 parser_stack_push (context_p, &for_statement, sizeof (parser_for_statement_t));
1549 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1550 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_FOR);
1551 parser_stack_iterator_init (context_p, &context_p->last_statement);
1552 } /* parser_parse_for_statement_start */
1553
1554 /**
1555 * Parse for statement (ending part).
1556 */
1557 static void JERRY_ATTR_NOINLINE
parser_parse_for_statement_end(parser_context_t * context_p)1558 parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
1559 {
1560 parser_for_statement_t for_statement;
1561 parser_loop_statement_t loop;
1562 lexer_token_t current_token;
1563 scanner_location_t location;
1564 cbc_opcode_t opcode;
1565
1566 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_FOR);
1567
1568 parser_stack_iterator_t iterator;
1569 parser_stack_iterator_init (context_p, &iterator);
1570
1571 parser_stack_iterator_skip (&iterator, 1);
1572 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
1573 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
1574 parser_stack_iterator_read (&iterator, &for_statement, sizeof (parser_for_statement_t));
1575
1576 #if ENABLED (JERRY_ES2015)
1577 bool has_block_context = false;
1578 uint8_t next_statement_type;
1579
1580 parser_stack_iterator_skip (&iterator, sizeof (parser_for_statement_t));
1581 parser_stack_iterator_read (&iterator, &next_statement_type, 1);
1582
1583 if (next_statement_type == PARSER_STATEMENT_PRIVATE_CONTEXT)
1584 {
1585 has_block_context = true;
1586 }
1587 #endif
1588
1589 scanner_get_location (&location, context_p);
1590 current_token = context_p->token;
1591
1592 scanner_set_location (context_p, &for_statement.expression_location);
1593 scanner_seek (context_p);
1594 lexer_next_token (context_p);
1595
1596 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
1597
1598 #if ENABLED (JERRY_ES2015)
1599 if (has_block_context)
1600 {
1601 parser_emit_cbc_ext (context_p, CBC_EXT_CLONE_FULL_CONTEXT);
1602 }
1603 #endif
1604
1605 if (context_p->token.type != LEXER_RIGHT_PAREN)
1606 {
1607 parser_parse_expression_statement (context_p, PARSE_EXPR);
1608
1609 if (context_p->token.type != LEXER_RIGHT_PAREN)
1610 {
1611 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1612 }
1613 }
1614
1615 parser_set_branch_to_current_position (context_p, &for_statement.branch);
1616
1617 scanner_set_location (context_p, &for_statement.condition_location);
1618 scanner_seek (context_p);
1619 lexer_next_token (context_p);
1620
1621 if (context_p->token.type != LEXER_SEMICOLON)
1622 {
1623 parser_parse_expression (context_p, PARSE_EXPR);
1624
1625 if (context_p->token.type != LEXER_SEMICOLON)
1626 {
1627 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
1628 }
1629
1630 opcode = CBC_BRANCH_IF_TRUE_BACKWARD;
1631 if (context_p->last_cbc_opcode == CBC_LOGICAL_NOT)
1632 {
1633 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1634 opcode = CBC_BRANCH_IF_FALSE_BACKWARD;
1635 }
1636 else if (context_p->last_cbc_opcode == CBC_PUSH_TRUE)
1637 {
1638 context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
1639 opcode = CBC_JUMP_BACKWARD;
1640 }
1641 }
1642 else
1643 {
1644 opcode = CBC_JUMP_BACKWARD;
1645 }
1646
1647 parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_for_statement_t));
1648 parser_stack_iterator_init (context_p, &context_p->last_statement);
1649
1650 parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, for_statement.start_offset);
1651 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
1652
1653 #if ENABLED (JERRY_ES2015)
1654 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
1655 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
1656 {
1657 parser_pop_block_context (context_p);
1658 }
1659 #endif
1660
1661 /* Calling scanner_seek is unnecessary because all
1662 * info blocks inside the for statement should be processed. */
1663 scanner_set_location (context_p, &location);
1664 context_p->token = current_token;
1665 } /* parser_parse_for_statement_end */
1666
1667 /**
1668 * Parse switch statement (starting part).
1669 */
1670 static void JERRY_ATTR_NOINLINE
parser_parse_switch_statement_start(parser_context_t * context_p)1671 parser_parse_switch_statement_start (parser_context_t *context_p) /**< context */
1672 {
1673 parser_switch_statement_t switch_statement;
1674 parser_loop_statement_t loop;
1675 parser_stack_iterator_t iterator;
1676 scanner_location_t start_location;
1677 bool switch_case_was_found;
1678 bool default_case_was_found;
1679 parser_branch_node_t *case_branches_p = NULL;
1680
1681 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_SWITCH);
1682
1683 parser_parse_enclosed_expr (context_p);
1684
1685 if (context_p->token.type != LEXER_LEFT_BRACE)
1686 {
1687 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
1688 }
1689
1690 #if ENABLED (JERRY_ES2015)
1691 if (context_p->next_scanner_info_p->source_p == context_p->source_p - 1)
1692 {
1693 parser_push_block_context (context_p, true);
1694 }
1695 #endif /* ENABLED (JERRY_ES2015) */
1696
1697 JERRY_ASSERT (context_p->next_scanner_info_p->source_p == context_p->source_p
1698 && context_p->next_scanner_info_p->type == SCANNER_TYPE_SWITCH);
1699
1700 scanner_case_info_t *case_info_p = ((scanner_switch_info_t *) context_p->next_scanner_info_p)->case_p;
1701 scanner_set_active (context_p);
1702
1703 if (case_info_p == NULL)
1704 {
1705 lexer_next_token (context_p);
1706
1707 if (context_p->token.type == LEXER_RIGHT_BRACE)
1708 {
1709 scanner_release_active (context_p, sizeof (scanner_switch_info_t));
1710
1711 parser_emit_cbc (context_p, CBC_POP);
1712 parser_flush_cbc (context_p);
1713
1714 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
1715 parser_stack_iterator_init (context_p, &context_p->last_statement);
1716 return;
1717 }
1718
1719 parser_raise_error (context_p, PARSER_ERR_INVALID_SWITCH);
1720 }
1721
1722 scanner_get_location (&start_location, context_p);
1723
1724 /* The reason of using an iterator is error management. If an error
1725 * occures, parser_free_jumps() free all data. However, the branches
1726 * created by parser_emit_cbc_forward_branch_item() would not be freed.
1727 * To free these branches, the current switch data is always stored
1728 * on the stack. If any change happens, this data is updated. Updates
1729 * are done using the iterator. */
1730
1731 switch_statement.branch_list_p = NULL;
1732 loop.branch_list_p = NULL;
1733
1734 parser_stack_push (context_p, &switch_statement, sizeof (parser_switch_statement_t));
1735 parser_stack_iterator_init (context_p, &iterator);
1736 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
1737 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_SWITCH);
1738 parser_stack_iterator_init (context_p, &context_p->last_statement);
1739
1740 switch_case_was_found = false;
1741 default_case_was_found = false;
1742
1743 #if ENABLED (JERRY_LINE_INFO)
1744 uint32_t last_line_info_line = context_p->last_line_info_line;
1745 #endif /* ENABLED (JERRY_LINE_INFO) */
1746
1747 do
1748 {
1749 scanner_set_location (context_p, &case_info_p->location);
1750 scanner_seek (context_p);
1751 case_info_p = case_info_p->next_p;
1752
1753 /* The last letter of case and default is 'e' and 't' respectively. */
1754 JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LOWERCASE_E
1755 || context_p->source_p[-1] == LIT_CHAR_LOWERCASE_T);
1756
1757 bool is_default = context_p->source_p[-1] == LIT_CHAR_LOWERCASE_T;
1758 lexer_next_token (context_p);
1759
1760 if (is_default)
1761 {
1762 if (default_case_was_found)
1763 {
1764 parser_raise_error (context_p, PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED);
1765 }
1766
1767 if (context_p->token.type != LEXER_COLON)
1768 {
1769 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1770 }
1771
1772 default_case_was_found = true;
1773 continue;
1774 }
1775
1776 switch_case_was_found = true;
1777
1778 #if ENABLED (JERRY_LINE_INFO)
1779 if (context_p->token.line != context_p->last_line_info_line)
1780 {
1781 parser_emit_line_info (context_p, context_p->token.line, true);
1782 }
1783 #endif /* ENABLED (JERRY_LINE_INFO) */
1784
1785 parser_parse_expression (context_p, PARSE_EXPR);
1786
1787 if (context_p->token.type != LEXER_COLON)
1788 {
1789 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
1790 }
1791
1792 uint16_t opcode = CBC_BRANCH_IF_STRICT_EQUAL;
1793
1794 if (case_info_p == NULL
1795 || (case_info_p->next_p == NULL && case_info_p->location.source_p[-1] == LIT_CHAR_LOWERCASE_T))
1796 {
1797 /* There are no more 'case' statements in the switch. */
1798 parser_emit_cbc (context_p, CBC_STRICT_EQUAL);
1799 opcode = CBC_BRANCH_IF_TRUE_FORWARD;
1800 }
1801
1802 parser_branch_node_t *new_case_p = parser_emit_cbc_forward_branch_item (context_p, opcode, NULL);
1803
1804 if (case_branches_p == NULL)
1805 {
1806 switch_statement.branch_list_p = new_case_p;
1807 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
1808 }
1809 else
1810 {
1811 case_branches_p->next_p = new_case_p;
1812 }
1813
1814 case_branches_p = new_case_p;
1815 }
1816 while (case_info_p != NULL);
1817
1818 JERRY_ASSERT (switch_case_was_found || default_case_was_found);
1819
1820 #if ENABLED (JERRY_LINE_INFO)
1821 context_p->last_line_info_line = last_line_info_line;
1822 #endif /* ENABLED (JERRY_LINE_INFO) */
1823
1824 if (!switch_case_was_found)
1825 {
1826 /* There was no case statement, so the expression result
1827 * of the switch must be popped from the stack */
1828 parser_emit_cbc (context_p, CBC_POP);
1829 }
1830
1831 parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &switch_statement.default_branch);
1832 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
1833
1834 if (!default_case_was_found)
1835 {
1836 parser_stack_change_last_uint8 (context_p, PARSER_STATEMENT_SWITCH_NO_DEFAULT);
1837 }
1838
1839 scanner_release_switch_cases (((scanner_switch_info_t *) context_p->active_scanner_info_p)->case_p);
1840 scanner_release_active (context_p, sizeof (scanner_switch_info_t));
1841
1842 scanner_set_location (context_p, &start_location);
1843 scanner_seek (context_p);
1844 lexer_next_token (context_p);
1845 } /* parser_parse_switch_statement_start */
1846
1847 /**
1848 * Parse try statement (ending part).
1849 */
1850 static void
parser_parse_try_statement_end(parser_context_t * context_p)1851 parser_parse_try_statement_end (parser_context_t *context_p) /**< context */
1852 {
1853 parser_try_statement_t try_statement;
1854 parser_stack_iterator_t iterator;
1855
1856 JERRY_ASSERT (context_p->stack_top_uint8 == PARSER_STATEMENT_TRY);
1857
1858 parser_stack_iterator_init (context_p, &iterator);
1859 parser_stack_iterator_skip (&iterator, 1);
1860 parser_stack_iterator_read (&iterator, &try_statement, sizeof (parser_try_statement_t));
1861
1862 #if ENABLED (JERRY_ES2015)
1863 context_p->scope_stack_top = try_statement.scope_stack_top;
1864 context_p->scope_stack_reg_top = try_statement.scope_stack_reg_top;
1865 #endif /* ENABLED (JERRY_ES2015) */
1866
1867 lexer_next_token (context_p);
1868
1869 if (try_statement.type == parser_finally_block)
1870 {
1871 parser_flush_cbc (context_p);
1872 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1873 #ifndef JERRY_NDEBUG
1874 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1875 #endif /* !JERRY_NDEBUG */
1876
1877 parser_emit_cbc (context_p, CBC_CONTEXT_END);
1878 parser_set_branch_to_current_position (context_p, &try_statement.branch);
1879 }
1880 else
1881 {
1882 parser_set_branch_to_current_position (context_p, &try_statement.branch);
1883
1884 if (try_statement.type == parser_catch_block)
1885 {
1886 #if !ENABLED (JERRY_ES2015)
1887 context_p->scope_stack_top = try_statement.scope_stack_top;
1888 context_p->scope_stack_reg_top = try_statement.scope_stack_reg_top;
1889 #endif /* !ENABLED (JERRY_ES2015) */
1890
1891 if (context_p->token.type != LEXER_KEYW_FINALLY)
1892 {
1893 parser_flush_cbc (context_p);
1894 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1895 #ifndef JERRY_NDEBUG
1896 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
1897 #endif /* !JERRY_NDEBUG */
1898
1899 parser_emit_cbc (context_p, CBC_CONTEXT_END);
1900 parser_flush_cbc (context_p);
1901
1902 try_statement.type = parser_finally_block;
1903 }
1904 }
1905 else if (try_statement.type == parser_try_block
1906 && context_p->token.type != LEXER_KEYW_CATCH
1907 && context_p->token.type != LEXER_KEYW_FINALLY)
1908 {
1909 parser_raise_error (context_p, PARSER_ERR_CATCH_FINALLY_EXPECTED);
1910 }
1911 }
1912
1913 if (try_statement.type == parser_finally_block)
1914 {
1915 parser_stack_pop (context_p, NULL, (uint32_t) (sizeof (parser_try_statement_t) + 1));
1916 parser_stack_iterator_init (context_p, &context_p->last_statement);
1917 return;
1918 }
1919
1920 if (context_p->token.type == LEXER_KEYW_CATCH)
1921 {
1922 lexer_next_token (context_p);
1923
1924 if (context_p->token.type != LEXER_LEFT_PAREN)
1925 {
1926 parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
1927 }
1928
1929 try_statement.type = parser_catch_block;
1930 parser_emit_cbc_ext_forward_branch (context_p,
1931 CBC_EXT_CATCH,
1932 &try_statement.branch);
1933
1934 try_statement.scope_stack_top = context_p->scope_stack_top;
1935 try_statement.scope_stack_reg_top = context_p->scope_stack_reg_top;
1936
1937 #ifndef JERRY_NDEBUG
1938 bool block_found = false;
1939 #endif /* !JERRY_NDEBUG */
1940
1941 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
1942 {
1943 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
1944 #ifndef JERRY_NDEBUG
1945 block_found = true;
1946 #endif /* !JERRY_NDEBUG */
1947
1948 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
1949 {
1950 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
1951 }
1952
1953 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
1954 }
1955
1956 #if ENABLED (JERRY_ES2015)
1957 if (lexer_check_next_characters (context_p, LIT_CHAR_LEFT_SQUARE, LIT_CHAR_LEFT_BRACE))
1958 {
1959 parser_pattern_flags_t flags = (PARSER_PATTERN_BINDING
1960 | PARSER_PATTERN_TARGET_ON_STACK
1961 | PARSER_PATTERN_LET);
1962
1963 parser_parse_initializer_by_next_char (context_p, flags);
1964 }
1965 else
1966 {
1967 #endif /* ENABLED (JERRY_ES2015) */
1968 lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
1969 JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
1970 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
1971
1972 #if ENABLED (JERRY_ES2015)
1973 uint16_t literal_index = context_p->lit_object.index;
1974 parser_emit_cbc_literal (context_p,
1975 (literal_index >= PARSER_REGISTER_START) ? CBC_ASSIGN_SET_IDENT : CBC_ASSIGN_LET_CONST,
1976 literal_index);
1977 #else /* !ENABLED (JERRY_ES2015) */
1978 parser_emit_cbc_literal (context_p, CBC_ASSIGN_SET_IDENT, context_p->lit_object.index);
1979 #endif /* ENABLED (JERRY_ES2015) */
1980
1981 lexer_next_token (context_p);
1982
1983 #ifndef JERRY_NDEBUG
1984 JERRY_ASSERT (block_found);
1985 #endif /* !JERRY_NDEBUG */
1986 #if ENABLED (JERRY_ES2015)
1987 }
1988 #endif /* ENABLED (JERRY_ES2015) */
1989
1990 if (context_p->token.type != LEXER_RIGHT_PAREN)
1991 {
1992 parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
1993 }
1994
1995 lexer_next_token (context_p);
1996
1997 if (context_p->token.type != LEXER_LEFT_BRACE)
1998 {
1999 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2000 }
2001
2002 parser_flush_cbc (context_p);
2003 }
2004 else
2005 {
2006 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FINALLY);
2007
2008 lexer_next_token (context_p);
2009
2010 if (context_p->token.type != LEXER_LEFT_BRACE)
2011 {
2012 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2013 }
2014
2015 try_statement.type = parser_finally_block;
2016 parser_emit_cbc_ext_forward_branch (context_p,
2017 CBC_EXT_FINALLY,
2018 &try_statement.branch);
2019
2020 #if ENABLED (JERRY_ES2015)
2021 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2022 {
2023 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
2024
2025 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
2026 {
2027 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
2028 }
2029
2030 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
2031 }
2032 #endif /* ENABLED (JERRY_ES2015) */
2033 }
2034
2035 lexer_next_token (context_p);
2036 parser_stack_iterator_write (&iterator, &try_statement, sizeof (parser_try_statement_t));
2037 } /* parser_parse_try_statement_end */
2038
2039 /**
2040 * Parse default statement.
2041 */
2042 static void
parser_parse_default_statement(parser_context_t * context_p)2043 parser_parse_default_statement (parser_context_t *context_p) /**< context */
2044 {
2045 parser_stack_iterator_t iterator;
2046 parser_switch_statement_t switch_statement;
2047
2048 if (context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH
2049 && context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH_NO_DEFAULT)
2050 {
2051 parser_raise_error (context_p, PARSER_ERR_DEFAULT_NOT_IN_SWITCH);
2052 }
2053
2054 lexer_next_token (context_p);
2055 /* Already checked in parser_parse_switch_statement_start. */
2056 JERRY_ASSERT (context_p->token.type == LEXER_COLON);
2057 lexer_next_token (context_p);
2058
2059 parser_stack_iterator_init (context_p, &iterator);
2060 parser_stack_iterator_skip (&iterator, 1 + sizeof (parser_loop_statement_t));
2061 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2062
2063 parser_set_branch_to_current_position (context_p, &switch_statement.default_branch);
2064 } /* parser_parse_default_statement */
2065
2066 /**
2067 * Parse case statement.
2068 */
2069 static void
parser_parse_case_statement(parser_context_t * context_p)2070 parser_parse_case_statement (parser_context_t *context_p) /**< context */
2071 {
2072 parser_stack_iterator_t iterator;
2073 parser_switch_statement_t switch_statement;
2074 parser_branch_node_t *branch_p;
2075
2076 if (context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH
2077 && context_p->stack_top_uint8 != PARSER_STATEMENT_SWITCH_NO_DEFAULT)
2078 {
2079 parser_raise_error (context_p, PARSER_ERR_CASE_NOT_IN_SWITCH);
2080 }
2081
2082 if (context_p->next_scanner_info_p->source_p != context_p->source_p)
2083 {
2084 lexer_next_token (context_p);
2085
2086 parser_parse_expression (context_p, PARSE_EXPR);
2087
2088 JERRY_ASSERT (context_p->token.type != LEXER_COLON);
2089 parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
2090 }
2091
2092 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_CASE);
2093
2094 scanner_set_location (context_p, &((scanner_location_info_t *) context_p->next_scanner_info_p)->location);
2095 scanner_release_next (context_p, sizeof (scanner_location_info_t));
2096 scanner_seek (context_p);
2097 lexer_next_token (context_p);
2098
2099 parser_stack_iterator_init (context_p, &iterator);
2100 parser_stack_iterator_skip (&iterator, 1 + sizeof (parser_loop_statement_t));
2101 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2102
2103 /* Free memory after the case statement is found. */
2104
2105 branch_p = switch_statement.branch_list_p;
2106 JERRY_ASSERT (branch_p != NULL);
2107 switch_statement.branch_list_p = branch_p->next_p;
2108 parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
2109
2110 parser_set_branch_to_current_position (context_p, &branch_p->branch);
2111 parser_free (branch_p, sizeof (parser_branch_node_t));
2112 } /* parser_parse_case_statement */
2113
2114 /**
2115 * Parse break statement.
2116 */
2117 static void
parser_parse_break_statement(parser_context_t * context_p)2118 parser_parse_break_statement (parser_context_t *context_p) /**< context */
2119 {
2120 parser_stack_iterator_t iterator;
2121 cbc_opcode_t opcode = CBC_JUMP_FORWARD;
2122
2123 lexer_next_token (context_p);
2124 parser_stack_iterator_init (context_p, &iterator);
2125
2126 if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2127 && context_p->token.type == LEXER_LITERAL
2128 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
2129 {
2130 /* The label with the same name is searched on the stack. */
2131 while (true)
2132 {
2133 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2134 if (type == PARSER_STATEMENT_START)
2135 {
2136 parser_raise_error (context_p, PARSER_ERR_INVALID_BREAK_LABEL);
2137 }
2138
2139 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2140 {
2141 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2142 }
2143
2144 if (type == PARSER_STATEMENT_LABEL)
2145 {
2146 parser_label_statement_t label_statement;
2147
2148 parser_stack_iterator_skip (&iterator, 1);
2149 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2150
2151 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2152 {
2153 label_statement.break_list_p = parser_emit_cbc_forward_branch_item (context_p,
2154 (uint16_t) opcode,
2155 label_statement.break_list_p);
2156 parser_stack_iterator_write (&iterator, &label_statement, sizeof (parser_label_statement_t));
2157 lexer_next_token (context_p);
2158 return;
2159 }
2160 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2161 }
2162 else
2163 {
2164 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2165 }
2166 }
2167 }
2168
2169 /* The first switch or loop statement is searched. */
2170 while (true)
2171 {
2172 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2173 if (type == PARSER_STATEMENT_START)
2174 {
2175 parser_raise_error (context_p, PARSER_ERR_INVALID_BREAK);
2176 }
2177
2178 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2179 {
2180 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2181 }
2182
2183 if (parser_statement_flags[type] & PARSER_STATM_BREAK_TARGET)
2184 {
2185 parser_loop_statement_t loop;
2186
2187 parser_stack_iterator_skip (&iterator, 1);
2188 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
2189 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2190 (uint16_t) opcode,
2191 loop.branch_list_p);
2192 parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
2193 return;
2194 }
2195
2196 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2197 }
2198 } /* parser_parse_break_statement */
2199
2200 /**
2201 * Parse continue statement.
2202 */
2203 static void
parser_parse_continue_statement(parser_context_t * context_p)2204 parser_parse_continue_statement (parser_context_t *context_p) /**< context */
2205 {
2206 parser_stack_iterator_t iterator;
2207 cbc_opcode_t opcode = CBC_JUMP_FORWARD;
2208
2209 lexer_next_token (context_p);
2210 parser_stack_iterator_init (context_p, &iterator);
2211
2212 if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
2213 && context_p->token.type == LEXER_LITERAL
2214 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
2215 {
2216 parser_stack_iterator_t loop_iterator;
2217
2218 loop_iterator.current_p = NULL;
2219
2220 /* The label with the same name is searched on the stack. */
2221 while (true)
2222 {
2223 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2224
2225 if (type == PARSER_STATEMENT_START)
2226 {
2227 parser_raise_error (context_p, PARSER_ERR_INVALID_CONTINUE_LABEL);
2228 }
2229
2230 /* Only those labels are checked, whose are label of a loop. */
2231 if (loop_iterator.current_p != NULL && type == PARSER_STATEMENT_LABEL)
2232 {
2233 parser_label_statement_t label_statement;
2234
2235 parser_stack_iterator_skip (&iterator, 1);
2236 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2237
2238 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2239 {
2240 parser_loop_statement_t loop;
2241
2242 parser_stack_iterator_skip (&loop_iterator, 1);
2243 parser_stack_iterator_read (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
2244 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2245 (uint16_t) opcode,
2246 loop.branch_list_p);
2247 loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
2248 parser_stack_iterator_write (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
2249 lexer_next_token (context_p);
2250 return;
2251 }
2252 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2253 continue;
2254 }
2255
2256 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2257 {
2258 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2259 }
2260
2261 if (parser_statement_flags[type] & PARSER_STATM_CONTINUE_TARGET)
2262 {
2263 loop_iterator = iterator;
2264 }
2265 else
2266 {
2267 loop_iterator.current_p = NULL;
2268 }
2269
2270 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2271 }
2272 }
2273
2274 /* The first loop statement is searched. */
2275 while (true)
2276 {
2277 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2278 if (type == PARSER_STATEMENT_START)
2279 {
2280 parser_raise_error (context_p, PARSER_ERR_INVALID_CONTINUE);
2281 }
2282
2283 if (parser_statement_flags[type] & PARSER_STATM_CONTINUE_TARGET)
2284 {
2285 parser_loop_statement_t loop;
2286
2287 parser_stack_iterator_skip (&iterator, 1);
2288 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
2289 loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
2290 (uint16_t) opcode,
2291 loop.branch_list_p);
2292 loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
2293 parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
2294 return;
2295 }
2296
2297 if (parser_statement_flags[type] & PARSER_STATM_CONTEXT_BREAK)
2298 {
2299 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
2300 }
2301
2302 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2303 }
2304 } /* parser_parse_continue_statement */
2305
2306 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2307 /**
2308 * Parse import statement.
2309 * Note: See 15.2.2
2310 */
2311 static void
parser_parse_import_statement(parser_context_t * context_p)2312 parser_parse_import_statement (parser_context_t *context_p) /**< parser context */
2313 {
2314 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_IMPORT);
2315
2316 parser_module_check_request_place (context_p);
2317 parser_module_context_init ();
2318
2319 context_p->module_current_node_p = parser_module_create_module_node (context_p);
2320
2321 lexer_next_token (context_p);
2322
2323 /* Check for a ModuleSpecifier*/
2324 if (context_p->token.type != LEXER_LITERAL
2325 || context_p->token.lit_location.type != LEXER_STRING_LITERAL)
2326 {
2327 if (!(context_p->token.type == LEXER_LEFT_BRACE
2328 || context_p->token.type == LEXER_MULTIPLY
2329 || (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)))
2330 {
2331 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED);
2332 }
2333
2334 if (context_p->token.type == LEXER_LITERAL)
2335 {
2336 /* Handle ImportedDefaultBinding */
2337 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2338
2339 ecma_string_t *local_name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
2340 context_p->lit_object.literal_p->prop.length);
2341
2342 if (parser_module_check_duplicate_import (context_p, local_name_p))
2343 {
2344 ecma_deref_ecma_string (local_name_p);
2345 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_IMPORT_BINDING);
2346 }
2347
2348 ecma_string_t *import_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_DEFAULT);
2349 parser_module_add_names_to_node (context_p, import_name_p, local_name_p);
2350
2351 ecma_deref_ecma_string (local_name_p);
2352 ecma_deref_ecma_string (import_name_p);
2353
2354 lexer_next_token (context_p);
2355
2356 if (context_p->token.type == LEXER_COMMA)
2357 {
2358 lexer_next_token (context_p);
2359 if (context_p->token.type != LEXER_MULTIPLY
2360 && context_p->token.type != LEXER_LEFT_BRACE)
2361 {
2362 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED);
2363 }
2364 }
2365 else if (!lexer_token_is_identifier (context_p, "from", 4))
2366 {
2367 parser_raise_error (context_p, PARSER_ERR_FROM_COMMA_EXPECTED);
2368 }
2369 }
2370
2371 if (context_p->token.type == LEXER_MULTIPLY)
2372 {
2373 /* NameSpaceImport*/
2374 lexer_next_token (context_p);
2375 if (!lexer_token_is_identifier (context_p, "as", 2))
2376 {
2377 parser_raise_error (context_p, PARSER_ERR_AS_EXPECTED);
2378 }
2379
2380 lexer_next_token (context_p);
2381 if (context_p->token.type != LEXER_LITERAL)
2382 {
2383 parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
2384 }
2385
2386 lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_IDENT_LITERAL);
2387
2388 ecma_string_t *local_name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
2389 context_p->lit_object.literal_p->prop.length);
2390
2391 if (parser_module_check_duplicate_import (context_p, local_name_p))
2392 {
2393 ecma_deref_ecma_string (local_name_p);
2394 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_IMPORT_BINDING);
2395 }
2396
2397 ecma_string_t *import_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR);
2398
2399 parser_module_add_names_to_node (context_p, import_name_p, local_name_p);
2400 ecma_deref_ecma_string (local_name_p);
2401 ecma_deref_ecma_string (import_name_p);
2402
2403 lexer_next_token (context_p);
2404 }
2405 else if (context_p->token.type == LEXER_LEFT_BRACE)
2406 {
2407 /* Handle NamedImports */
2408 parser_module_parse_import_clause (context_p);
2409 }
2410
2411 if (!lexer_token_is_identifier (context_p, "from", 4))
2412 {
2413 parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
2414 }
2415 lexer_next_token (context_p);
2416 }
2417
2418 parser_module_handle_module_specifier (context_p);
2419 parser_module_add_import_node_to_context (context_p);
2420
2421 context_p->module_current_node_p = NULL;
2422 } /* parser_parse_import_statement */
2423
2424 /**
2425 * Parse export statement.
2426 */
2427 static void
parser_parse_export_statement(parser_context_t * context_p)2428 parser_parse_export_statement (parser_context_t *context_p) /**< context */
2429 {
2430 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_EXPORT);
2431
2432 parser_module_check_request_place (context_p);
2433 parser_module_context_init ();
2434
2435 context_p->module_current_node_p = parser_module_create_module_node (context_p);
2436
2437 lexer_next_token (context_p);
2438 switch (context_p->token.type)
2439 {
2440 case LEXER_KEYW_DEFAULT:
2441 {
2442 scanner_location_t location;
2443 scanner_get_location (&location, context_p);
2444
2445 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2446
2447 lexer_next_token (context_p);
2448 if (context_p->token.type == LEXER_KEYW_CLASS)
2449 {
2450 context_p->status_flags |= PARSER_MODULE_DEFAULT_CLASS_OR_FUNC;
2451 parser_parse_class (context_p, true);
2452 }
2453 else if (context_p->token.type == LEXER_KEYW_FUNCTION)
2454 {
2455 context_p->status_flags |= PARSER_MODULE_DEFAULT_CLASS_OR_FUNC;
2456 parser_parse_function_statement (context_p);
2457 }
2458 else
2459 {
2460 /* Assignment expression */
2461 scanner_set_location (context_p, &location);
2462
2463 /* 15.2.3.5 Use the synthetic name '*default*' as the identifier. */
2464 lexer_construct_literal_object (context_p, &lexer_default_literal, lexer_default_literal.type);
2465
2466 context_p->token.lit_location.type = LEXER_IDENT_LITERAL;
2467 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2468
2469 context_p->module_identifier_lit_p = context_p->lit_object.literal_p;
2470
2471 /* Fake an assignment to the default identifier */
2472 context_p->token.type = LEXER_ASSIGN;
2473
2474 parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
2475 }
2476
2477 ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->module_identifier_lit_p->u.char_p,
2478 context_p->module_identifier_lit_p->prop.length);
2479 ecma_string_t *export_name_p = ecma_get_magic_string (LIT_MAGIC_STRING_DEFAULT);
2480
2481 if (parser_module_check_duplicate_export (context_p, export_name_p))
2482 {
2483 ecma_deref_ecma_string (name_p);
2484 ecma_deref_ecma_string (export_name_p);
2485 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER);
2486 }
2487
2488 parser_module_add_names_to_node (context_p,
2489 export_name_p,
2490 name_p);
2491 ecma_deref_ecma_string (name_p);
2492 ecma_deref_ecma_string (export_name_p);
2493 break;
2494 }
2495 case LEXER_MULTIPLY:
2496 {
2497 lexer_next_token (context_p);
2498 if (!lexer_token_is_identifier (context_p, "from", 4))
2499 {
2500 parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
2501 }
2502
2503 lexer_next_token (context_p);
2504 parser_module_handle_module_specifier (context_p);
2505 break;
2506 }
2507 case LEXER_KEYW_VAR:
2508 case LEXER_KEYW_LET:
2509 case LEXER_KEYW_CONST:
2510 {
2511 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2512 parser_parse_var_statement (context_p);
2513 break;
2514 }
2515 case LEXER_KEYW_CLASS:
2516 {
2517 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2518 parser_parse_class (context_p, true);
2519 break;
2520 }
2521 case LEXER_KEYW_FUNCTION:
2522 {
2523 context_p->status_flags |= PARSER_MODULE_STORE_IDENT;
2524 parser_parse_function_statement (context_p);
2525 break;
2526 }
2527 case LEXER_LEFT_BRACE:
2528 {
2529 parser_module_parse_export_clause (context_p);
2530
2531 if (lexer_token_is_identifier (context_p, "from", 4))
2532 {
2533 lexer_next_token (context_p);
2534 parser_module_handle_module_specifier (context_p);
2535 }
2536 break;
2537 }
2538 default:
2539 {
2540 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_LITERAL_EXPECTED);
2541 break;
2542 }
2543 }
2544
2545 context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC | PARSER_MODULE_STORE_IDENT);
2546 parser_module_add_export_node_to_context (context_p);
2547 context_p->module_current_node_p = NULL;
2548 } /* parser_parse_export_statement */
2549 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2550
2551 /**
2552 * Parse label statement.
2553 */
2554 static void
parser_parse_label(parser_context_t * context_p)2555 parser_parse_label (parser_context_t *context_p) /**< context */
2556 {
2557 parser_stack_iterator_t iterator;
2558 parser_label_statement_t label_statement;
2559
2560 parser_stack_iterator_init (context_p, &iterator);
2561
2562 while (true)
2563 {
2564 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
2565 if (type == PARSER_STATEMENT_START)
2566 {
2567 break;
2568 }
2569
2570 if (type == PARSER_STATEMENT_LABEL)
2571 {
2572 parser_stack_iterator_skip (&iterator, 1);
2573 parser_stack_iterator_read (&iterator, &label_statement, sizeof (parser_label_statement_t));
2574 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
2575
2576 if (lexer_current_is_literal (context_p, &label_statement.label_ident))
2577 {
2578 parser_raise_error (context_p, PARSER_ERR_DUPLICATED_LABEL);
2579 }
2580 }
2581 else
2582 {
2583 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
2584 }
2585 }
2586
2587 label_statement.label_ident = context_p->token.lit_location;
2588 label_statement.break_list_p = NULL;
2589 parser_stack_push (context_p, &label_statement, sizeof (parser_label_statement_t));
2590 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_LABEL);
2591 parser_stack_iterator_init (context_p, &context_p->last_statement);
2592 } /* parser_parse_label */
2593
2594 /**
2595 * Strict mode types for statement parsing.
2596 */
2597 typedef enum
2598 {
2599 PARSER_USE_STRICT_NOT_FOUND = 0, /**< 'use strict' directive is not found */
2600 PARSER_USE_STRICT_FOUND = 1, /**< 'use strict' directive is found but strict mode has already been enabled */
2601 PARSER_USE_STRICT_SET = 2, /**< strict mode is enabled after 'use strict' directive is found */
2602 } parser_strict_mode_type_t;
2603
2604 /**
2605 * Parse statements.
2606 */
2607 void
parser_parse_statements(parser_context_t * context_p)2608 parser_parse_statements (parser_context_t *context_p) /**< context */
2609 {
2610 /* Statement parsing cannot be nested. */
2611 JERRY_ASSERT (context_p->last_statement.current_p == NULL);
2612 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_START);
2613 parser_stack_iterator_init (context_p, &context_p->last_statement);
2614
2615 #if ENABLED (JERRY_DEBUGGER)
2616 /* Set lexical enviroment for the debugger. */
2617 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2618 {
2619 context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
2620 context_p->last_breakpoint_line = 0;
2621 }
2622 #endif /* ENABLED (JERRY_DEBUGGER) */
2623
2624 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2625 if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
2626 {
2627 parser_emit_cbc_ext (context_p, CBC_EXT_RESOURCE_NAME);
2628 parser_flush_cbc (context_p);
2629 }
2630 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2631 #if ENABLED (JERRY_LINE_INFO)
2632 context_p->last_line_info_line = 0;
2633 #endif /* ENABLED (JERRY_LINE_INFO) */
2634
2635 while (context_p->token.type == LEXER_LITERAL
2636 && context_p->token.lit_location.type == LEXER_STRING_LITERAL)
2637 {
2638 lexer_lit_location_t lit_location;
2639 parser_strict_mode_type_t strict_mode = PARSER_USE_STRICT_NOT_FOUND;
2640
2641 JERRY_ASSERT (context_p->stack_depth <= 1);
2642 #ifndef JERRY_NDEBUG
2643 JERRY_ASSERT (context_p->context_stack_depth == context_p->stack_depth);
2644 #endif /* !JERRY_NDEBUG */
2645
2646 if (lexer_string_is_use_strict (context_p))
2647 {
2648 strict_mode = PARSER_USE_STRICT_FOUND;
2649
2650 if (!(context_p->status_flags & PARSER_IS_STRICT))
2651 {
2652 /* The next token should be parsed in strict mode. */
2653 context_p->status_flags |= PARSER_IS_STRICT;
2654 strict_mode = PARSER_USE_STRICT_SET;
2655 }
2656 }
2657
2658 lit_location = context_p->token.lit_location;
2659 lexer_next_token (context_p);
2660
2661 if (!lexer_string_is_directive (context_p))
2662 {
2663 /* The string is part of an expression statement. */
2664 if (strict_mode == PARSER_USE_STRICT_SET)
2665 {
2666 context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
2667 }
2668
2669 #if ENABLED (JERRY_DEBUGGER)
2670 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2671 {
2672 JERRY_ASSERT (context_p->last_breakpoint_line == 0);
2673
2674 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2675 parser_flush_cbc (context_p);
2676
2677 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
2678
2679 context_p->last_breakpoint_line = context_p->token.line;
2680 }
2681 #endif /* ENABLED (JERRY_DEBUGGER) */
2682 #if ENABLED (JERRY_LINE_INFO)
2683 parser_emit_line_info (context_p, context_p->token.line, false);
2684 #endif /* ENABLED (JERRY_LINE_INFO) */
2685
2686 lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
2687 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2688 /* The extra_value is used for saving the token. */
2689 context_p->token.extra_value = context_p->token.type;
2690 context_p->token.type = LEXER_EXPRESSION_START;
2691 break;
2692 }
2693
2694 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2695 if (strict_mode == PARSER_USE_STRICT_SET && context_p->is_show_opcodes)
2696 {
2697 JERRY_DEBUG_MSG (" Note: switch to strict mode\n\n");
2698 }
2699 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2700
2701 #if ENABLED (JERRY_ES2015)
2702 if (strict_mode != PARSER_USE_STRICT_NOT_FOUND
2703 && (context_p->status_flags & PARSER_FUNCTION_HAS_NON_SIMPLE_PARAM))
2704 {
2705 parser_raise_error (context_p, PARSER_ERR_USE_STRICT_NOT_ALLOWED);
2706 }
2707 #endif /* ENABLED (JERRY_ES2015) */
2708
2709 if (context_p->token.type == LEXER_SEMICOLON)
2710 {
2711 lexer_next_token (context_p);
2712 }
2713
2714 /* The last directive prologue can be the result of the script. */
2715 if (!(context_p->status_flags & PARSER_IS_FUNCTION)
2716 && (context_p->token.type != LEXER_LITERAL
2717 || context_p->token.lit_location.type != LEXER_STRING_LITERAL))
2718 {
2719 lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
2720 parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
2721 parser_emit_cbc (context_p, CBC_POP_BLOCK);
2722 parser_flush_cbc (context_p);
2723 break;
2724 }
2725 }
2726
2727 CHECK_JERRY_STACK_USAGE(context_p);
2728
2729 if (context_p->status_flags & PARSER_IS_STRICT
2730 && context_p->status_flags & PARSER_HAS_NON_STRICT_ARG)
2731 {
2732 parser_raise_error (context_p, PARSER_ERR_NON_STRICT_ARG_DEFINITION);
2733 }
2734
2735 while (context_p->token.type != LEXER_EOS
2736 || context_p->stack_top_uint8 != PARSER_STATEMENT_START)
2737 {
2738 #ifndef JERRY_NDEBUG
2739 JERRY_ASSERT (context_p->stack_depth == context_p->context_stack_depth);
2740 #endif /* !JERRY_NDEBUG */
2741
2742 #if ENABLED (JERRY_ES2015)
2743 JERRY_ASSERT (context_p->stack_top_uint8 != PARSER_STATEMENT_PRIVATE_SCOPE
2744 && context_p->stack_top_uint8 != PARSER_STATEMENT_PRIVATE_CONTEXT);
2745 #endif /* ENABLED (JERRY_ES2015) */
2746
2747 #if ENABLED (JERRY_DEBUGGER)
2748 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED
2749 && context_p->token.line != context_p->last_breakpoint_line
2750 && context_p->token.type != LEXER_SEMICOLON
2751 && context_p->token.type != LEXER_LEFT_BRACE
2752 && context_p->token.type != LEXER_RIGHT_BRACE
2753 && context_p->token.type != LEXER_KEYW_VAR
2754 && context_p->token.type != LEXER_KEYW_LET
2755 && context_p->token.type != LEXER_KEYW_CONST
2756 && context_p->token.type != LEXER_KEYW_FUNCTION
2757 && context_p->token.type != LEXER_KEYW_CASE
2758 && context_p->token.type != LEXER_KEYW_DEFAULT)
2759 {
2760 parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
2761 parser_flush_cbc (context_p);
2762
2763 parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
2764
2765 context_p->last_breakpoint_line = context_p->token.line;
2766 }
2767 #endif /* ENABLED (JERRY_DEBUGGER) */
2768
2769 #if ENABLED (JERRY_LINE_INFO)
2770 if (context_p->token.line != context_p->last_line_info_line
2771 && context_p->token.type != LEXER_SEMICOLON
2772 && context_p->token.type != LEXER_LEFT_BRACE
2773 && context_p->token.type != LEXER_RIGHT_BRACE
2774 && context_p->token.type != LEXER_KEYW_VAR
2775 && context_p->token.type != LEXER_KEYW_LET
2776 && context_p->token.type != LEXER_KEYW_CONST
2777 && context_p->token.type != LEXER_KEYW_FUNCTION
2778 && context_p->token.type != LEXER_KEYW_CASE
2779 && context_p->token.type != LEXER_KEYW_DEFAULT)
2780 {
2781 parser_emit_line_info (context_p, context_p->token.line, true);
2782 }
2783 #endif /* ENABLED (JERRY_LINE_INFO) */
2784
2785 switch (context_p->token.type)
2786 {
2787 case LEXER_SEMICOLON:
2788 {
2789 break;
2790 }
2791
2792 case LEXER_RIGHT_BRACE:
2793 {
2794 if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
2795 {
2796 parser_raise_error (context_p, PARSER_ERR_STATEMENT_EXPECTED);
2797 }
2798 break;
2799 }
2800
2801 case LEXER_LEFT_BRACE:
2802 {
2803 #if ENABLED (JERRY_ES2015)
2804 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2805 {
2806 parser_push_block_context (context_p, false);
2807 }
2808 else
2809 {
2810 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
2811 }
2812 #else /* !ENABLED (JERRY_ES2015) */
2813 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_BLOCK);
2814 #endif /* ENABLED (JERRY_ES2015) */
2815
2816 parser_stack_iterator_init (context_p, &context_p->last_statement);
2817 lexer_next_token (context_p);
2818 continue;
2819 }
2820
2821 case LEXER_KEYW_VAR:
2822 #if ENABLED (JERRY_ES2015)
2823 case LEXER_KEYW_LET:
2824 case LEXER_KEYW_CONST:
2825 #endif /* ENABLED (JERRY_ES2015) */
2826 {
2827 parser_parse_var_statement (context_p);
2828 break;
2829 }
2830
2831 #if ENABLED (JERRY_ES2015)
2832 case LEXER_KEYW_CLASS:
2833 {
2834 parser_validate_lexical_context (context_p);
2835 parser_parse_class (context_p, true);
2836 goto consume_last_statement;
2837 }
2838 #endif /* ENABLED (JERRY_ES2015) */
2839
2840 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2841 case LEXER_KEYW_IMPORT:
2842 {
2843 parser_parse_import_statement (context_p);
2844 break;
2845 }
2846
2847 case LEXER_KEYW_EXPORT:
2848 {
2849 parser_parse_export_statement (context_p);
2850 break;
2851 }
2852 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2853
2854 case LEXER_KEYW_FUNCTION:
2855 {
2856 parser_parse_function_statement (context_p);
2857 goto consume_last_statement;
2858 }
2859
2860 case LEXER_KEYW_IF:
2861 {
2862 parser_parse_if_statement_start (context_p);
2863 continue;
2864 }
2865
2866 case LEXER_KEYW_SWITCH:
2867 {
2868 parser_parse_switch_statement_start (context_p);
2869 continue;
2870 }
2871
2872 case LEXER_KEYW_DO:
2873 {
2874 parser_do_while_statement_t do_while_statement;
2875 parser_loop_statement_t loop;
2876
2877 JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
2878
2879 do_while_statement.start_offset = context_p->byte_code_size;
2880 loop.branch_list_p = NULL;
2881
2882 parser_stack_push (context_p, &do_while_statement, sizeof (parser_do_while_statement_t));
2883 parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
2884 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_DO_WHILE);
2885 parser_stack_iterator_init (context_p, &context_p->last_statement);
2886 lexer_next_token (context_p);
2887 continue;
2888 }
2889
2890 case LEXER_KEYW_WHILE:
2891 {
2892 parser_parse_while_statement_start (context_p);
2893 continue;
2894 }
2895
2896 case LEXER_KEYW_FOR:
2897 {
2898 parser_parse_for_statement_start (context_p);
2899 continue;
2900 }
2901
2902 case LEXER_KEYW_WITH:
2903 {
2904 parser_parse_with_statement_start (context_p);
2905 continue;
2906 }
2907
2908 case LEXER_KEYW_TRY:
2909 {
2910 parser_try_statement_t try_statement;
2911
2912 lexer_next_token (context_p);
2913
2914 if (context_p->token.type != LEXER_LEFT_BRACE)
2915 {
2916 parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
2917 }
2918
2919 #ifndef JERRY_NDEBUG
2920 PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
2921 #endif /* !JERRY_NDEBUG */
2922
2923 try_statement.type = parser_try_block;
2924 parser_emit_cbc_ext_forward_branch (context_p,
2925 CBC_EXT_TRY_CREATE_CONTEXT,
2926 &try_statement.branch);
2927
2928 #if ENABLED (JERRY_ES2015)
2929 try_statement.scope_stack_top = context_p->scope_stack_top;
2930 try_statement.scope_stack_reg_top = context_p->scope_stack_reg_top;
2931
2932 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
2933 {
2934 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_BLOCK);
2935
2936 if (scanner_is_context_needed (context_p, PARSER_CHECK_BLOCK_CONTEXT))
2937 {
2938 parser_emit_cbc_ext (context_p, CBC_EXT_TRY_CREATE_ENV);
2939 }
2940
2941 scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
2942 }
2943 #endif /* ENABLED (JERRY_ES2015) */
2944
2945 parser_stack_push (context_p, &try_statement, sizeof (parser_try_statement_t));
2946 parser_stack_push_uint8 (context_p, PARSER_STATEMENT_TRY);
2947 parser_stack_iterator_init (context_p, &context_p->last_statement);
2948 lexer_next_token (context_p);
2949 continue;
2950 }
2951
2952 case LEXER_KEYW_DEFAULT:
2953 {
2954 parser_parse_default_statement (context_p);
2955 continue;
2956 }
2957
2958 case LEXER_KEYW_CASE:
2959 {
2960 parser_parse_case_statement (context_p);
2961 continue;
2962 }
2963
2964 case LEXER_KEYW_BREAK:
2965 {
2966 parser_parse_break_statement (context_p);
2967 break;
2968 }
2969
2970 case LEXER_KEYW_CONTINUE:
2971 {
2972 parser_parse_continue_statement (context_p);
2973 break;
2974 }
2975
2976 case LEXER_KEYW_THROW:
2977 {
2978 lexer_next_token (context_p);
2979 if (context_p->token.flags & LEXER_WAS_NEWLINE)
2980 {
2981 parser_raise_error (context_p, PARSER_ERR_EXPRESSION_EXPECTED);
2982 }
2983 parser_parse_expression (context_p, PARSE_EXPR);
2984 parser_emit_cbc (context_p, CBC_THROW);
2985 break;
2986 }
2987
2988 case LEXER_KEYW_RETURN:
2989 {
2990 if (!(context_p->status_flags & PARSER_IS_FUNCTION))
2991 {
2992 parser_raise_error (context_p, PARSER_ERR_INVALID_RETURN);
2993 }
2994
2995 lexer_next_token (context_p);
2996
2997 if ((context_p->token.flags & LEXER_WAS_NEWLINE)
2998 || context_p->token.type == LEXER_SEMICOLON
2999 || context_p->token.type == LEXER_EOS
3000 || context_p->token.type == LEXER_RIGHT_BRACE)
3001 {
3002 #if ENABLED (JERRY_ES2015)
3003 if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
3004 {
3005 parser_emit_cbc_ext (context_p, CBC_EXT_RETURN_PROMISE_UNDEFINED);
3006 break;
3007 }
3008 #endif /* ENABLED (JERRY_ES2015) */
3009
3010 parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK);
3011 break;
3012 }
3013
3014 parser_parse_expression (context_p, PARSE_EXPR);
3015
3016 #if ENABLED (JERRY_ES2015)
3017 if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
3018 {
3019 parser_emit_cbc_ext (context_p, CBC_EXT_RETURN_PROMISE);
3020 break;
3021 }
3022 #endif /* ENABLED (JERRY_ES2015) */
3023
3024 if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
3025 {
3026 context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
3027 break;
3028 }
3029
3030 parser_emit_cbc (context_p, CBC_RETURN);
3031 break;
3032 }
3033
3034 case LEXER_KEYW_DEBUGGER:
3035 {
3036 #if ENABLED (JERRY_DEBUGGER)
3037 /* This breakpoint location is not reported to the
3038 * debugger, so it is impossible to disable it. */
3039 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
3040 {
3041 parser_emit_cbc (context_p, CBC_BREAKPOINT_ENABLED);
3042 }
3043 #endif /* ENABLED (JERRY_DEBUGGER) */
3044 lexer_next_token (context_p);
3045 break;
3046 }
3047
3048 case LEXER_LITERAL:
3049 {
3050 if (context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
3051 {
3052 if (JERRY_UNLIKELY (lexer_check_next_character (context_p, LIT_CHAR_COLON)))
3053 {
3054 parser_parse_label (context_p);
3055 lexer_consume_next_character (context_p);
3056 lexer_next_token (context_p);
3057 continue;
3058 }
3059 #if ENABLED (JERRY_ES2015)
3060 if (JERRY_UNLIKELY (lexer_token_is_let (context_p)))
3061 {
3062 if (context_p->next_scanner_info_p->source_p == context_p->source_p)
3063 {
3064 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION)
3065 {
3066 scanner_release_next (context_p, sizeof (scanner_info_t));
3067 }
3068
3069 if (context_p->status_flags & PARSER_IS_FUNCTION)
3070 {
3071 parser_parse_expression_statement (context_p, PARSE_EXPR);
3072 break;
3073 }
3074
3075 parser_parse_block_expression (context_p, PARSE_EXPR);
3076 break;
3077 }
3078
3079 context_p->token.type = LEXER_KEYW_LET;
3080 parser_parse_var_statement (context_p);
3081 break;
3082 }
3083
3084 if (JERRY_UNLIKELY (lexer_token_is_async (context_p))
3085 && context_p->next_scanner_info_p->source_p == context_p->source_p)
3086 {
3087 bool is_statement = true;
3088
3089 if (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION)
3090 {
3091 is_statement = (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT) != 0;
3092
3093 JERRY_ASSERT (!is_statement || (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC));
3094 }
3095 else
3096 {
3097 JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
3098
3099 scanner_release_next (context_p, sizeof (scanner_info_t));
3100 }
3101
3102 if (is_statement)
3103 {
3104 if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
3105 {
3106 parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
3107 }
3108
3109 lexer_next_token (context_p);
3110 JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FUNCTION);
3111 continue;
3112 }
3113 }
3114 #endif /* ENABLED (JERRY_ES2015) */
3115 }
3116 /* FALLTHRU */
3117 }
3118
3119 default:
3120 {
3121 int options = PARSE_EXPR;
3122
3123 if (context_p->token.type == LEXER_EXPRESSION_START)
3124 {
3125 /* Restore the token type form the extra_value. */
3126 context_p->token.type = context_p->token.extra_value;
3127 options |= PARSE_EXPR_HAS_LITERAL;
3128 }
3129
3130 if (context_p->status_flags & PARSER_IS_FUNCTION)
3131 {
3132 parser_parse_expression_statement (context_p, options);
3133 }
3134 else
3135 {
3136 parser_parse_block_expression (context_p, options);
3137 }
3138
3139 break;
3140 }
3141 }
3142
3143 parser_flush_cbc (context_p);
3144
3145 if (context_p->token.type == LEXER_RIGHT_BRACE)
3146 {
3147 if (context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK)
3148 {
3149 parser_stack_pop_uint8 (context_p);
3150 parser_stack_iterator_init (context_p, &context_p->last_statement);
3151 lexer_next_token (context_p);
3152 }
3153 #if ENABLED (JERRY_ES2015)
3154 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_SCOPE
3155 || context_p->stack_top_uint8 == PARSER_STATEMENT_BLOCK_CONTEXT)
3156 {
3157 parser_pop_block_context (context_p);
3158 lexer_next_token (context_p);
3159 }
3160 #endif /* ENABLED (JERRY_ES2015) */
3161 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH
3162 || context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH_NO_DEFAULT)
3163 {
3164 int has_default = (context_p->stack_top_uint8 == PARSER_STATEMENT_SWITCH);
3165 parser_loop_statement_t loop;
3166 parser_switch_statement_t switch_statement;
3167
3168 parser_stack_pop_uint8 (context_p);
3169 parser_stack_pop (context_p, &loop, sizeof (parser_loop_statement_t));
3170 parser_stack_pop (context_p, &switch_statement, sizeof (parser_switch_statement_t));
3171 parser_stack_iterator_init (context_p, &context_p->last_statement);
3172
3173 JERRY_ASSERT (switch_statement.branch_list_p == NULL);
3174
3175 if (!has_default)
3176 {
3177 parser_set_branch_to_current_position (context_p, &switch_statement.default_branch);
3178 }
3179
3180 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
3181 lexer_next_token (context_p);
3182
3183 #if ENABLED (JERRY_ES2015)
3184 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
3185 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
3186 {
3187 parser_pop_block_context (context_p);
3188 }
3189 #endif /* ENABLED (JERRY_ES2015) */
3190 }
3191 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_TRY)
3192 {
3193 parser_parse_try_statement_end (context_p);
3194 }
3195 else if (context_p->stack_top_uint8 == PARSER_STATEMENT_START)
3196 {
3197 if (context_p->status_flags & PARSER_IS_CLOSURE)
3198 {
3199 parser_stack_pop_uint8 (context_p);
3200 context_p->last_statement.current_p = NULL;
3201 /* There is no lexer_next_token here, since the
3202 * next token belongs to the parent context. */
3203 return;
3204 }
3205 parser_raise_error (context_p, PARSER_ERR_INVALID_RIGHT_SQUARE);
3206 }
3207 }
3208 else if (context_p->token.type == LEXER_SEMICOLON)
3209 {
3210 lexer_next_token (context_p);
3211 }
3212 else if (context_p->token.type != LEXER_EOS
3213 && !(context_p->token.flags & LEXER_WAS_NEWLINE))
3214 {
3215 parser_raise_error (context_p, PARSER_ERR_SEMICOLON_EXPECTED);
3216 }
3217
3218 consume_last_statement:
3219 while (true)
3220 {
3221 switch (context_p->stack_top_uint8)
3222 {
3223 case PARSER_STATEMENT_LABEL:
3224 {
3225 parser_label_statement_t label;
3226
3227 parser_stack_pop_uint8 (context_p);
3228 parser_stack_pop (context_p, &label, sizeof (parser_label_statement_t));
3229 parser_stack_iterator_init (context_p, &context_p->last_statement);
3230
3231 parser_set_breaks_to_current_position (context_p, label.break_list_p);
3232 continue;
3233 }
3234
3235 case PARSER_STATEMENT_IF:
3236 {
3237 if (parser_parse_if_statement_end (context_p))
3238 {
3239 break;
3240 }
3241 continue;
3242 }
3243
3244 case PARSER_STATEMENT_ELSE:
3245 {
3246 parser_if_else_statement_t else_statement;
3247
3248 parser_stack_pop_uint8 (context_p);
3249 parser_stack_pop (context_p, &else_statement, sizeof (parser_if_else_statement_t));
3250 parser_stack_iterator_init (context_p, &context_p->last_statement);
3251
3252 parser_set_branch_to_current_position (context_p, &else_statement.branch);
3253 continue;
3254 }
3255
3256 case PARSER_STATEMENT_DO_WHILE:
3257 {
3258 parser_parse_do_while_statement_end (context_p);
3259 if (context_p->token.type == LEXER_SEMICOLON)
3260 {
3261 lexer_next_token (context_p);
3262 }
3263 continue;
3264 }
3265
3266 case PARSER_STATEMENT_WHILE:
3267 {
3268 parser_parse_while_statement_end (context_p);
3269 continue;
3270 }
3271
3272 case PARSER_STATEMENT_FOR:
3273 {
3274 parser_parse_for_statement_end (context_p);
3275 continue;
3276 }
3277
3278 case PARSER_STATEMENT_FOR_IN:
3279 #if ENABLED (JERRY_ES2015)
3280 case PARSER_STATEMENT_FOR_OF:
3281 #endif /* ENABLED (JERRY_ES2015) */
3282 {
3283 parser_for_in_of_statement_t for_in_of_statement;
3284 parser_loop_statement_t loop;
3285
3286 #if ENABLED (JERRY_ES2015)
3287 bool is_for_in = (context_p->stack_top_uint8 == PARSER_STATEMENT_FOR_IN);
3288 #else
3289 bool is_for_in = true;
3290 #endif /* ENABLED (JERRY_ES2015) */
3291
3292 parser_stack_pop_uint8 (context_p);
3293 parser_stack_pop (context_p, &loop, sizeof (parser_loop_statement_t));
3294 parser_stack_pop (context_p, &for_in_of_statement, sizeof (parser_for_in_of_statement_t));
3295 parser_stack_iterator_init (context_p, &context_p->last_statement);
3296
3297 parser_set_continues_to_current_position (context_p, loop.branch_list_p);
3298
3299 parser_flush_cbc (context_p);
3300 PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, is_for_in ? PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION
3301 : PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
3302 #ifndef JERRY_NDEBUG
3303 PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth,
3304 is_for_in ? PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION
3305 : PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
3306 #endif /* !JERRY_NDEBUG */
3307
3308 parser_emit_cbc_ext_backward_branch (context_p,
3309 is_for_in ? CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT
3310 : CBC_EXT_BRANCH_IF_FOR_OF_HAS_NEXT,
3311 for_in_of_statement.start_offset);
3312
3313 parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
3314 parser_set_branch_to_current_position (context_p, &for_in_of_statement.branch);
3315
3316 #if ENABLED (JERRY_ES2015)
3317 if (context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_SCOPE
3318 || context_p->stack_top_uint8 == PARSER_STATEMENT_PRIVATE_CONTEXT)
3319 {
3320 parser_pop_block_context (context_p);
3321 }
3322 #endif /* ENABLED (JERRY_ES2015) */
3323 continue;
3324 }
3325
3326 case PARSER_STATEMENT_WITH:
3327 {
3328 parser_parse_with_statement_end (context_p);
3329 continue;
3330 }
3331
3332 default:
3333 {
3334 break;
3335 }
3336 }
3337 break;
3338 }
3339 }
3340
3341 parser_stack_pop_uint8 (context_p);
3342 context_p->last_statement.current_p = NULL;
3343
3344 if (context_p->status_flags & PARSER_IS_CLOSURE)
3345 {
3346 parser_raise_error (context_p, PARSER_ERR_STATEMENT_EXPECTED);
3347 }
3348 } /* parser_parse_statements */
3349
3350 /**
3351 * Free jumps stored on the stack if a parse error is occured.
3352 */
3353 void JERRY_ATTR_NOINLINE
parser_free_jumps(parser_stack_iterator_t iterator)3354 parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
3355 {
3356 while (true)
3357 {
3358 uint8_t type = parser_stack_iterator_read_uint8 (&iterator);
3359 parser_branch_node_t *branch_list_p = NULL;
3360
3361 switch (type)
3362 {
3363 case PARSER_STATEMENT_START:
3364 {
3365 return;
3366 }
3367
3368 case PARSER_STATEMENT_LABEL:
3369 {
3370 parser_label_statement_t label;
3371
3372 parser_stack_iterator_skip (&iterator, 1);
3373 parser_stack_iterator_read (&iterator, &label, sizeof (parser_label_statement_t));
3374 parser_stack_iterator_skip (&iterator, sizeof (parser_label_statement_t));
3375 branch_list_p = label.break_list_p;
3376 break;
3377 }
3378
3379 case PARSER_STATEMENT_SWITCH:
3380 case PARSER_STATEMENT_SWITCH_NO_DEFAULT:
3381 {
3382 parser_switch_statement_t switch_statement;
3383 parser_loop_statement_t loop;
3384
3385 parser_stack_iterator_skip (&iterator, 1);
3386 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
3387 parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
3388 parser_stack_iterator_read (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
3389 parser_stack_iterator_skip (&iterator, sizeof (parser_switch_statement_t));
3390
3391 branch_list_p = switch_statement.branch_list_p;
3392 while (branch_list_p != NULL)
3393 {
3394 parser_branch_node_t *next_p = branch_list_p->next_p;
3395 parser_free (branch_list_p, sizeof (parser_branch_node_t));
3396 branch_list_p = next_p;
3397 }
3398 branch_list_p = loop.branch_list_p;
3399 break;
3400 }
3401
3402 case PARSER_STATEMENT_DO_WHILE:
3403 case PARSER_STATEMENT_WHILE:
3404 case PARSER_STATEMENT_FOR:
3405 case PARSER_STATEMENT_FOR_IN:
3406 #if ENABLED (JERRY_ES2015)
3407 case PARSER_STATEMENT_FOR_OF:
3408 #endif /* ENABLED (JERRY_ES2015) */
3409 {
3410 parser_loop_statement_t loop;
3411
3412 parser_stack_iterator_skip (&iterator, 1);
3413 parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
3414 parser_stack_iterator_skip (&iterator, parser_statement_length (type) - 1);
3415 branch_list_p = loop.branch_list_p;
3416 break;
3417 }
3418
3419 default:
3420 {
3421 parser_stack_iterator_skip (&iterator, parser_statement_length (type));
3422 continue;
3423 }
3424 }
3425
3426 while (branch_list_p != NULL)
3427 {
3428 parser_branch_node_t *next_p = branch_list_p->next_p;
3429 parser_free (branch_list_p, sizeof (parser_branch_node_t));
3430 branch_list_p = next_p;
3431 }
3432 }
3433 } /* parser_free_jumps */
3434
3435 /**
3436 * @}
3437 * @}
3438 * @}
3439 */
3440
3441 #endif /* ENABLED (JERRY_PARSER) */
3442