• 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 "jcontext.h"
17 #include "js-parser-internal.h"
18 #include "js-scanner-internal.h"
19 #include "lit-char-helpers.h"
20 
21 #if ENABLED (JERRY_PARSER)
22 
23 /** \addtogroup parser Parser
24  * @{
25  *
26  * \addtogroup jsparser JavaScript
27  * @{
28  *
29  * \addtogroup jsparser_scanner Scanner
30  * @{
31  */
32 
33 /**
34  * Scan return types.
35  */
36 typedef enum
37 {
38   SCAN_NEXT_TOKEN, /**< get next token after return */
39   SCAN_KEEP_TOKEN, /**< keep the current token after return */
40 } scan_return_types_t;
41 
42 /**
43  * Checks whether token type is "of".
44  */
45 #if ENABLED (JERRY_ES2015)
46 #define SCANNER_IDENTIFIER_IS_OF() (lexer_token_is_identifier (context_p, "of", 2))
47 #else
48 #define SCANNER_IDENTIFIER_IS_OF() (false)
49 #endif /* ENABLED (JERRY_ES2015) */
50 
51 #if ENABLED (JERRY_ES2015)
52 
53 JERRY_STATIC_ASSERT (SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (SCANNER_LITERAL_POOL_GENERATOR)
54                      == SCAN_STACK_COMPUTED_GENERATOR,
55                      scanner_invalid_conversion_from_literal_pool_generator_to_computed_generator);
56 JERRY_STATIC_ASSERT (SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (SCANNER_LITERAL_POOL_ASYNC)
57                      == SCAN_STACK_COMPUTED_ASYNC,
58                      scanner_invalid_conversion_from_literal_pool_async_to_computed_async);
59 
60 JERRY_STATIC_ASSERT (SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (SCAN_STACK_COMPUTED_GENERATOR)
61                      == SCANNER_LITERAL_POOL_GENERATOR,
62                      scanner_invalid_conversion_from_computed_generator_to_literal_pool_generator);
63 JERRY_STATIC_ASSERT (SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (SCAN_STACK_COMPUTED_ASYNC)
64                      == SCANNER_LITERAL_POOL_ASYNC,
65                      scanner_invalid_conversion_from_computed_async_to_literal_pool_async);
66 
67 #endif /* ENABLED (JERRY_ES2015) */
68 
69 /**
70  * Scan primary expression.
71  *
72  * @return SCAN_NEXT_TOKEN to read the next token, or SCAN_KEEP_TOKEN to do nothing
73  */
74 static scan_return_types_t
scanner_scan_primary_expression(parser_context_t * context_p,scanner_context_t * scanner_context_p,lexer_token_type_t type,scan_stack_modes_t stack_top)75 scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
76                                  scanner_context_t *scanner_context_p, /* scanner context */
77                                  lexer_token_type_t type, /**< current token type */
78                                  scan_stack_modes_t stack_top) /**< current stack top */
79 {
80   switch (type)
81   {
82     case LEXER_KEYW_NEW:
83     {
84       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_AFTER_NEW;
85 
86 #if ENABLED (JERRY_ES2015)
87       if (scanner_try_scan_new_target (context_p))
88       {
89         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
90       }
91 #endif /* ENABLED (JERRY_ES2015) */
92       break;
93     }
94     case LEXER_DIVIDE:
95     case LEXER_ASSIGN_DIVIDE:
96     {
97       lexer_construct_regexp_object (context_p, true);
98       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
99       break;
100     }
101     case LEXER_KEYW_FUNCTION:
102     {
103       uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
104 
105 #if ENABLED (JERRY_ES2015)
106       if (scanner_context_p->async_source_p != NULL)
107       {
108         status_flags |= SCANNER_LITERAL_POOL_ASYNC;
109       }
110 
111       if (lexer_consume_generator (context_p))
112       {
113         status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
114       }
115 #endif /* ENABLED (JERRY_ES2015) */
116 
117       scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
118 
119       lexer_next_token (context_p);
120 
121       if (context_p->token.type == LEXER_LITERAL
122           && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
123       {
124         lexer_next_token (context_p);
125       }
126 
127       parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_EXPRESSION);
128       scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
129       return SCAN_KEEP_TOKEN;
130     }
131     case LEXER_LEFT_PAREN:
132     {
133       scanner_scan_bracket (context_p, scanner_context_p);
134       return SCAN_KEEP_TOKEN;
135     }
136     case LEXER_LEFT_SQUARE:
137     {
138 #if ENABLED (JERRY_ES2015)
139       scanner_push_destructuring_pattern (context_p, scanner_context_p, SCANNER_BINDING_NONE, false);
140 #endif /* ENABLED (JERRY_ES2015) */
141 
142       parser_stack_push_uint8 (context_p, SCAN_STACK_ARRAY_LITERAL);
143       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
144       break;
145     }
146     case LEXER_LEFT_BRACE:
147     {
148 #if ENABLED (JERRY_ES2015)
149       scanner_push_destructuring_pattern (context_p, scanner_context_p, SCANNER_BINDING_NONE, false);
150 #endif /* ENABLED (JERRY_ES2015) */
151 
152       parser_stack_push_uint8 (context_p, SCAN_STACK_OBJECT_LITERAL);
153       scanner_context_p->mode = SCAN_MODE_PROPERTY_NAME;
154       return SCAN_KEEP_TOKEN;
155     }
156 #if ENABLED (JERRY_ES2015)
157     case LEXER_TEMPLATE_LITERAL:
158     {
159       if (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
160       {
161         parser_stack_push_uint8 (context_p, SCAN_STACK_TEMPLATE_STRING);
162         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
163         break;
164       }
165 
166       /* The string is a normal string literal. */
167       /* FALLTHRU */
168     }
169 #endif /* ENABLED (JERRY_ES2015) */
170     case LEXER_LITERAL:
171     {
172 #if ENABLED (JERRY_ES2015)
173       const uint8_t *source_p = context_p->source_p;
174 
175       if (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
176           && lexer_check_arrow (context_p))
177       {
178         scanner_scan_simple_arrow (context_p, scanner_context_p, source_p);
179         return SCAN_KEEP_TOKEN;
180       }
181       else if (JERRY_UNLIKELY (lexer_token_is_async (context_p)))
182       {
183         scanner_context_p->async_source_p = source_p;
184         scanner_check_async_function (context_p, scanner_context_p);
185         return SCAN_KEEP_TOKEN;
186       }
187 #endif /* ENABLED (JERRY_ES2015) */
188 
189       if (context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
190       {
191         scanner_add_reference (context_p, scanner_context_p);
192       }
193       /* FALLTHRU */
194     }
195     case LEXER_KEYW_THIS:
196     case LEXER_KEYW_SUPER:
197     case LEXER_LIT_TRUE:
198     case LEXER_LIT_FALSE:
199     case LEXER_LIT_NULL:
200     {
201       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
202       break;
203     }
204 #if ENABLED (JERRY_ES2015)
205     case LEXER_KEYW_CLASS:
206     {
207       scanner_push_class_declaration (context_p, scanner_context_p, SCAN_STACK_CLASS_EXPRESSION);
208 
209       if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
210       {
211         return SCAN_KEEP_TOKEN;
212       }
213       break;
214     }
215 #endif /* ENABLED (JERRY_ES2015) */
216     case LEXER_RIGHT_SQUARE:
217     {
218       if (stack_top != SCAN_STACK_ARRAY_LITERAL)
219       {
220         scanner_raise_error (context_p);
221       }
222 
223       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
224       return SCAN_KEEP_TOKEN;
225     }
226 #if ENABLED (JERRY_ES2015)
227     case LEXER_THREE_DOTS:
228     {
229       /* Elision or spread arguments */
230       if (stack_top != SCAN_STACK_PAREN_EXPRESSION && stack_top != SCAN_STACK_ARRAY_LITERAL)
231       {
232         scanner_raise_error (context_p);
233       }
234       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
235       break;
236     }
237 #endif /* ENABLED (JERRY_ES2015) */
238     case LEXER_COMMA:
239     {
240       if (stack_top != SCAN_STACK_ARRAY_LITERAL)
241       {
242         scanner_raise_error (context_p);
243       }
244       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
245 
246 #if ENABLED (JERRY_ES2015)
247       if (scanner_context_p->binding_type != SCANNER_BINDING_NONE)
248       {
249         scanner_context_p->mode = SCAN_MODE_BINDING;
250       }
251 #endif /* ENABLED (JERRY_ES2015) */
252       break;
253     }
254 #if ENABLED (JERRY_ES2015)
255     case LEXER_KEYW_YIELD:
256     {
257       lexer_next_token (context_p);
258 
259       if (lexer_check_yield_no_arg (context_p))
260       {
261         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
262       }
263 
264       if (context_p->token.type == LEXER_MULTIPLY)
265       {
266         return SCAN_NEXT_TOKEN;
267       }
268       return SCAN_KEEP_TOKEN;
269     }
270 #endif /* ENABLED (JERRY_ES2015) */
271     case LEXER_RIGHT_PAREN:
272     {
273       if (stack_top == SCAN_STACK_PAREN_EXPRESSION)
274       {
275         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
276         parser_stack_pop_uint8 (context_p);
277         break;
278       }
279       /* FALLTHRU */
280     }
281     default:
282     {
283       scanner_raise_error (context_p);
284     }
285   }
286   return SCAN_NEXT_TOKEN;
287 } /* scanner_scan_primary_expression */
288 
289 /**
290  * Scan the tokens after the primary expression.
291  *
292  * @return true for break, false for fall through
293  */
294 static bool
scanner_scan_post_primary_expression(parser_context_t * context_p,scanner_context_t * scanner_context_p,lexer_token_type_t type,scan_stack_modes_t stack_top)295 scanner_scan_post_primary_expression (parser_context_t *context_p, /**< context */
296                                       scanner_context_t *scanner_context_p, /**< scanner context */
297                                       lexer_token_type_t type, /**< current token type */
298                                       scan_stack_modes_t stack_top) /**< current stack top */
299 {
300   switch (type)
301   {
302     case LEXER_DOT:
303     {
304       lexer_scan_identifier (context_p);
305 
306       if (context_p->token.type != LEXER_LITERAL
307           || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
308       {
309         scanner_raise_error (context_p);
310       }
311 
312       return true;
313     }
314     case LEXER_LEFT_PAREN:
315     {
316       parser_stack_push_uint8 (context_p, SCAN_STACK_PAREN_EXPRESSION);
317       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
318       return true;
319     }
320 #if ENABLED (JERRY_ES2015)
321     case LEXER_TEMPLATE_LITERAL:
322     {
323       if (JERRY_UNLIKELY (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT))
324       {
325         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
326         parser_stack_push_uint8 (context_p, SCAN_STACK_TAGGED_TEMPLATE_LITERAL);
327       }
328       return true;
329     }
330 #endif /* ENABLED (JERRY_ES2015) */
331     case LEXER_LEFT_SQUARE:
332     {
333       parser_stack_push_uint8 (context_p, SCAN_STACK_PROPERTY_ACCESSOR);
334       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
335       return true;
336     }
337     case LEXER_INCREASE:
338     case LEXER_DECREASE:
339     {
340       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
341 
342       if (context_p->token.flags & LEXER_WAS_NEWLINE)
343       {
344         return false;
345       }
346 
347       lexer_next_token (context_p);
348       type = (lexer_token_type_t) context_p->token.type;
349 
350       if (type != LEXER_QUESTION_MARK)
351       {
352         break;
353       }
354       /* FALLTHRU */
355     }
356     case LEXER_QUESTION_MARK:
357     {
358       parser_stack_push_uint8 (context_p, SCAN_STACK_COLON_EXPRESSION);
359       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
360       return true;
361     }
362     default:
363     {
364       break;
365     }
366   }
367 
368   if (LEXER_IS_BINARY_OP_TOKEN (type)
369       && (type != LEXER_KEYW_IN || !SCANNER_IS_FOR_START (stack_top)))
370   {
371     scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
372     return true;
373   }
374 
375   return false;
376 } /* scanner_scan_post_primary_expression */
377 
378 /**
379  * Scan the tokens after the primary expression.
380  *
381  * @return SCAN_NEXT_TOKEN to read the next token, or SCAN_KEEP_TOKEN to do nothing
382  */
383 static scan_return_types_t
scanner_scan_primary_expression_end(parser_context_t * context_p,scanner_context_t * scanner_context_p,lexer_token_type_t type,scan_stack_modes_t stack_top)384 scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context */
385                                      scanner_context_t *scanner_context_p, /**< scanner context */
386                                      lexer_token_type_t type, /**< current token type */
387                                      scan_stack_modes_t stack_top) /**< current stack top */
388 {
389   if (type == LEXER_COMMA)
390   {
391     switch (stack_top)
392     {
393       case SCAN_STACK_VAR:
394 #if ENABLED (JERRY_ES2015)
395       case SCAN_STACK_LET:
396       case SCAN_STACK_CONST:
397 #endif /* ENABLED (JERRY_ES2015) */
398       case SCAN_STACK_FOR_VAR_START:
399 #if ENABLED (JERRY_ES2015)
400       case SCAN_STACK_FOR_LET_START:
401       case SCAN_STACK_FOR_CONST_START:
402 #endif /* ENABLED (JERRY_ES2015) */
403       {
404         scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
405         return SCAN_NEXT_TOKEN;
406       }
407       case SCAN_STACK_COLON_EXPRESSION:
408       {
409         scanner_raise_error (context_p);
410         break;
411       }
412 #if ENABLED (JERRY_ES2015)
413       case SCAN_STACK_BINDING_INIT:
414       case SCAN_STACK_BINDING_LIST_INIT:
415       {
416         break;
417       }
418       case SCAN_STACK_ARROW_ARGUMENTS:
419       {
420         lexer_next_token (context_p);
421         scanner_check_arrow_arg (context_p, scanner_context_p);
422         return SCAN_KEEP_TOKEN;
423       }
424       case SCAN_STACK_ARROW_EXPRESSION:
425       {
426         break;
427       }
428       case SCAN_STACK_FUNCTION_PARAMETERS:
429       {
430         scanner_context_p->mode = SCAN_MODE_CONTINUE_FUNCTION_ARGUMENTS;
431         parser_stack_pop_uint8 (context_p);
432         return SCAN_NEXT_TOKEN;
433       }
434       case SCAN_STACK_ARRAY_LITERAL:
435       {
436         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
437 
438         if (scanner_context_p->binding_type != SCANNER_BINDING_NONE)
439         {
440           scanner_context_p->mode = SCAN_MODE_BINDING;
441         }
442 
443         return SCAN_NEXT_TOKEN;
444       }
445 #endif /* ENABLED (JERRY_ES2015) */
446       case SCAN_STACK_OBJECT_LITERAL:
447       {
448         scanner_context_p->mode = SCAN_MODE_PROPERTY_NAME;
449         return SCAN_KEEP_TOKEN;
450       }
451       default:
452       {
453         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
454         return SCAN_NEXT_TOKEN;
455       }
456     }
457   }
458 
459   switch (stack_top)
460   {
461     case SCAN_STACK_WITH_EXPRESSION:
462     {
463       if (type != LEXER_RIGHT_PAREN)
464       {
465         break;
466       }
467 
468       parser_stack_pop_uint8 (context_p);
469 
470       uint16_t status_flags = scanner_context_p->active_literal_pool_p->status_flags;
471       parser_stack_push_uint8 (context_p, (status_flags & SCANNER_LITERAL_POOL_IN_WITH) ? 1 : 0);
472       parser_stack_push_uint8 (context_p, SCAN_STACK_WITH_STATEMENT);
473       status_flags |= SCANNER_LITERAL_POOL_IN_WITH;
474       scanner_context_p->active_literal_pool_p->status_flags = status_flags;
475 
476       scanner_context_p->mode = SCAN_MODE_STATEMENT;
477       return SCAN_NEXT_TOKEN;
478     }
479     case SCAN_STACK_DO_EXPRESSION:
480     {
481       if (type != LEXER_RIGHT_PAREN)
482       {
483         break;
484       }
485 
486       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
487       return SCAN_NEXT_TOKEN;
488     }
489     case SCAN_STACK_WHILE_EXPRESSION:
490     {
491       if (type != LEXER_RIGHT_PAREN)
492       {
493         break;
494       }
495 
496       scanner_source_start_t source_start;
497 
498       parser_stack_pop_uint8 (context_p);
499       parser_stack_pop (context_p, &source_start, sizeof (scanner_source_start_t));
500 
501       scanner_location_info_t *location_info_p;
502       location_info_p = (scanner_location_info_t *) scanner_insert_info (context_p,
503                                                                          source_start.source_p,
504                                                                          sizeof (scanner_location_info_t));
505       location_info_p->info.type = SCANNER_TYPE_WHILE;
506 
507       scanner_get_location (&location_info_p->location, context_p);
508 
509       scanner_context_p->mode = SCAN_MODE_STATEMENT;
510       return SCAN_NEXT_TOKEN;
511     }
512     case SCAN_STACK_PAREN_EXPRESSION:
513     {
514       if (type != LEXER_RIGHT_PAREN)
515       {
516         break;
517       }
518 
519       parser_stack_pop_uint8 (context_p);
520 
521 #if ENABLED (JERRY_ES2015)
522       if (context_p->stack_top_uint8 == SCAN_STACK_USE_ASYNC)
523       {
524         scanner_add_async_literal (context_p, scanner_context_p);
525       }
526 #endif /* ENABLED (JERRY_ES2015) */
527 
528       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
529       return SCAN_NEXT_TOKEN;
530     }
531     case SCAN_STACK_STATEMENT_WITH_EXPR:
532     {
533       if (type != LEXER_RIGHT_PAREN)
534       {
535         break;
536       }
537 
538       parser_stack_pop_uint8 (context_p);
539 
540 #if ENABLED (JERRY_ES2015)
541       if (context_p->stack_top_uint8 == SCAN_STACK_IF_STATEMENT)
542       {
543         scanner_check_function_after_if (context_p, scanner_context_p);
544         return SCAN_KEEP_TOKEN;
545       }
546 #endif /* ENABLED (JERRY_ES2015) */
547 
548       scanner_context_p->mode = SCAN_MODE_STATEMENT;
549       return SCAN_NEXT_TOKEN;
550     }
551 #if ENABLED (JERRY_ES2015)
552     case SCAN_STACK_BINDING_LIST_INIT:
553     {
554       parser_stack_pop_uint8 (context_p);
555 
556       JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_ARRAY_LITERAL
557                     || context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL
558                     || context_p->stack_top_uint8 == SCAN_STACK_LET
559                     || context_p->stack_top_uint8 == SCAN_STACK_CONST
560                     || context_p->stack_top_uint8 == SCAN_STACK_FOR_LET_START
561                     || context_p->stack_top_uint8 == SCAN_STACK_FOR_CONST_START
562                     || context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_PARAMETERS
563                     || context_p->stack_top_uint8 == SCAN_STACK_ARROW_ARGUMENTS);
564 
565       scanner_binding_item_t *item_p = scanner_context_p->active_binding_list_p->items_p;
566 
567       while (item_p != NULL)
568       {
569         if (item_p->literal_p->type & SCANNER_LITERAL_IS_USED)
570         {
571           item_p->literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
572         }
573         item_p = item_p->next_p;
574       }
575 
576       scanner_pop_binding_list (scanner_context_p);
577       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
578       return SCAN_KEEP_TOKEN;
579     }
580     case SCAN_STACK_BINDING_INIT:
581     {
582       scanner_binding_literal_t binding_literal;
583 
584       parser_stack_pop_uint8 (context_p);
585       parser_stack_pop (context_p, &binding_literal, sizeof (scanner_binding_literal_t));
586 
587       JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_ARRAY_LITERAL
588                     || context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL
589                     || context_p->stack_top_uint8 == SCAN_STACK_LET
590                     || context_p->stack_top_uint8 == SCAN_STACK_CONST
591                     || context_p->stack_top_uint8 == SCAN_STACK_FOR_LET_START
592                     || context_p->stack_top_uint8 == SCAN_STACK_FOR_CONST_START
593                     || context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_PARAMETERS
594                     || context_p->stack_top_uint8 == SCAN_STACK_ARROW_ARGUMENTS);
595 
596       JERRY_ASSERT ((stack_top != SCAN_STACK_ARRAY_LITERAL && stack_top != SCAN_STACK_OBJECT_LITERAL)
597                     || SCANNER_NEEDS_BINDING_LIST (scanner_context_p->binding_type));
598 
599       if (binding_literal.literal_p->type & SCANNER_LITERAL_IS_USED)
600       {
601         binding_literal.literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
602       }
603 
604       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
605       return SCAN_KEEP_TOKEN;
606     }
607 #endif /* ENABLED (JERRY_ES2015) */
608     case SCAN_STACK_VAR:
609 #if ENABLED (JERRY_ES2015)
610     case SCAN_STACK_LET:
611     case SCAN_STACK_CONST:
612 #endif /* ENABLED (JERRY_ES2015) */
613     {
614 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
615       scanner_context_p->active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT;
616 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
617 
618       parser_stack_pop_uint8 (context_p);
619       return SCAN_KEEP_TOKEN;
620     }
621     case SCAN_STACK_FOR_VAR_START:
622 #if ENABLED (JERRY_ES2015)
623     case SCAN_STACK_FOR_LET_START:
624     case SCAN_STACK_FOR_CONST_START:
625 #endif /* ENABLED (JERRY_ES2015) */
626     case SCAN_STACK_FOR_START:
627     {
628       if (type == LEXER_KEYW_IN || SCANNER_IDENTIFIER_IS_OF ())
629       {
630         scanner_for_statement_t for_statement;
631 
632         parser_stack_pop_uint8 (context_p);
633         parser_stack_pop (context_p, &for_statement, sizeof (scanner_for_statement_t));
634 
635         scanner_location_info_t *location_info;
636         location_info = (scanner_location_info_t *) scanner_insert_info (context_p,
637                                                                          for_statement.u.source_p,
638                                                                          sizeof (scanner_location_info_t));
639 #if ENABLED (JERRY_ES2015)
640         location_info->info.type = (type == LEXER_KEYW_IN) ? SCANNER_TYPE_FOR_IN : SCANNER_TYPE_FOR_OF;
641 
642         if (stack_top == SCAN_STACK_FOR_LET_START || stack_top == SCAN_STACK_FOR_CONST_START)
643         {
644           parser_stack_push_uint8 (context_p, SCAN_STACK_PRIVATE_BLOCK_EARLY);
645         }
646 #else /* !ENABLED (JERRY_ES2015) */
647         location_info->info.type = SCANNER_TYPE_FOR_IN;
648 #endif /* ENABLED (JERRY_ES2015) */
649 
650         scanner_get_location (&location_info->location, context_p);
651 
652         parser_stack_push_uint8 (context_p, SCAN_STACK_STATEMENT_WITH_EXPR);
653         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
654         return SCAN_NEXT_TOKEN;
655       }
656 
657       if (type != LEXER_SEMICOLON)
658       {
659         break;
660       }
661 
662       scanner_for_statement_t for_statement;
663 
664       parser_stack_pop_uint8 (context_p);
665       parser_stack_pop (context_p, NULL, sizeof (scanner_for_statement_t));
666 
667 #if ENABLED (JERRY_ES2015)
668       if (stack_top == SCAN_STACK_FOR_LET_START || stack_top == SCAN_STACK_FOR_CONST_START)
669       {
670         parser_stack_push_uint8 (context_p, SCAN_STACK_PRIVATE_BLOCK);
671       }
672 #endif /* ENABLED (JERRY_ES2015) */
673 
674       for_statement.u.source_p = context_p->source_p;
675       parser_stack_push (context_p, &for_statement, sizeof (scanner_for_statement_t));
676       parser_stack_push_uint8 (context_p, SCAN_STACK_FOR_CONDITION);
677 
678       lexer_next_token (context_p);
679 
680       if (context_p->token.type != LEXER_SEMICOLON)
681       {
682         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
683         return SCAN_KEEP_TOKEN;
684       }
685 
686       type = LEXER_SEMICOLON;
687       /* FALLTHRU */
688     }
689     case SCAN_STACK_FOR_CONDITION:
690     {
691       if (type != LEXER_SEMICOLON)
692       {
693         break;
694       }
695 
696       scanner_for_statement_t for_statement;
697 
698       parser_stack_pop_uint8 (context_p);
699       parser_stack_pop (context_p, &for_statement, sizeof (scanner_for_statement_t));
700 
701       scanner_for_info_t *for_info_p;
702       for_info_p = (scanner_for_info_t *) scanner_insert_info (context_p,
703                                                                for_statement.u.source_p,
704                                                                sizeof (scanner_for_info_t));
705       for_info_p->info.type = SCANNER_TYPE_FOR;
706 
707       scanner_get_location (&for_info_p->expression_location, context_p);
708       for_info_p->end_location.source_p = NULL;
709 
710       for_statement.u.for_info_p = for_info_p;
711 
712       parser_stack_push (context_p, &for_statement, sizeof (scanner_for_statement_t));
713       parser_stack_push_uint8 (context_p, SCAN_STACK_FOR_EXPRESSION);
714 
715       lexer_next_token (context_p);
716 
717       if (context_p->token.type != LEXER_RIGHT_PAREN)
718       {
719         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
720         return SCAN_KEEP_TOKEN;
721       }
722 
723       type = LEXER_RIGHT_PAREN;
724       /* FALLTHRU */
725     }
726     case SCAN_STACK_FOR_EXPRESSION:
727     {
728       if (type != LEXER_RIGHT_PAREN)
729       {
730         break;
731       }
732 
733       scanner_for_statement_t for_statement;
734 
735       parser_stack_pop_uint8 (context_p);
736       parser_stack_pop (context_p, &for_statement, sizeof (scanner_for_statement_t));
737 
738       scanner_get_location (&for_statement.u.for_info_p->end_location, context_p);
739 
740       scanner_context_p->mode = SCAN_MODE_STATEMENT;
741       return SCAN_NEXT_TOKEN;
742     }
743     case SCAN_STACK_SWITCH_EXPRESSION:
744     {
745       if (type != LEXER_RIGHT_PAREN)
746       {
747         break;
748       }
749 
750       lexer_next_token (context_p);
751 
752       if (context_p->token.type != LEXER_LEFT_BRACE)
753       {
754         break;
755       }
756 
757 #if ENABLED (JERRY_ES2015)
758       scanner_literal_pool_t *literal_pool_p;
759       literal_pool_p = scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_BLOCK);
760       literal_pool_p->source_p = context_p->source_p - 1;
761 #endif /* ENABLED (JERRY_ES2015) */
762 
763       parser_stack_pop_uint8 (context_p);
764 
765       scanner_switch_statement_t switch_statement = scanner_context_p->active_switch_statement;
766       parser_stack_push (context_p, &switch_statement, sizeof (scanner_switch_statement_t));
767       parser_stack_push_uint8 (context_p, SCAN_STACK_SWITCH_BLOCK);
768 
769       scanner_switch_info_t *switch_info_p;
770       switch_info_p = (scanner_switch_info_t *) scanner_insert_info (context_p,
771                                                                      context_p->source_p,
772                                                                      sizeof (scanner_switch_info_t));
773       switch_info_p->info.type = SCANNER_TYPE_SWITCH;
774       switch_info_p->case_p = NULL;
775       scanner_context_p->active_switch_statement.last_case_p = &switch_info_p->case_p;
776 
777       lexer_next_token (context_p);
778 
779       if (context_p->token.type != LEXER_RIGHT_BRACE
780           && context_p->token.type != LEXER_KEYW_CASE
781           && context_p->token.type != LEXER_KEYW_DEFAULT)
782       {
783         break;
784       }
785 
786       scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
787       return SCAN_KEEP_TOKEN;
788     }
789     case SCAN_STACK_CASE_STATEMENT:
790     {
791       if (type != LEXER_COLON)
792       {
793         break;
794       }
795 
796       scanner_source_start_t source_start;
797 
798       parser_stack_pop_uint8 (context_p);
799       parser_stack_pop (context_p, &source_start, sizeof (scanner_source_start_t));
800 
801       scanner_location_info_t *location_info_p;
802       location_info_p = (scanner_location_info_t *) scanner_insert_info (context_p,
803                                                                          source_start.source_p,
804                                                                          sizeof (scanner_location_info_t));
805       location_info_p->info.type = SCANNER_TYPE_CASE;
806 
807       scanner_get_location (&location_info_p->location, context_p);
808 
809       scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
810       return SCAN_NEXT_TOKEN;
811     }
812     case SCAN_STACK_COLON_EXPRESSION:
813     {
814       if (type != LEXER_COLON)
815       {
816         break;
817       }
818 
819       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
820       parser_stack_pop_uint8 (context_p);
821       return SCAN_NEXT_TOKEN;
822     }
823 #if ENABLED (JERRY_ES2015)
824     case SCAN_STACK_ARRAY_LITERAL:
825     case SCAN_STACK_OBJECT_LITERAL:
826     {
827       if (((stack_top == SCAN_STACK_ARRAY_LITERAL) && (type != LEXER_RIGHT_SQUARE))
828           || ((stack_top == SCAN_STACK_OBJECT_LITERAL) && (type != LEXER_RIGHT_BRACE)))
829       {
830         break;
831       }
832 
833       scanner_source_start_t source_start;
834       uint8_t binding_type = scanner_context_p->binding_type;
835 
836       parser_stack_pop_uint8 (context_p);
837       scanner_context_p->binding_type = context_p->stack_top_uint8;
838       parser_stack_pop_uint8 (context_p);
839       parser_stack_pop (context_p, &source_start, sizeof (scanner_source_start_t));
840 
841       lexer_next_token (context_p);
842 
843       if (binding_type == SCANNER_BINDING_CATCH && context_p->stack_top_uint8 == SCAN_STACK_CATCH_STATEMENT)
844       {
845         scanner_pop_binding_list (scanner_context_p);
846 
847         if (context_p->token.type != LEXER_RIGHT_PAREN)
848         {
849           scanner_raise_error (context_p);
850         }
851 
852         lexer_next_token (context_p);
853 
854         if (context_p->token.type != LEXER_LEFT_BRACE)
855         {
856           scanner_raise_error (context_p);
857         }
858 
859         scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
860         return SCAN_NEXT_TOKEN;
861       }
862 
863       if (context_p->token.type != LEXER_ASSIGN)
864       {
865         if (SCANNER_NEEDS_BINDING_LIST (binding_type))
866         {
867           scanner_pop_binding_list (scanner_context_p);
868         }
869 
870         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
871         return SCAN_KEEP_TOKEN;
872       }
873 
874       scanner_location_info_t *location_info_p;
875       location_info_p = (scanner_location_info_t *) scanner_insert_info (context_p,
876                                                                          source_start.source_p,
877                                                                          sizeof (scanner_location_info_t));
878       location_info_p->info.type = SCANNER_TYPE_INITIALIZER;
879       scanner_get_location (&location_info_p->location, context_p);
880       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
881 
882       if (SCANNER_NEEDS_BINDING_LIST (binding_type))
883       {
884         scanner_binding_item_t *item_p = scanner_context_p->active_binding_list_p->items_p;
885 
886         while (item_p != NULL)
887         {
888           item_p->literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_USED;
889           item_p = item_p->next_p;
890         }
891 
892         parser_stack_push_uint8 (context_p, SCAN_STACK_BINDING_LIST_INIT);
893       }
894       return SCAN_NEXT_TOKEN;
895     }
896 #else /* !ENABLED (JERRY_ES2015) */
897     case SCAN_STACK_ARRAY_LITERAL:
898 #endif /* ENABLED (JERRY_ES2015) */
899     case SCAN_STACK_PROPERTY_ACCESSOR:
900     {
901       if (type != LEXER_RIGHT_SQUARE)
902       {
903         break;
904       }
905 
906       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
907       parser_stack_pop_uint8 (context_p);
908       return SCAN_NEXT_TOKEN;
909     }
910 #if !ENABLED (JERRY_ES2015)
911     case SCAN_STACK_OBJECT_LITERAL:
912     {
913       if (type != LEXER_RIGHT_BRACE)
914       {
915         break;
916       }
917 
918       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
919       parser_stack_pop_uint8 (context_p);
920       return SCAN_NEXT_TOKEN;
921     }
922 #endif /* !ENABLED (JERRY_ES2015) */
923 #if ENABLED (JERRY_ES2015)
924     case SCAN_STACK_COMPUTED_PROPERTY:
925     {
926       if (type != LEXER_RIGHT_SQUARE)
927       {
928         break;
929       }
930 
931       lexer_next_token (context_p);
932 
933       parser_stack_pop_uint8 (context_p);
934       stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
935 
936       if (stack_top == SCAN_STACK_FUNCTION_PROPERTY)
937       {
938         scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION);
939 
940         scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
941         return SCAN_KEEP_TOKEN;
942       }
943 
944       JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
945 
946       if (context_p->token.type == LEXER_LEFT_PAREN)
947       {
948         scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION);
949 
950         parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PROPERTY);
951         scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
952         return SCAN_KEEP_TOKEN;
953       }
954 
955       if (context_p->token.type != LEXER_COLON)
956       {
957         scanner_raise_error (context_p);
958       }
959 
960       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
961 
962       if (scanner_context_p->binding_type != SCANNER_BINDING_NONE)
963       {
964         scanner_context_p->mode = SCAN_MODE_BINDING;
965       }
966       return SCAN_NEXT_TOKEN;
967     }
968     case SCAN_STACK_COMPUTED_GENERATOR:
969     case SCAN_STACK_COMPUTED_ASYNC:
970     case SCAN_STACK_COMPUTED_ASYNC_GENERATOR:
971     {
972       if (type != LEXER_RIGHT_SQUARE)
973       {
974         break;
975       }
976 
977       lexer_next_token (context_p);
978       parser_stack_pop_uint8 (context_p);
979 
980       JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL
981                     || context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_PROPERTY);
982 
983       uint16_t status_flags = (uint16_t) (SCANNER_LITERAL_POOL_FUNCTION
984                                           | SCANNER_LITERAL_POOL_GENERATOR
985                                           | SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (stack_top));
986 
987       scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
988 
989       scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
990       return SCAN_KEEP_TOKEN;
991     }
992     case SCAN_STACK_TEMPLATE_STRING:
993     case SCAN_STACK_TAGGED_TEMPLATE_LITERAL:
994     {
995       if (type != LEXER_RIGHT_BRACE)
996       {
997         break;
998       }
999 
1000       context_p->source_p--;
1001       context_p->column--;
1002       lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);
1003 
1004       if (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
1005       {
1006         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1007       }
1008       else
1009       {
1010         parser_stack_pop_uint8 (context_p);
1011         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1012       }
1013       return SCAN_NEXT_TOKEN;
1014     }
1015     case SCAN_STACK_ARROW_ARGUMENTS:
1016     {
1017       if (type != LEXER_RIGHT_PAREN)
1018       {
1019         break;
1020       }
1021 
1022       scanner_check_arrow (context_p, scanner_context_p);
1023       return SCAN_KEEP_TOKEN;
1024     }
1025     case SCAN_STACK_ARROW_EXPRESSION:
1026     {
1027       scanner_pop_literal_pool (context_p, scanner_context_p);
1028       parser_stack_pop_uint8 (context_p);
1029       lexer_update_await_yield (context_p, context_p->status_flags);
1030       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
1031       return SCAN_KEEP_TOKEN;
1032     }
1033     case SCAN_STACK_CLASS_EXTENDS:
1034     {
1035       if (type != LEXER_LEFT_BRACE)
1036       {
1037         break;
1038       }
1039 
1040       scanner_context_p->mode = SCAN_MODE_CLASS_METHOD;
1041       parser_stack_pop_uint8 (context_p);
1042 
1043       return SCAN_KEEP_TOKEN;
1044     }
1045     case SCAN_STACK_FUNCTION_PARAMETERS:
1046     {
1047       parser_stack_pop_uint8 (context_p);
1048 
1049       if (type != LEXER_RIGHT_PAREN
1050           && (type != LEXER_EOS || context_p->stack_top_uint8 != SCAN_STACK_SCRIPT_FUNCTION))
1051       {
1052         break;
1053       }
1054 
1055       scanner_context_p->mode = SCAN_MODE_CONTINUE_FUNCTION_ARGUMENTS;
1056       return SCAN_KEEP_TOKEN;
1057     }
1058 #endif /* ENABLED (JERRY_ES2015) */
1059     default:
1060     {
1061       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1062       return SCAN_KEEP_TOKEN;
1063     }
1064   }
1065 
1066   scanner_raise_error (context_p);
1067   return SCAN_NEXT_TOKEN;
1068 } /* scanner_scan_primary_expression_end */
1069 
1070 /**
1071  * Scan statements.
1072  *
1073  * @return SCAN_NEXT_TOKEN to read the next token, or SCAN_KEEP_TOKEN to do nothing
1074  */
1075 static scan_return_types_t
scanner_scan_statement(parser_context_t * context_p,scanner_context_t * scanner_context_p,lexer_token_type_t type,scan_stack_modes_t stack_top)1076 scanner_scan_statement (parser_context_t *context_p, /**< context */
1077                         scanner_context_t *scanner_context_p, /**< scanner context */
1078                         lexer_token_type_t type, /**< current token type */
1079                         scan_stack_modes_t stack_top) /**< current stack top */
1080 {
1081   switch (type)
1082   {
1083     case LEXER_SEMICOLON:
1084     {
1085       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1086       return SCAN_KEEP_TOKEN;
1087     }
1088     case LEXER_LEFT_BRACE:
1089     {
1090 #if ENABLED (JERRY_ES2015)
1091       scanner_literal_pool_t *literal_pool_p;
1092       literal_pool_p = scanner_push_literal_pool (context_p,
1093                                                   scanner_context_p,
1094                                                   SCANNER_LITERAL_POOL_BLOCK);
1095       literal_pool_p->source_p = context_p->source_p;
1096 #endif /* ENABLED (JERRY_ES2015) */
1097 
1098       scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
1099       parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_STATEMENT);
1100       return SCAN_NEXT_TOKEN;
1101     }
1102     case LEXER_KEYW_DO:
1103     {
1104       scanner_context_p->mode = SCAN_MODE_STATEMENT;
1105       parser_stack_push_uint8 (context_p, SCAN_STACK_DO_STATEMENT);
1106       return SCAN_NEXT_TOKEN;
1107     }
1108     case LEXER_KEYW_TRY:
1109     {
1110       lexer_next_token (context_p);
1111 
1112       if (context_p->token.type != LEXER_LEFT_BRACE)
1113       {
1114         scanner_raise_error (context_p);
1115       }
1116 
1117 #if ENABLED (JERRY_ES2015)
1118       scanner_literal_pool_t *literal_pool_p;
1119       literal_pool_p = scanner_push_literal_pool (context_p,
1120                                                   scanner_context_p,
1121                                                   SCANNER_LITERAL_POOL_BLOCK);
1122       literal_pool_p->source_p = context_p->source_p;
1123 #endif /* ENABLED (JERRY_ES2015) */
1124 
1125       scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
1126       parser_stack_push_uint8 (context_p, SCAN_STACK_TRY_STATEMENT);
1127       return SCAN_NEXT_TOKEN;
1128     }
1129     case LEXER_KEYW_DEBUGGER:
1130     {
1131       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1132       return SCAN_NEXT_TOKEN;
1133     }
1134     case LEXER_KEYW_IF:
1135     case LEXER_KEYW_WITH:
1136     case LEXER_KEYW_SWITCH:
1137     {
1138       lexer_next_token (context_p);
1139       if (context_p->token.type != LEXER_LEFT_PAREN)
1140       {
1141         scanner_raise_error (context_p);
1142       }
1143 
1144       uint8_t mode = SCAN_STACK_STATEMENT_WITH_EXPR;
1145 
1146       if (type == LEXER_KEYW_IF)
1147       {
1148         parser_stack_push_uint8 (context_p, SCAN_STACK_IF_STATEMENT);
1149       }
1150       else if (type == LEXER_KEYW_WITH)
1151       {
1152         mode = SCAN_STACK_WITH_EXPRESSION;
1153       }
1154       else if (type == LEXER_KEYW_SWITCH)
1155       {
1156         mode = SCAN_STACK_SWITCH_EXPRESSION;
1157       }
1158 
1159       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1160       parser_stack_push_uint8 (context_p, mode);
1161       return SCAN_NEXT_TOKEN;
1162     }
1163     case LEXER_KEYW_WHILE:
1164     {
1165       lexer_next_token (context_p);
1166 
1167       if (context_p->token.type != LEXER_LEFT_PAREN)
1168       {
1169         scanner_raise_error (context_p);
1170       }
1171 
1172       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1173 
1174       scanner_source_start_t source_start;
1175       source_start.source_p = context_p->source_p;
1176 
1177       parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t));
1178       parser_stack_push_uint8 (context_p, SCAN_STACK_WHILE_EXPRESSION);
1179       return SCAN_NEXT_TOKEN;
1180     }
1181     case LEXER_KEYW_FOR:
1182     {
1183       lexer_next_token (context_p);
1184       if (context_p->token.type != LEXER_LEFT_PAREN)
1185       {
1186         scanner_raise_error (context_p);
1187       }
1188 
1189       scanner_for_statement_t for_statement;
1190       for_statement.u.source_p = context_p->source_p;
1191       uint8_t stack_mode = SCAN_STACK_FOR_START;
1192       scan_return_types_t return_type = SCAN_KEEP_TOKEN;
1193 
1194       lexer_next_token (context_p);
1195       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1196 
1197 #if ENABLED (JERRY_ES2015)
1198       const uint8_t *source_p = context_p->source_p;
1199 #endif /* ENABLED (JERRY_ES2015) */
1200 
1201       switch (context_p->token.type)
1202       {
1203         case LEXER_SEMICOLON:
1204         {
1205           scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
1206           break;
1207         }
1208         case LEXER_KEYW_VAR:
1209         {
1210           scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1211           stack_mode = SCAN_STACK_FOR_VAR_START;
1212           return_type = SCAN_NEXT_TOKEN;
1213           break;
1214         }
1215 #if ENABLED (JERRY_ES2015)
1216         case LEXER_LITERAL:
1217         {
1218           if (!lexer_token_is_let (context_p))
1219           {
1220             break;
1221           }
1222 
1223           parser_line_counter_t line = context_p->line;
1224           parser_line_counter_t column = context_p->column;
1225 
1226           if (lexer_check_arrow (context_p))
1227           {
1228             context_p->source_p = source_p;
1229             context_p->line = line;
1230             context_p->column = column;
1231             context_p->token.flags &= (uint8_t) ~LEXER_NO_SKIP_SPACES;
1232             break;
1233           }
1234 
1235           lexer_next_token (context_p);
1236 
1237           type = (lexer_token_type_t) context_p->token.type;
1238 
1239           if (type != LEXER_LEFT_SQUARE
1240               && type != LEXER_LEFT_BRACE
1241               && (type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL))
1242           {
1243             scanner_info_t *info_p = scanner_insert_info (context_p, source_p, sizeof (scanner_info_t));
1244             info_p->type = SCANNER_TYPE_LET_EXPRESSION;
1245 
1246             scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1247             break;
1248           }
1249 
1250           scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1251           /* FALLTHRU */
1252         }
1253         case LEXER_KEYW_LET:
1254         case LEXER_KEYW_CONST:
1255         {
1256           scanner_literal_pool_t *literal_pool_p;
1257           literal_pool_p = scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_BLOCK);
1258           literal_pool_p->source_p = source_p;
1259 
1260           if (scanner_context_p->mode == SCAN_MODE_PRIMARY_EXPRESSION)
1261           {
1262             scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1263             return_type = SCAN_NEXT_TOKEN;
1264           }
1265 
1266           stack_mode = ((context_p->token.type == LEXER_KEYW_CONST) ? SCAN_STACK_FOR_CONST_START
1267                                                                     : SCAN_STACK_FOR_LET_START);
1268           break;
1269         }
1270 #endif /* ENABLED (JERRY_ES2015) */
1271       }
1272 
1273       parser_stack_push (context_p, &for_statement, sizeof (scanner_for_statement_t));
1274       parser_stack_push_uint8 (context_p, stack_mode);
1275       return return_type;
1276     }
1277     case LEXER_KEYW_VAR:
1278     {
1279       scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1280       parser_stack_push_uint8 (context_p, SCAN_STACK_VAR);
1281       return SCAN_NEXT_TOKEN;
1282     }
1283 #if ENABLED (JERRY_ES2015)
1284     case LEXER_KEYW_LET:
1285     {
1286       scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1287       parser_stack_push_uint8 (context_p, SCAN_STACK_LET);
1288       return SCAN_NEXT_TOKEN;
1289     }
1290     case LEXER_KEYW_CONST:
1291     {
1292       scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1293       parser_stack_push_uint8 (context_p, SCAN_STACK_CONST);
1294       return SCAN_NEXT_TOKEN;
1295     }
1296 #endif /* ENABLED (JERRY_ES2015) */
1297     case LEXER_KEYW_THROW:
1298     {
1299       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1300       return SCAN_NEXT_TOKEN;
1301     }
1302     case LEXER_KEYW_RETURN:
1303     {
1304       lexer_next_token (context_p);
1305 
1306       if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
1307           && context_p->token.type != LEXER_SEMICOLON
1308           && context_p->token.type != LEXER_EOS
1309           && context_p->token.type != LEXER_RIGHT_BRACE)
1310       {
1311         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1312         return SCAN_KEEP_TOKEN;
1313       }
1314 
1315       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1316       return SCAN_KEEP_TOKEN;
1317     }
1318     case LEXER_KEYW_BREAK:
1319     case LEXER_KEYW_CONTINUE:
1320     {
1321       lexer_next_token (context_p);
1322       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1323 
1324       if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
1325           && context_p->token.type == LEXER_LITERAL
1326           && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1327       {
1328         return SCAN_NEXT_TOKEN;
1329       }
1330       return SCAN_KEEP_TOKEN;
1331     }
1332     case LEXER_KEYW_CASE:
1333     case LEXER_KEYW_DEFAULT:
1334     {
1335       if (stack_top != SCAN_STACK_SWITCH_BLOCK)
1336       {
1337         scanner_raise_error (context_p);
1338       }
1339 
1340       scanner_case_info_t *case_info_p;
1341       case_info_p = (scanner_case_info_t *) scanner_malloc (context_p, sizeof (scanner_case_info_t));
1342 
1343       *(scanner_context_p->active_switch_statement.last_case_p) = case_info_p;
1344       scanner_context_p->active_switch_statement.last_case_p = &case_info_p->next_p;
1345 
1346       case_info_p->next_p = NULL;
1347       scanner_get_location (&case_info_p->location, context_p);
1348 
1349       if (type == LEXER_KEYW_DEFAULT)
1350       {
1351         lexer_next_token (context_p);
1352 
1353         if (context_p->token.type != LEXER_COLON)
1354         {
1355           scanner_raise_error (context_p);
1356         }
1357 
1358         scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
1359         return SCAN_NEXT_TOKEN;
1360       }
1361 
1362       scanner_source_start_t source_start;
1363       source_start.source_p = context_p->source_p;
1364 
1365       parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t));
1366       parser_stack_push_uint8 (context_p, SCAN_STACK_CASE_STATEMENT);
1367 
1368       scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1369       return SCAN_NEXT_TOKEN;
1370     }
1371     case LEXER_KEYW_FUNCTION:
1372     {
1373 #if ENABLED (JERRY_ES2015)
1374       uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_FUNCTION_STATEMENT;
1375 
1376       if (scanner_context_p->async_source_p != NULL)
1377       {
1378         scanner_context_p->status_flags |= SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION;
1379         status_flags |= SCANNER_LITERAL_POOL_ASYNC;
1380       }
1381 #endif /* ENABLED (JERRY_ES2015) */
1382 
1383       lexer_next_token (context_p);
1384 
1385 #if ENABLED (JERRY_ES2015)
1386       if (context_p->token.type == LEXER_MULTIPLY)
1387       {
1388         status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
1389         lexer_next_token (context_p);
1390       }
1391 #endif /* ENABLED (JERRY_ES2015) */
1392 
1393       if (context_p->token.type != LEXER_LITERAL
1394           || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1395       {
1396         scanner_raise_error (context_p);
1397       }
1398 
1399       lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1400 
1401 #if ENABLED (JERRY_ES2015)
1402       const uint8_t mask = (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LOCAL);
1403 
1404       if ((literal_p->type & SCANNER_LITERAL_IS_LOCAL)
1405           && (literal_p->type & mask) != (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
1406           && (literal_p->type & mask) != (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION))
1407       {
1408         scanner_raise_redeclaration_error (context_p);
1409       }
1410 
1411       literal_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION;
1412 
1413       scanner_context_p->status_flags &= (uint16_t) ~SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION;
1414 #else
1415       literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC;
1416 
1417       uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
1418 #endif /* ENABLED (JERRY_ES2015) */
1419 
1420       scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
1421 
1422       scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
1423       parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_STATEMENT);
1424       return SCAN_NEXT_TOKEN;
1425     }
1426 #if ENABLED (JERRY_ES2015)
1427     case LEXER_KEYW_CLASS:
1428     {
1429       scanner_push_class_declaration (context_p, scanner_context_p, SCAN_STACK_CLASS_STATEMENT);
1430 
1431       if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1432       {
1433         scanner_raise_error (context_p);
1434       }
1435 
1436       lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1437 
1438       scanner_detect_invalid_let (context_p, literal_p);
1439       literal_p->type |= SCANNER_LITERAL_IS_LET;
1440 
1441 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1442       if (scanner_context_p->active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT)
1443       {
1444         literal_p->type |= SCANNER_LITERAL_NO_REG;
1445         scanner_context_p->active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT;
1446       }
1447 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1448 
1449       return SCAN_NEXT_TOKEN;
1450     }
1451 #endif /* ENABLED (JERRY_ES2015) */
1452 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1453     case LEXER_KEYW_IMPORT:
1454     {
1455       if (stack_top != SCAN_STACK_SCRIPT)
1456       {
1457         scanner_raise_error (context_p);
1458       }
1459 
1460       context_p->global_status_flags |= ECMA_PARSE_MODULE;
1461 
1462       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1463       lexer_next_token (context_p);
1464 
1465       if (context_p->token.type == LEXER_LITERAL
1466           && context_p->token.lit_location.type == LEXER_STRING_LITERAL)
1467       {
1468         return SCAN_NEXT_TOKEN;
1469       }
1470 
1471       bool parse_imports = true;
1472 
1473       if (context_p->token.type == LEXER_LITERAL
1474           && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1475       {
1476         lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1477 
1478 #if ENABLED (JERRY_ES2015)
1479         scanner_detect_invalid_let (context_p, literal_p);
1480         literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG;
1481 #else /* !ENABLED (JERRY_ES2015) */
1482         literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG;
1483 #endif /* ENABLED (JERRY_ES2015) */
1484 
1485         lexer_next_token (context_p);
1486 
1487         if (context_p->token.type == LEXER_COMMA)
1488         {
1489           lexer_next_token (context_p);
1490         }
1491         else
1492         {
1493           parse_imports = false;
1494         }
1495       }
1496 
1497       if (parse_imports)
1498       {
1499         if (context_p->token.type == LEXER_MULTIPLY)
1500         {
1501           lexer_next_token (context_p);
1502           if (!lexer_token_is_identifier (context_p, "as", 2))
1503           {
1504             scanner_raise_error (context_p);
1505           }
1506 
1507           lexer_next_token (context_p);
1508 
1509           if (context_p->token.type != LEXER_LITERAL
1510               && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1511           {
1512             scanner_raise_error (context_p);
1513           }
1514 
1515           lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1516 
1517 #if ENABLED (JERRY_ES2015)
1518           scanner_detect_invalid_let (context_p, literal_p);
1519           literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG;
1520 #else /* !ENABLED (JERRY_ES2015) */
1521           literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG;
1522 #endif /* ENABLED (JERRY_ES2015) */
1523 
1524           lexer_next_token (context_p);
1525         }
1526         else if (context_p->token.type == LEXER_LEFT_BRACE)
1527         {
1528           lexer_next_token (context_p);
1529 
1530           while (context_p->token.type != LEXER_RIGHT_BRACE)
1531           {
1532             if (context_p->token.type != LEXER_LITERAL
1533                 || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1534             {
1535               scanner_raise_error (context_p);
1536             }
1537 
1538 #if ENABLED (JERRY_ES2015)
1539             const uint8_t *source_p = context_p->source_p;
1540 #endif /* ENABLED (JERRY_ES2015) */
1541 
1542             if (lexer_check_next_character (context_p, LIT_CHAR_LOWERCASE_A))
1543             {
1544               lexer_next_token (context_p);
1545 
1546               if (!lexer_token_is_identifier (context_p, "as", 2))
1547               {
1548                 scanner_raise_error (context_p);
1549               }
1550 
1551               lexer_next_token (context_p);
1552 
1553               if (context_p->token.type != LEXER_LITERAL
1554                   && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1555               {
1556                 scanner_raise_error (context_p);
1557               }
1558 
1559 #if ENABLED (JERRY_ES2015)
1560               source_p = context_p->source_p;
1561 #endif /* ENABLED (JERRY_ES2015) */
1562             }
1563 
1564             lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1565 
1566 #if ENABLED (JERRY_ES2015)
1567             if (literal_p->type & (SCANNER_LITERAL_IS_ARG
1568                                    | SCANNER_LITERAL_IS_VAR
1569                                    | SCANNER_LITERAL_IS_LOCAL))
1570             {
1571               context_p->source_p = source_p;
1572               scanner_raise_redeclaration_error (context_p);
1573             }
1574 
1575             if (literal_p->type & SCANNER_LITERAL_IS_FUNC)
1576             {
1577               literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC;
1578             }
1579 
1580             literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG;
1581 #else /* !ENABLED (JERRY_ES2015) */
1582             literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG;
1583 #endif /* ENABLED (JERRY_ES2015) */
1584 
1585             lexer_next_token (context_p);
1586 
1587             if (context_p->token.type != LEXER_RIGHT_BRACE)
1588             {
1589               if (context_p->token.type != LEXER_COMMA)
1590               {
1591                 scanner_raise_error (context_p);
1592               }
1593 
1594               lexer_next_token (context_p);
1595             }
1596           }
1597 
1598           lexer_next_token (context_p);
1599         }
1600         else
1601         {
1602           scanner_raise_error (context_p);
1603         }
1604       }
1605 
1606       if (!lexer_token_is_identifier (context_p, "from", 4))
1607       {
1608         scanner_raise_error (context_p);
1609       }
1610 
1611       lexer_next_token (context_p);
1612 
1613       if (context_p->token.type != LEXER_LITERAL
1614           && context_p->token.lit_location.type != LEXER_STRING_LITERAL)
1615       {
1616         scanner_raise_error (context_p);
1617       }
1618 
1619       return SCAN_NEXT_TOKEN;
1620     }
1621     case LEXER_KEYW_EXPORT:
1622     {
1623       if (stack_top != SCAN_STACK_SCRIPT)
1624       {
1625         scanner_raise_error (context_p);
1626       }
1627 
1628       context_p->global_status_flags |= ECMA_PARSE_MODULE;
1629 
1630       lexer_next_token (context_p);
1631 
1632       if (context_p->token.type == LEXER_KEYW_DEFAULT)
1633       {
1634         lexer_next_token (context_p);
1635 
1636         if (context_p->token.type == LEXER_KEYW_FUNCTION)
1637         {
1638           lexer_next_token (context_p);
1639           if (context_p->token.type == LEXER_LITERAL
1640               && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1641           {
1642             lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p);
1643 
1644 #if ENABLED (JERRY_ES2015)
1645             if (location_p->type & SCANNER_LITERAL_IS_LOCAL
1646                 && !(location_p->type & SCANNER_LITERAL_IS_FUNC))
1647             {
1648               scanner_raise_redeclaration_error (context_p);
1649             }
1650             location_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LET;
1651 #else /* !ENABLED (JERRY_ES2015) */
1652             location_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC;
1653 #endif /* ENABLED (JERRY_ES2015) */
1654 
1655             lexer_next_token (context_p);
1656           }
1657           else
1658           {
1659             lexer_lit_location_t *location_p;
1660             location_p = scanner_add_custom_literal (context_p,
1661                                                      scanner_context_p->active_literal_pool_p,
1662                                                      &lexer_default_literal);
1663 #if ENABLED (JERRY_ES2015)
1664             location_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LET;
1665 #else /* !ENABLED (JERRY_ES2015) */
1666             location_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC;
1667 #endif /* ENABLED (JERRY_ES2015) */
1668           }
1669 
1670           scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION);
1671 
1672           parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_STATEMENT);
1673           scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
1674           return SCAN_KEEP_TOKEN;
1675         }
1676 #if ENABLED (JERRY_ES2015)
1677         if (context_p->token.type == LEXER_KEYW_CLASS)
1678         {
1679           scanner_push_class_declaration (context_p, scanner_context_p, SCAN_STACK_CLASS_STATEMENT);
1680 
1681           if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1682           {
1683             lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p);
1684 
1685             scanner_detect_invalid_let (context_p, literal_p);
1686 
1687             literal_p->type |= SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_NO_REG;
1688             return SCAN_NEXT_TOKEN;
1689           }
1690 
1691           lexer_lit_location_t *literal_p;
1692           literal_p = scanner_add_custom_literal (context_p,
1693                                                   scanner_context_p->active_literal_pool_p,
1694                                                   &lexer_default_literal);
1695           literal_p->type |= SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_NO_REG;
1696           return SCAN_KEEP_TOKEN;
1697         }
1698 #endif /* ENABLED (JERRY_ES2015) */
1699 
1700         /* Assignment expression. */
1701         lexer_lit_location_t *location_p;
1702         location_p = scanner_add_custom_literal (context_p,
1703                                                  scanner_context_p->active_literal_pool_p,
1704                                                  &lexer_default_literal);
1705         location_p->type |= SCANNER_LITERAL_IS_VAR;
1706         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1707 
1708         if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1709         {
1710           return SCAN_KEEP_TOKEN;
1711         }
1712 
1713         location_p = scanner_add_literal (context_p, scanner_context_p);
1714         location_p->type |= SCANNER_LITERAL_IS_VAR;
1715         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1716         return SCAN_NEXT_TOKEN;
1717       }
1718 
1719       scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
1720 
1721       if (context_p->token.type == LEXER_MULTIPLY)
1722       {
1723         lexer_next_token (context_p);
1724         if (!lexer_token_is_identifier (context_p, "from", 4))
1725         {
1726           scanner_raise_error (context_p);
1727         }
1728 
1729         lexer_next_token (context_p);
1730 
1731         if (context_p->token.type != LEXER_LITERAL
1732             && context_p->token.lit_location.type == LEXER_STRING_LITERAL)
1733         {
1734           scanner_raise_error (context_p);
1735         }
1736 
1737         return SCAN_NEXT_TOKEN;
1738       }
1739 
1740       if (context_p->token.type == LEXER_LEFT_BRACE)
1741       {
1742         lexer_next_token (context_p);
1743 
1744         while (context_p->token.type != LEXER_RIGHT_BRACE)
1745         {
1746           if (context_p->token.type != LEXER_LITERAL
1747               || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
1748           {
1749             scanner_raise_error (context_p);
1750           }
1751 
1752           lexer_next_token (context_p);
1753 
1754           if (lexer_token_is_identifier (context_p, "as", 2))
1755           {
1756             lexer_next_token (context_p);
1757 
1758             if (context_p->token.type != LEXER_LITERAL
1759                 && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1760             {
1761               scanner_raise_error (context_p);
1762             }
1763 
1764             lexer_next_token (context_p);
1765           }
1766 
1767           if (context_p->token.type != LEXER_RIGHT_BRACE)
1768           {
1769             if (context_p->token.type != LEXER_COMMA)
1770             {
1771               scanner_raise_error (context_p);
1772             }
1773 
1774             lexer_next_token (context_p);
1775           }
1776         }
1777 
1778         lexer_next_token (context_p);
1779 
1780         if (!lexer_token_is_identifier (context_p, "from", 4))
1781         {
1782           return SCAN_KEEP_TOKEN;
1783         }
1784 
1785         lexer_next_token (context_p);
1786 
1787         if (context_p->token.type != LEXER_LITERAL
1788             && context_p->token.lit_location.type == LEXER_STRING_LITERAL)
1789         {
1790           scanner_raise_error (context_p);
1791         }
1792 
1793         return SCAN_NEXT_TOKEN;
1794       }
1795 
1796       switch (context_p->token.type)
1797       {
1798 #if ENABLED (JERRY_ES2015)
1799         case LEXER_KEYW_CLASS:
1800         case LEXER_KEYW_LET:
1801         case LEXER_KEYW_CONST:
1802 #endif /* ENABLED (JERRY_ES2015) */
1803         case LEXER_KEYW_VAR:
1804         {
1805           scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_IN_EXPORT;
1806           break;
1807         }
1808       }
1809 
1810       scanner_context_p->mode = SCAN_MODE_STATEMENT;
1811       return SCAN_KEEP_TOKEN;
1812     }
1813 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1814     default:
1815     {
1816       break;
1817     }
1818   }
1819 
1820   scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
1821 
1822   if (type == LEXER_LITERAL
1823       && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
1824   {
1825     if (JERRY_UNLIKELY (lexer_check_next_character (context_p, LIT_CHAR_COLON)))
1826     {
1827       lexer_consume_next_character (context_p);
1828       scanner_context_p->mode = SCAN_MODE_STATEMENT;
1829       return SCAN_NEXT_TOKEN;
1830     }
1831 
1832     JERRY_ASSERT (context_p->token.flags & LEXER_NO_SKIP_SPACES);
1833 
1834 #if ENABLED (JERRY_ES2015)
1835     /* The colon needs to be checked first because the parser also checks
1836      * it first, and this check skips the spaces which affects source_p. */
1837     if (JERRY_UNLIKELY (lexer_check_arrow (context_p)))
1838     {
1839       scanner_scan_simple_arrow (context_p, scanner_context_p, context_p->source_p);
1840       return SCAN_KEEP_TOKEN;
1841     }
1842 
1843     if (JERRY_UNLIKELY (lexer_token_is_let (context_p)))
1844     {
1845       lexer_lit_location_t let_literal = context_p->token.lit_location;
1846       const uint8_t *source_p = context_p->source_p;
1847 
1848       lexer_next_token (context_p);
1849 
1850       type = (lexer_token_type_t) context_p->token.type;
1851 
1852       if (type == LEXER_LEFT_SQUARE
1853           || type == LEXER_LEFT_BRACE
1854           || (type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL))
1855       {
1856         scanner_context_p->mode = SCAN_MODE_VAR_STATEMENT;
1857         parser_stack_push_uint8 (context_p, SCAN_STACK_LET);
1858         return SCAN_KEEP_TOKEN;
1859       }
1860 
1861       scanner_info_t *info_p = scanner_insert_info (context_p, source_p, sizeof (scanner_info_t));
1862       info_p->type = SCANNER_TYPE_LET_EXPRESSION;
1863 
1864       lexer_lit_location_t *lit_location_p = scanner_add_custom_literal (context_p,
1865                                                                          scanner_context_p->active_literal_pool_p,
1866                                                                          &let_literal);
1867       lit_location_p->type |= SCANNER_LITERAL_IS_USED;
1868 
1869       if (scanner_context_p->active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
1870       {
1871         lit_location_p->type |= SCANNER_LITERAL_NO_REG;
1872       }
1873 
1874       scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1875       return SCAN_KEEP_TOKEN;
1876     }
1877 
1878     if (JERRY_UNLIKELY (lexer_token_is_async (context_p)))
1879     {
1880       scanner_context_p->async_source_p = context_p->source_p;
1881 
1882       if (scanner_check_async_function (context_p, scanner_context_p))
1883       {
1884         scanner_context_p->mode = SCAN_MODE_STATEMENT;
1885       }
1886       return SCAN_KEEP_TOKEN;
1887     }
1888 #endif /* ENABLED (JERRY_ES2015) */
1889 
1890     scanner_add_reference (context_p, scanner_context_p);
1891 
1892     scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1893     return SCAN_NEXT_TOKEN;
1894   }
1895 
1896   return SCAN_KEEP_TOKEN;
1897 } /* scanner_scan_statement */
1898 
1899 /**
1900  * Scan statement terminator.
1901  *
1902  * @return SCAN_NEXT_TOKEN to read the next token, or SCAN_KEEP_TOKEN to do nothing
1903  */
1904 static scan_return_types_t
scanner_scan_statement_end(parser_context_t * context_p,scanner_context_t * scanner_context_p,lexer_token_type_t type)1905 scanner_scan_statement_end (parser_context_t *context_p, /**< context */
1906                             scanner_context_t *scanner_context_p, /**< scanner context */
1907                             lexer_token_type_t type) /**< current token type */
1908 {
1909   bool terminator_found = false;
1910 
1911   if (type == LEXER_SEMICOLON)
1912   {
1913     lexer_next_token (context_p);
1914     terminator_found = true;
1915   }
1916 
1917   while (true)
1918   {
1919     type = (lexer_token_type_t) context_p->token.type;
1920 
1921     switch (context_p->stack_top_uint8)
1922     {
1923       case SCAN_STACK_SCRIPT:
1924       case SCAN_STACK_SCRIPT_FUNCTION:
1925       {
1926         if (type == LEXER_EOS)
1927         {
1928           return SCAN_NEXT_TOKEN;
1929         }
1930         break;
1931       }
1932       case SCAN_STACK_BLOCK_STATEMENT:
1933 #if ENABLED (JERRY_ES2015)
1934       case SCAN_STACK_CLASS_STATEMENT:
1935 #endif /* ENABLED (JERRY_ES2015) */
1936       case SCAN_STACK_FUNCTION_STATEMENT:
1937       {
1938         if (type != LEXER_RIGHT_BRACE)
1939         {
1940           break;
1941         }
1942 
1943 #if ENABLED (JERRY_ES2015)
1944         if (context_p->stack_top_uint8 != SCAN_STACK_CLASS_STATEMENT)
1945         {
1946           scanner_pop_literal_pool (context_p, scanner_context_p);
1947         }
1948 #else /* !ENABLED (JERRY_ES2015) */
1949         if (context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_STATEMENT)
1950         {
1951           scanner_pop_literal_pool (context_p, scanner_context_p);
1952         }
1953 #endif /* ENABLED (JERRY_ES2015) */
1954 
1955         terminator_found = true;
1956         parser_stack_pop_uint8 (context_p);
1957         lexer_next_token (context_p);
1958         continue;
1959       }
1960       case SCAN_STACK_FUNCTION_EXPRESSION:
1961 #if ENABLED (JERRY_ES2015)
1962       case SCAN_STACK_FUNCTION_ARROW:
1963 #endif /* ENABLED (JERRY_ES2015) */
1964       {
1965         if (type != LEXER_RIGHT_BRACE)
1966         {
1967           break;
1968         }
1969 
1970         scanner_context_p->mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
1971 #if ENABLED (JERRY_ES2015)
1972         if (context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_ARROW)
1973         {
1974           scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
1975         }
1976 #endif /* ENABLED (JERRY_ES2015) */
1977 
1978         scanner_pop_literal_pool (context_p, scanner_context_p);
1979         parser_stack_pop_uint8 (context_p);
1980         return SCAN_NEXT_TOKEN;
1981       }
1982       case SCAN_STACK_FUNCTION_PROPERTY:
1983       {
1984         if (type != LEXER_RIGHT_BRACE)
1985         {
1986           break;
1987         }
1988 
1989         scanner_pop_literal_pool (context_p, scanner_context_p);
1990         parser_stack_pop_uint8 (context_p);
1991 
1992 #if ENABLED (JERRY_ES2015)
1993         if (context_p->stack_top_uint8 == SCAN_STACK_EXPLICIT_CLASS_CONSTRUCTOR
1994             || context_p->stack_top_uint8 == SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR)
1995         {
1996           scanner_context_p->mode = SCAN_MODE_CLASS_METHOD;
1997           return SCAN_KEEP_TOKEN;
1998         }
1999 #endif /* ENABLED (JERRY_ES2015) */
2000 
2001         JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL);
2002 
2003         lexer_next_token (context_p);
2004 
2005         if (context_p->token.type == LEXER_RIGHT_BRACE)
2006         {
2007           scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
2008           return SCAN_KEEP_TOKEN;
2009         }
2010 
2011         if (context_p->token.type != LEXER_COMMA)
2012         {
2013           scanner_raise_error (context_p);
2014         }
2015 
2016         scanner_context_p->mode = SCAN_MODE_PROPERTY_NAME;
2017         return SCAN_KEEP_TOKEN;
2018       }
2019       case SCAN_STACK_SWITCH_BLOCK:
2020       {
2021         if (type != LEXER_RIGHT_BRACE)
2022         {
2023           break;
2024         }
2025 
2026         scanner_switch_statement_t switch_statement;
2027 
2028         parser_stack_pop_uint8 (context_p);
2029         parser_stack_pop (context_p, &switch_statement, sizeof (scanner_switch_statement_t));
2030 
2031         scanner_context_p->active_switch_statement = switch_statement;
2032 
2033 #if ENABLED (JERRY_ES2015)
2034         scanner_pop_literal_pool (context_p, scanner_context_p);
2035 #endif /* ENABLED (JERRY_ES2015) */
2036 
2037         terminator_found = true;
2038         lexer_next_token (context_p);
2039         continue;
2040       }
2041       case SCAN_STACK_IF_STATEMENT:
2042       {
2043         parser_stack_pop_uint8 (context_p);
2044 
2045         if (type == LEXER_KEYW_ELSE
2046             && (terminator_found || (context_p->token.flags & LEXER_WAS_NEWLINE)))
2047         {
2048 #if ENABLED (JERRY_ES2015)
2049           scanner_check_function_after_if (context_p, scanner_context_p);
2050           return SCAN_KEEP_TOKEN;
2051 #else /* !ENABLED (JERRY_ES2015) */
2052           scanner_context_p->mode = SCAN_MODE_STATEMENT;
2053           return SCAN_NEXT_TOKEN;
2054 #endif /* ENABLED (JERRY_ES2015) */
2055         }
2056         continue;
2057       }
2058       case SCAN_STACK_WITH_STATEMENT:
2059       {
2060         scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
2061 
2062         JERRY_ASSERT (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH);
2063 
2064         parser_stack_pop_uint8 (context_p);
2065 
2066         if (context_p->stack_top_uint8 == 0)
2067         {
2068           literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_WITH;
2069         }
2070 
2071         parser_stack_pop_uint8 (context_p);
2072         continue;
2073       }
2074       case SCAN_STACK_DO_STATEMENT:
2075       {
2076         parser_stack_pop_uint8 (context_p);
2077 
2078         if (type != LEXER_KEYW_WHILE
2079             || (!terminator_found && !(context_p->token.flags & LEXER_WAS_NEWLINE)))
2080         {
2081           scanner_raise_error (context_p);
2082         }
2083 
2084         lexer_next_token (context_p);
2085         if (context_p->token.type != LEXER_LEFT_PAREN)
2086         {
2087           scanner_raise_error (context_p);
2088         }
2089 
2090         parser_stack_push_uint8 (context_p, SCAN_STACK_DO_EXPRESSION);
2091         scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
2092         return SCAN_NEXT_TOKEN;
2093       }
2094       case SCAN_STACK_DO_EXPRESSION:
2095       {
2096         parser_stack_pop_uint8 (context_p);
2097         terminator_found = true;
2098         continue;
2099       }
2100 #if ENABLED (JERRY_ES2015)
2101       case SCAN_STACK_PRIVATE_BLOCK_EARLY:
2102       {
2103         parser_list_iterator_t literal_iterator;
2104         lexer_lit_location_t *literal_p;
2105 
2106         parser_list_iterator_init (&scanner_context_p->active_literal_pool_p->literal_pool, &literal_iterator);
2107 
2108         while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
2109         {
2110           if ((literal_p->type & (SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_IS_CONST))
2111               && (literal_p->type & SCANNER_LITERAL_IS_USED))
2112           {
2113             literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
2114           }
2115         }
2116         /* FALLTHRU */
2117       }
2118       case SCAN_STACK_PRIVATE_BLOCK:
2119       {
2120         parser_stack_pop_uint8 (context_p);
2121         scanner_pop_literal_pool (context_p, scanner_context_p);
2122         continue;
2123       }
2124 #endif /* ENABLED (JERRY_ES2015) */
2125       default:
2126       {
2127         JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_TRY_STATEMENT
2128                       || context_p->stack_top_uint8 == SCAN_STACK_CATCH_STATEMENT);
2129 
2130         if (type != LEXER_RIGHT_BRACE)
2131         {
2132           break;
2133         }
2134 
2135         uint8_t stack_top = context_p->stack_top_uint8;
2136         parser_stack_pop_uint8 (context_p);
2137         lexer_next_token (context_p);
2138 
2139 #if ENABLED (JERRY_ES2015)
2140         scanner_pop_literal_pool (context_p, scanner_context_p);
2141 #else /* !ENABLED (JERRY_ES2015) */
2142         if (stack_top == SCAN_STACK_CATCH_STATEMENT)
2143         {
2144           scanner_pop_literal_pool (context_p, scanner_context_p);
2145         }
2146 #endif /* ENABLED (JERRY_ES2015) */
2147 
2148         /* A finally statement is optional after a try or catch statement. */
2149         if (context_p->token.type == LEXER_KEYW_FINALLY)
2150         {
2151           lexer_next_token (context_p);
2152 
2153           if (context_p->token.type != LEXER_LEFT_BRACE)
2154           {
2155             scanner_raise_error (context_p);
2156           }
2157 
2158 #if ENABLED (JERRY_ES2015)
2159           scanner_literal_pool_t *literal_pool_p;
2160           literal_pool_p = scanner_push_literal_pool (context_p,
2161                                                       scanner_context_p,
2162                                                       SCANNER_LITERAL_POOL_BLOCK);
2163           literal_pool_p->source_p = context_p->source_p;
2164 #endif /* ENABLED (JERRY_ES2015) */
2165 
2166           parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_STATEMENT);
2167           scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
2168           return SCAN_NEXT_TOKEN;
2169         }
2170 
2171         if (stack_top == SCAN_STACK_CATCH_STATEMENT)
2172         {
2173           terminator_found = true;
2174           continue;
2175         }
2176 
2177         /* A catch statement must be present after a try statement unless a finally is provided. */
2178         if (context_p->token.type != LEXER_KEYW_CATCH)
2179         {
2180           scanner_raise_error (context_p);
2181         }
2182 
2183         lexer_next_token (context_p);
2184 
2185         if (context_p->token.type != LEXER_LEFT_PAREN)
2186         {
2187           scanner_raise_error (context_p);
2188         }
2189 
2190         scanner_literal_pool_t *literal_pool_p;
2191         literal_pool_p = scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_BLOCK);
2192         literal_pool_p->source_p = context_p->source_p;
2193 
2194         lexer_next_token (context_p);
2195         parser_stack_push_uint8 (context_p, SCAN_STACK_CATCH_STATEMENT);
2196 
2197 #if ENABLED (JERRY_ES2015)
2198         if (context_p->token.type == LEXER_LEFT_SQUARE || context_p->token.type == LEXER_LEFT_BRACE)
2199         {
2200           scanner_push_destructuring_pattern (context_p, scanner_context_p, SCANNER_BINDING_CATCH, false);
2201 
2202           if (context_p->token.type == LEXER_LEFT_SQUARE)
2203           {
2204             parser_stack_push_uint8 (context_p, SCAN_STACK_ARRAY_LITERAL);
2205             scanner_context_p->mode = SCAN_MODE_BINDING;
2206             return SCAN_NEXT_TOKEN;
2207           }
2208 
2209           parser_stack_push_uint8 (context_p, SCAN_STACK_OBJECT_LITERAL);
2210           scanner_context_p->mode = SCAN_MODE_PROPERTY_NAME;
2211           return SCAN_KEEP_TOKEN;
2212         }
2213 #endif /* ENABLED (JERRY_ES2015) */
2214 
2215         if (context_p->token.type != LEXER_LITERAL
2216             || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
2217         {
2218           scanner_raise_error (context_p);
2219         }
2220 
2221         lexer_lit_location_t *lit_location_p = scanner_add_literal (context_p, scanner_context_p);
2222         lit_location_p->type |= SCANNER_LITERAL_IS_LOCAL;
2223 
2224         lexer_next_token (context_p);
2225 
2226         if (context_p->token.type != LEXER_RIGHT_PAREN)
2227         {
2228           scanner_raise_error (context_p);
2229         }
2230 
2231         lexer_next_token (context_p);
2232 
2233         if (context_p->token.type != LEXER_LEFT_BRACE)
2234         {
2235           scanner_raise_error (context_p);
2236         }
2237 
2238         scanner_context_p->mode = SCAN_MODE_STATEMENT_OR_TERMINATOR;
2239         return SCAN_NEXT_TOKEN;
2240       }
2241     }
2242 
2243     if (!terminator_found && !(context_p->token.flags & LEXER_WAS_NEWLINE))
2244     {
2245       scanner_raise_error (context_p);
2246     }
2247 
2248     scanner_context_p->mode = SCAN_MODE_STATEMENT;
2249     return SCAN_KEEP_TOKEN;
2250   }
2251 } /* scanner_scan_statement_end */
2252 
2253 #if defined(JERRY_FOR_IAR_CONFIG)
2254 // IAR 8.20.2 generates incorrect code for this function.
2255 // When the function is compiled with 'High:Balanced' optimization level.
2256 // In the line context_p->source_end_p = source_end_p
2257 // IAR assumes that source_end_p is in R5 register, but
2258 // the compiled doesn't initialize it since the function start.
2259 // The workaround is to compile this function without optimizations.
2260 #pragma optimize=none
2261 #endif
2262 /**
2263  * Scan the whole source code.
2264  */
2265 void JERRY_ATTR_NOINLINE
scanner_scan_all(parser_context_t * context_p,const uint8_t * arg_list_p,const uint8_t * arg_list_end_p,const uint8_t * source_p,const uint8_t * source_end_p)2266 scanner_scan_all (parser_context_t *context_p, /**< context */
2267                   const uint8_t *arg_list_p, /**< function argument list */
2268                   const uint8_t *arg_list_end_p, /**< end of argument list */
2269                   const uint8_t *source_p, /**< valid UTF-8 source code */
2270                   const uint8_t *source_end_p) /**< end of source code */
2271 {
2272   scanner_context_t scanner_context;
2273 
2274 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2275   if (context_p->is_show_opcodes)
2276   {
2277     JERRY_DEBUG_MSG ("\n--- Scanning start ---\n\n");
2278   }
2279 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2280 
2281   scanner_context.context_status_flags = context_p->status_flags;
2282   scanner_context.status_flags = SCANNER_CONTEXT_NO_FLAGS;
2283 #if ENABLED (JERRY_DEBUGGER)
2284   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
2285   {
2286     scanner_context.status_flags |= SCANNER_CONTEXT_DEBUGGER_ENABLED;
2287   }
2288 #endif /* ENABLED (JERRY_DEBUGGER) */
2289 #if ENABLED (JERRY_ES2015)
2290   scanner_context.binding_type = SCANNER_BINDING_NONE;
2291   scanner_context.active_binding_list_p = NULL;
2292 #endif /* ENABLED (JERRY_ES2015) */
2293   scanner_context.active_literal_pool_p = NULL;
2294   scanner_context.active_switch_statement.last_case_p = NULL;
2295   scanner_context.end_arguments_p = NULL;
2296 #if ENABLED (JERRY_ES2015)
2297   scanner_context.async_source_p = NULL;
2298 #endif /* ENABLED (JERRY_ES2015) */
2299 
2300   /* This assignment must be here because of Apple compilers. */
2301   context_p->u.scanner_context_p = &scanner_context;
2302 
2303   parser_stack_init (context_p);
2304 
2305   PARSER_TRY (context_p->try_buffer)
2306   {
2307     context_p->line = 1;
2308     context_p->column = 1;
2309 
2310     if (arg_list_p == NULL)
2311     {
2312       context_p->source_p = source_p;
2313       context_p->source_end_p = source_end_p;
2314 
2315       uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS | SCANNER_LITERAL_POOL_CAN_EVAL;
2316 
2317       if (context_p->status_flags & PARSER_IS_STRICT)
2318       {
2319         status_flags |= SCANNER_LITERAL_POOL_IS_STRICT;
2320       }
2321 
2322       scanner_literal_pool_t *literal_pool_p = scanner_push_literal_pool (context_p, &scanner_context, status_flags);
2323       literal_pool_p->source_p = source_p;
2324 
2325       parser_stack_push_uint8 (context_p, SCAN_STACK_SCRIPT);
2326 
2327       lexer_next_token (context_p);
2328       scanner_check_directives (context_p, &scanner_context);
2329     }
2330     else
2331     {
2332       context_p->source_p = arg_list_p;
2333       context_p->source_end_p = arg_list_end_p;
2334 
2335       uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
2336 
2337       if (context_p->status_flags & PARSER_IS_STRICT)
2338       {
2339         status_flags |= SCANNER_LITERAL_POOL_IS_STRICT;
2340       }
2341 
2342 #if ENABLED (JERRY_ES2015)
2343       if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
2344       {
2345         status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
2346       }
2347 #endif /* ENABLED (JERRY_ES2015) */
2348 
2349       scanner_push_literal_pool (context_p, &scanner_context, status_flags);
2350       scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
2351       parser_stack_push_uint8 (context_p, SCAN_STACK_SCRIPT_FUNCTION);
2352 
2353       /* Faking the first token. */
2354       context_p->token.type = LEXER_LEFT_PAREN;
2355     }
2356 
2357     while (true)
2358     {
2359       lexer_token_type_t type = (lexer_token_type_t) context_p->token.type;
2360       scan_stack_modes_t stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
2361 
2362       switch (scanner_context.mode)
2363       {
2364         case SCAN_MODE_PRIMARY_EXPRESSION:
2365         {
2366           if (type == LEXER_ADD
2367               || type == LEXER_SUBTRACT
2368               || LEXER_IS_UNARY_OP_TOKEN (type))
2369           {
2370             break;
2371           }
2372           /* FALLTHRU */
2373         }
2374         case SCAN_MODE_PRIMARY_EXPRESSION_AFTER_NEW:
2375         {
2376           if (scanner_scan_primary_expression (context_p, &scanner_context, type, stack_top) != SCAN_NEXT_TOKEN)
2377           {
2378             continue;
2379           }
2380           break;
2381         }
2382 #if ENABLED (JERRY_ES2015)
2383         case SCAN_MODE_CLASS_DECLARATION:
2384         {
2385           if (context_p->token.type == LEXER_KEYW_EXTENDS)
2386           {
2387             parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS_EXTENDS);
2388             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2389             break;
2390           }
2391           else if (context_p->token.type != LEXER_LEFT_BRACE)
2392           {
2393             scanner_raise_error (context_p);
2394           }
2395 
2396           scanner_context.mode = SCAN_MODE_CLASS_METHOD;
2397           /* FALLTHRU */
2398         }
2399         case SCAN_MODE_CLASS_METHOD:
2400         {
2401           JERRY_ASSERT (stack_top == SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR
2402                         || stack_top == SCAN_STACK_EXPLICIT_CLASS_CONSTRUCTOR);
2403 
2404           lexer_skip_empty_statements (context_p);
2405 
2406           lexer_scan_identifier (context_p);
2407 
2408           if (context_p->token.type == LEXER_RIGHT_BRACE)
2409           {
2410             scanner_source_start_t source_start;
2411 
2412             parser_stack_pop_uint8 (context_p);
2413 
2414             if (stack_top == SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR)
2415             {
2416               parser_stack_pop (context_p, &source_start, sizeof (scanner_source_start_t));
2417             }
2418 
2419             stack_top = context_p->stack_top_uint8;
2420 
2421             JERRY_ASSERT (stack_top == SCAN_STACK_CLASS_STATEMENT || stack_top == SCAN_STACK_CLASS_EXPRESSION);
2422 
2423             if (stack_top == SCAN_STACK_CLASS_STATEMENT)
2424             {
2425               /* The token is kept to disallow consuming a semicolon after it. */
2426               scanner_context.mode = SCAN_MODE_STATEMENT_END;
2427               continue;
2428             }
2429 
2430             scanner_context.mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
2431             parser_stack_pop_uint8 (context_p);
2432             break;
2433           }
2434 
2435           if (context_p->token.type == LEXER_LITERAL
2436               && LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)
2437               && lexer_compare_literal_to_string (context_p, "constructor", 11))
2438           {
2439             if (stack_top == SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR)
2440             {
2441               scanner_source_start_t source_start;
2442               parser_stack_pop_uint8 (context_p);
2443               parser_stack_pop (context_p, &source_start, sizeof (scanner_source_start_t));
2444 
2445               scanner_info_t *info_p = scanner_insert_info (context_p, source_start.source_p, sizeof (scanner_info_t));
2446               info_p->type = SCANNER_TYPE_CLASS_CONSTRUCTOR;
2447               parser_stack_push_uint8 (context_p, SCAN_STACK_EXPLICIT_CLASS_CONSTRUCTOR);
2448             }
2449           }
2450 
2451           if (lexer_token_is_identifier (context_p, "static", 6))
2452           {
2453             lexer_scan_identifier (context_p);
2454           }
2455 
2456           parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PROPERTY);
2457           scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
2458 
2459           uint16_t literal_pool_flags = SCANNER_LITERAL_POOL_FUNCTION;
2460 
2461           if (lexer_token_is_identifier (context_p, "get", 3)
2462               || lexer_token_is_identifier (context_p, "set", 3))
2463           {
2464             lexer_scan_identifier (context_p);
2465 
2466             if (context_p->token.type == LEXER_LEFT_PAREN)
2467             {
2468               scanner_push_literal_pool (context_p, &scanner_context, SCANNER_LITERAL_POOL_FUNCTION);
2469               continue;
2470             }
2471           }
2472           else if (lexer_token_is_identifier (context_p, "async", 5))
2473           {
2474             lexer_scan_identifier (context_p);
2475 
2476             if (context_p->token.type == LEXER_LEFT_PAREN)
2477             {
2478               scanner_push_literal_pool (context_p, &scanner_context, SCANNER_LITERAL_POOL_FUNCTION);
2479               continue;
2480             }
2481 
2482             literal_pool_flags |= SCANNER_LITERAL_POOL_ASYNC;
2483 
2484             if (context_p->token.type == LEXER_MULTIPLY)
2485             {
2486               lexer_scan_identifier (context_p);
2487               literal_pool_flags |= SCANNER_LITERAL_POOL_GENERATOR;
2488             }
2489           }
2490           else if (context_p->token.type == LEXER_MULTIPLY)
2491           {
2492             lexer_scan_identifier (context_p);
2493             literal_pool_flags |= SCANNER_LITERAL_POOL_GENERATOR;
2494           }
2495 
2496           if (context_p->token.type == LEXER_LEFT_SQUARE)
2497           {
2498             parser_stack_push_uint8 (context_p, SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (literal_pool_flags));
2499             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2500             break;
2501           }
2502 
2503           if (context_p->token.type != LEXER_LITERAL)
2504           {
2505             scanner_raise_error (context_p);
2506           }
2507 
2508           if (literal_pool_flags & SCANNER_LITERAL_POOL_GENERATOR)
2509           {
2510             context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
2511           }
2512 
2513           scanner_push_literal_pool (context_p, &scanner_context, literal_pool_flags);
2514           lexer_next_token (context_p);
2515           continue;
2516         }
2517 #endif /* ENABLED (JERRY_ES2015) */
2518         case SCAN_MODE_POST_PRIMARY_EXPRESSION:
2519         {
2520           if (scanner_scan_post_primary_expression (context_p, &scanner_context, type, stack_top))
2521           {
2522             break;
2523           }
2524           type = (lexer_token_type_t) context_p->token.type;
2525           /* FALLTHRU */
2526         }
2527         case SCAN_MODE_PRIMARY_EXPRESSION_END:
2528         {
2529           if (scanner_scan_primary_expression_end (context_p, &scanner_context, type, stack_top) != SCAN_NEXT_TOKEN)
2530           {
2531             continue;
2532           }
2533           break;
2534         }
2535         case SCAN_MODE_STATEMENT_OR_TERMINATOR:
2536         {
2537           if (type == LEXER_RIGHT_BRACE || type == LEXER_EOS)
2538           {
2539             scanner_context.mode = SCAN_MODE_STATEMENT_END;
2540             continue;
2541           }
2542           /* FALLTHRU */
2543         }
2544         case SCAN_MODE_STATEMENT:
2545         {
2546           if (scanner_scan_statement (context_p, &scanner_context, type, stack_top) != SCAN_NEXT_TOKEN)
2547           {
2548             continue;
2549           }
2550           break;
2551         }
2552         case SCAN_MODE_STATEMENT_END:
2553         {
2554           if (scanner_scan_statement_end (context_p, &scanner_context, type) != SCAN_NEXT_TOKEN)
2555           {
2556             continue;
2557           }
2558 
2559           if (context_p->token.type == LEXER_EOS)
2560           {
2561             goto scan_completed;
2562           }
2563 
2564           break;
2565         }
2566         case SCAN_MODE_VAR_STATEMENT:
2567         {
2568 #if ENABLED (JERRY_ES2015)
2569           if (type == LEXER_LEFT_SQUARE || type == LEXER_LEFT_BRACE)
2570           {
2571             uint8_t binding_type = SCANNER_BINDING_VAR;
2572 
2573             if (stack_top == SCAN_STACK_LET || stack_top == SCAN_STACK_FOR_LET_START)
2574             {
2575               binding_type = SCANNER_BINDING_LET;
2576             }
2577             else if (stack_top == SCAN_STACK_CONST || stack_top == SCAN_STACK_FOR_CONST_START)
2578             {
2579               binding_type = SCANNER_BINDING_CONST;
2580             }
2581 
2582             scanner_push_destructuring_pattern (context_p, &scanner_context, binding_type, false);
2583 
2584             if (type == LEXER_LEFT_SQUARE)
2585             {
2586               parser_stack_push_uint8 (context_p, SCAN_STACK_ARRAY_LITERAL);
2587               scanner_context.mode = SCAN_MODE_BINDING;
2588               break;
2589             }
2590 
2591             parser_stack_push_uint8 (context_p, SCAN_STACK_OBJECT_LITERAL);
2592             scanner_context.mode = SCAN_MODE_PROPERTY_NAME;
2593             continue;
2594           }
2595 #endif /* ENABLED (JERRY_ES2015) */
2596 
2597           if (type != LEXER_LITERAL
2598               || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
2599           {
2600             scanner_raise_error (context_p);
2601           }
2602 
2603           lexer_lit_location_t *literal_p = scanner_add_literal (context_p, &scanner_context);
2604 
2605 #if ENABLED (JERRY_ES2015)
2606           if (stack_top != SCAN_STACK_VAR && stack_top != SCAN_STACK_FOR_VAR_START)
2607           {
2608             scanner_detect_invalid_let (context_p, literal_p);
2609 
2610             if (stack_top == SCAN_STACK_LET || stack_top == SCAN_STACK_FOR_LET_START)
2611             {
2612               literal_p->type |= SCANNER_LITERAL_IS_LET;
2613             }
2614             else
2615             {
2616               JERRY_ASSERT (stack_top == SCAN_STACK_CONST || stack_top == SCAN_STACK_FOR_CONST_START);
2617               literal_p->type |= SCANNER_LITERAL_IS_CONST;
2618             }
2619 
2620             lexer_next_token (context_p);
2621 
2622             if (literal_p->type & SCANNER_LITERAL_IS_USED)
2623             {
2624               literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
2625             }
2626             else if (context_p->token.type == LEXER_ASSIGN)
2627             {
2628               scanner_binding_literal_t binding_literal;
2629               binding_literal.literal_p = literal_p;
2630 
2631               parser_stack_push (context_p, &binding_literal, sizeof (scanner_binding_literal_t));
2632               parser_stack_push_uint8 (context_p, SCAN_STACK_BINDING_INIT);
2633             }
2634           }
2635           else
2636           {
2637             if (!(literal_p->type & SCANNER_LITERAL_IS_VAR))
2638             {
2639               scanner_detect_invalid_var (context_p, &scanner_context, literal_p);
2640               literal_p->type |= SCANNER_LITERAL_IS_VAR;
2641 
2642               if (scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
2643               {
2644                 literal_p->type |= SCANNER_LITERAL_NO_REG;
2645               }
2646             }
2647 
2648             lexer_next_token (context_p);
2649           }
2650 #else /* !ENABLED (JERRY_ES2015) */
2651           literal_p->type |= SCANNER_LITERAL_IS_VAR;
2652 
2653           if (scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
2654           {
2655             literal_p->type |= SCANNER_LITERAL_NO_REG;
2656           }
2657 
2658           lexer_next_token (context_p);
2659 #endif /* ENABLED (JERRY_ES2015) */
2660 
2661 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2662           if (scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT)
2663           {
2664             literal_p->type |= SCANNER_LITERAL_NO_REG;
2665           }
2666 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2667 
2668           switch (context_p->token.type)
2669           {
2670             case LEXER_ASSIGN:
2671             {
2672               scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2673               /* FALLTHRU */
2674             }
2675             case LEXER_COMMA:
2676             {
2677               lexer_next_token (context_p);
2678               continue;
2679             }
2680           }
2681 
2682           if (SCANNER_IS_FOR_START (stack_top))
2683           {
2684 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2685             JERRY_ASSERT (!(scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT));
2686 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2687 
2688             if (context_p->token.type != LEXER_SEMICOLON
2689                 && context_p->token.type != LEXER_KEYW_IN
2690                 && !SCANNER_IDENTIFIER_IS_OF ())
2691             {
2692               scanner_raise_error (context_p);
2693             }
2694 
2695             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
2696             continue;
2697           }
2698 
2699 #if ENABLED (JERRY_ES2015)
2700           JERRY_ASSERT (stack_top == SCAN_STACK_VAR || stack_top == SCAN_STACK_LET || stack_top == SCAN_STACK_CONST);
2701 #else /* !ENABLED (JERRY_ES2015) */
2702           JERRY_ASSERT (stack_top == SCAN_STACK_VAR);
2703 #endif /* ENABLED (JERRY_ES2015) */
2704 
2705 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2706           scanner_context.active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT;
2707 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2708 
2709           scanner_context.mode = SCAN_MODE_STATEMENT_END;
2710           parser_stack_pop_uint8 (context_p);
2711           continue;
2712         }
2713         case SCAN_MODE_FUNCTION_ARGUMENTS:
2714         {
2715           JERRY_ASSERT (stack_top == SCAN_STACK_SCRIPT_FUNCTION
2716                         || stack_top == SCAN_STACK_FUNCTION_STATEMENT
2717                         || stack_top == SCAN_STACK_FUNCTION_EXPRESSION
2718                         || stack_top == SCAN_STACK_FUNCTION_PROPERTY);
2719 
2720           scanner_literal_pool_t *literal_pool_p = scanner_context.active_literal_pool_p;
2721 
2722           JERRY_ASSERT (literal_pool_p != NULL && (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_FUNCTION));
2723 
2724           literal_pool_p->source_p = context_p->source_p;
2725 
2726 #if ENABLED (JERRY_ES2015)
2727           if (JERRY_UNLIKELY (scanner_context.async_source_p != NULL))
2728           {
2729             literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ASYNC;
2730             literal_pool_p->source_p = scanner_context.async_source_p;
2731             scanner_context.async_source_p = NULL;
2732           }
2733 #endif /* ENABLED (JERRY_ES2015) */
2734 
2735           if (type != LEXER_LEFT_PAREN)
2736           {
2737             scanner_raise_error (context_p);
2738           }
2739           lexer_next_token (context_p);
2740 
2741 #if ENABLED (JERRY_ES2015)
2742           /* FALLTHRU */
2743         }
2744         case SCAN_MODE_CONTINUE_FUNCTION_ARGUMENTS:
2745         {
2746 #endif /* ENABLED (JERRY_ES2015) */
2747           if (context_p->token.type != LEXER_RIGHT_PAREN && context_p->token.type != LEXER_EOS)
2748           {
2749 #if ENABLED (JERRY_ES2015)
2750             lexer_lit_location_t *argument_literal_p;
2751 #endif /* ENABLED (JERRY_ES2015) */
2752 
2753             while (true)
2754             {
2755 #if ENABLED (JERRY_ES2015)
2756               if (context_p->token.type == LEXER_THREE_DOTS)
2757               {
2758                 scanner_context.active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED;
2759 
2760                 lexer_next_token (context_p);
2761               }
2762 
2763               if (context_p->token.type == LEXER_LEFT_SQUARE || context_p->token.type == LEXER_LEFT_BRACE)
2764               {
2765                 argument_literal_p = NULL;
2766                 break;
2767               }
2768 #endif /* ENABLED (JERRY_ES2015) */
2769 
2770               if (context_p->token.type != LEXER_LITERAL
2771                   || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
2772               {
2773                 scanner_raise_error (context_p);
2774               }
2775 
2776 #if ENABLED (JERRY_ES2015)
2777               argument_literal_p = scanner_append_argument (context_p, &scanner_context);
2778 #else /* !ENABLED (JERRY_ES2015) */
2779               scanner_append_argument (context_p, &scanner_context);
2780 #endif /* ENABLED (JERRY_ES2015) */
2781 
2782               lexer_next_token (context_p);
2783 
2784               if (context_p->token.type != LEXER_COMMA)
2785               {
2786                 break;
2787               }
2788               lexer_next_token (context_p);
2789             }
2790 
2791 #if ENABLED (JERRY_ES2015)
2792             if (argument_literal_p == NULL)
2793             {
2794               scanner_context.active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED;
2795 
2796               parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PARAMETERS);
2797               scanner_append_hole (context_p, &scanner_context);
2798               scanner_push_destructuring_pattern (context_p, &scanner_context, SCANNER_BINDING_ARG, false);
2799 
2800               if (context_p->token.type == LEXER_LEFT_SQUARE)
2801               {
2802                 parser_stack_push_uint8 (context_p, SCAN_STACK_ARRAY_LITERAL);
2803                 scanner_context.mode = SCAN_MODE_BINDING;
2804                 break;
2805               }
2806 
2807               parser_stack_push_uint8 (context_p, SCAN_STACK_OBJECT_LITERAL);
2808               scanner_context.mode = SCAN_MODE_PROPERTY_NAME;
2809               continue;
2810             }
2811 
2812             if (context_p->token.type == LEXER_ASSIGN)
2813             {
2814               scanner_context.active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED;
2815 
2816               parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PARAMETERS);
2817               scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2818 
2819               if (argument_literal_p->type & SCANNER_LITERAL_IS_USED)
2820               {
2821                 JERRY_ASSERT (argument_literal_p->type & SCANNER_LITERAL_EARLY_CREATE);
2822                 break;
2823               }
2824 
2825               scanner_binding_literal_t binding_literal;
2826               binding_literal.literal_p = argument_literal_p;
2827 
2828               parser_stack_push (context_p, &binding_literal, sizeof (scanner_binding_literal_t));
2829               parser_stack_push_uint8 (context_p, SCAN_STACK_BINDING_INIT);
2830               break;
2831             }
2832 #endif /* ENABLED (JERRY_ES2015) */
2833           }
2834 
2835           if (context_p->token.type == LEXER_EOS && stack_top == SCAN_STACK_SCRIPT_FUNCTION)
2836           {
2837             /* End of argument parsing. */
2838             scanner_info_t *scanner_info_p = (scanner_info_t *) scanner_malloc (context_p, sizeof (scanner_info_t));
2839             scanner_info_p->next_p = context_p->next_scanner_info_p;
2840             scanner_info_p->source_p = NULL;
2841             scanner_info_p->type = SCANNER_TYPE_END_ARGUMENTS;
2842             scanner_context.end_arguments_p = scanner_info_p;
2843 
2844             context_p->next_scanner_info_p = scanner_info_p;
2845             context_p->source_p = source_p;
2846             context_p->source_end_p = source_end_p;
2847             context_p->line = 1;
2848             context_p->column = 1;
2849 
2850             scanner_filter_arguments (context_p, &scanner_context);
2851             lexer_next_token (context_p);
2852             scanner_check_directives (context_p, &scanner_context);
2853             continue;
2854           }
2855 
2856           if (context_p->token.type != LEXER_RIGHT_PAREN)
2857           {
2858             scanner_raise_error (context_p);
2859           }
2860 
2861           lexer_next_token (context_p);
2862 
2863           if (context_p->token.type != LEXER_LEFT_BRACE)
2864           {
2865             scanner_raise_error (context_p);
2866           }
2867 
2868           scanner_filter_arguments (context_p, &scanner_context);
2869           lexer_next_token (context_p);
2870           scanner_check_directives (context_p, &scanner_context);
2871           continue;
2872         }
2873         case SCAN_MODE_PROPERTY_NAME:
2874         {
2875           JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
2876 
2877           if (lexer_scan_identifier (context_p))
2878           {
2879             lexer_check_property_modifier (context_p);
2880           }
2881 
2882 #if ENABLED (JERRY_ES2015)
2883           if (context_p->token.type == LEXER_LEFT_SQUARE)
2884           {
2885             parser_stack_push_uint8 (context_p, SCAN_STACK_COMPUTED_PROPERTY);
2886             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2887             break;
2888           }
2889 #endif /* ENABLED (JERRY_ES2015) */
2890 
2891           if (context_p->token.type == LEXER_RIGHT_BRACE)
2892           {
2893             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
2894             continue;
2895           }
2896 
2897           if (context_p->token.type == LEXER_PROPERTY_GETTER
2898 #if ENABLED (JERRY_ES2015)
2899               || context_p->token.type == LEXER_KEYW_ASYNC
2900               || context_p->token.type == LEXER_MULTIPLY
2901 #endif /* ENABLED (JERRY_ES2015) */
2902               || context_p->token.type == LEXER_PROPERTY_SETTER)
2903           {
2904             uint16_t literal_pool_flags = SCANNER_LITERAL_POOL_FUNCTION;
2905 
2906 #if ENABLED (JERRY_ES2015)
2907             if (context_p->token.type == LEXER_MULTIPLY)
2908             {
2909               literal_pool_flags |= SCANNER_LITERAL_POOL_GENERATOR;
2910             }
2911             else if (context_p->token.type == LEXER_KEYW_ASYNC)
2912             {
2913               literal_pool_flags |= SCANNER_LITERAL_POOL_ASYNC;
2914 
2915               if (lexer_consume_generator (context_p))
2916               {
2917                 literal_pool_flags |= SCANNER_LITERAL_POOL_GENERATOR;
2918               }
2919             }
2920 #endif /* ENABLED (JERRY_ES2015) */
2921 
2922             parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PROPERTY);
2923             lexer_scan_identifier (context_p);
2924 
2925 #if ENABLED (JERRY_ES2015)
2926             if (context_p->token.type == LEXER_LEFT_SQUARE)
2927             {
2928               parser_stack_push_uint8 (context_p, SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (literal_pool_flags));
2929               scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2930               break;
2931             }
2932 #endif /* ENABLED (JERRY_ES2015) */
2933 
2934             if (context_p->token.type != LEXER_LITERAL)
2935             {
2936               scanner_raise_error (context_p);
2937             }
2938 
2939             scanner_push_literal_pool (context_p, &scanner_context, literal_pool_flags);
2940             scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
2941             break;
2942           }
2943 
2944           if (context_p->token.type != LEXER_LITERAL)
2945           {
2946             scanner_raise_error (context_p);
2947           }
2948 
2949 #if ENABLED (JERRY_ES2015)
2950           parser_line_counter_t start_line = context_p->token.line;
2951           parser_line_counter_t start_column = context_p->token.column;
2952           bool is_ident = (context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
2953 #endif /* ENABLED (JERRY_ES2015) */
2954 
2955           lexer_next_token (context_p);
2956 
2957 #if ENABLED (JERRY_ES2015)
2958           if (context_p->token.type == LEXER_LEFT_PAREN)
2959           {
2960             scanner_push_literal_pool (context_p, &scanner_context, SCANNER_LITERAL_POOL_FUNCTION);
2961 
2962             parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PROPERTY);
2963             scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
2964             continue;
2965           }
2966 
2967           if (is_ident
2968               && (context_p->token.type == LEXER_COMMA
2969                   || context_p->token.type == LEXER_RIGHT_BRACE
2970                   || context_p->token.type == LEXER_ASSIGN))
2971           {
2972             context_p->source_p = context_p->token.lit_location.char_p;
2973             context_p->line = start_line;
2974             context_p->column = start_column;
2975 
2976             lexer_next_token (context_p);
2977 
2978             JERRY_ASSERT (context_p->token.type != LEXER_LITERAL
2979                           || context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
2980 
2981             if (context_p->token.type != LEXER_LITERAL)
2982             {
2983               scanner_raise_error (context_p);
2984             }
2985 
2986             if (scanner_context.binding_type != SCANNER_BINDING_NONE)
2987             {
2988               scanner_context.mode = SCAN_MODE_BINDING;
2989               continue;
2990             }
2991 
2992             scanner_add_reference (context_p, &scanner_context);
2993 
2994             lexer_next_token (context_p);
2995 
2996             if (context_p->token.type == LEXER_ASSIGN)
2997             {
2998               scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
2999               break;
3000             }
3001 
3002             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
3003             continue;
3004           }
3005 #endif /* ENABLED (JERRY_ES2015) */
3006 
3007           if (context_p->token.type != LEXER_COLON)
3008           {
3009             scanner_raise_error (context_p);
3010           }
3011 
3012           scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
3013 
3014 #if ENABLED (JERRY_ES2015)
3015           if (scanner_context.binding_type != SCANNER_BINDING_NONE)
3016           {
3017             scanner_context.mode = SCAN_MODE_BINDING;
3018           }
3019 #endif /* ENABLED (JERRY_ES2015) */
3020           break;
3021         }
3022 #if ENABLED (JERRY_ES2015)
3023         case SCAN_MODE_BINDING:
3024         {
3025           JERRY_ASSERT (scanner_context.binding_type == SCANNER_BINDING_VAR
3026                         || scanner_context.binding_type == SCANNER_BINDING_LET
3027                         || scanner_context.binding_type == SCANNER_BINDING_CATCH
3028                         || scanner_context.binding_type == SCANNER_BINDING_CONST
3029                         || scanner_context.binding_type == SCANNER_BINDING_ARG
3030                         || scanner_context.binding_type == SCANNER_BINDING_ARROW_ARG);
3031 
3032           if (type == LEXER_THREE_DOTS)
3033           {
3034             lexer_next_token (context_p);
3035             type = (lexer_token_type_t) context_p->token.type;
3036           }
3037 
3038           if (type == LEXER_LEFT_SQUARE || type == LEXER_LEFT_BRACE)
3039           {
3040             scanner_push_destructuring_pattern (context_p, &scanner_context, scanner_context.binding_type, true);
3041 
3042             if (type == LEXER_LEFT_SQUARE)
3043             {
3044               parser_stack_push_uint8 (context_p, SCAN_STACK_ARRAY_LITERAL);
3045               break;
3046             }
3047 
3048             parser_stack_push_uint8 (context_p, SCAN_STACK_OBJECT_LITERAL);
3049             scanner_context.mode = SCAN_MODE_PROPERTY_NAME;
3050             continue;
3051           }
3052 
3053           if (type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
3054           {
3055             scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
3056             continue;
3057           }
3058 
3059           lexer_lit_location_t *literal_p = scanner_add_literal (context_p, &scanner_context);
3060 
3061           scanner_context.mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
3062 
3063           if (scanner_context.binding_type == SCANNER_BINDING_VAR)
3064           {
3065             if (!(literal_p->type & SCANNER_LITERAL_IS_VAR))
3066             {
3067               scanner_detect_invalid_var (context_p, &scanner_context, literal_p);
3068               literal_p->type |= SCANNER_LITERAL_IS_VAR;
3069 
3070               if (scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
3071               {
3072                 literal_p->type |= SCANNER_LITERAL_NO_REG;
3073               }
3074             }
3075             break;
3076           }
3077 
3078           if (scanner_context.binding_type == SCANNER_BINDING_ARROW_ARG)
3079           {
3080             literal_p->type |= SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG;
3081 
3082             if (literal_p->type & SCANNER_LITERAL_IS_USED)
3083             {
3084               literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
3085               break;
3086             }
3087           }
3088           else
3089           {
3090             scanner_detect_invalid_let (context_p, literal_p);
3091 
3092             if (scanner_context.binding_type <= SCANNER_BINDING_CATCH)
3093             {
3094               JERRY_ASSERT ((scanner_context.binding_type == SCANNER_BINDING_LET)
3095                             || (scanner_context.binding_type == SCANNER_BINDING_CATCH));
3096 
3097               literal_p->type |= SCANNER_LITERAL_IS_LET;
3098             }
3099             else
3100             {
3101               literal_p->type |= SCANNER_LITERAL_IS_CONST;
3102 
3103               if (scanner_context.binding_type == SCANNER_BINDING_ARG)
3104               {
3105                 literal_p->type |= SCANNER_LITERAL_IS_ARG;
3106 
3107                 if (literal_p->type & SCANNER_LITERAL_IS_USED)
3108                 {
3109                   literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
3110                   break;
3111                 }
3112               }
3113             }
3114 
3115             if (literal_p->type & SCANNER_LITERAL_IS_USED)
3116             {
3117               literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
3118               break;
3119             }
3120           }
3121 
3122           scanner_binding_item_t *binding_item_p;
3123           binding_item_p = (scanner_binding_item_t *) scanner_malloc (context_p, sizeof (scanner_binding_item_t));
3124 
3125           binding_item_p->next_p = scanner_context.active_binding_list_p->items_p;
3126           binding_item_p->literal_p = literal_p;
3127 
3128           scanner_context.active_binding_list_p->items_p = binding_item_p;
3129 
3130           lexer_next_token (context_p);
3131           if (context_p->token.type != LEXER_ASSIGN)
3132           {
3133             continue;
3134           }
3135 
3136           scanner_binding_literal_t binding_literal;
3137           binding_literal.literal_p = literal_p;
3138 
3139           parser_stack_push (context_p, &binding_literal, sizeof (scanner_binding_literal_t));
3140           parser_stack_push_uint8 (context_p, SCAN_STACK_BINDING_INIT);
3141 
3142           scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
3143           break;
3144         }
3145 #endif /* ENABLED (JERRY_ES2015) */
3146       }
3147 
3148       lexer_next_token (context_p);
3149     }
3150 
3151 scan_completed:
3152     if (context_p->stack_top_uint8 != SCAN_STACK_SCRIPT
3153         && context_p->stack_top_uint8 != SCAN_STACK_SCRIPT_FUNCTION)
3154     {
3155       scanner_raise_error (context_p);
3156     }
3157 
3158     scanner_pop_literal_pool (context_p, &scanner_context);
3159 
3160 #if ENABLED (JERRY_ES2015)
3161     JERRY_ASSERT (scanner_context.active_binding_list_p == NULL);
3162 #endif /* ENABLED (JERRY_ES2015) */
3163     JERRY_ASSERT (scanner_context.active_literal_pool_p == NULL);
3164 
3165 #ifndef JERRY_NDEBUG
3166     scanner_context.context_status_flags |= PARSER_SCANNING_SUCCESSFUL;
3167 #endif /* !JERRY_NDEBUG */
3168   }
3169   PARSER_CATCH
3170   {
3171 #if ENABLED (JERRY_ES2015)
3172     while (scanner_context.active_binding_list_p != NULL)
3173     {
3174       scanner_pop_binding_list (&scanner_context);
3175     }
3176 #endif /* ENABLED (JERRY_ES2015) */
3177 
3178     if (JERRY_UNLIKELY (context_p->error != PARSER_ERR_OUT_OF_MEMORY))
3179     {
3180       /* Ignore the errors thrown by the lexer. */
3181       context_p->error = PARSER_ERR_NO_ERROR;
3182 
3183       /* The following code may allocate memory, so it is enclosed in a try/catch. */
3184       PARSER_TRY (context_p->try_buffer)
3185       {
3186   #if ENABLED (JERRY_ES2015)
3187         if (scanner_context.status_flags & SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION)
3188         {
3189           JERRY_ASSERT (scanner_context.async_source_p != NULL);
3190 
3191           scanner_info_t *info_p;
3192           info_p = scanner_insert_info (context_p, scanner_context.async_source_p, sizeof (scanner_info_t));
3193           info_p->type = SCANNER_TYPE_ERR_ASYNC_FUNCTION;
3194         }
3195   #endif /* ENABLED (JERRY_ES2015) */
3196 
3197         while (scanner_context.active_literal_pool_p != NULL)
3198         {
3199           scanner_pop_literal_pool (context_p, &scanner_context);
3200         }
3201       }
3202       PARSER_CATCH
3203       {
3204         JERRY_ASSERT (context_p->error == PARSER_ERR_OUT_OF_MEMORY);
3205       }
3206       PARSER_TRY_END
3207     }
3208 
3209     JERRY_ASSERT (context_p->error == PARSER_ERR_NO_ERROR || context_p->error == PARSER_ERR_OUT_OF_MEMORY);
3210 
3211     if (context_p->error == PARSER_ERR_OUT_OF_MEMORY)
3212     {
3213       while (scanner_context.active_literal_pool_p != NULL)
3214       {
3215         scanner_literal_pool_t *literal_pool_p = scanner_context.active_literal_pool_p;
3216 
3217         scanner_context.active_literal_pool_p = literal_pool_p->prev_p;
3218 
3219         parser_list_free (&literal_pool_p->literal_pool);
3220         scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
3221       }
3222 
3223       parser_stack_free (context_p);
3224       return;
3225     }
3226   }
3227   PARSER_TRY_END
3228 
3229   context_p->status_flags = scanner_context.context_status_flags;
3230   scanner_reverse_info_list (context_p);
3231 
3232 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
3233   if (context_p->is_show_opcodes)
3234   {
3235     scanner_info_t *info_p = context_p->next_scanner_info_p;
3236     const uint8_t *source_start_p = (arg_list_p == NULL) ? source_p : arg_list_p;
3237 
3238     while (info_p->type != SCANNER_TYPE_END)
3239     {
3240       const char *name_p = NULL;
3241       bool print_location = false;
3242 
3243       switch (info_p->type)
3244       {
3245         case SCANNER_TYPE_END_ARGUMENTS:
3246         {
3247           JERRY_DEBUG_MSG ("  END_ARGUMENTS\n");
3248           source_start_p = source_p;
3249           break;
3250         }
3251         case SCANNER_TYPE_FUNCTION:
3252         case SCANNER_TYPE_BLOCK:
3253         {
3254           const uint8_t *prev_source_p = info_p->source_p - 1;
3255           const uint8_t *data_p;
3256 
3257           if (info_p->type == SCANNER_TYPE_FUNCTION)
3258           {
3259             data_p = (const uint8_t *) (info_p + 1);
3260 
3261             JERRY_DEBUG_MSG ("  FUNCTION: flags: 0x%x declarations: %d",
3262                              (int) info_p->u8_arg,
3263                              (int) info_p->u16_arg);
3264           }
3265           else
3266           {
3267             data_p = (const uint8_t *) (info_p + 1);
3268 
3269             JERRY_DEBUG_MSG ("  BLOCK:");
3270           }
3271 
3272           JERRY_DEBUG_MSG (" source:%d\n", (int) (info_p->source_p - source_start_p));
3273 
3274           while (data_p[0] != SCANNER_STREAM_TYPE_END)
3275           {
3276             switch (data_p[0] & SCANNER_STREAM_TYPE_MASK)
3277             {
3278               case SCANNER_STREAM_TYPE_VAR:
3279               {
3280                 JERRY_DEBUG_MSG ("    VAR ");
3281                 break;
3282               }
3283 #if ENABLED (JERRY_ES2015)
3284               case SCANNER_STREAM_TYPE_LET:
3285               {
3286                 JERRY_DEBUG_MSG ("    LET ");
3287                 break;
3288               }
3289               case SCANNER_STREAM_TYPE_CONST:
3290               {
3291                 JERRY_DEBUG_MSG ("    CONST ");
3292                 break;
3293               }
3294               case SCANNER_STREAM_TYPE_LOCAL:
3295               {
3296                 JERRY_DEBUG_MSG ("    LOCAL ");
3297                 break;
3298               }
3299 #endif /* ENABLED (JERRY_ES2015) */
3300 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3301               case SCANNER_STREAM_TYPE_IMPORT:
3302               {
3303                 JERRY_DEBUG_MSG ("    IMPORT ");
3304                 break;
3305               }
3306 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3307               case SCANNER_STREAM_TYPE_ARG:
3308               {
3309                 JERRY_DEBUG_MSG ("    ARG ");
3310                 break;
3311               }
3312 #if ENABLED (JERRY_ES2015)
3313               case SCANNER_STREAM_TYPE_ARG_VAR:
3314               {
3315                 JERRY_DEBUG_MSG ("    ARG_VAR ");
3316                 break;
3317               }
3318               case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG:
3319               {
3320                 JERRY_DEBUG_MSG ("    DESTRUCTURED_ARG ");
3321                 break;
3322               }
3323               case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR:
3324               {
3325                 JERRY_DEBUG_MSG ("    DESTRUCTURED_ARG_VAR ");
3326                 break;
3327               }
3328 #endif /* ENABLED (JERRY_ES2015) */
3329               case SCANNER_STREAM_TYPE_ARG_FUNC:
3330               {
3331                 JERRY_DEBUG_MSG ("    ARG_FUNC ");
3332                 break;
3333               }
3334 #if ENABLED (JERRY_ES2015)
3335               case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC:
3336               {
3337                 JERRY_DEBUG_MSG ("    DESTRUCTURED_ARG_FUNC ");
3338                 break;
3339               }
3340 #endif /* ENABLED (JERRY_ES2015) */
3341               case SCANNER_STREAM_TYPE_FUNC:
3342               {
3343                 JERRY_DEBUG_MSG ("    FUNC ");
3344                 break;
3345               }
3346               default:
3347               {
3348                 JERRY_ASSERT ((data_p[0] & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_HOLE);
3349                 JERRY_DEBUG_MSG ("    HOLE\n");
3350                 data_p++;
3351                 continue;
3352               }
3353             }
3354 
3355             size_t length;
3356 
3357             if (!(data_p[0] & SCANNER_STREAM_UINT16_DIFF))
3358             {
3359               if (data_p[2] != 0)
3360               {
3361                 prev_source_p += data_p[2];
3362                 length = 2 + 1;
3363               }
3364               else
3365               {
3366                 memcpy (&prev_source_p, data_p + 2 + 1, sizeof (const uint8_t *));
3367                 length = 2 + 1 + sizeof (const uint8_t *);
3368               }
3369             }
3370             else
3371             {
3372               int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8;
3373 
3374               if (diff <= UINT8_MAX)
3375               {
3376                 diff = -diff;
3377               }
3378 
3379               prev_source_p += diff;
3380               length = 2 + 2;
3381             }
3382 
3383 #if ENABLED (JERRY_ES2015)
3384             if (data_p[0] & SCANNER_STREAM_EARLY_CREATE)
3385             {
3386               JERRY_ASSERT (data_p[0] & SCANNER_STREAM_NO_REG);
3387               JERRY_DEBUG_MSG ("*");
3388             }
3389 #endif /* ENABLED (JERRY_ES2015) */
3390 
3391             if (data_p[0] & SCANNER_STREAM_NO_REG)
3392             {
3393               JERRY_DEBUG_MSG ("* ");
3394             }
3395 
3396             JERRY_DEBUG_MSG ("'%.*s'\n", data_p[1], (char *) prev_source_p);
3397             prev_source_p += data_p[1];
3398             data_p += length;
3399           }
3400           break;
3401         }
3402         case SCANNER_TYPE_WHILE:
3403         {
3404           name_p = "WHILE";
3405           print_location = true;
3406           break;
3407         }
3408         case SCANNER_TYPE_FOR:
3409         {
3410           scanner_for_info_t *for_info_p = (scanner_for_info_t *) info_p;
3411           JERRY_DEBUG_MSG ("  FOR: source:%d expression:%d[%d:%d] end:%d[%d:%d]\n",
3412                            (int) (for_info_p->info.source_p - source_start_p),
3413                            (int) (for_info_p->expression_location.source_p - source_start_p),
3414                            (int) for_info_p->expression_location.line,
3415                            (int) for_info_p->expression_location.column,
3416                            (int) (for_info_p->end_location.source_p - source_start_p),
3417                            (int) for_info_p->end_location.line,
3418                            (int) for_info_p->end_location.column);
3419           break;
3420         }
3421         case SCANNER_TYPE_FOR_IN:
3422         {
3423           name_p = "FOR-IN";
3424           print_location = true;
3425           break;
3426         }
3427 #if ENABLED (JERRY_ES2015)
3428         case SCANNER_TYPE_FOR_OF:
3429         {
3430           name_p = "FOR-OF";
3431           print_location = true;
3432           break;
3433         }
3434 #endif /* ENABLED (JERRY_ES2015) */
3435         case SCANNER_TYPE_SWITCH:
3436         {
3437           JERRY_DEBUG_MSG ("  SWITCH: source:%d\n",
3438                            (int) (info_p->source_p - source_start_p));
3439 
3440           scanner_case_info_t *current_case_p = ((scanner_switch_info_t *) info_p)->case_p;
3441 
3442           while (current_case_p != NULL)
3443           {
3444             JERRY_DEBUG_MSG ("    CASE: location:%d[%d:%d]\n",
3445                              (int) (current_case_p->location.source_p - source_start_p),
3446                              (int) current_case_p->location.line,
3447                              (int) current_case_p->location.column);
3448 
3449             current_case_p = current_case_p->next_p;
3450           }
3451           break;
3452         }
3453         case SCANNER_TYPE_CASE:
3454         {
3455           name_p = "CASE";
3456           print_location = true;
3457           break;
3458         }
3459 #if ENABLED (JERRY_ES2015)
3460         case SCANNER_TYPE_INITIALIZER:
3461         {
3462           name_p = "INITIALIZER";
3463           print_location = true;
3464           break;
3465         }
3466         case SCANNER_TYPE_CLASS_CONSTRUCTOR:
3467         {
3468           JERRY_DEBUG_MSG ("  CLASS-CONSTRUCTOR: source:%d\n",
3469                            (int) (info_p->source_p - source_start_p));
3470           print_location = false;
3471           break;
3472         }
3473         case SCANNER_TYPE_LET_EXPRESSION:
3474         {
3475           JERRY_DEBUG_MSG ("  LET_EXPRESSION: source:%d\n",
3476                            (int) (info_p->source_p - source_start_p));
3477           break;
3478         }
3479         case SCANNER_TYPE_ERR_REDECLARED:
3480         {
3481           JERRY_DEBUG_MSG ("  ERR_REDECLARED: source:%d\n",
3482                            (int) (info_p->source_p - source_start_p));
3483           break;
3484         }
3485         case SCANNER_TYPE_ERR_ASYNC_FUNCTION:
3486         {
3487           JERRY_DEBUG_MSG ("  ERR_ASYNC_FUNCTION: source:%d\n",
3488                            (int) (info_p->source_p - source_start_p));
3489           break;
3490         }
3491 #endif /* ENABLED (JERRY_ES2015) */
3492       }
3493 
3494       if (print_location)
3495       {
3496         scanner_location_info_t *location_info_p = (scanner_location_info_t *) info_p;
3497         JERRY_DEBUG_MSG ("  %s: source:%d location:%d[%d:%d]\n",
3498                          name_p,
3499                          (int) (location_info_p->info.source_p - source_start_p),
3500                          (int) (location_info_p->location.source_p - source_start_p),
3501                          (int) location_info_p->location.line,
3502                          (int) location_info_p->location.column);
3503       }
3504 
3505       info_p = info_p->next_p;
3506     }
3507 
3508     JERRY_DEBUG_MSG ("\n--- Scanning end ---\n\n");
3509   }
3510 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
3511 
3512   parser_stack_free (context_p);
3513 } /* scanner_scan_all */
3514 
3515 /**
3516  * @}
3517  * @}
3518  * @}
3519  */
3520 
3521 #endif /* ENABLED (JERRY_PARSER) */
3522