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