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