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 "ecma-helpers.h"
17#include "jcontext.h"
18#include "js-parser-internal.h"
19#include "js-scanner-internal.h"
20#include "lit-char-helpers.h"
21
22#if ENABLED (JERRY_PARSER)
23
24/** \addtogroup parser Parser
25 * @{
26 *
27 * \addtogroup jsparser JavaScript
28 * @{
29 *
30 * \addtogroup jsparser_scanner Scanner
31 * @{
32 */
33
34JERRY_STATIC_ASSERT (PARSER_MAXIMUM_NUMBER_OF_LITERALS + PARSER_MAXIMUM_NUMBER_OF_REGISTERS < PARSER_REGISTER_START,
35                     maximum_number_of_literals_plus_registers_must_be_less_than_register_start);
36
37#if ENABLED (JERRY_ES2015)
38
39JERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG & SCANNER_LITERAL_IS_LOCAL) == 0,
40                     is_arrow_arg_binding_flag_must_not_use_local_flags);
41
42JERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_LET & SCANNER_LITERAL_IS_LOCAL) != 0,
43                     is_let_flag_must_use_local_flags);
44
45JERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_CONST & SCANNER_LITERAL_IS_LOCAL) != 0,
46                     is_const_flag_must_use_local_flags);
47
48JERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_FUNC_DECLARATION & SCANNER_LITERAL_IS_LOCAL) != 0,
49                     is_func_declaration_flag_must_use_local_flags);
50
51JERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_DESTRUCTURED_ARG & SCANNER_LITERAL_IS_LOCAL) != 0,
52                     is_arg_binding_flag_must_use_local_flags);
53
54JERRY_STATIC_ASSERT (SCANNER_LITERAL_IS_FUNC_DECLARATION != SCANNER_LITERAL_IS_DESTRUCTURED_ARG,
55                     is_func_declaration_must_be_different_from_is_arg_binding);
56
57JERRY_STATIC_ASSERT (PARSER_SCOPE_STACK_IS_CONST_REG == PARSER_SCOPE_STACK_IS_LOCAL_CREATED,
58                     scope_stack_is_const_reg_and_scope_stack_is_local_created_must_be_the_same);
59
60#endif /* ENABLED (JERRY_ES2015) */
61
62/**
63 * Raise a scanner error.
64 */
65void
66scanner_raise_error (parser_context_t *context_p) /**< context */
67{
68  PARSER_THROW (context_p->try_buffer);
69  /* Should never been reached. */
70  JERRY_ASSERT (0);
71} /* scanner_raise_error */
72
73#if ENABLED (JERRY_ES2015)
74
75/**
76 * Raise a variable redeclaration error.
77 */
78void
79scanner_raise_redeclaration_error (parser_context_t *context_p) /**< context */
80{
81  scanner_info_t *info_p = scanner_insert_info (context_p, context_p->source_p, sizeof (scanner_info_t));
82  info_p->type = SCANNER_TYPE_ERR_REDECLARED;
83
84  scanner_raise_error (context_p);
85} /* scanner_raise_redeclaration_error */
86
87#endif /* ENABLED (JERRY_ES2015) */
88
89/**
90 * Allocate memory for scanner.
91 *
92 * @return allocated memory
93 */
94void *
95scanner_malloc (parser_context_t *context_p, /**< context */
96                size_t size) /**< size of the memory block */
97{
98  void *result;
99
100  JERRY_ASSERT (size > 0);
101  result = jmem_heap_alloc_block_null_on_error (size);
102
103  if (result == NULL)
104  {
105    scanner_cleanup (context_p);
106
107    /* This is the only error which specify its reason. */
108    context_p->error = PARSER_ERR_OUT_OF_MEMORY;
109    PARSER_THROW (context_p->try_buffer);
110  }
111  return result;
112} /* scanner_malloc */
113
114/**
115 * Free memory allocated by scanner_malloc.
116 */
117inline void JERRY_ATTR_ALWAYS_INLINE
118scanner_free (void *ptr, /**< pointer to free */
119              size_t size) /**< size of the memory block */
120{
121  jmem_heap_free_block (ptr, size);
122} /* scanner_free */
123
124/**
125 * Count the size of a stream after an info block.
126 *
127 * @return the size in bytes
128 */
129size_t
130scanner_get_stream_size (scanner_info_t *info_p, /**< scanner info block */
131                         size_t size) /**< size excluding the stream */
132{
133  const uint8_t *data_p = ((const uint8_t *) info_p) + size;
134  const uint8_t *data_p_start = data_p;
135
136  while (data_p[0] != SCANNER_STREAM_TYPE_END)
137  {
138    switch (data_p[0] & SCANNER_STREAM_TYPE_MASK)
139    {
140      case SCANNER_STREAM_TYPE_VAR:
141#if ENABLED (JERRY_ES2015)
142      case SCANNER_STREAM_TYPE_LET:
143      case SCANNER_STREAM_TYPE_CONST:
144      case SCANNER_STREAM_TYPE_LOCAL:
145#endif /* ENABLED (JERRY_ES2015) */
146#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
147      case SCANNER_STREAM_TYPE_IMPORT:
148#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
149      case SCANNER_STREAM_TYPE_ARG:
150#if ENABLED (JERRY_ES2015)
151      case SCANNER_STREAM_TYPE_ARG_VAR:
152      case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG:
153      case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR:
154#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
155      case SCANNER_STREAM_TYPE_ARG_FUNC:
156#if ENABLED (JERRY_ES2015)
157      case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC:
158#endif /* ENABLED (JERRY_ES2015) */
159      case SCANNER_STREAM_TYPE_FUNC:
160      {
161        break;
162      }
163      default:
164      {
165        JERRY_ASSERT ((data_p[0] & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_HOLE);
166        data_p++;
167        continue;
168      }
169    }
170
171    data_p += 3;
172
173    if (data_p[-3] & SCANNER_STREAM_UINT16_DIFF)
174    {
175      data_p++;
176    }
177    else if (data_p[-1] == 0)
178    {
179      data_p += sizeof (const uint8_t *);
180    }
181  }
182
183  return size + 1 + (size_t) (data_p - data_p_start);
184} /* scanner_get_stream_size */
185
186/**
187 * Insert a scanner info block into the scanner info chain.
188 *
189 * @return newly allocated scanner info
190 */
191scanner_info_t *
192scanner_insert_info (parser_context_t *context_p, /**< context */
193                     const uint8_t *source_p, /**< triggering position */
194                     size_t size) /**< size of the memory block */
195{
196  scanner_info_t *new_scanner_info_p = (scanner_info_t *) scanner_malloc (context_p, size);
197  scanner_info_t *scanner_info_p = context_p->next_scanner_info_p;
198  scanner_info_t *prev_scanner_info_p = NULL;
199
200  JERRY_ASSERT (scanner_info_p != NULL);
201  JERRY_ASSERT (source_p != NULL);
202
203  new_scanner_info_p->source_p = source_p;
204
205  while (source_p < scanner_info_p->source_p)
206  {
207    prev_scanner_info_p = scanner_info_p;
208    scanner_info_p = scanner_info_p->next_p;
209
210    JERRY_ASSERT (scanner_info_p != NULL);
211  }
212
213  /* Multiple scanner info blocks cannot be assigned to the same position. */
214  JERRY_ASSERT (source_p != scanner_info_p->source_p);
215
216  new_scanner_info_p->next_p = scanner_info_p;
217
218  if (JERRY_LIKELY (prev_scanner_info_p == NULL))
219  {
220    context_p->next_scanner_info_p = new_scanner_info_p;
221  }
222  else
223  {
224    prev_scanner_info_p->next_p = new_scanner_info_p;
225  }
226
227  return new_scanner_info_p;
228} /* scanner_insert_info */
229
230/**
231 * Insert a scanner info block into the scanner info chain before a given info block.
232 *
233 * @return newly allocated scanner info
234 */
235scanner_info_t *
236scanner_insert_info_before (parser_context_t *context_p, /**< context */
237                            const uint8_t *source_p, /**< triggering position */
238                            scanner_info_t *start_info_p, /**< first info position */
239                            size_t size) /**< size of the memory block */
240{
241  JERRY_ASSERT (start_info_p != NULL);
242
243  scanner_info_t *new_scanner_info_p = (scanner_info_t *) scanner_malloc (context_p, size);
244  scanner_info_t *scanner_info_p = start_info_p->next_p;
245  scanner_info_t *prev_scanner_info_p = start_info_p;
246
247  new_scanner_info_p->source_p = source_p;
248
249  while (source_p < scanner_info_p->source_p)
250  {
251    prev_scanner_info_p = scanner_info_p;
252    scanner_info_p = scanner_info_p->next_p;
253
254    JERRY_ASSERT (scanner_info_p != NULL);
255  }
256
257  /* Multiple scanner info blocks cannot be assigned to the same position. */
258  JERRY_ASSERT (source_p != scanner_info_p->source_p);
259
260  new_scanner_info_p->next_p = scanner_info_p;
261
262  prev_scanner_info_p->next_p = new_scanner_info_p;
263  return new_scanner_info_p;
264} /* scanner_insert_info_before */
265
266/**
267 * Release the next scanner info.
268 */
269inline void JERRY_ATTR_ALWAYS_INLINE
270scanner_release_next (parser_context_t *context_p, /**< context */
271                      size_t size) /**< size of the memory block */
272{
273  scanner_info_t *next_p = context_p->next_scanner_info_p->next_p;
274
275  jmem_heap_free_block (context_p->next_scanner_info_p, size);
276  context_p->next_scanner_info_p = next_p;
277} /* scanner_release_next */
278
279/**
280 * Set the active scanner info to the next scanner info.
281 */
282inline void JERRY_ATTR_ALWAYS_INLINE
283scanner_set_active (parser_context_t *context_p) /**< context */
284{
285  scanner_info_t *scanner_info_p = context_p->next_scanner_info_p;
286
287  context_p->next_scanner_info_p = scanner_info_p->next_p;
288  scanner_info_p->next_p = context_p->active_scanner_info_p;
289  context_p->active_scanner_info_p = scanner_info_p;
290} /* scanner_set_active */
291
292/**
293 * Set the next scanner info to the active scanner info.
294 */
295inline void JERRY_ATTR_ALWAYS_INLINE
296scanner_revert_active (parser_context_t *context_p) /**< context */
297{
298  scanner_info_t *scanner_info_p = context_p->active_scanner_info_p;
299
300  context_p->active_scanner_info_p = scanner_info_p->next_p;
301  scanner_info_p->next_p = context_p->next_scanner_info_p;
302  context_p->next_scanner_info_p = scanner_info_p;
303} /* scanner_revert_active */
304
305/**
306 * Release the active scanner info.
307 */
308inline void JERRY_ATTR_ALWAYS_INLINE
309scanner_release_active (parser_context_t *context_p, /**< context */
310                        size_t size) /**< size of the memory block */
311{
312  scanner_info_t *next_p = context_p->active_scanner_info_p->next_p;
313
314  jmem_heap_free_block (context_p->active_scanner_info_p, size);
315  context_p->active_scanner_info_p = next_p;
316} /* scanner_release_active */
317
318/**
319 * Release switch cases.
320 */
321void
322scanner_release_switch_cases (scanner_case_info_t *case_p) /**< case list */
323{
324  while (case_p != NULL)
325  {
326    scanner_case_info_t *next_p = case_p->next_p;
327
328    jmem_heap_free_block (case_p, sizeof (scanner_case_info_t));
329    case_p = next_p;
330  }
331} /* scanner_release_switch_cases */
332
333/**
334 * Seek to correct position in the scanner info list.
335 */
336void
337scanner_seek (parser_context_t *context_p) /**< context */
338{
339  const uint8_t *source_p = context_p->source_p;
340  scanner_info_t *prev_p;
341
342  if (context_p->skipped_scanner_info_p != NULL)
343  {
344    JERRY_ASSERT (context_p->skipped_scanner_info_p->source_p != NULL);
345
346    context_p->skipped_scanner_info_end_p->next_p = context_p->next_scanner_info_p;
347
348    if (context_p->skipped_scanner_info_end_p->source_p <= source_p)
349    {
350      prev_p = context_p->skipped_scanner_info_end_p;
351    }
352    else
353    {
354      prev_p = context_p->skipped_scanner_info_p;
355
356      if (prev_p->source_p > source_p)
357      {
358        context_p->next_scanner_info_p = prev_p;
359        context_p->skipped_scanner_info_p = NULL;
360        return;
361      }
362
363      context_p->skipped_scanner_info_p = prev_p;
364    }
365  }
366  else
367  {
368    prev_p = context_p->next_scanner_info_p;
369
370    if (prev_p->source_p == NULL || prev_p->source_p > source_p)
371    {
372      return;
373    }
374
375    context_p->skipped_scanner_info_p = prev_p;
376  }
377
378  while (prev_p->next_p->source_p != NULL && prev_p->next_p->source_p <= source_p)
379  {
380    prev_p = prev_p->next_p;
381  }
382
383  context_p->skipped_scanner_info_end_p = prev_p;
384  context_p->next_scanner_info_p = prev_p->next_p;
385} /* scanner_seek */
386
387/**
388 * Push a new literal pool.
389 *
390 * @return the newly created literal pool
391 */
392scanner_literal_pool_t *
393scanner_push_literal_pool (parser_context_t *context_p, /**< context */
394                           scanner_context_t *scanner_context_p, /**< scanner context */
395                           uint16_t status_flags) /**< combination of scanner_literal_pool_flags_t flags */
396{
397  scanner_literal_pool_t *prev_literal_pool_p = scanner_context_p->active_literal_pool_p;
398  scanner_literal_pool_t *literal_pool_p;
399
400  literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t));
401
402  if (!(status_flags & SCANNER_LITERAL_POOL_FUNCTION))
403  {
404    JERRY_ASSERT (prev_literal_pool_p != NULL);
405    status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
406
407#if ENABLED (JERRY_ES2015)
408    const uint16_t copied_flags = (SCANNER_LITERAL_POOL_IN_WITH
409                                   | SCANNER_LITERAL_POOL_GENERATOR
410                                   | SCANNER_LITERAL_POOL_ASYNC);
411#else /* !ENABLED (JERRY_ES2015) */
412    const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH;
413#endif /* ENABLED (JERRY_ES2015) */
414
415    status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags);
416  }
417#if ENABLED (JERRY_ES2015)
418  else
419  {
420    context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION);
421
422    if (status_flags & SCANNER_LITERAL_POOL_GENERATOR)
423    {
424      context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
425    }
426
427    if (status_flags & SCANNER_LITERAL_POOL_ASYNC)
428    {
429      context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
430    }
431  }
432#endif /* ENABLED (JERRY_ES2015) */
433
434  if (prev_literal_pool_p != NULL)
435  {
436    const uint16_t copied_flags = SCANNER_LITERAL_POOL_IS_STRICT;
437    status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags);
438
439    /* The logical value of these flags must be the same. */
440    JERRY_ASSERT (!(status_flags & SCANNER_LITERAL_POOL_IS_STRICT) == !(context_p->status_flags & PARSER_IS_STRICT));
441  }
442
443  parser_list_init (&literal_pool_p->literal_pool,
444                    sizeof (lexer_lit_location_t),
445                    (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t)));
446  literal_pool_p->source_p = NULL;
447  literal_pool_p->status_flags = status_flags;
448  literal_pool_p->no_declarations = 0;
449
450  literal_pool_p->prev_p = prev_literal_pool_p;
451  scanner_context_p->active_literal_pool_p = literal_pool_p;
452
453  return literal_pool_p;
454} /* scanner_push_literal_pool */
455
456JERRY_STATIC_ASSERT (PARSER_MAXIMUM_IDENT_LENGTH <= UINT8_MAX,
457                     maximum_ident_length_must_fit_in_a_byte);
458
459/**
460 * Checks whether a literal is equal to "arguments".
461 */
462static inline bool JERRY_ATTR_ALWAYS_INLINE
463scanner_literal_is_arguments (lexer_lit_location_t *literal_p) /**< literal */
464{
465  return lexer_compare_identifier_to_string (literal_p, (const uint8_t *) "arguments", 9);
466} /* scanner_literal_is_arguments */
467
468/**
469 * Pop the last literal pool from the end.
470 */
471void
472scanner_pop_literal_pool (parser_context_t *context_p, /**< context */
473                          scanner_context_t *scanner_context_p) /**< scanner context */
474{
475  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
476  scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p;
477
478  if (literal_pool_p->source_p == NULL)
479  {
480    JERRY_ASSERT (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_FUNCTION);
481    JERRY_ASSERT (literal_pool_p->literal_pool.data.first_p == NULL
482                  && literal_pool_p->literal_pool.data.last_p == NULL);
483
484    scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p;
485    scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
486    return;
487  }
488
489  parser_list_iterator_t literal_iterator;
490  lexer_lit_location_t *literal_p;
491  uint16_t status_flags = literal_pool_p->status_flags;
492  bool arguments_required = ((status_flags & (SCANNER_LITERAL_POOL_CAN_EVAL | SCANNER_LITERAL_POOL_NO_ARGUMENTS))
493                             == SCANNER_LITERAL_POOL_CAN_EVAL);
494
495  uint8_t can_eval_types = 0;
496#if ENABLED (JERRY_ES2015)
497  if (prev_literal_pool_p == NULL && !(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL))
498  {
499    can_eval_types |= SCANNER_LITERAL_IS_FUNC;
500  }
501#endif /* ENABLED (JERRY_ES2015) */
502
503  if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && prev_literal_pool_p != NULL)
504  {
505    prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
506  }
507
508#if ENABLED (JERRY_DEBUGGER)
509  if (scanner_context_p->status_flags & SCANNER_CONTEXT_DEBUGGER_ENABLED)
510  {
511    /* When debugger is enabled, identifiers are not stored in registers. However,
512     * this does not affect 'eval' detection, so 'arguments' object is not created. */
513    status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
514  }
515#endif /* ENABLED (JERRY_DEBUGGER) */
516
517  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
518
519  const uint8_t *prev_source_p = literal_pool_p->source_p - 1;
520  size_t compressed_size = 1;
521  uint32_t no_declarations = literal_pool_p->no_declarations;
522
523  while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
524  {
525    uint8_t type = literal_p->type;
526
527    if (JERRY_UNLIKELY (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK))
528    {
529      continue;
530    }
531
532    if (!(status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) && scanner_literal_is_arguments (literal_p))
533    {
534      status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
535
536      if (type & (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LOCAL))
537      {
538        arguments_required = false;
539      }
540      else
541      {
542        literal_p->type = 0;
543        arguments_required = true;
544        continue;
545      }
546    }
547
548#if ENABLED (JERRY_ES2015)
549    if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION)
550        && (type & (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION)) == SCANNER_LITERAL_IS_FUNC)
551    {
552      if (prev_literal_pool_p == NULL
553          && (context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)
554          && scanner_scope_find_let_declaration (context_p, literal_p))
555      {
556        literal_p->type = 0;
557        continue;
558      }
559
560      if (!(type & SCANNER_LITERAL_IS_ARG))
561      {
562        type |= SCANNER_LITERAL_IS_VAR;
563      }
564
565      type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC;
566      literal_p->type = type;
567    }
568#endif /* ENABLED (JERRY_ES2015) */
569
570    if ((type & SCANNER_LITERAL_IS_LOCAL)
571        || ((type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_ARG))
572            && (status_flags & SCANNER_LITERAL_POOL_FUNCTION)))
573    {
574      JERRY_ASSERT ((status_flags & SCANNER_LITERAL_POOL_FUNCTION)
575                    || !(literal_p->type & SCANNER_LITERAL_IS_ARG));
576
577      if (literal_p->length == 0)
578      {
579        compressed_size += 1;
580        continue;
581      }
582
583      no_declarations++;
584
585      if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) || (type & can_eval_types))
586      {
587        type |= SCANNER_LITERAL_NO_REG;
588        literal_p->type = type;
589      }
590
591      if (type & SCANNER_LITERAL_IS_FUNC)
592      {
593        no_declarations++;
594
595#if ENABLED (JERRY_ES2015)
596        if ((type & (SCANNER_LITERAL_IS_CONST | SCANNER_LITERAL_IS_ARG)) == SCANNER_LITERAL_IS_CONST)
597        {
598          JERRY_ASSERT (type & SCANNER_LITERAL_IS_LET);
599
600          /* Catch parameters cannot be functions. */
601          literal_p->type = (uint8_t) (type & ~SCANNER_LITERAL_IS_FUNC);
602          no_declarations--;
603        }
604#else /* !ENABLED (JERRY_ES2015) */
605        if (type & SCANNER_LITERAL_IS_LOCAL)
606        {
607          /* Catch parameters cannot be functions. */
608          literal_p->type = (uint8_t) (type & ~SCANNER_LITERAL_IS_FUNC);
609          no_declarations--;
610        }
611#endif /* ENABLED (JERRY_ES2015) */
612      }
613
614      intptr_t diff = (intptr_t) (literal_p->char_p - prev_source_p);
615
616      if (diff >= 1 && diff <= UINT8_MAX)
617      {
618        compressed_size += 2 + 1;
619      }
620      else if (diff >= -UINT8_MAX && diff <= UINT16_MAX)
621      {
622        compressed_size += 2 + 2;
623      }
624      else
625      {
626        compressed_size += 2 + 1 + sizeof (const uint8_t *);
627      }
628
629      prev_source_p = literal_p->char_p + literal_p->length;
630
631      if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION)
632#if ENABLED (JERRY_ES2015)
633          || ((type & SCANNER_LITERAL_IS_FUNC) && (status_flags & SCANNER_LITERAL_POOL_IS_STRICT))
634#endif /* ENABLED (JERRY_ES2015) */
635          || !(type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC)))
636      {
637        continue;
638      }
639    }
640
641    if (prev_literal_pool_p != NULL && literal_p->length > 0)
642    {
643      /* Propagate literal to upper level. */
644      lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p,
645                                                                             prev_literal_pool_p,
646                                                                             literal_p);
647      uint8_t extended_type = literal_location_p->type;
648
649      if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) || (type & SCANNER_LITERAL_NO_REG))
650      {
651        extended_type |= SCANNER_LITERAL_NO_REG;
652      }
653
654#if ENABLED (JERRY_ES2015)
655      extended_type |= SCANNER_LITERAL_IS_USED;
656
657      if (status_flags & SCANNER_LITERAL_POOL_FUNCTION_STATEMENT)
658      {
659        extended_type |= SCANNER_LITERAL_EARLY_CREATE;
660      }
661
662      const uint8_t mask = (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_LOCAL);
663
664      if ((type & SCANNER_LITERAL_IS_ARG)
665          || (literal_location_p->type & mask) == SCANNER_LITERAL_IS_LET
666          || (literal_location_p->type & mask) == SCANNER_LITERAL_IS_CONST)
667      {
668        /* Clears the SCANNER_LITERAL_IS_VAR and SCANNER_LITERAL_IS_FUNC flags
669         * for speculative arrow parameters and local (non-var) functions. */
670        type = 0;
671      }
672#endif /* ENABLED (JERRY_ES2015) */
673
674      type = (uint8_t) (type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC));
675      JERRY_ASSERT (type == 0 || !(status_flags & SCANNER_LITERAL_POOL_FUNCTION));
676
677      literal_location_p->type = (uint8_t) (extended_type | type);
678    }
679  }
680
681  if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) || (compressed_size > 1))
682  {
683    compressed_size += sizeof (scanner_info_t);
684
685    scanner_info_t *info_p;
686
687    if (prev_literal_pool_p != NULL || scanner_context_p->end_arguments_p == NULL)
688    {
689      info_p = scanner_insert_info (context_p, literal_pool_p->source_p, compressed_size);
690    }
691    else
692    {
693      scanner_info_t *start_info_p = scanner_context_p->end_arguments_p;
694      info_p = scanner_insert_info_before (context_p, literal_pool_p->source_p, start_info_p, compressed_size);
695    }
696
697    if (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK)
698    {
699      no_declarations = PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK;
700    }
701
702    uint8_t *data_p = (uint8_t *) (info_p + 1);
703
704    if (status_flags & SCANNER_LITERAL_POOL_FUNCTION)
705    {
706      info_p->type = SCANNER_TYPE_FUNCTION;
707
708      uint8_t u8_arg = 0;
709
710      if (arguments_required)
711      {
712        u8_arg |= SCANNER_FUNCTION_ARGUMENTS_NEEDED;
713
714        if (no_declarations < PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK)
715        {
716          no_declarations++;
717        }
718
719#if ENABLED (JERRY_ES2015)
720        const uint16_t is_unmapped = SCANNER_LITERAL_POOL_IS_STRICT | SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED;
721#else /* !ENABLED (JERRY_ES2015) */
722        const uint16_t is_unmapped = SCANNER_LITERAL_POOL_IS_STRICT;
723#endif /* ENABLED (JERRY_ES2015) */
724
725        if (status_flags & is_unmapped)
726        {
727          arguments_required = false;
728        }
729        else
730        {
731          u8_arg |= SCANNER_FUNCTION_MAPPED_ARGUMENTS;
732        }
733      }
734
735#if ENABLED (JERRY_ES2015)
736      if (status_flags & SCANNER_LITERAL_POOL_ASYNC)
737      {
738        u8_arg |= SCANNER_FUNCTION_ASYNC;
739
740        if (status_flags & SCANNER_LITERAL_POOL_FUNCTION_STATEMENT)
741        {
742          u8_arg |= SCANNER_FUNCTION_STATEMENT;
743        }
744      }
745
746      if (status_flags & SCANNER_LITERAL_POOL_CAN_EVAL)
747      {
748        u8_arg |= SCANNER_FUNCTION_LEXICAL_ENV_NEEDED;
749      }
750#endif /* ENABLED (JERRY_ES2015) */
751
752      info_p->u8_arg = u8_arg;
753      info_p->u16_arg = (uint16_t) no_declarations;
754    }
755    else
756    {
757      info_p->type = SCANNER_TYPE_BLOCK;
758
759      JERRY_ASSERT (prev_literal_pool_p != NULL);
760    }
761
762    parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
763    prev_source_p = literal_pool_p->source_p - 1;
764    no_declarations = literal_pool_p->no_declarations;
765
766    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
767    {
768      if (JERRY_UNLIKELY (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK)
769          || (!(literal_p->type & SCANNER_LITERAL_IS_LOCAL)
770              && (!(literal_p->type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_ARG))
771                  || !(status_flags & SCANNER_LITERAL_POOL_FUNCTION))))
772      {
773        continue;
774      }
775
776      if (literal_p->length == 0)
777      {
778        *data_p++ = SCANNER_STREAM_TYPE_HOLE;
779        continue;
780      }
781
782      no_declarations++;
783
784      uint8_t type = SCANNER_STREAM_TYPE_VAR;
785
786      if (literal_p->type & SCANNER_LITERAL_IS_FUNC)
787      {
788        no_declarations++;
789        type = SCANNER_STREAM_TYPE_FUNC;
790
791        if (literal_p->type & SCANNER_LITERAL_IS_ARG)
792        {
793          type = SCANNER_STREAM_TYPE_ARG_FUNC;
794
795#if ENABLED (JERRY_ES2015)
796          if (literal_p->type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
797          {
798            type = SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC;
799          }
800#endif /* ENABLED (JERRY_ES2015) */
801        }
802      }
803      else if (literal_p->type & SCANNER_LITERAL_IS_ARG)
804      {
805        type = SCANNER_STREAM_TYPE_ARG;
806
807#if ENABLED (JERRY_ES2015)
808        if (literal_p->type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
809        {
810          type = SCANNER_STREAM_TYPE_DESTRUCTURED_ARG;
811        }
812
813        if (literal_p->type & SCANNER_LITERAL_IS_VAR)
814        {
815          type = (uint8_t) (type + 1);
816
817          JERRY_ASSERT (type == SCANNER_STREAM_TYPE_ARG_VAR
818                        || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR);
819        }
820#endif /* ENABLED (JERRY_ES2015) */
821      }
822#if ENABLED (JERRY_ES2015)
823      else if (literal_p->type & SCANNER_LITERAL_IS_LET)
824      {
825        if (!(literal_p->type & SCANNER_LITERAL_IS_CONST))
826        {
827          type = SCANNER_STREAM_TYPE_LET;
828
829          if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && (literal_p->type & SCANNER_LITERAL_NO_REG))
830          {
831            literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
832          }
833        }
834#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
835        else if (prev_literal_pool_p == NULL)
836        {
837          type = SCANNER_STREAM_TYPE_IMPORT;
838        }
839#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
840        else
841        {
842          type = SCANNER_STREAM_TYPE_LOCAL;
843        }
844      }
845      else if (literal_p->type & SCANNER_LITERAL_IS_CONST)
846      {
847        type = SCANNER_STREAM_TYPE_CONST;
848
849        if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && (literal_p->type & SCANNER_LITERAL_NO_REG))
850        {
851          literal_p->type |= SCANNER_LITERAL_EARLY_CREATE;
852        }
853      }
854
855      if (literal_p->type & SCANNER_LITERAL_EARLY_CREATE)
856      {
857        type |= SCANNER_STREAM_NO_REG | SCANNER_STREAM_EARLY_CREATE;
858      }
859#endif /* ENABLED (JERRY_ES2015) */
860
861      if (literal_p->has_escape)
862      {
863        type |= SCANNER_STREAM_HAS_ESCAPE;
864      }
865
866      if ((literal_p->type & SCANNER_LITERAL_NO_REG)
867          || (arguments_required && (literal_p->type & SCANNER_LITERAL_IS_ARG)))
868      {
869        type |= SCANNER_STREAM_NO_REG;
870      }
871
872      data_p[0] = type;
873      data_p[1] = (uint8_t) literal_p->length;
874      data_p += 3;
875
876      intptr_t diff = (intptr_t) (literal_p->char_p - prev_source_p);
877
878      if (diff >= 1 && diff <= UINT8_MAX)
879      {
880        data_p[-1] = (uint8_t) diff;
881      }
882      else if (diff >= -UINT8_MAX && diff <= UINT16_MAX)
883      {
884        if (diff < 0)
885        {
886          diff = -diff;
887        }
888
889        data_p[-3] |= SCANNER_STREAM_UINT16_DIFF;
890        data_p[-1] = (uint8_t) diff;
891        data_p[0] = (uint8_t) (diff >> 8);
892        data_p += 1;
893      }
894      else
895      {
896        data_p[-1] = 0;
897        memcpy (data_p, &literal_p->char_p, sizeof (const uint8_t *));
898        data_p += sizeof (const uint8_t *);
899      }
900
901      prev_source_p = literal_p->char_p + literal_p->length;
902    }
903
904    data_p[0] = SCANNER_STREAM_TYPE_END;
905
906    JERRY_ASSERT (((uint8_t *) info_p) + compressed_size == data_p + 1);
907  }
908
909  if (!(status_flags & SCANNER_LITERAL_POOL_FUNCTION)
910      && prev_literal_pool_p->no_declarations < no_declarations)
911  {
912    prev_literal_pool_p->no_declarations = (uint16_t) no_declarations;
913  }
914
915  if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) && prev_literal_pool_p != NULL)
916  {
917    if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IS_STRICT)
918    {
919      context_p->status_flags |= PARSER_IS_STRICT;
920    }
921    else
922    {
923      context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
924    }
925
926#if ENABLED (JERRY_ES2015)
927    if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_GENERATOR)
928    {
929      context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
930    }
931    else
932    {
933      context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
934    }
935
936    if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_ASYNC)
937    {
938      context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
939    }
940    else
941    {
942      context_p->status_flags &= (uint32_t) ~PARSER_IS_ASYNC_FUNCTION;
943    }
944#endif /* ENABLED (JERRY_ES2015) */
945  }
946
947  scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p;
948
949  parser_list_free (&literal_pool_p->literal_pool);
950  scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
951} /* scanner_pop_literal_pool */
952
953/**
954 * Filter out the arguments from a literal pool.
955 */
956void
957scanner_filter_arguments (parser_context_t *context_p, /**< context */
958                          scanner_context_t *scanner_context_p) /**< scanner context */
959{
960  /* Fast case: check whether all literals are arguments. */
961  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
962  scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p;
963  parser_list_iterator_t literal_iterator;
964  lexer_lit_location_t *literal_p;
965  bool can_eval = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) != 0;
966  bool has_arguments = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) == 0;
967
968  if (can_eval && prev_literal_pool_p != NULL)
969  {
970    prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
971  }
972
973  literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_CAN_EVAL;
974
975  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
976
977  while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
978  {
979#if ENABLED (JERRY_ES2015)
980    if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE))
981    {
982      literal_p->type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE;
983    }
984#else /* !ENABLED (JERRY_ES2015) */
985    if (can_eval)
986    {
987      literal_p->type |= SCANNER_LITERAL_NO_REG;
988    }
989#endif /* ENABLED (JERRY_ES2015) */
990
991    uint8_t type = literal_p->type;
992
993    if (!(type & SCANNER_LITERAL_IS_ARG) && !(has_arguments && scanner_literal_is_arguments (literal_p)))
994    {
995      break;
996    }
997
998#if ENABLED (JERRY_ES2015)
999    if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG))
1000    {
1001      break;
1002    }
1003#endif /* ENABLED (JERRY_ES2015) */
1004  }
1005
1006  if (literal_p == NULL)
1007  {
1008    return;
1009  }
1010
1011  scanner_literal_pool_t *new_literal_pool_p;
1012
1013  new_literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t));
1014
1015  new_literal_pool_p->prev_p = literal_pool_p;
1016  scanner_context_p->active_literal_pool_p = new_literal_pool_p;
1017
1018  *new_literal_pool_p = *literal_pool_p;
1019  parser_list_init (&new_literal_pool_p->literal_pool,
1020                    sizeof (lexer_lit_location_t),
1021                    (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t)));
1022
1023  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
1024
1025#if ENABLED (JERRY_ES2015)
1026  /* Destructured args are placed after the other arguments because of register assignments. */
1027  bool has_destructured_arg = false;
1028#endif /* ENABLED (JERRY_ES2015) */
1029
1030  while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1031  {
1032    uint8_t type = literal_p->type;
1033
1034    if ((type & SCANNER_LITERAL_IS_ARG) || (has_arguments && scanner_literal_is_arguments (literal_p)))
1035    {
1036#if ENABLED (JERRY_ES2015)
1037      if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE))
1038      {
1039        type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE;
1040        literal_p->type = type;
1041      }
1042
1043      if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG))
1044      {
1045        has_destructured_arg = true;
1046
1047        if (type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG)
1048        {
1049          continue;
1050        }
1051
1052        type &= (uint8_t) ~SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG;
1053        type |= SCANNER_LITERAL_IS_DESTRUCTURED_ARG;
1054
1055        literal_p->type = type;
1056        continue;
1057      }
1058#else /* !ENABLED (JERRY_ES2015) */
1059      if (can_eval)
1060      {
1061        literal_p->type |= SCANNER_LITERAL_NO_REG;
1062      }
1063#endif /* ENABLED (JERRY_ES2015) */
1064
1065      lexer_lit_location_t *new_literal_p;
1066      new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
1067      *new_literal_p = *literal_p;
1068    }
1069    else if (prev_literal_pool_p != NULL)
1070    {
1071      /* Propagate literal to upper level. */
1072      lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p,
1073                                                                             prev_literal_pool_p,
1074                                                                             literal_p);
1075      type |= SCANNER_LITERAL_NO_REG;
1076
1077#if ENABLED (JERRY_ES2015)
1078      type |= SCANNER_LITERAL_IS_USED;
1079#endif /* ENABLED (JERRY_ES2015) */
1080
1081      literal_location_p->type |= type;
1082    }
1083  }
1084
1085#if ENABLED (JERRY_ES2015)
1086  if (has_destructured_arg)
1087  {
1088    parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
1089
1090    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1091    {
1092      const uint8_t expected_flags = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG;
1093
1094      if ((literal_p->type & expected_flags) == expected_flags)
1095      {
1096        lexer_lit_location_t *new_literal_p;
1097        new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool);
1098        *new_literal_p = *literal_p;
1099      }
1100    }
1101  }
1102#endif /* ENABLED (JERRY_ES2015) */
1103
1104  new_literal_pool_p->prev_p = prev_literal_pool_p;
1105
1106  parser_list_free (&literal_pool_p->literal_pool);
1107  scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t));
1108} /* scanner_filter_arguments */
1109
1110/**
1111 * Add any literal to the specified literal pool.
1112 *
1113 * @return pointer to the literal
1114 */
1115lexer_lit_location_t *
1116scanner_add_custom_literal (parser_context_t *context_p, /**< context */
1117                            scanner_literal_pool_t *literal_pool_p, /**< literal pool */
1118                            const lexer_lit_location_t *literal_location_p) /**< literal */
1119{
1120  parser_list_iterator_t literal_iterator;
1121  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
1122  lexer_lit_location_t *literal_p;
1123
1124  const uint8_t *char_p = literal_location_p->char_p;
1125  prop_length_t length = literal_location_p->length;
1126
1127  if (JERRY_LIKELY (!literal_location_p->has_escape))
1128  {
1129    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1130    {
1131      if (literal_p->length == length)
1132      {
1133        if (JERRY_LIKELY (!literal_p->has_escape))
1134        {
1135          if (memcmp (literal_p->char_p, char_p, length) == 0)
1136          {
1137            return literal_p;
1138          }
1139        }
1140        else if (lexer_compare_identifier_to_string (literal_p, char_p, length))
1141        {
1142          /* The non-escaped version is preferred. */
1143          literal_p->char_p = char_p;
1144          literal_p->has_escape = 0;
1145          return literal_p;
1146        }
1147      }
1148    }
1149  }
1150  else
1151  {
1152    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1153    {
1154      if (lexer_compare_identifiers (context_p, literal_p, literal_location_p))
1155      {
1156        return literal_p;
1157      }
1158    }
1159  }
1160
1161  literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool);
1162  *literal_p = *literal_location_p;
1163
1164  literal_p->type = 0;
1165
1166  return literal_p;
1167} /* scanner_add_custom_literal */
1168
1169/**
1170 * Add the current literal token to the current literal pool.
1171 *
1172 * @return pointer to the literal
1173 */
1174inline lexer_lit_location_t * JERRY_ATTR_ALWAYS_INLINE
1175scanner_add_literal (parser_context_t *context_p, /**< context */
1176                     scanner_context_t *scanner_context_p) /**< scanner context */
1177{
1178  return scanner_add_custom_literal (context_p,
1179                                     scanner_context_p->active_literal_pool_p,
1180                                     &context_p->token.lit_location);
1181} /* scanner_add_literal */
1182
1183/**
1184 * Add the current literal token to the current literal pool and
1185 * set SCANNER_LITERAL_NO_REG if it is inside a with statement.
1186 *
1187 * @return pointer to the literal
1188 */
1189inline void JERRY_ATTR_ALWAYS_INLINE
1190scanner_add_reference (parser_context_t *context_p, /**< context */
1191                       scanner_context_t *scanner_context_p) /**< scanner context */
1192{
1193  lexer_lit_location_t *lit_location_p = scanner_add_custom_literal (context_p,
1194                                                                     scanner_context_p->active_literal_pool_p,
1195                                                                     &context_p->token.lit_location);
1196#if ENABLED (JERRY_ES2015)
1197  lit_location_p->type |= SCANNER_LITERAL_IS_USED;
1198#endif /* ENABLED (JERRY_ES2015) */
1199
1200  if (scanner_context_p->active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
1201  {
1202    lit_location_p->type |= SCANNER_LITERAL_NO_REG;
1203  }
1204
1205  scanner_detect_eval_call (context_p, scanner_context_p);
1206} /* scanner_add_reference */
1207
1208/**
1209 * Append an argument to the literal pool. If the argument is already present, make it a "hole".
1210 *
1211 * @return newly created literal
1212 */
1213lexer_lit_location_t *
1214scanner_append_argument (parser_context_t *context_p, /**< context */
1215                         scanner_context_t *scanner_context_p) /**< scanner context */
1216{
1217  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
1218  parser_list_iterator_t literal_iterator;
1219  parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
1220  lexer_lit_location_t *literal_location_p = &context_p->token.lit_location;
1221  lexer_lit_location_t *literal_p;
1222
1223  const uint8_t *char_p = literal_location_p->char_p;
1224  prop_length_t length = literal_location_p->length;
1225
1226  if (JERRY_LIKELY (!context_p->token.lit_location.has_escape))
1227  {
1228    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1229    {
1230      if (literal_p->length == length)
1231      {
1232        if (JERRY_LIKELY (!literal_p->has_escape))
1233        {
1234          if (memcmp (literal_p->char_p, char_p, length) == 0)
1235          {
1236            break;
1237          }
1238        }
1239        else if (lexer_compare_identifier_to_string (literal_p, char_p, length))
1240        {
1241          break;
1242        }
1243      }
1244    }
1245  }
1246  else
1247  {
1248    while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1249    {
1250      if (lexer_compare_identifiers (context_p, literal_p, literal_location_p))
1251      {
1252        break;
1253      }
1254    }
1255  }
1256
1257  uint8_t literal_type = SCANNER_LITERAL_IS_ARG;
1258
1259  if (literal_p != NULL)
1260  {
1261    literal_p->length = 0;
1262
1263#if ENABLED (JERRY_ES2015)
1264    if (literal_p->type & SCANNER_LITERAL_IS_USED)
1265    {
1266      literal_type = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_EARLY_CREATE;
1267    }
1268#endif /* ENABLED (JERRY_ES2015) */
1269  }
1270
1271  literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool);
1272
1273  *literal_p = context_p->token.lit_location;
1274  literal_p->type = literal_type;
1275
1276  return literal_p;
1277} /* scanner_append_argument */
1278
1279/**
1280 * Check whether an eval call is performed and update the status flags accordingly.
1281 */
1282void
1283scanner_detect_eval_call (parser_context_t *context_p, /**< context */
1284                          scanner_context_t *scanner_context_p) /**< scanner context */
1285{
1286  if (context_p->token.keyword_type == LEXER_KEYW_EVAL
1287      && lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
1288  {
1289    scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL;
1290  }
1291} /* scanner_detect_eval_call */
1292
1293#if ENABLED (JERRY_ES2015)
1294
1295/**
1296 * Find a let/const declaration of a given literal.
1297 *
1298 * @return true - if the literal is found, false - otherwise
1299 */
1300bool
1301scanner_scope_find_let_declaration (parser_context_t *context_p, /**< context */
1302                                    lexer_lit_location_t *literal_p) /**< literal */
1303{
1304  ecma_string_t *name_p;
1305
1306  if (JERRY_LIKELY (!literal_p->has_escape))
1307  {
1308    name_p = ecma_new_ecma_string_from_utf8 (literal_p->char_p, literal_p->length);
1309  }
1310  else
1311  {
1312    uint8_t *destination_p = (uint8_t *) scanner_malloc (context_p, literal_p->length);
1313
1314    lexer_convert_ident_to_cesu8 (destination_p, literal_p->char_p, literal_p->length);
1315
1316    name_p = ecma_new_ecma_string_from_utf8 (destination_p, literal_p->length);
1317    scanner_free (destination_p, literal_p->length);
1318  }
1319
1320  ecma_object_t *lex_env_p = JERRY_CONTEXT (vm_top_context_p)->lex_env_p;
1321
1322  while (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK)
1323  {
1324    if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
1325    {
1326      ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
1327
1328      if (property_p != NULL && ecma_is_property_enumerable (*property_p))
1329      {
1330        ecma_deref_ecma_string (name_p);
1331        return true;
1332      }
1333    }
1334
1335    JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
1336    lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
1337  }
1338
1339  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
1340  {
1341    ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
1342
1343    if (property_p != NULL && ecma_is_property_enumerable (*property_p))
1344    {
1345      ecma_deref_ecma_string (name_p);
1346      return true;
1347    }
1348  }
1349
1350  ecma_deref_ecma_string (name_p);
1351  return false;
1352} /* scanner_scope_find_let_declaration */
1353
1354/**
1355 * Throws an error for invalid var statements.
1356 */
1357void
1358scanner_detect_invalid_var (parser_context_t *context_p, /**< context */
1359                            scanner_context_t *scanner_context_p, /**< scanner context */
1360                            lexer_lit_location_t *var_literal_p) /**< var literal */
1361{
1362  if (var_literal_p->type & SCANNER_LITERAL_IS_LOCAL
1363      && !(var_literal_p->type & (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_ARG))
1364      && (var_literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL)
1365  {
1366    scanner_raise_redeclaration_error (context_p);
1367  }
1368
1369  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
1370  const uint8_t *char_p = var_literal_p->char_p;
1371  prop_length_t length = var_literal_p->length;
1372
1373  while (!(literal_pool_p->status_flags & SCANNER_LITERAL_POOL_FUNCTION))
1374  {
1375    literal_pool_p = literal_pool_p->prev_p;
1376
1377    parser_list_iterator_t literal_iterator;
1378    parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator);
1379    lexer_lit_location_t *literal_p;
1380
1381    if (JERRY_LIKELY (!context_p->token.lit_location.has_escape))
1382    {
1383      while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1384      {
1385        if (literal_p->type & SCANNER_LITERAL_IS_LOCAL
1386            && !(literal_p->type & SCANNER_LITERAL_IS_ARG)
1387            && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL
1388            && literal_p->length == length)
1389        {
1390          if (JERRY_LIKELY (!literal_p->has_escape))
1391          {
1392            if (memcmp (literal_p->char_p, char_p, length) == 0)
1393            {
1394              scanner_raise_redeclaration_error (context_p);
1395              return;
1396            }
1397          }
1398          else if (lexer_compare_identifier_to_string (literal_p, char_p, length))
1399          {
1400            scanner_raise_redeclaration_error (context_p);
1401            return;
1402          }
1403        }
1404      }
1405    }
1406    else
1407    {
1408      while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
1409      {
1410        if (literal_p->type & SCANNER_LITERAL_IS_LOCAL
1411            && !(literal_p->type & SCANNER_LITERAL_IS_ARG)
1412            && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL
1413            && lexer_compare_identifiers (context_p, literal_p, var_literal_p))
1414        {
1415          scanner_raise_redeclaration_error (context_p);
1416          return;
1417        }
1418      }
1419    }
1420  }
1421
1422  if ((context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)
1423      && scanner_scope_find_let_declaration (context_p, var_literal_p))
1424  {
1425    scanner_raise_redeclaration_error (context_p);
1426  }
1427} /* scanner_detect_invalid_var */
1428
1429/**
1430 * Throws an error for invalid let statements.
1431 */
1432void
1433scanner_detect_invalid_let (parser_context_t *context_p, /**< context */
1434                            lexer_lit_location_t *let_literal_p) /**< let literal */
1435{
1436  if (let_literal_p->type & (SCANNER_LITERAL_IS_ARG
1437                             | SCANNER_LITERAL_IS_VAR
1438                             | SCANNER_LITERAL_IS_LOCAL))
1439  {
1440    scanner_raise_redeclaration_error (context_p);
1441  }
1442
1443  if (let_literal_p->type & SCANNER_LITERAL_IS_FUNC)
1444  {
1445    let_literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC;
1446  }
1447} /* scanner_detect_invalid_let */
1448
1449/**
1450 * Push the values required for class declaration parsing.
1451 */
1452void
1453scanner_push_class_declaration (parser_context_t *context_p, /**< context */
1454                                scanner_context_t *scanner_context_p, /* scanner context */
1455                                uint8_t stack_mode) /**< stack mode */
1456{
1457  JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS);
1458
1459  parser_stack_push_uint8 (context_p, stack_mode);
1460  scanner_source_start_t source_start;
1461  source_start.source_p = context_p->source_p;
1462
1463  parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t));
1464  parser_stack_push_uint8 (context_p, SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR);
1465  scanner_context_p->mode = SCAN_MODE_CLASS_DECLARATION;
1466
1467  lexer_next_token (context_p);
1468} /* scanner_push_class_declaration */
1469
1470/**
1471 * Push the values required for destructuring assignment or binding parsing.
1472 */
1473void
1474scanner_push_destructuring_pattern (parser_context_t *context_p, /**< context */
1475                                    scanner_context_t *scanner_context_p, /**< scanner context */
1476                                    uint8_t binding_type, /**< type of destructuring binding pattern */
1477                                    bool is_nested) /**< nested declaration */
1478{
1479  JERRY_ASSERT (binding_type != SCANNER_BINDING_NONE || !is_nested);
1480
1481  scanner_source_start_t source_start;
1482  source_start.source_p = context_p->source_p;
1483
1484  parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t));
1485  parser_stack_push_uint8 (context_p, scanner_context_p->binding_type);
1486  scanner_context_p->binding_type = binding_type;
1487
1488  if (SCANNER_NEEDS_BINDING_LIST (binding_type))
1489  {
1490    scanner_binding_list_t *binding_list_p;
1491    binding_list_p = (scanner_binding_list_t *) scanner_malloc (context_p, sizeof (scanner_binding_list_t));
1492
1493    binding_list_p->prev_p = scanner_context_p->active_binding_list_p;
1494    binding_list_p->items_p = NULL;
1495    binding_list_p->is_nested = is_nested;
1496
1497    scanner_context_p->active_binding_list_p = binding_list_p;
1498  }
1499} /* scanner_push_destructuring_pattern */
1500
1501/**
1502 * Pop binding list.
1503 */
1504void
1505scanner_pop_binding_list (scanner_context_t *scanner_context_p) /**< scanner context */
1506{
1507  scanner_binding_list_t *binding_list_p = scanner_context_p->active_binding_list_p;
1508  scanner_binding_item_t *item_p = binding_list_p->items_p;
1509  scanner_binding_list_t *prev_binding_list_p = binding_list_p->prev_p;
1510  bool is_nested = binding_list_p->is_nested;
1511
1512  scanner_free (binding_list_p, sizeof (scanner_binding_list_t));
1513  scanner_context_p->active_binding_list_p = prev_binding_list_p;
1514
1515  JERRY_ASSERT (binding_list_p != NULL);
1516
1517  if (!is_nested)
1518  {
1519    while (item_p != NULL)
1520    {
1521      scanner_binding_item_t *next_p = item_p->next_p;
1522
1523      JERRY_ASSERT (item_p->literal_p->type & (SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_IS_ARG));
1524
1525      scanner_free (item_p, sizeof (scanner_binding_item_t));
1526      item_p = next_p;
1527    }
1528    return;
1529  }
1530
1531  JERRY_ASSERT (prev_binding_list_p != NULL);
1532
1533  while (item_p != NULL)
1534  {
1535    scanner_binding_item_t *next_p = item_p->next_p;
1536
1537    item_p->next_p = prev_binding_list_p->items_p;
1538    prev_binding_list_p->items_p = item_p;
1539
1540    item_p = next_p;
1541  }
1542} /* scanner_pop_binding_list */
1543
1544/**
1545 * Append a hole into the literal pool.
1546 */
1547void
1548scanner_append_hole (parser_context_t *context_p, scanner_context_t *scanner_context_p)
1549{
1550  scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
1551
1552  lexer_lit_location_t *literal_p;
1553  literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool);
1554
1555  literal_p->char_p = NULL;
1556  literal_p->length = 0;
1557  literal_p->type = SCANNER_LITERAL_IS_ARG;
1558  literal_p->has_escape = 0;
1559} /* scanner_append_hole */
1560
1561#endif /* ENABLED (JERRY_ES2015) */
1562
1563/**
1564 * Reverse the scanner info chain after the scanning is completed.
1565 */
1566void
1567scanner_reverse_info_list (parser_context_t *context_p) /**< context */
1568{
1569  scanner_info_t *scanner_info_p = context_p->next_scanner_info_p;
1570  scanner_info_t *last_scanner_info_p = NULL;
1571
1572  if (scanner_info_p->type == SCANNER_TYPE_END)
1573  {
1574    return;
1575  }
1576
1577  do
1578  {
1579    scanner_info_t *next_scanner_info_p = scanner_info_p->next_p;
1580    scanner_info_p->next_p = last_scanner_info_p;
1581
1582    last_scanner_info_p = scanner_info_p;
1583    scanner_info_p = next_scanner_info_p;
1584  }
1585  while (scanner_info_p->type != SCANNER_TYPE_END);
1586
1587  context_p->next_scanner_info_p->next_p = scanner_info_p;
1588  context_p->next_scanner_info_p = last_scanner_info_p;
1589} /* scanner_reverse_info_list */
1590
1591/**
1592 * Release unused scanner info blocks.
1593 * This should happen only if an error is occured.
1594 */
1595void
1596scanner_cleanup (parser_context_t *context_p) /**< context */
1597{
1598  if (context_p->skipped_scanner_info_p != NULL)
1599  {
1600    context_p->skipped_scanner_info_end_p->next_p = context_p->next_scanner_info_p;
1601    context_p->next_scanner_info_p = context_p->skipped_scanner_info_p;
1602    context_p->skipped_scanner_info_p = NULL;
1603  }
1604
1605  scanner_info_t *scanner_info_p = context_p->next_scanner_info_p;
1606
1607  while (scanner_info_p != NULL)
1608  {
1609    scanner_info_t *next_scanner_info_p = scanner_info_p->next_p;
1610
1611    size_t size = sizeof (scanner_info_t);
1612
1613    switch (scanner_info_p->type)
1614    {
1615      case SCANNER_TYPE_END:
1616      {
1617        scanner_info_p = context_p->active_scanner_info_p;
1618        continue;
1619      }
1620      case SCANNER_TYPE_FUNCTION:
1621      case SCANNER_TYPE_BLOCK:
1622      {
1623        size = scanner_get_stream_size (scanner_info_p, sizeof (scanner_info_t));
1624        break;
1625      }
1626      case SCANNER_TYPE_WHILE:
1627      case SCANNER_TYPE_FOR_IN:
1628#if ENABLED (JERRY_ES2015)
1629      case SCANNER_TYPE_FOR_OF:
1630#endif /* ENABLED (JERRY_ES2015) */
1631      case SCANNER_TYPE_CASE:
1632#if ENABLED (JERRY_ES2015)
1633      case SCANNER_TYPE_INITIALIZER:
1634#endif /* ENABLED (JERRY_ES2015) */
1635      {
1636        size = sizeof (scanner_location_info_t);
1637        break;
1638      }
1639      case SCANNER_TYPE_FOR:
1640      {
1641        size = sizeof (scanner_for_info_t);
1642        break;
1643      }
1644      case SCANNER_TYPE_SWITCH:
1645      {
1646        scanner_release_switch_cases (((scanner_switch_info_t *) scanner_info_p)->case_p);
1647        size = sizeof (scanner_switch_info_t);
1648        break;
1649      }
1650      default:
1651      {
1652#if ENABLED (JERRY_ES2015)
1653        JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS
1654                      || scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION
1655                      || scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR
1656                      || scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
1657                      || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
1658#else /* !ENABLED (JERRY_ES2015) */
1659        JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS);
1660#endif /* ENABLED (JERRY_ES2015) */
1661        break;
1662      }
1663    }
1664
1665    scanner_free (scanner_info_p, size);
1666    scanner_info_p = next_scanner_info_p;
1667  }
1668
1669  context_p->next_scanner_info_p = NULL;
1670  context_p->active_scanner_info_p = NULL;
1671} /* scanner_cleanup */
1672
1673/**
1674 * Checks whether a context needs to be created for a block.
1675 *
1676 * @return true - if context is needed,
1677 *         false - otherwise
1678 */
1679bool
1680scanner_is_context_needed (parser_context_t *context_p, /**< context */
1681                           parser_check_context_type_t check_type) /**< context type */
1682{
1683  scanner_info_t *info_p = context_p->next_scanner_info_p;
1684  const uint8_t *data_p = (const uint8_t *) (info_p + 1);
1685
1686  JERRY_UNUSED (check_type);
1687
1688#if ENABLED (JERRY_ES2015)
1689  JERRY_ASSERT ((check_type == PARSER_CHECK_BLOCK_CONTEXT ? info_p->type == SCANNER_TYPE_BLOCK
1690                                                          : info_p->type == SCANNER_TYPE_FUNCTION));
1691
1692  uint32_t scope_stack_reg_top = (check_type != PARSER_CHECK_GLOBAL_CONTEXT ? context_p->scope_stack_reg_top
1693                                                                            : 0);
1694#else /* !ENABLED (JERRY_ES2015) */
1695  JERRY_ASSERT (check_type == PARSER_CHECK_BLOCK_CONTEXT);
1696  JERRY_ASSERT (info_p->type == SCANNER_TYPE_BLOCK);
1697
1698  uint32_t scope_stack_reg_top = context_p->scope_stack_reg_top;
1699#endif /* !JERRY_NDEBUG */
1700
1701  while (data_p[0] != SCANNER_STREAM_TYPE_END)
1702  {
1703    uint8_t data = data_p[0];
1704
1705#if ENABLED (JERRY_ES2015)
1706    uint32_t type = data & SCANNER_STREAM_TYPE_MASK;
1707
1708    if (JERRY_UNLIKELY (type == SCANNER_STREAM_TYPE_HOLE))
1709    {
1710      JERRY_ASSERT (check_type == PARSER_CHECK_FUNCTION_CONTEXT);
1711      data_p++;
1712      continue;
1713    }
1714
1715#ifndef JERRY_NDEBUG
1716    if (check_type == PARSER_CHECK_BLOCK_CONTEXT)
1717    {
1718      JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR
1719                    || type == SCANNER_STREAM_TYPE_LET
1720                    || type == SCANNER_STREAM_TYPE_CONST
1721                    || type == SCANNER_STREAM_TYPE_LOCAL
1722                    || type == SCANNER_STREAM_TYPE_FUNC);
1723    }
1724    else if (check_type == PARSER_CHECK_GLOBAL_CONTEXT)
1725    {
1726      /* FIXME: a private declarative lexical environment should always be present
1727       * for modules. Remove SCANNER_STREAM_TYPE_IMPORT after it is implemented. */
1728      JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR
1729                    || type == SCANNER_STREAM_TYPE_LET
1730                    || type == SCANNER_STREAM_TYPE_CONST
1731                    || type == SCANNER_STREAM_TYPE_FUNC
1732                    || type == SCANNER_STREAM_TYPE_IMPORT);
1733
1734      /* Only let/const can be stored in registers */
1735      JERRY_ASSERT ((data & SCANNER_STREAM_NO_REG)
1736                    || (type == SCANNER_STREAM_TYPE_FUNC && (context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL))
1737                    || type == SCANNER_STREAM_TYPE_LET
1738                    || type == SCANNER_STREAM_TYPE_CONST);
1739    }
1740    else
1741    {
1742      JERRY_ASSERT (check_type == PARSER_CHECK_FUNCTION_CONTEXT);
1743
1744      JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR
1745                    || type == SCANNER_STREAM_TYPE_LET
1746                    || type == SCANNER_STREAM_TYPE_CONST
1747                    || type == SCANNER_STREAM_TYPE_LOCAL
1748                    || type == SCANNER_STREAM_TYPE_ARG
1749                    || type == SCANNER_STREAM_TYPE_ARG_VAR
1750                    || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG
1751                    || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR
1752                    || type == SCANNER_STREAM_TYPE_ARG_FUNC
1753                    || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC
1754                    || type == SCANNER_STREAM_TYPE_FUNC);
1755    }
1756#endif /* !JERRY_NDEBUG */
1757
1758#else /* !ENABLED (JERRY_ES2015) */
1759    JERRY_ASSERT ((data & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_VAR);
1760#endif /* ENABLED (JERRY_ES2015) */
1761
1762    if (!(data & SCANNER_STREAM_UINT16_DIFF))
1763    {
1764      if (data_p[2] != 0)
1765      {
1766        data_p += 2 + 1;
1767      }
1768      else
1769      {
1770        data_p += 2 + 1 + sizeof (const uint8_t *);
1771      }
1772    }
1773    else
1774    {
1775      data_p += 2 + 2;
1776    }
1777
1778#if ENABLED (JERRY_ES2015)
1779    if (JERRY_UNLIKELY (check_type == PARSER_CHECK_GLOBAL_CONTEXT)
1780        && (type == SCANNER_STREAM_TYPE_VAR
1781            || (type == SCANNER_STREAM_TYPE_FUNC && !(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL))
1782            || type == SCANNER_STREAM_TYPE_IMPORT))
1783    {
1784      continue;
1785    }
1786
1787    if (JERRY_UNLIKELY (check_type == PARSER_CHECK_FUNCTION_CONTEXT))
1788    {
1789      if (SCANNER_STREAM_TYPE_IS_ARG_FUNC (type)
1790          || type == SCANNER_STREAM_TYPE_ARG_VAR
1791          || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR)
1792      {
1793        /* The return value is true, if the variable is stored in the lexical environment
1794         * or all registers have already been used for function arguments. This can be
1795         * inprecise in the latter case, but this is a very rare corner case. A more
1796         * sophisticated check would require to decode the literal. */
1797        if ((data & SCANNER_STREAM_NO_REG)
1798            || scope_stack_reg_top >= PARSER_MAXIMUM_NUMBER_OF_REGISTERS)
1799        {
1800          return true;
1801        }
1802        continue;
1803      }
1804
1805      if (SCANNER_STREAM_TYPE_IS_ARG (type))
1806      {
1807        continue;
1808      }
1809    }
1810#endif /* ENABLED (JERRY_ES2015) */
1811
1812    if ((data & SCANNER_STREAM_NO_REG)
1813        || scope_stack_reg_top >= PARSER_MAXIMUM_NUMBER_OF_REGISTERS)
1814    {
1815      return true;
1816    }
1817
1818    scope_stack_reg_top++;
1819  }
1820
1821  return false;
1822} /* scanner_is_context_needed */
1823
1824#if ENABLED (JERRY_ES2015)
1825
1826/**
1827 * Try to scan/parse the ".target" part in the "new.target" expression.
1828 *
1829 * Upon exiting with "true" the current token will point to the "target"
1830 * literal.
1831 *
1832 * If the "target" literal is not after the "new." then a scanner/parser
1833 * error will be raised.
1834 *
1835 * @returns true if the ".target" part was found
1836 *          false if there is no "." after the new.
1837 */
1838bool
1839scanner_try_scan_new_target (parser_context_t *context_p) /**< parser/scanner context */
1840{
1841  JERRY_ASSERT (context_p->token.type == LEXER_KEYW_NEW);
1842
1843  if (lexer_check_next_character (context_p, LIT_CHAR_DOT))
1844  {
1845    lexer_next_token (context_p);
1846    if (context_p->token.type != LEXER_DOT)
1847    {
1848      parser_raise_error (context_p, PARSER_ERR_INVALID_CHARACTER);
1849    }
1850
1851    lexer_next_token (context_p);
1852    if (!lexer_token_is_identifier (context_p, "target", 6))
1853    {
1854      parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_EXPECTED);
1855    }
1856
1857    return true;
1858  }
1859  return false;
1860} /* scanner_try_scan_new_target */
1861
1862#endif /* ENABLED (JERRY_ES2015) */
1863
1864/**
1865 * Description of "arguments" literal string.
1866 */
1867const lexer_lit_location_t lexer_arguments_literal =
1868{
1869  (const uint8_t *) "arguments", 9, LEXER_IDENT_LITERAL, false
1870};
1871
1872/**
1873 * Create an unused literal.
1874 */
1875static void
1876scanner_create_unused_literal (parser_context_t *context_p, /**< context */
1877                               uint8_t status_flags) /**< initial status flags */
1878{
1879  if (JERRY_UNLIKELY (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS))
1880  {
1881    parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
1882  }
1883
1884  lexer_literal_t *literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
1885
1886  literal_p->type = LEXER_UNUSED_LITERAL;
1887  literal_p->status_flags = status_flags;
1888
1889  context_p->literal_count++;
1890} /* scanner_create_unused_literal */
1891
1892#if ENABLED (JERRY_ES2015)
1893/**
1894 * Emit checks for redeclared bindings in the global lexical scope.
1895 */
1896void
1897scanner_check_variables (parser_context_t *context_p) /**< context */
1898{
1899  scanner_info_t *info_p = context_p->next_scanner_info_p;
1900  const uint8_t *next_data_p = (const uint8_t *) (info_p + 1);
1901  lexer_lit_location_t literal;
1902
1903  JERRY_ASSERT (info_p->type == SCANNER_TYPE_FUNCTION);
1904
1905  literal.char_p = info_p->source_p - 1;
1906
1907  while (next_data_p[0] != SCANNER_STREAM_TYPE_END)
1908  {
1909    uint32_t type = next_data_p[0] & SCANNER_STREAM_TYPE_MASK;
1910    const uint8_t *data_p = next_data_p;
1911
1912    JERRY_ASSERT (type != SCANNER_STREAM_TYPE_HOLE
1913                  && !SCANNER_STREAM_TYPE_IS_ARG (type)
1914                  && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type));
1915    JERRY_ASSERT (data_p[0] & SCANNER_STREAM_NO_REG);
1916
1917    if (!(data_p[0] & SCANNER_STREAM_UINT16_DIFF))
1918    {
1919      if (data_p[2] != 0)
1920      {
1921        literal.char_p += data_p[2];
1922        next_data_p += 2 + 1;
1923      }
1924      else
1925      {
1926        memcpy (&literal.char_p, data_p + 2 + 1, sizeof (const uint8_t *));
1927        next_data_p += 2 + 1 + sizeof (const uint8_t *);
1928      }
1929    }
1930    else
1931    {
1932      int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8;
1933
1934      if (diff <= UINT8_MAX)
1935      {
1936        diff = -diff;
1937      }
1938
1939      literal.char_p += diff;
1940      next_data_p += 2 + 2;
1941    }
1942
1943    literal.length = data_p[1];
1944    literal.type = LEXER_IDENT_LITERAL;
1945    literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0;
1946
1947    lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL);
1948    literal.char_p += data_p[1];
1949
1950#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
1951    if (type == SCANNER_STREAM_TYPE_IMPORT)
1952    {
1953      continue;
1954    }
1955#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1956
1957    context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED;
1958
1959    uint16_t opcode;
1960    if (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_FUNC)
1961    {
1962      opcode = CBC_CHECK_VAR;
1963    }
1964    else
1965    {
1966      opcode = CBC_CHECK_LET;
1967    }
1968
1969    parser_emit_cbc_literal (context_p, opcode, context_p->lit_object.index);
1970  }
1971
1972  parser_flush_cbc (context_p);
1973} /* scanner_check_variables */
1974#endif /* ENABLED (JERRY_ES2015) */
1975
1976/**
1977 * Create and/or initialize var/let/const/function/etc. variables.
1978 */
1979void
1980scanner_create_variables (parser_context_t *context_p, /**< context */
1981                          uint32_t option_flags) /**< combination of scanner_create_variables_flags_t bits */
1982{
1983  scanner_info_t *info_p = context_p->next_scanner_info_p;
1984  const uint8_t *next_data_p = (const uint8_t *) (info_p + 1);
1985  uint8_t info_type = info_p->type;
1986  uint8_t info_u8_arg = info_p->u8_arg;
1987  lexer_lit_location_t literal;
1988  parser_scope_stack_t *scope_stack_p;
1989  parser_scope_stack_t *scope_stack_end_p;
1990
1991  JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION || info_type == SCANNER_TYPE_BLOCK);
1992  JERRY_ASSERT (!(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS)
1993                || !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY));
1994  JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION
1995                || !(option_flags & (SCANNER_CREATE_VARS_IS_FUNCTION_ARGS | SCANNER_CREATE_VARS_IS_FUNCTION_BODY)));
1996
1997  if (info_type == SCANNER_TYPE_FUNCTION && !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY))
1998  {
1999    JERRY_ASSERT (context_p->scope_stack_p == NULL);
2000
2001    size_t stack_size = info_p->u16_arg * sizeof (parser_scope_stack_t);
2002    context_p->scope_stack_size = info_p->u16_arg;
2003
2004    scope_stack_p = NULL;
2005
2006    if (stack_size > 0)
2007    {
2008      scope_stack_p = (parser_scope_stack_t *) parser_malloc (context_p, stack_size);
2009    }
2010
2011    context_p->scope_stack_p = scope_stack_p;
2012    scope_stack_end_p = scope_stack_p + context_p->scope_stack_size;
2013  }
2014  else
2015  {
2016    JERRY_ASSERT (context_p->scope_stack_p != NULL || context_p->scope_stack_size == 0);
2017
2018    scope_stack_p = context_p->scope_stack_p;
2019    scope_stack_end_p = scope_stack_p + context_p->scope_stack_size;
2020    scope_stack_p += context_p->scope_stack_top;
2021  }
2022
2023  uint32_t scope_stack_reg_top = context_p->scope_stack_reg_top;
2024
2025  literal.char_p = info_p->source_p - 1;
2026
2027  while (next_data_p[0] != SCANNER_STREAM_TYPE_END)
2028  {
2029    uint32_t type = next_data_p[0] & SCANNER_STREAM_TYPE_MASK;
2030    const uint8_t *data_p = next_data_p;
2031
2032    JERRY_ASSERT ((option_flags & (SCANNER_CREATE_VARS_IS_FUNCTION_BODY | SCANNER_CREATE_VARS_IS_FUNCTION_ARGS))
2033                  || (type != SCANNER_STREAM_TYPE_HOLE
2034                      && !SCANNER_STREAM_TYPE_IS_ARG (type)
2035                      && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type)));
2036
2037#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2038    JERRY_ASSERT (type != SCANNER_STREAM_TYPE_IMPORT || (data_p[0] & SCANNER_STREAM_NO_REG));
2039#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2040
2041    if (type == SCANNER_STREAM_TYPE_HOLE)
2042    {
2043      next_data_p++;
2044
2045      if (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)
2046      {
2047        continue;
2048      }
2049
2050      if (info_u8_arg & SCANNER_FUNCTION_MAPPED_ARGUMENTS)
2051      {
2052        scanner_create_unused_literal (context_p, LEXER_FLAG_FUNCTION_ARGUMENT);
2053      }
2054
2055      if (scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS)
2056      {
2057        scope_stack_reg_top++;
2058      }
2059      continue;
2060    }
2061
2062    JERRY_ASSERT (context_p->scope_stack_size != 0);
2063
2064    if (!(data_p[0] & SCANNER_STREAM_UINT16_DIFF))
2065    {
2066      if (data_p[2] != 0)
2067      {
2068        literal.char_p += data_p[2];
2069        next_data_p += 2 + 1;
2070      }
2071      else
2072      {
2073        memcpy (&literal.char_p, data_p + 2 + 1, sizeof (const uint8_t *));
2074        next_data_p += 2 + 1 + sizeof (const uint8_t *);
2075      }
2076    }
2077    else
2078    {
2079      int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8;
2080
2081      if (diff <= UINT8_MAX)
2082      {
2083        diff = -diff;
2084      }
2085
2086      literal.char_p += diff;
2087      next_data_p += 2 + 2;
2088    }
2089
2090    if (SCANNER_STREAM_TYPE_IS_ARG (type))
2091    {
2092      if (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)
2093      {
2094#if ENABLED (JERRY_ES2015)
2095        if ((context_p->status_flags & PARSER_LEXICAL_BLOCK_NEEDED)
2096            && (type == SCANNER_STREAM_TYPE_ARG_VAR || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR))
2097        {
2098          literal.length = data_p[1];
2099          literal.type = LEXER_IDENT_LITERAL;
2100          literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0;
2101
2102          /* Literal must be exists. */
2103          lexer_construct_literal_object (context_p, &literal, LEXER_IDENT_LITERAL);
2104
2105          if (context_p->lit_object.index < PARSER_REGISTER_START)
2106          {
2107            parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_COPY_FROM_ARG);
2108          }
2109        }
2110#endif /* ENABLED (JERRY_ES2015) */
2111
2112        literal.char_p += data_p[1];
2113        continue;
2114      }
2115    }
2116    else if ((option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS)
2117             && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type))
2118    {
2119      /* Function arguments must come first. */
2120      break;
2121    }
2122
2123    literal.length = data_p[1];
2124    literal.type = LEXER_IDENT_LITERAL;
2125    literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0;
2126
2127    lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL);
2128    literal.char_p += data_p[1];
2129
2130    if (SCANNER_STREAM_TYPE_IS_ARG_FUNC (type) && (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY))
2131    {
2132      JERRY_ASSERT (scope_stack_p >= context_p->scope_stack_p + 2);
2133      JERRY_ASSERT (context_p->status_flags & PARSER_IS_FUNCTION);
2134#if ENABLED (JERRY_ES2015)
2135      JERRY_ASSERT (!(context_p->status_flags & PARSER_FUNCTION_IS_PARSING_ARGS));
2136#endif /* ENABLED (JERRY_ES2015) */
2137
2138      parser_scope_stack_t *function_map_p = scope_stack_p - 2;
2139      uint16_t literal_index = context_p->lit_object.index;
2140
2141      while (literal_index != function_map_p->map_from)
2142      {
2143        function_map_p--;
2144
2145        JERRY_ASSERT (function_map_p >= context_p->scope_stack_p);
2146      }
2147
2148      JERRY_ASSERT (function_map_p[1].map_from == PARSER_SCOPE_STACK_FUNC);
2149
2150      cbc_opcode_t opcode = CBC_SET_VAR_FUNC;
2151
2152#if ENABLED (JERRY_ES2015)
2153      if (JERRY_UNLIKELY (context_p->status_flags & PARSER_LEXICAL_BLOCK_NEEDED)
2154          && (function_map_p[0].map_to & PARSER_SCOPE_STACK_REGISTER_MASK) == 0)
2155      {
2156        opcode = CBC_INIT_ARG_OR_FUNC;
2157      }
2158#endif /* ENABLED (JERRY_ES2015) */
2159
2160      parser_emit_cbc_literal_value (context_p,
2161                                     (uint16_t) opcode,
2162                                     function_map_p[1].map_to,
2163                                     scanner_decode_map_to (function_map_p));
2164      continue;
2165    }
2166
2167    if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p))
2168    {
2169      JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK);
2170      parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED);
2171    }
2172
2173    scope_stack_p->map_from = context_p->lit_object.index;
2174
2175#if ENABLED (JERRY_ES2015)
2176    if (info_type == SCANNER_TYPE_FUNCTION)
2177    {
2178      if (type != SCANNER_STREAM_TYPE_LET
2179#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
2180          && type != SCANNER_STREAM_TYPE_IMPORT
2181#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2182          && type != SCANNER_STREAM_TYPE_CONST)
2183      {
2184        context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_GLOBAL;
2185      }
2186    }
2187#endif /* ENABLED (JERRY_ES2015) */
2188
2189    uint16_t map_to;
2190    uint16_t func_init_opcode = CBC_INIT_ARG_OR_FUNC;
2191
2192    if (!(data_p[0] & SCANNER_STREAM_NO_REG)
2193        && scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS)
2194    {
2195      map_to = (uint16_t) (PARSER_REGISTER_START + scope_stack_reg_top);
2196
2197#if ENABLED (JERRY_ES2015)
2198      scope_stack_p->map_to = (uint16_t) (scope_stack_reg_top + 1);
2199#else /* !ENABLED (JERRY_ES2015) */
2200      scope_stack_p->map_to = map_to;
2201#endif /* ENABLED (JERRY_ES2015) */
2202
2203      scope_stack_reg_top++;
2204#if ENABLED (JERRY_ES2015)
2205      switch (type)
2206      {
2207        case SCANNER_STREAM_TYPE_CONST:
2208        {
2209          scope_stack_p->map_to |= PARSER_SCOPE_STACK_IS_CONST_REG;
2210          /* FALLTHRU */
2211        }
2212        case SCANNER_STREAM_TYPE_LET:
2213        case SCANNER_STREAM_TYPE_ARG:
2214        case SCANNER_STREAM_TYPE_ARG_VAR:
2215        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG:
2216        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR:
2217        case SCANNER_STREAM_TYPE_ARG_FUNC:
2218        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC:
2219        {
2220          scope_stack_p->map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY;
2221          break;
2222        }
2223      }
2224
2225      func_init_opcode = CBC_SET_VAR_FUNC;
2226#endif /* ENABLED (JERRY_ES2015) */
2227    }
2228    else
2229    {
2230      context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED;
2231      map_to = context_p->lit_object.index;
2232
2233#if ENABLED (JERRY_ES2015)
2234      uint16_t scope_stack_map_to = 0;
2235#else /* !ENABLED (JERRY_ES2015) */
2236      scope_stack_p->map_to = map_to;
2237#endif /* ENABLED (JERRY_ES2015) */
2238
2239      if (info_type == SCANNER_TYPE_FUNCTION)
2240      {
2241        context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
2242      }
2243
2244      switch (type)
2245      {
2246#if ENABLED (JERRY_ES2015)
2247        case SCANNER_STREAM_TYPE_LET:
2248        case SCANNER_STREAM_TYPE_CONST:
2249        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG:
2250        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR:
2251        case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC:
2252        {
2253          scope_stack_map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY;
2254
2255          if (!(data_p[0] & SCANNER_STREAM_EARLY_CREATE))
2256          {
2257            break;
2258          }
2259          scope_stack_map_to |= PARSER_SCOPE_STACK_IS_LOCAL_CREATED;
2260          /* FALLTHRU */
2261        }
2262        case SCANNER_STREAM_TYPE_LOCAL:
2263#endif /* ENABLED (JERRY_ES2015) */
2264        case SCANNER_STREAM_TYPE_VAR:
2265        {
2266#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2267          context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p);
2268#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2269
2270#if ENABLED (JERRY_ES2015)
2271          uint16_t opcode;
2272
2273          switch (type)
2274          {
2275            case SCANNER_STREAM_TYPE_LET:
2276            {
2277              opcode = CBC_CREATE_LET;
2278              break;
2279            }
2280            case SCANNER_STREAM_TYPE_CONST:
2281            {
2282              opcode = CBC_CREATE_CONST;
2283              break;
2284            }
2285            case SCANNER_STREAM_TYPE_VAR:
2286            {
2287              opcode = CBC_CREATE_VAR;
2288
2289              if (option_flags & SCANNER_CREATE_VARS_IS_SCRIPT)
2290              {
2291                opcode = CBC_CREATE_VAR_EVAL;
2292
2293                if (context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT)
2294                {
2295                  opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CREATE_VAR_EVAL);
2296                }
2297              }
2298              break;
2299            }
2300            default:
2301            {
2302              JERRY_ASSERT (type == SCANNER_STREAM_TYPE_LOCAL
2303                            || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG
2304                            || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR
2305                            || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC);
2306
2307              opcode = CBC_CREATE_LOCAL;
2308              break;
2309            }
2310          }
2311#else /* !ENABLED (JERRY_ES2015) */
2312          uint16_t opcode = ((option_flags & SCANNER_CREATE_VARS_IS_SCRIPT) ? CBC_CREATE_VAR_EVAL
2313                                                                            : CBC_CREATE_VAR);
2314#endif /* ENABLED (JERRY_ES2015) */
2315
2316          parser_emit_cbc_literal (context_p, opcode, map_to);
2317          break;
2318        }
2319        case SCANNER_STREAM_TYPE_ARG:
2320#if ENABLED (JERRY_ES2015)
2321        case SCANNER_STREAM_TYPE_ARG_VAR:
2322#endif /* ENABLED (JERRY_ES2015) */
2323        case SCANNER_STREAM_TYPE_ARG_FUNC:
2324        {
2325#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2326          context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p);
2327#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2328
2329#if ENABLED (JERRY_ES2015)
2330          scope_stack_map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY;
2331
2332          /* Argument initializers of functions with mapped arguments (e.g. function f(a,b,a) {}) are
2333           * generated here. The other initializers are handled by parser_parse_function_arguments(). */
2334          if (info_u8_arg & SCANNER_FUNCTION_MAPPED_ARGUMENTS)
2335          {
2336#endif /* ENABLED (JERRY_ES2015) */
2337            parser_emit_cbc_literal_value (context_p,
2338                                           CBC_INIT_ARG_OR_FUNC,
2339                                           (uint16_t) (PARSER_REGISTER_START + scope_stack_reg_top),
2340                                           map_to);
2341#if ENABLED (JERRY_ES2015)
2342          }
2343          else if (data_p[0] & SCANNER_STREAM_EARLY_CREATE)
2344          {
2345            parser_emit_cbc_literal (context_p, CBC_CREATE_LOCAL, map_to);
2346            scope_stack_map_to |= PARSER_SCOPE_STACK_IS_LOCAL_CREATED;
2347          }
2348#endif /* ENABLED (JERRY_ES2015) */
2349
2350          if (scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS)
2351          {
2352            scope_stack_reg_top++;
2353          }
2354          break;
2355        }
2356      }
2357
2358#if ENABLED (JERRY_ES2015)
2359      scope_stack_p->map_to = scope_stack_map_to;
2360#endif /* ENABLED (JERRY_ES2015) */
2361    }
2362
2363    scope_stack_p++;
2364
2365    if (!SCANNER_STREAM_TYPE_IS_FUNCTION (type))
2366    {
2367      continue;
2368    }
2369
2370    if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p))
2371    {
2372      JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK);
2373      parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED);
2374    }
2375
2376#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
2377    context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p);
2378#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
2379
2380    if (!SCANNER_STREAM_TYPE_IS_ARG_FUNC (type))
2381    {
2382      if (func_init_opcode == CBC_INIT_ARG_OR_FUNC && (option_flags & SCANNER_CREATE_VARS_IS_SCRIPT))
2383      {
2384#if ENABLED (JERRY_ES2015)
2385        literal.char_p -= data_p[1];
2386        if (!(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)
2387            || !scanner_scope_find_let_declaration (context_p, &literal))
2388        {
2389          func_init_opcode = CBC_CREATE_VAR_FUNC_EVAL;
2390
2391          if (context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT)
2392          {
2393            func_init_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CREATE_VAR_FUNC_EVAL);
2394          }
2395        }
2396        literal.char_p += data_p[1];
2397#else /* !ENABLED (JERRY_ES2015) */
2398        func_init_opcode = CBC_CREATE_VAR_FUNC_EVAL;
2399#endif /* ENABLED (JERRY_ES2015) */
2400      }
2401
2402      parser_emit_cbc_literal_value (context_p, func_init_opcode, context_p->literal_count, map_to);
2403    }
2404
2405    scope_stack_p->map_from = PARSER_SCOPE_STACK_FUNC;
2406    scope_stack_p->map_to = context_p->literal_count;
2407    scope_stack_p++;
2408
2409    scanner_create_unused_literal (context_p, 0);
2410  }
2411
2412  if (info_type == SCANNER_TYPE_FUNCTION
2413      && !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)
2414      && (info_u8_arg & SCANNER_FUNCTION_ARGUMENTS_NEEDED))
2415  {
2416    JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION);
2417
2418    if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p))
2419    {
2420      JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK);
2421      parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED);
2422    }
2423
2424    context_p->status_flags |= PARSER_ARGUMENTS_NEEDED | PARSER_LEXICAL_ENV_NEEDED;
2425
2426    lexer_construct_literal_object (context_p, &lexer_arguments_literal, lexer_arguments_literal.type);
2427
2428    scope_stack_p->map_from = context_p->lit_object.index;
2429#if ENABLED (JERRY_ES2015)
2430    scope_stack_p->map_to = 0;
2431#else /* !ENABLED (JERRY_ES2015) */
2432    scope_stack_p->map_to = context_p->lit_object.index;
2433#endif /* ENABLED (JERRY_ES2015) */
2434    scope_stack_p++;
2435  }
2436
2437  context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p);
2438  context_p->scope_stack_reg_top = (uint16_t) scope_stack_reg_top;
2439
2440#if ENABLED (JERRY_ES2015)
2441  if (info_type == SCANNER_TYPE_FUNCTION)
2442  {
2443    context_p->scope_stack_global_end = context_p->scope_stack_top;
2444  }
2445#endif /* ENABLED (JERRY_ES2015) */
2446
2447  if (context_p->register_count < scope_stack_reg_top)
2448  {
2449    context_p->register_count = (uint16_t) scope_stack_reg_top;
2450  }
2451
2452  if (!(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS))
2453  {
2454    scanner_release_next (context_p, (size_t) (next_data_p + 1 - ((const uint8_t *) info_p)));
2455  }
2456  parser_flush_cbc (context_p);
2457} /* scanner_create_variables */
2458
2459/**
2460 * Get location from context.
2461 */
2462inline void JERRY_ATTR_ALWAYS_INLINE
2463scanner_get_location (scanner_location_t *location_p, /**< location */
2464                      parser_context_t *context_p) /**< context */
2465{
2466  location_p->source_p = context_p->source_p;
2467  location_p->line = context_p->line;
2468  location_p->column = context_p->column;
2469} /* scanner_get_location */
2470
2471/**
2472 * Set context location.
2473 */
2474inline void JERRY_ATTR_ALWAYS_INLINE
2475scanner_set_location (parser_context_t *context_p, /**< context */
2476                      scanner_location_t *location_p) /**< location */
2477{
2478  context_p->source_p = location_p->source_p;
2479  context_p->line = location_p->line;
2480  context_p->column = location_p->column;
2481} /* scanner_set_location */
2482
2483/**
2484 * Get the real map_to value.
2485 */
2486inline uint16_t JERRY_ATTR_ALWAYS_INLINE
2487scanner_decode_map_to (parser_scope_stack_t *stack_item_p) /**< scope stack item */
2488{
2489  JERRY_ASSERT (stack_item_p->map_from != PARSER_SCOPE_STACK_FUNC);
2490
2491#if ENABLED (JERRY_ES2015)
2492  uint16_t value = (stack_item_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK);
2493  return (value == 0) ? stack_item_p->map_from : (uint16_t) (value + (PARSER_REGISTER_START - 1));
2494#else /* !ENABLED (JERRY_ES2015) */
2495  return stack_item_p->map_to;
2496#endif /* ENABLED (JERRY_ES2015) */
2497} /* scanner_decode_map_to */
2498
2499#if ENABLED (JERRY_ES2015)
2500
2501/**
2502 * Checks whether the literal is a const in the current scope.
2503 *
2504 * @return true if the literal is a const, false otherwise
2505 */
2506bool
2507scanner_literal_is_const_reg (parser_context_t *context_p, /**< context */
2508                              uint16_t literal_index) /**< literal index */
2509{
2510  if (literal_index < PARSER_REGISTER_START)
2511  {
2512    /* Re-assignment of non-register const bindings are detected elsewhere. */
2513    return false;
2514  }
2515
2516  parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top;
2517
2518  literal_index = (uint16_t) (literal_index - (PARSER_REGISTER_START - 1));
2519
2520  do
2521  {
2522    /* Registers must be found in the scope stack. */
2523    JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p);
2524    scope_stack_p--;
2525  }
2526  while (literal_index != (scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK));
2527
2528  return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_CONST_REG) != 0;
2529} /* scanner_literal_is_const_reg */
2530
2531/**
2532 * Checks whether the literal is created before.
2533 *
2534 * @return true if the literal is created before, false otherwise
2535 */
2536bool
2537scanner_literal_is_created (parser_context_t *context_p, /**< context */
2538                            uint16_t literal_index) /**< literal index */
2539{
2540  JERRY_ASSERT (literal_index < PARSER_REGISTER_START);
2541
2542  parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top;
2543
2544  do
2545  {
2546    /* These literals must be found in the scope stack. */
2547    JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p);
2548    scope_stack_p--;
2549  }
2550  while (literal_index != scope_stack_p->map_from);
2551
2552  JERRY_ASSERT ((scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK) == 0);
2553
2554  return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_LOCAL_CREATED) != 0;
2555} /* scanner_literal_is_created */
2556
2557#endif /* ENABLED (JERRY_ES2015) */
2558
2559/**
2560 * @}
2561 * @}
2562 * @}
2563 */
2564
2565#endif /* ENABLED (JERRY_PARSER) */
2566