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