1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-helpers.h" 17425bb815Sopenharmony_ci#include "jcontext.h" 18425bb815Sopenharmony_ci#include "js-parser-internal.h" 19425bb815Sopenharmony_ci#include "js-scanner-internal.h" 20425bb815Sopenharmony_ci#include "lit-char-helpers.h" 21425bb815Sopenharmony_ci 22425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER) 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_ci/** \addtogroup parser Parser 25425bb815Sopenharmony_ci * @{ 26425bb815Sopenharmony_ci * 27425bb815Sopenharmony_ci * \addtogroup jsparser JavaScript 28425bb815Sopenharmony_ci * @{ 29425bb815Sopenharmony_ci * 30425bb815Sopenharmony_ci * \addtogroup jsparser_scanner Scanner 31425bb815Sopenharmony_ci * @{ 32425bb815Sopenharmony_ci */ 33425bb815Sopenharmony_ci 34425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSER_MAXIMUM_NUMBER_OF_LITERALS + PARSER_MAXIMUM_NUMBER_OF_REGISTERS < PARSER_REGISTER_START, 35425bb815Sopenharmony_ci maximum_number_of_literals_plus_registers_must_be_less_than_register_start); 36425bb815Sopenharmony_ci 37425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 38425bb815Sopenharmony_ci 39425bb815Sopenharmony_ciJERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG & SCANNER_LITERAL_IS_LOCAL) == 0, 40425bb815Sopenharmony_ci is_arrow_arg_binding_flag_must_not_use_local_flags); 41425bb815Sopenharmony_ci 42425bb815Sopenharmony_ciJERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_LET & SCANNER_LITERAL_IS_LOCAL) != 0, 43425bb815Sopenharmony_ci is_let_flag_must_use_local_flags); 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ciJERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_CONST & SCANNER_LITERAL_IS_LOCAL) != 0, 46425bb815Sopenharmony_ci is_const_flag_must_use_local_flags); 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ciJERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_FUNC_DECLARATION & SCANNER_LITERAL_IS_LOCAL) != 0, 49425bb815Sopenharmony_ci is_func_declaration_flag_must_use_local_flags); 50425bb815Sopenharmony_ci 51425bb815Sopenharmony_ciJERRY_STATIC_ASSERT ((SCANNER_LITERAL_IS_DESTRUCTURED_ARG & SCANNER_LITERAL_IS_LOCAL) != 0, 52425bb815Sopenharmony_ci is_arg_binding_flag_must_use_local_flags); 53425bb815Sopenharmony_ci 54425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (SCANNER_LITERAL_IS_FUNC_DECLARATION != SCANNER_LITERAL_IS_DESTRUCTURED_ARG, 55425bb815Sopenharmony_ci is_func_declaration_must_be_different_from_is_arg_binding); 56425bb815Sopenharmony_ci 57425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSER_SCOPE_STACK_IS_CONST_REG == PARSER_SCOPE_STACK_IS_LOCAL_CREATED, 58425bb815Sopenharmony_ci scope_stack_is_const_reg_and_scope_stack_is_local_created_must_be_the_same); 59425bb815Sopenharmony_ci 60425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci/** 63425bb815Sopenharmony_ci * Raise a scanner error. 64425bb815Sopenharmony_ci */ 65425bb815Sopenharmony_civoid 66425bb815Sopenharmony_ciscanner_raise_error (parser_context_t *context_p) /**< context */ 67425bb815Sopenharmony_ci{ 68425bb815Sopenharmony_ci PARSER_THROW (context_p->try_buffer); 69425bb815Sopenharmony_ci /* Should never been reached. */ 70425bb815Sopenharmony_ci JERRY_ASSERT (0); 71425bb815Sopenharmony_ci} /* scanner_raise_error */ 72425bb815Sopenharmony_ci 73425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 74425bb815Sopenharmony_ci 75425bb815Sopenharmony_ci/** 76425bb815Sopenharmony_ci * Raise a variable redeclaration error. 77425bb815Sopenharmony_ci */ 78425bb815Sopenharmony_civoid 79425bb815Sopenharmony_ciscanner_raise_redeclaration_error (parser_context_t *context_p) /**< context */ 80425bb815Sopenharmony_ci{ 81425bb815Sopenharmony_ci scanner_info_t *info_p = scanner_insert_info (context_p, context_p->source_p, sizeof (scanner_info_t)); 82425bb815Sopenharmony_ci info_p->type = SCANNER_TYPE_ERR_REDECLARED; 83425bb815Sopenharmony_ci 84425bb815Sopenharmony_ci scanner_raise_error (context_p); 85425bb815Sopenharmony_ci} /* scanner_raise_redeclaration_error */ 86425bb815Sopenharmony_ci 87425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 88425bb815Sopenharmony_ci 89425bb815Sopenharmony_ci/** 90425bb815Sopenharmony_ci * Allocate memory for scanner. 91425bb815Sopenharmony_ci * 92425bb815Sopenharmony_ci * @return allocated memory 93425bb815Sopenharmony_ci */ 94425bb815Sopenharmony_civoid * 95425bb815Sopenharmony_ciscanner_malloc (parser_context_t *context_p, /**< context */ 96425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 97425bb815Sopenharmony_ci{ 98425bb815Sopenharmony_ci void *result; 99425bb815Sopenharmony_ci 100425bb815Sopenharmony_ci JERRY_ASSERT (size > 0); 101425bb815Sopenharmony_ci result = jmem_heap_alloc_block_null_on_error (size); 102425bb815Sopenharmony_ci 103425bb815Sopenharmony_ci if (result == NULL) 104425bb815Sopenharmony_ci { 105425bb815Sopenharmony_ci scanner_cleanup (context_p); 106425bb815Sopenharmony_ci 107425bb815Sopenharmony_ci /* This is the only error which specify its reason. */ 108425bb815Sopenharmony_ci context_p->error = PARSER_ERR_OUT_OF_MEMORY; 109425bb815Sopenharmony_ci PARSER_THROW (context_p->try_buffer); 110425bb815Sopenharmony_ci } 111425bb815Sopenharmony_ci return result; 112425bb815Sopenharmony_ci} /* scanner_malloc */ 113425bb815Sopenharmony_ci 114425bb815Sopenharmony_ci/** 115425bb815Sopenharmony_ci * Free memory allocated by scanner_malloc. 116425bb815Sopenharmony_ci */ 117425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 118425bb815Sopenharmony_ciscanner_free (void *ptr, /**< pointer to free */ 119425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 120425bb815Sopenharmony_ci{ 121425bb815Sopenharmony_ci jmem_heap_free_block (ptr, size); 122425bb815Sopenharmony_ci} /* scanner_free */ 123425bb815Sopenharmony_ci 124425bb815Sopenharmony_ci/** 125425bb815Sopenharmony_ci * Count the size of a stream after an info block. 126425bb815Sopenharmony_ci * 127425bb815Sopenharmony_ci * @return the size in bytes 128425bb815Sopenharmony_ci */ 129425bb815Sopenharmony_cisize_t 130425bb815Sopenharmony_ciscanner_get_stream_size (scanner_info_t *info_p, /**< scanner info block */ 131425bb815Sopenharmony_ci size_t size) /**< size excluding the stream */ 132425bb815Sopenharmony_ci{ 133425bb815Sopenharmony_ci const uint8_t *data_p = ((const uint8_t *) info_p) + size; 134425bb815Sopenharmony_ci const uint8_t *data_p_start = data_p; 135425bb815Sopenharmony_ci 136425bb815Sopenharmony_ci while (data_p[0] != SCANNER_STREAM_TYPE_END) 137425bb815Sopenharmony_ci { 138425bb815Sopenharmony_ci switch (data_p[0] & SCANNER_STREAM_TYPE_MASK) 139425bb815Sopenharmony_ci { 140425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_VAR: 141425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 142425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LET: 143425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_CONST: 144425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LOCAL: 145425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 146425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 147425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_IMPORT: 148425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 149425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG: 150425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 151425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_VAR: 152425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG: 153425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR: 154425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 155425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_FUNC: 156425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 157425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC: 158425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 159425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_FUNC: 160425bb815Sopenharmony_ci { 161425bb815Sopenharmony_ci break; 162425bb815Sopenharmony_ci } 163425bb815Sopenharmony_ci default: 164425bb815Sopenharmony_ci { 165425bb815Sopenharmony_ci JERRY_ASSERT ((data_p[0] & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_HOLE); 166425bb815Sopenharmony_ci data_p++; 167425bb815Sopenharmony_ci continue; 168425bb815Sopenharmony_ci } 169425bb815Sopenharmony_ci } 170425bb815Sopenharmony_ci 171425bb815Sopenharmony_ci data_p += 3; 172425bb815Sopenharmony_ci 173425bb815Sopenharmony_ci if (data_p[-3] & SCANNER_STREAM_UINT16_DIFF) 174425bb815Sopenharmony_ci { 175425bb815Sopenharmony_ci data_p++; 176425bb815Sopenharmony_ci } 177425bb815Sopenharmony_ci else if (data_p[-1] == 0) 178425bb815Sopenharmony_ci { 179425bb815Sopenharmony_ci data_p += sizeof (const uint8_t *); 180425bb815Sopenharmony_ci } 181425bb815Sopenharmony_ci } 182425bb815Sopenharmony_ci 183425bb815Sopenharmony_ci return size + 1 + (size_t) (data_p - data_p_start); 184425bb815Sopenharmony_ci} /* scanner_get_stream_size */ 185425bb815Sopenharmony_ci 186425bb815Sopenharmony_ci/** 187425bb815Sopenharmony_ci * Insert a scanner info block into the scanner info chain. 188425bb815Sopenharmony_ci * 189425bb815Sopenharmony_ci * @return newly allocated scanner info 190425bb815Sopenharmony_ci */ 191425bb815Sopenharmony_ciscanner_info_t * 192425bb815Sopenharmony_ciscanner_insert_info (parser_context_t *context_p, /**< context */ 193425bb815Sopenharmony_ci const uint8_t *source_p, /**< triggering position */ 194425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 195425bb815Sopenharmony_ci{ 196425bb815Sopenharmony_ci scanner_info_t *new_scanner_info_p = (scanner_info_t *) scanner_malloc (context_p, size); 197425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = context_p->next_scanner_info_p; 198425bb815Sopenharmony_ci scanner_info_t *prev_scanner_info_p = NULL; 199425bb815Sopenharmony_ci 200425bb815Sopenharmony_ci JERRY_ASSERT (scanner_info_p != NULL); 201425bb815Sopenharmony_ci JERRY_ASSERT (source_p != NULL); 202425bb815Sopenharmony_ci 203425bb815Sopenharmony_ci new_scanner_info_p->source_p = source_p; 204425bb815Sopenharmony_ci 205425bb815Sopenharmony_ci while (source_p < scanner_info_p->source_p) 206425bb815Sopenharmony_ci { 207425bb815Sopenharmony_ci prev_scanner_info_p = scanner_info_p; 208425bb815Sopenharmony_ci scanner_info_p = scanner_info_p->next_p; 209425bb815Sopenharmony_ci 210425bb815Sopenharmony_ci JERRY_ASSERT (scanner_info_p != NULL); 211425bb815Sopenharmony_ci } 212425bb815Sopenharmony_ci 213425bb815Sopenharmony_ci /* Multiple scanner info blocks cannot be assigned to the same position. */ 214425bb815Sopenharmony_ci JERRY_ASSERT (source_p != scanner_info_p->source_p); 215425bb815Sopenharmony_ci 216425bb815Sopenharmony_ci new_scanner_info_p->next_p = scanner_info_p; 217425bb815Sopenharmony_ci 218425bb815Sopenharmony_ci if (JERRY_LIKELY (prev_scanner_info_p == NULL)) 219425bb815Sopenharmony_ci { 220425bb815Sopenharmony_ci context_p->next_scanner_info_p = new_scanner_info_p; 221425bb815Sopenharmony_ci } 222425bb815Sopenharmony_ci else 223425bb815Sopenharmony_ci { 224425bb815Sopenharmony_ci prev_scanner_info_p->next_p = new_scanner_info_p; 225425bb815Sopenharmony_ci } 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci return new_scanner_info_p; 228425bb815Sopenharmony_ci} /* scanner_insert_info */ 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci/** 231425bb815Sopenharmony_ci * Insert a scanner info block into the scanner info chain before a given info block. 232425bb815Sopenharmony_ci * 233425bb815Sopenharmony_ci * @return newly allocated scanner info 234425bb815Sopenharmony_ci */ 235425bb815Sopenharmony_ciscanner_info_t * 236425bb815Sopenharmony_ciscanner_insert_info_before (parser_context_t *context_p, /**< context */ 237425bb815Sopenharmony_ci const uint8_t *source_p, /**< triggering position */ 238425bb815Sopenharmony_ci scanner_info_t *start_info_p, /**< first info position */ 239425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 240425bb815Sopenharmony_ci{ 241425bb815Sopenharmony_ci JERRY_ASSERT (start_info_p != NULL); 242425bb815Sopenharmony_ci 243425bb815Sopenharmony_ci scanner_info_t *new_scanner_info_p = (scanner_info_t *) scanner_malloc (context_p, size); 244425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = start_info_p->next_p; 245425bb815Sopenharmony_ci scanner_info_t *prev_scanner_info_p = start_info_p; 246425bb815Sopenharmony_ci 247425bb815Sopenharmony_ci new_scanner_info_p->source_p = source_p; 248425bb815Sopenharmony_ci 249425bb815Sopenharmony_ci while (source_p < scanner_info_p->source_p) 250425bb815Sopenharmony_ci { 251425bb815Sopenharmony_ci prev_scanner_info_p = scanner_info_p; 252425bb815Sopenharmony_ci scanner_info_p = scanner_info_p->next_p; 253425bb815Sopenharmony_ci 254425bb815Sopenharmony_ci JERRY_ASSERT (scanner_info_p != NULL); 255425bb815Sopenharmony_ci } 256425bb815Sopenharmony_ci 257425bb815Sopenharmony_ci /* Multiple scanner info blocks cannot be assigned to the same position. */ 258425bb815Sopenharmony_ci JERRY_ASSERT (source_p != scanner_info_p->source_p); 259425bb815Sopenharmony_ci 260425bb815Sopenharmony_ci new_scanner_info_p->next_p = scanner_info_p; 261425bb815Sopenharmony_ci 262425bb815Sopenharmony_ci prev_scanner_info_p->next_p = new_scanner_info_p; 263425bb815Sopenharmony_ci return new_scanner_info_p; 264425bb815Sopenharmony_ci} /* scanner_insert_info_before */ 265425bb815Sopenharmony_ci 266425bb815Sopenharmony_ci/** 267425bb815Sopenharmony_ci * Release the next scanner info. 268425bb815Sopenharmony_ci */ 269425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 270425bb815Sopenharmony_ciscanner_release_next (parser_context_t *context_p, /**< context */ 271425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 272425bb815Sopenharmony_ci{ 273425bb815Sopenharmony_ci scanner_info_t *next_p = context_p->next_scanner_info_p->next_p; 274425bb815Sopenharmony_ci 275425bb815Sopenharmony_ci jmem_heap_free_block (context_p->next_scanner_info_p, size); 276425bb815Sopenharmony_ci context_p->next_scanner_info_p = next_p; 277425bb815Sopenharmony_ci} /* scanner_release_next */ 278425bb815Sopenharmony_ci 279425bb815Sopenharmony_ci/** 280425bb815Sopenharmony_ci * Set the active scanner info to the next scanner info. 281425bb815Sopenharmony_ci */ 282425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 283425bb815Sopenharmony_ciscanner_set_active (parser_context_t *context_p) /**< context */ 284425bb815Sopenharmony_ci{ 285425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = context_p->next_scanner_info_p; 286425bb815Sopenharmony_ci 287425bb815Sopenharmony_ci context_p->next_scanner_info_p = scanner_info_p->next_p; 288425bb815Sopenharmony_ci scanner_info_p->next_p = context_p->active_scanner_info_p; 289425bb815Sopenharmony_ci context_p->active_scanner_info_p = scanner_info_p; 290425bb815Sopenharmony_ci} /* scanner_set_active */ 291425bb815Sopenharmony_ci 292425bb815Sopenharmony_ci/** 293425bb815Sopenharmony_ci * Set the next scanner info to the active scanner info. 294425bb815Sopenharmony_ci */ 295425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 296425bb815Sopenharmony_ciscanner_revert_active (parser_context_t *context_p) /**< context */ 297425bb815Sopenharmony_ci{ 298425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = context_p->active_scanner_info_p; 299425bb815Sopenharmony_ci 300425bb815Sopenharmony_ci context_p->active_scanner_info_p = scanner_info_p->next_p; 301425bb815Sopenharmony_ci scanner_info_p->next_p = context_p->next_scanner_info_p; 302425bb815Sopenharmony_ci context_p->next_scanner_info_p = scanner_info_p; 303425bb815Sopenharmony_ci} /* scanner_revert_active */ 304425bb815Sopenharmony_ci 305425bb815Sopenharmony_ci/** 306425bb815Sopenharmony_ci * Release the active scanner info. 307425bb815Sopenharmony_ci */ 308425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 309425bb815Sopenharmony_ciscanner_release_active (parser_context_t *context_p, /**< context */ 310425bb815Sopenharmony_ci size_t size) /**< size of the memory block */ 311425bb815Sopenharmony_ci{ 312425bb815Sopenharmony_ci scanner_info_t *next_p = context_p->active_scanner_info_p->next_p; 313425bb815Sopenharmony_ci 314425bb815Sopenharmony_ci jmem_heap_free_block (context_p->active_scanner_info_p, size); 315425bb815Sopenharmony_ci context_p->active_scanner_info_p = next_p; 316425bb815Sopenharmony_ci} /* scanner_release_active */ 317425bb815Sopenharmony_ci 318425bb815Sopenharmony_ci/** 319425bb815Sopenharmony_ci * Release switch cases. 320425bb815Sopenharmony_ci */ 321425bb815Sopenharmony_civoid 322425bb815Sopenharmony_ciscanner_release_switch_cases (scanner_case_info_t *case_p) /**< case list */ 323425bb815Sopenharmony_ci{ 324425bb815Sopenharmony_ci while (case_p != NULL) 325425bb815Sopenharmony_ci { 326425bb815Sopenharmony_ci scanner_case_info_t *next_p = case_p->next_p; 327425bb815Sopenharmony_ci 328425bb815Sopenharmony_ci jmem_heap_free_block (case_p, sizeof (scanner_case_info_t)); 329425bb815Sopenharmony_ci case_p = next_p; 330425bb815Sopenharmony_ci } 331425bb815Sopenharmony_ci} /* scanner_release_switch_cases */ 332425bb815Sopenharmony_ci 333425bb815Sopenharmony_ci/** 334425bb815Sopenharmony_ci * Seek to correct position in the scanner info list. 335425bb815Sopenharmony_ci */ 336425bb815Sopenharmony_civoid 337425bb815Sopenharmony_ciscanner_seek (parser_context_t *context_p) /**< context */ 338425bb815Sopenharmony_ci{ 339425bb815Sopenharmony_ci const uint8_t *source_p = context_p->source_p; 340425bb815Sopenharmony_ci scanner_info_t *prev_p; 341425bb815Sopenharmony_ci 342425bb815Sopenharmony_ci if (context_p->skipped_scanner_info_p != NULL) 343425bb815Sopenharmony_ci { 344425bb815Sopenharmony_ci JERRY_ASSERT (context_p->skipped_scanner_info_p->source_p != NULL); 345425bb815Sopenharmony_ci 346425bb815Sopenharmony_ci context_p->skipped_scanner_info_end_p->next_p = context_p->next_scanner_info_p; 347425bb815Sopenharmony_ci 348425bb815Sopenharmony_ci if (context_p->skipped_scanner_info_end_p->source_p <= source_p) 349425bb815Sopenharmony_ci { 350425bb815Sopenharmony_ci prev_p = context_p->skipped_scanner_info_end_p; 351425bb815Sopenharmony_ci } 352425bb815Sopenharmony_ci else 353425bb815Sopenharmony_ci { 354425bb815Sopenharmony_ci prev_p = context_p->skipped_scanner_info_p; 355425bb815Sopenharmony_ci 356425bb815Sopenharmony_ci if (prev_p->source_p > source_p) 357425bb815Sopenharmony_ci { 358425bb815Sopenharmony_ci context_p->next_scanner_info_p = prev_p; 359425bb815Sopenharmony_ci context_p->skipped_scanner_info_p = NULL; 360425bb815Sopenharmony_ci return; 361425bb815Sopenharmony_ci } 362425bb815Sopenharmony_ci 363425bb815Sopenharmony_ci context_p->skipped_scanner_info_p = prev_p; 364425bb815Sopenharmony_ci } 365425bb815Sopenharmony_ci } 366425bb815Sopenharmony_ci else 367425bb815Sopenharmony_ci { 368425bb815Sopenharmony_ci prev_p = context_p->next_scanner_info_p; 369425bb815Sopenharmony_ci 370425bb815Sopenharmony_ci if (prev_p->source_p == NULL || prev_p->source_p > source_p) 371425bb815Sopenharmony_ci { 372425bb815Sopenharmony_ci return; 373425bb815Sopenharmony_ci } 374425bb815Sopenharmony_ci 375425bb815Sopenharmony_ci context_p->skipped_scanner_info_p = prev_p; 376425bb815Sopenharmony_ci } 377425bb815Sopenharmony_ci 378425bb815Sopenharmony_ci while (prev_p->next_p->source_p != NULL && prev_p->next_p->source_p <= source_p) 379425bb815Sopenharmony_ci { 380425bb815Sopenharmony_ci prev_p = prev_p->next_p; 381425bb815Sopenharmony_ci } 382425bb815Sopenharmony_ci 383425bb815Sopenharmony_ci context_p->skipped_scanner_info_end_p = prev_p; 384425bb815Sopenharmony_ci context_p->next_scanner_info_p = prev_p->next_p; 385425bb815Sopenharmony_ci} /* scanner_seek */ 386425bb815Sopenharmony_ci 387425bb815Sopenharmony_ci/** 388425bb815Sopenharmony_ci * Push a new literal pool. 389425bb815Sopenharmony_ci * 390425bb815Sopenharmony_ci * @return the newly created literal pool 391425bb815Sopenharmony_ci */ 392425bb815Sopenharmony_ciscanner_literal_pool_t * 393425bb815Sopenharmony_ciscanner_push_literal_pool (parser_context_t *context_p, /**< context */ 394425bb815Sopenharmony_ci scanner_context_t *scanner_context_p, /**< scanner context */ 395425bb815Sopenharmony_ci uint16_t status_flags) /**< combination of scanner_literal_pool_flags_t flags */ 396425bb815Sopenharmony_ci{ 397425bb815Sopenharmony_ci scanner_literal_pool_t *prev_literal_pool_p = scanner_context_p->active_literal_pool_p; 398425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p; 399425bb815Sopenharmony_ci 400425bb815Sopenharmony_ci literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t)); 401425bb815Sopenharmony_ci 402425bb815Sopenharmony_ci if (!(status_flags & SCANNER_LITERAL_POOL_FUNCTION)) 403425bb815Sopenharmony_ci { 404425bb815Sopenharmony_ci JERRY_ASSERT (prev_literal_pool_p != NULL); 405425bb815Sopenharmony_ci status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS; 406425bb815Sopenharmony_ci 407425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 408425bb815Sopenharmony_ci const uint16_t copied_flags = (SCANNER_LITERAL_POOL_IN_WITH 409425bb815Sopenharmony_ci | SCANNER_LITERAL_POOL_GENERATOR 410425bb815Sopenharmony_ci | SCANNER_LITERAL_POOL_ASYNC); 411425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 412425bb815Sopenharmony_ci const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH; 413425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 414425bb815Sopenharmony_ci 415425bb815Sopenharmony_ci status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags); 416425bb815Sopenharmony_ci } 417425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 418425bb815Sopenharmony_ci else 419425bb815Sopenharmony_ci { 420425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION); 421425bb815Sopenharmony_ci 422425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_GENERATOR) 423425bb815Sopenharmony_ci { 424425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION; 425425bb815Sopenharmony_ci } 426425bb815Sopenharmony_ci 427425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_ASYNC) 428425bb815Sopenharmony_ci { 429425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION; 430425bb815Sopenharmony_ci } 431425bb815Sopenharmony_ci } 432425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 433425bb815Sopenharmony_ci 434425bb815Sopenharmony_ci if (prev_literal_pool_p != NULL) 435425bb815Sopenharmony_ci { 436425bb815Sopenharmony_ci const uint16_t copied_flags = SCANNER_LITERAL_POOL_IS_STRICT; 437425bb815Sopenharmony_ci status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags); 438425bb815Sopenharmony_ci 439425bb815Sopenharmony_ci /* The logical value of these flags must be the same. */ 440425bb815Sopenharmony_ci JERRY_ASSERT (!(status_flags & SCANNER_LITERAL_POOL_IS_STRICT) == !(context_p->status_flags & PARSER_IS_STRICT)); 441425bb815Sopenharmony_ci } 442425bb815Sopenharmony_ci 443425bb815Sopenharmony_ci parser_list_init (&literal_pool_p->literal_pool, 444425bb815Sopenharmony_ci sizeof (lexer_lit_location_t), 445425bb815Sopenharmony_ci (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t))); 446425bb815Sopenharmony_ci literal_pool_p->source_p = NULL; 447425bb815Sopenharmony_ci literal_pool_p->status_flags = status_flags; 448425bb815Sopenharmony_ci literal_pool_p->no_declarations = 0; 449425bb815Sopenharmony_ci 450425bb815Sopenharmony_ci literal_pool_p->prev_p = prev_literal_pool_p; 451425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p = literal_pool_p; 452425bb815Sopenharmony_ci 453425bb815Sopenharmony_ci return literal_pool_p; 454425bb815Sopenharmony_ci} /* scanner_push_literal_pool */ 455425bb815Sopenharmony_ci 456425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSER_MAXIMUM_IDENT_LENGTH <= UINT8_MAX, 457425bb815Sopenharmony_ci maximum_ident_length_must_fit_in_a_byte); 458425bb815Sopenharmony_ci 459425bb815Sopenharmony_ci/** 460425bb815Sopenharmony_ci * Checks whether a literal is equal to "arguments". 461425bb815Sopenharmony_ci */ 462425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE 463425bb815Sopenharmony_ciscanner_literal_is_arguments (lexer_lit_location_t *literal_p) /**< literal */ 464425bb815Sopenharmony_ci{ 465425bb815Sopenharmony_ci return lexer_compare_identifier_to_string (literal_p, (const uint8_t *) "arguments", 9); 466425bb815Sopenharmony_ci} /* scanner_literal_is_arguments */ 467425bb815Sopenharmony_ci 468425bb815Sopenharmony_ci/** 469425bb815Sopenharmony_ci * Pop the last literal pool from the end. 470425bb815Sopenharmony_ci */ 471425bb815Sopenharmony_civoid 472425bb815Sopenharmony_ciscanner_pop_literal_pool (parser_context_t *context_p, /**< context */ 473425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 474425bb815Sopenharmony_ci{ 475425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; 476425bb815Sopenharmony_ci scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p; 477425bb815Sopenharmony_ci 478425bb815Sopenharmony_ci if (literal_pool_p->source_p == NULL) 479425bb815Sopenharmony_ci { 480425bb815Sopenharmony_ci JERRY_ASSERT (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_FUNCTION); 481425bb815Sopenharmony_ci JERRY_ASSERT (literal_pool_p->literal_pool.data.first_p == NULL 482425bb815Sopenharmony_ci && literal_pool_p->literal_pool.data.last_p == NULL); 483425bb815Sopenharmony_ci 484425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p; 485425bb815Sopenharmony_ci scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t)); 486425bb815Sopenharmony_ci return; 487425bb815Sopenharmony_ci } 488425bb815Sopenharmony_ci 489425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 490425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 491425bb815Sopenharmony_ci uint16_t status_flags = literal_pool_p->status_flags; 492425bb815Sopenharmony_ci bool arguments_required = ((status_flags & (SCANNER_LITERAL_POOL_CAN_EVAL | SCANNER_LITERAL_POOL_NO_ARGUMENTS)) 493425bb815Sopenharmony_ci == SCANNER_LITERAL_POOL_CAN_EVAL); 494425bb815Sopenharmony_ci 495425bb815Sopenharmony_ci uint8_t can_eval_types = 0; 496425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 497425bb815Sopenharmony_ci if (prev_literal_pool_p == NULL && !(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)) 498425bb815Sopenharmony_ci { 499425bb815Sopenharmony_ci can_eval_types |= SCANNER_LITERAL_IS_FUNC; 500425bb815Sopenharmony_ci } 501425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 502425bb815Sopenharmony_ci 503425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && prev_literal_pool_p != NULL) 504425bb815Sopenharmony_ci { 505425bb815Sopenharmony_ci prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL; 506425bb815Sopenharmony_ci } 507425bb815Sopenharmony_ci 508425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 509425bb815Sopenharmony_ci if (scanner_context_p->status_flags & SCANNER_CONTEXT_DEBUGGER_ENABLED) 510425bb815Sopenharmony_ci { 511425bb815Sopenharmony_ci /* When debugger is enabled, identifiers are not stored in registers. However, 512425bb815Sopenharmony_ci * this does not affect 'eval' detection, so 'arguments' object is not created. */ 513425bb815Sopenharmony_ci status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL; 514425bb815Sopenharmony_ci } 515425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 516425bb815Sopenharmony_ci 517425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 518425bb815Sopenharmony_ci 519425bb815Sopenharmony_ci const uint8_t *prev_source_p = literal_pool_p->source_p - 1; 520425bb815Sopenharmony_ci size_t compressed_size = 1; 521425bb815Sopenharmony_ci uint32_t no_declarations = literal_pool_p->no_declarations; 522425bb815Sopenharmony_ci 523425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 524425bb815Sopenharmony_ci { 525425bb815Sopenharmony_ci uint8_t type = literal_p->type; 526425bb815Sopenharmony_ci 527425bb815Sopenharmony_ci if (JERRY_UNLIKELY (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK)) 528425bb815Sopenharmony_ci { 529425bb815Sopenharmony_ci continue; 530425bb815Sopenharmony_ci } 531425bb815Sopenharmony_ci 532425bb815Sopenharmony_ci if (!(status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) && scanner_literal_is_arguments (literal_p)) 533425bb815Sopenharmony_ci { 534425bb815Sopenharmony_ci status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS; 535425bb815Sopenharmony_ci 536425bb815Sopenharmony_ci if (type & (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LOCAL)) 537425bb815Sopenharmony_ci { 538425bb815Sopenharmony_ci arguments_required = false; 539425bb815Sopenharmony_ci } 540425bb815Sopenharmony_ci else 541425bb815Sopenharmony_ci { 542425bb815Sopenharmony_ci literal_p->type = 0; 543425bb815Sopenharmony_ci arguments_required = true; 544425bb815Sopenharmony_ci continue; 545425bb815Sopenharmony_ci } 546425bb815Sopenharmony_ci } 547425bb815Sopenharmony_ci 548425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 549425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) 550425bb815Sopenharmony_ci && (type & (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION)) == SCANNER_LITERAL_IS_FUNC) 551425bb815Sopenharmony_ci { 552425bb815Sopenharmony_ci if (prev_literal_pool_p == NULL 553425bb815Sopenharmony_ci && (context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL) 554425bb815Sopenharmony_ci && scanner_scope_find_let_declaration (context_p, literal_p)) 555425bb815Sopenharmony_ci { 556425bb815Sopenharmony_ci literal_p->type = 0; 557425bb815Sopenharmony_ci continue; 558425bb815Sopenharmony_ci } 559425bb815Sopenharmony_ci 560425bb815Sopenharmony_ci if (!(type & SCANNER_LITERAL_IS_ARG)) 561425bb815Sopenharmony_ci { 562425bb815Sopenharmony_ci type |= SCANNER_LITERAL_IS_VAR; 563425bb815Sopenharmony_ci } 564425bb815Sopenharmony_ci 565425bb815Sopenharmony_ci type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC; 566425bb815Sopenharmony_ci literal_p->type = type; 567425bb815Sopenharmony_ci } 568425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 569425bb815Sopenharmony_ci 570425bb815Sopenharmony_ci if ((type & SCANNER_LITERAL_IS_LOCAL) 571425bb815Sopenharmony_ci || ((type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_ARG)) 572425bb815Sopenharmony_ci && (status_flags & SCANNER_LITERAL_POOL_FUNCTION))) 573425bb815Sopenharmony_ci { 574425bb815Sopenharmony_ci JERRY_ASSERT ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) 575425bb815Sopenharmony_ci || !(literal_p->type & SCANNER_LITERAL_IS_ARG)); 576425bb815Sopenharmony_ci 577425bb815Sopenharmony_ci if (literal_p->length == 0) 578425bb815Sopenharmony_ci { 579425bb815Sopenharmony_ci compressed_size += 1; 580425bb815Sopenharmony_ci continue; 581425bb815Sopenharmony_ci } 582425bb815Sopenharmony_ci 583425bb815Sopenharmony_ci no_declarations++; 584425bb815Sopenharmony_ci 585425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) || (type & can_eval_types)) 586425bb815Sopenharmony_ci { 587425bb815Sopenharmony_ci type |= SCANNER_LITERAL_NO_REG; 588425bb815Sopenharmony_ci literal_p->type = type; 589425bb815Sopenharmony_ci } 590425bb815Sopenharmony_ci 591425bb815Sopenharmony_ci if (type & SCANNER_LITERAL_IS_FUNC) 592425bb815Sopenharmony_ci { 593425bb815Sopenharmony_ci no_declarations++; 594425bb815Sopenharmony_ci 595425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 596425bb815Sopenharmony_ci if ((type & (SCANNER_LITERAL_IS_CONST | SCANNER_LITERAL_IS_ARG)) == SCANNER_LITERAL_IS_CONST) 597425bb815Sopenharmony_ci { 598425bb815Sopenharmony_ci JERRY_ASSERT (type & SCANNER_LITERAL_IS_LET); 599425bb815Sopenharmony_ci 600425bb815Sopenharmony_ci /* Catch parameters cannot be functions. */ 601425bb815Sopenharmony_ci literal_p->type = (uint8_t) (type & ~SCANNER_LITERAL_IS_FUNC); 602425bb815Sopenharmony_ci no_declarations--; 603425bb815Sopenharmony_ci } 604425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 605425bb815Sopenharmony_ci if (type & SCANNER_LITERAL_IS_LOCAL) 606425bb815Sopenharmony_ci { 607425bb815Sopenharmony_ci /* Catch parameters cannot be functions. */ 608425bb815Sopenharmony_ci literal_p->type = (uint8_t) (type & ~SCANNER_LITERAL_IS_FUNC); 609425bb815Sopenharmony_ci no_declarations--; 610425bb815Sopenharmony_ci } 611425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 612425bb815Sopenharmony_ci } 613425bb815Sopenharmony_ci 614425bb815Sopenharmony_ci intptr_t diff = (intptr_t) (literal_p->char_p - prev_source_p); 615425bb815Sopenharmony_ci 616425bb815Sopenharmony_ci if (diff >= 1 && diff <= UINT8_MAX) 617425bb815Sopenharmony_ci { 618425bb815Sopenharmony_ci compressed_size += 2 + 1; 619425bb815Sopenharmony_ci } 620425bb815Sopenharmony_ci else if (diff >= -UINT8_MAX && diff <= UINT16_MAX) 621425bb815Sopenharmony_ci { 622425bb815Sopenharmony_ci compressed_size += 2 + 2; 623425bb815Sopenharmony_ci } 624425bb815Sopenharmony_ci else 625425bb815Sopenharmony_ci { 626425bb815Sopenharmony_ci compressed_size += 2 + 1 + sizeof (const uint8_t *); 627425bb815Sopenharmony_ci } 628425bb815Sopenharmony_ci 629425bb815Sopenharmony_ci prev_source_p = literal_p->char_p + literal_p->length; 630425bb815Sopenharmony_ci 631425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) 632425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 633425bb815Sopenharmony_ci || ((type & SCANNER_LITERAL_IS_FUNC) && (status_flags & SCANNER_LITERAL_POOL_IS_STRICT)) 634425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 635425bb815Sopenharmony_ci || !(type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC))) 636425bb815Sopenharmony_ci { 637425bb815Sopenharmony_ci continue; 638425bb815Sopenharmony_ci } 639425bb815Sopenharmony_ci } 640425bb815Sopenharmony_ci 641425bb815Sopenharmony_ci if (prev_literal_pool_p != NULL && literal_p->length > 0) 642425bb815Sopenharmony_ci { 643425bb815Sopenharmony_ci /* Propagate literal to upper level. */ 644425bb815Sopenharmony_ci lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p, 645425bb815Sopenharmony_ci prev_literal_pool_p, 646425bb815Sopenharmony_ci literal_p); 647425bb815Sopenharmony_ci uint8_t extended_type = literal_location_p->type; 648425bb815Sopenharmony_ci 649425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) || (type & SCANNER_LITERAL_NO_REG)) 650425bb815Sopenharmony_ci { 651425bb815Sopenharmony_ci extended_type |= SCANNER_LITERAL_NO_REG; 652425bb815Sopenharmony_ci } 653425bb815Sopenharmony_ci 654425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 655425bb815Sopenharmony_ci extended_type |= SCANNER_LITERAL_IS_USED; 656425bb815Sopenharmony_ci 657425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_FUNCTION_STATEMENT) 658425bb815Sopenharmony_ci { 659425bb815Sopenharmony_ci extended_type |= SCANNER_LITERAL_EARLY_CREATE; 660425bb815Sopenharmony_ci } 661425bb815Sopenharmony_ci 662425bb815Sopenharmony_ci const uint8_t mask = (SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_LOCAL); 663425bb815Sopenharmony_ci 664425bb815Sopenharmony_ci if ((type & SCANNER_LITERAL_IS_ARG) 665425bb815Sopenharmony_ci || (literal_location_p->type & mask) == SCANNER_LITERAL_IS_LET 666425bb815Sopenharmony_ci || (literal_location_p->type & mask) == SCANNER_LITERAL_IS_CONST) 667425bb815Sopenharmony_ci { 668425bb815Sopenharmony_ci /* Clears the SCANNER_LITERAL_IS_VAR and SCANNER_LITERAL_IS_FUNC flags 669425bb815Sopenharmony_ci * for speculative arrow parameters and local (non-var) functions. */ 670425bb815Sopenharmony_ci type = 0; 671425bb815Sopenharmony_ci } 672425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 673425bb815Sopenharmony_ci 674425bb815Sopenharmony_ci type = (uint8_t) (type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC)); 675425bb815Sopenharmony_ci JERRY_ASSERT (type == 0 || !(status_flags & SCANNER_LITERAL_POOL_FUNCTION)); 676425bb815Sopenharmony_ci 677425bb815Sopenharmony_ci literal_location_p->type = (uint8_t) (extended_type | type); 678425bb815Sopenharmony_ci } 679425bb815Sopenharmony_ci } 680425bb815Sopenharmony_ci 681425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) || (compressed_size > 1)) 682425bb815Sopenharmony_ci { 683425bb815Sopenharmony_ci compressed_size += sizeof (scanner_info_t); 684425bb815Sopenharmony_ci 685425bb815Sopenharmony_ci scanner_info_t *info_p; 686425bb815Sopenharmony_ci 687425bb815Sopenharmony_ci if (prev_literal_pool_p != NULL || scanner_context_p->end_arguments_p == NULL) 688425bb815Sopenharmony_ci { 689425bb815Sopenharmony_ci info_p = scanner_insert_info (context_p, literal_pool_p->source_p, compressed_size); 690425bb815Sopenharmony_ci } 691425bb815Sopenharmony_ci else 692425bb815Sopenharmony_ci { 693425bb815Sopenharmony_ci scanner_info_t *start_info_p = scanner_context_p->end_arguments_p; 694425bb815Sopenharmony_ci info_p = scanner_insert_info_before (context_p, literal_pool_p->source_p, start_info_p, compressed_size); 695425bb815Sopenharmony_ci } 696425bb815Sopenharmony_ci 697425bb815Sopenharmony_ci if (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK) 698425bb815Sopenharmony_ci { 699425bb815Sopenharmony_ci no_declarations = PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK; 700425bb815Sopenharmony_ci } 701425bb815Sopenharmony_ci 702425bb815Sopenharmony_ci uint8_t *data_p = (uint8_t *) (info_p + 1); 703425bb815Sopenharmony_ci 704425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_FUNCTION) 705425bb815Sopenharmony_ci { 706425bb815Sopenharmony_ci info_p->type = SCANNER_TYPE_FUNCTION; 707425bb815Sopenharmony_ci 708425bb815Sopenharmony_ci uint8_t u8_arg = 0; 709425bb815Sopenharmony_ci 710425bb815Sopenharmony_ci if (arguments_required) 711425bb815Sopenharmony_ci { 712425bb815Sopenharmony_ci u8_arg |= SCANNER_FUNCTION_ARGUMENTS_NEEDED; 713425bb815Sopenharmony_ci 714425bb815Sopenharmony_ci if (no_declarations < PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK) 715425bb815Sopenharmony_ci { 716425bb815Sopenharmony_ci no_declarations++; 717425bb815Sopenharmony_ci } 718425bb815Sopenharmony_ci 719425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 720425bb815Sopenharmony_ci const uint16_t is_unmapped = SCANNER_LITERAL_POOL_IS_STRICT | SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED; 721425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 722425bb815Sopenharmony_ci const uint16_t is_unmapped = SCANNER_LITERAL_POOL_IS_STRICT; 723425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 724425bb815Sopenharmony_ci 725425bb815Sopenharmony_ci if (status_flags & is_unmapped) 726425bb815Sopenharmony_ci { 727425bb815Sopenharmony_ci arguments_required = false; 728425bb815Sopenharmony_ci } 729425bb815Sopenharmony_ci else 730425bb815Sopenharmony_ci { 731425bb815Sopenharmony_ci u8_arg |= SCANNER_FUNCTION_MAPPED_ARGUMENTS; 732425bb815Sopenharmony_ci } 733425bb815Sopenharmony_ci } 734425bb815Sopenharmony_ci 735425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 736425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_ASYNC) 737425bb815Sopenharmony_ci { 738425bb815Sopenharmony_ci u8_arg |= SCANNER_FUNCTION_ASYNC; 739425bb815Sopenharmony_ci 740425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_FUNCTION_STATEMENT) 741425bb815Sopenharmony_ci { 742425bb815Sopenharmony_ci u8_arg |= SCANNER_FUNCTION_STATEMENT; 743425bb815Sopenharmony_ci } 744425bb815Sopenharmony_ci } 745425bb815Sopenharmony_ci 746425bb815Sopenharmony_ci if (status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) 747425bb815Sopenharmony_ci { 748425bb815Sopenharmony_ci u8_arg |= SCANNER_FUNCTION_LEXICAL_ENV_NEEDED; 749425bb815Sopenharmony_ci } 750425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 751425bb815Sopenharmony_ci 752425bb815Sopenharmony_ci info_p->u8_arg = u8_arg; 753425bb815Sopenharmony_ci info_p->u16_arg = (uint16_t) no_declarations; 754425bb815Sopenharmony_ci } 755425bb815Sopenharmony_ci else 756425bb815Sopenharmony_ci { 757425bb815Sopenharmony_ci info_p->type = SCANNER_TYPE_BLOCK; 758425bb815Sopenharmony_ci 759425bb815Sopenharmony_ci JERRY_ASSERT (prev_literal_pool_p != NULL); 760425bb815Sopenharmony_ci } 761425bb815Sopenharmony_ci 762425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 763425bb815Sopenharmony_ci prev_source_p = literal_pool_p->source_p - 1; 764425bb815Sopenharmony_ci no_declarations = literal_pool_p->no_declarations; 765425bb815Sopenharmony_ci 766425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 767425bb815Sopenharmony_ci { 768425bb815Sopenharmony_ci if (JERRY_UNLIKELY (no_declarations > PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK) 769425bb815Sopenharmony_ci || (!(literal_p->type & SCANNER_LITERAL_IS_LOCAL) 770425bb815Sopenharmony_ci && (!(literal_p->type & (SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_ARG)) 771425bb815Sopenharmony_ci || !(status_flags & SCANNER_LITERAL_POOL_FUNCTION)))) 772425bb815Sopenharmony_ci { 773425bb815Sopenharmony_ci continue; 774425bb815Sopenharmony_ci } 775425bb815Sopenharmony_ci 776425bb815Sopenharmony_ci if (literal_p->length == 0) 777425bb815Sopenharmony_ci { 778425bb815Sopenharmony_ci *data_p++ = SCANNER_STREAM_TYPE_HOLE; 779425bb815Sopenharmony_ci continue; 780425bb815Sopenharmony_ci } 781425bb815Sopenharmony_ci 782425bb815Sopenharmony_ci no_declarations++; 783425bb815Sopenharmony_ci 784425bb815Sopenharmony_ci uint8_t type = SCANNER_STREAM_TYPE_VAR; 785425bb815Sopenharmony_ci 786425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_FUNC) 787425bb815Sopenharmony_ci { 788425bb815Sopenharmony_ci no_declarations++; 789425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_FUNC; 790425bb815Sopenharmony_ci 791425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_ARG) 792425bb815Sopenharmony_ci { 793425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_ARG_FUNC; 794425bb815Sopenharmony_ci 795425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 796425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG) 797425bb815Sopenharmony_ci { 798425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC; 799425bb815Sopenharmony_ci } 800425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 801425bb815Sopenharmony_ci } 802425bb815Sopenharmony_ci } 803425bb815Sopenharmony_ci else if (literal_p->type & SCANNER_LITERAL_IS_ARG) 804425bb815Sopenharmony_ci { 805425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_ARG; 806425bb815Sopenharmony_ci 807425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 808425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG) 809425bb815Sopenharmony_ci { 810425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_DESTRUCTURED_ARG; 811425bb815Sopenharmony_ci } 812425bb815Sopenharmony_ci 813425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_VAR) 814425bb815Sopenharmony_ci { 815425bb815Sopenharmony_ci type = (uint8_t) (type + 1); 816425bb815Sopenharmony_ci 817425bb815Sopenharmony_ci JERRY_ASSERT (type == SCANNER_STREAM_TYPE_ARG_VAR 818425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR); 819425bb815Sopenharmony_ci } 820425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 821425bb815Sopenharmony_ci } 822425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 823425bb815Sopenharmony_ci else if (literal_p->type & SCANNER_LITERAL_IS_LET) 824425bb815Sopenharmony_ci { 825425bb815Sopenharmony_ci if (!(literal_p->type & SCANNER_LITERAL_IS_CONST)) 826425bb815Sopenharmony_ci { 827425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_LET; 828425bb815Sopenharmony_ci 829425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && (literal_p->type & SCANNER_LITERAL_NO_REG)) 830425bb815Sopenharmony_ci { 831425bb815Sopenharmony_ci literal_p->type |= SCANNER_LITERAL_EARLY_CREATE; 832425bb815Sopenharmony_ci } 833425bb815Sopenharmony_ci } 834425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 835425bb815Sopenharmony_ci else if (prev_literal_pool_p == NULL) 836425bb815Sopenharmony_ci { 837425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_IMPORT; 838425bb815Sopenharmony_ci } 839425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 840425bb815Sopenharmony_ci else 841425bb815Sopenharmony_ci { 842425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_LOCAL; 843425bb815Sopenharmony_ci } 844425bb815Sopenharmony_ci } 845425bb815Sopenharmony_ci else if (literal_p->type & SCANNER_LITERAL_IS_CONST) 846425bb815Sopenharmony_ci { 847425bb815Sopenharmony_ci type = SCANNER_STREAM_TYPE_CONST; 848425bb815Sopenharmony_ci 849425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) && (literal_p->type & SCANNER_LITERAL_NO_REG)) 850425bb815Sopenharmony_ci { 851425bb815Sopenharmony_ci literal_p->type |= SCANNER_LITERAL_EARLY_CREATE; 852425bb815Sopenharmony_ci } 853425bb815Sopenharmony_ci } 854425bb815Sopenharmony_ci 855425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_EARLY_CREATE) 856425bb815Sopenharmony_ci { 857425bb815Sopenharmony_ci type |= SCANNER_STREAM_NO_REG | SCANNER_STREAM_EARLY_CREATE; 858425bb815Sopenharmony_ci } 859425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 860425bb815Sopenharmony_ci 861425bb815Sopenharmony_ci if (literal_p->has_escape) 862425bb815Sopenharmony_ci { 863425bb815Sopenharmony_ci type |= SCANNER_STREAM_HAS_ESCAPE; 864425bb815Sopenharmony_ci } 865425bb815Sopenharmony_ci 866425bb815Sopenharmony_ci if ((literal_p->type & SCANNER_LITERAL_NO_REG) 867425bb815Sopenharmony_ci || (arguments_required && (literal_p->type & SCANNER_LITERAL_IS_ARG))) 868425bb815Sopenharmony_ci { 869425bb815Sopenharmony_ci type |= SCANNER_STREAM_NO_REG; 870425bb815Sopenharmony_ci } 871425bb815Sopenharmony_ci 872425bb815Sopenharmony_ci data_p[0] = type; 873425bb815Sopenharmony_ci data_p[1] = (uint8_t) literal_p->length; 874425bb815Sopenharmony_ci data_p += 3; 875425bb815Sopenharmony_ci 876425bb815Sopenharmony_ci intptr_t diff = (intptr_t) (literal_p->char_p - prev_source_p); 877425bb815Sopenharmony_ci 878425bb815Sopenharmony_ci if (diff >= 1 && diff <= UINT8_MAX) 879425bb815Sopenharmony_ci { 880425bb815Sopenharmony_ci data_p[-1] = (uint8_t) diff; 881425bb815Sopenharmony_ci } 882425bb815Sopenharmony_ci else if (diff >= -UINT8_MAX && diff <= UINT16_MAX) 883425bb815Sopenharmony_ci { 884425bb815Sopenharmony_ci if (diff < 0) 885425bb815Sopenharmony_ci { 886425bb815Sopenharmony_ci diff = -diff; 887425bb815Sopenharmony_ci } 888425bb815Sopenharmony_ci 889425bb815Sopenharmony_ci data_p[-3] |= SCANNER_STREAM_UINT16_DIFF; 890425bb815Sopenharmony_ci data_p[-1] = (uint8_t) diff; 891425bb815Sopenharmony_ci data_p[0] = (uint8_t) (diff >> 8); 892425bb815Sopenharmony_ci data_p += 1; 893425bb815Sopenharmony_ci } 894425bb815Sopenharmony_ci else 895425bb815Sopenharmony_ci { 896425bb815Sopenharmony_ci data_p[-1] = 0; 897425bb815Sopenharmony_ci memcpy (data_p, &literal_p->char_p, sizeof (const uint8_t *)); 898425bb815Sopenharmony_ci data_p += sizeof (const uint8_t *); 899425bb815Sopenharmony_ci } 900425bb815Sopenharmony_ci 901425bb815Sopenharmony_ci prev_source_p = literal_p->char_p + literal_p->length; 902425bb815Sopenharmony_ci } 903425bb815Sopenharmony_ci 904425bb815Sopenharmony_ci data_p[0] = SCANNER_STREAM_TYPE_END; 905425bb815Sopenharmony_ci 906425bb815Sopenharmony_ci JERRY_ASSERT (((uint8_t *) info_p) + compressed_size == data_p + 1); 907425bb815Sopenharmony_ci } 908425bb815Sopenharmony_ci 909425bb815Sopenharmony_ci if (!(status_flags & SCANNER_LITERAL_POOL_FUNCTION) 910425bb815Sopenharmony_ci && prev_literal_pool_p->no_declarations < no_declarations) 911425bb815Sopenharmony_ci { 912425bb815Sopenharmony_ci prev_literal_pool_p->no_declarations = (uint16_t) no_declarations; 913425bb815Sopenharmony_ci } 914425bb815Sopenharmony_ci 915425bb815Sopenharmony_ci if ((status_flags & SCANNER_LITERAL_POOL_FUNCTION) && prev_literal_pool_p != NULL) 916425bb815Sopenharmony_ci { 917425bb815Sopenharmony_ci if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IS_STRICT) 918425bb815Sopenharmony_ci { 919425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_STRICT; 920425bb815Sopenharmony_ci } 921425bb815Sopenharmony_ci else 922425bb815Sopenharmony_ci { 923425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT; 924425bb815Sopenharmony_ci } 925425bb815Sopenharmony_ci 926425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 927425bb815Sopenharmony_ci if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_GENERATOR) 928425bb815Sopenharmony_ci { 929425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION; 930425bb815Sopenharmony_ci } 931425bb815Sopenharmony_ci else 932425bb815Sopenharmony_ci { 933425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION; 934425bb815Sopenharmony_ci } 935425bb815Sopenharmony_ci 936425bb815Sopenharmony_ci if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_ASYNC) 937425bb815Sopenharmony_ci { 938425bb815Sopenharmony_ci context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION; 939425bb815Sopenharmony_ci } 940425bb815Sopenharmony_ci else 941425bb815Sopenharmony_ci { 942425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~PARSER_IS_ASYNC_FUNCTION; 943425bb815Sopenharmony_ci } 944425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 945425bb815Sopenharmony_ci } 946425bb815Sopenharmony_ci 947425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p; 948425bb815Sopenharmony_ci 949425bb815Sopenharmony_ci parser_list_free (&literal_pool_p->literal_pool); 950425bb815Sopenharmony_ci scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t)); 951425bb815Sopenharmony_ci} /* scanner_pop_literal_pool */ 952425bb815Sopenharmony_ci 953425bb815Sopenharmony_ci/** 954425bb815Sopenharmony_ci * Filter out the arguments from a literal pool. 955425bb815Sopenharmony_ci */ 956425bb815Sopenharmony_civoid 957425bb815Sopenharmony_ciscanner_filter_arguments (parser_context_t *context_p, /**< context */ 958425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 959425bb815Sopenharmony_ci{ 960425bb815Sopenharmony_ci /* Fast case: check whether all literals are arguments. */ 961425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; 962425bb815Sopenharmony_ci scanner_literal_pool_t *prev_literal_pool_p = literal_pool_p->prev_p; 963425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 964425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 965425bb815Sopenharmony_ci bool can_eval = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_CAN_EVAL) != 0; 966425bb815Sopenharmony_ci bool has_arguments = (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_NO_ARGUMENTS) == 0; 967425bb815Sopenharmony_ci 968425bb815Sopenharmony_ci if (can_eval && prev_literal_pool_p != NULL) 969425bb815Sopenharmony_ci { 970425bb815Sopenharmony_ci prev_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL; 971425bb815Sopenharmony_ci } 972425bb815Sopenharmony_ci 973425bb815Sopenharmony_ci literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_CAN_EVAL; 974425bb815Sopenharmony_ci 975425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 976425bb815Sopenharmony_ci 977425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 978425bb815Sopenharmony_ci { 979425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 980425bb815Sopenharmony_ci if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE)) 981425bb815Sopenharmony_ci { 982425bb815Sopenharmony_ci literal_p->type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE; 983425bb815Sopenharmony_ci } 984425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 985425bb815Sopenharmony_ci if (can_eval) 986425bb815Sopenharmony_ci { 987425bb815Sopenharmony_ci literal_p->type |= SCANNER_LITERAL_NO_REG; 988425bb815Sopenharmony_ci } 989425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 990425bb815Sopenharmony_ci 991425bb815Sopenharmony_ci uint8_t type = literal_p->type; 992425bb815Sopenharmony_ci 993425bb815Sopenharmony_ci if (!(type & SCANNER_LITERAL_IS_ARG) && !(has_arguments && scanner_literal_is_arguments (literal_p))) 994425bb815Sopenharmony_ci { 995425bb815Sopenharmony_ci break; 996425bb815Sopenharmony_ci } 997425bb815Sopenharmony_ci 998425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 999425bb815Sopenharmony_ci if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG)) 1000425bb815Sopenharmony_ci { 1001425bb815Sopenharmony_ci break; 1002425bb815Sopenharmony_ci } 1003425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1004425bb815Sopenharmony_ci } 1005425bb815Sopenharmony_ci 1006425bb815Sopenharmony_ci if (literal_p == NULL) 1007425bb815Sopenharmony_ci { 1008425bb815Sopenharmony_ci return; 1009425bb815Sopenharmony_ci } 1010425bb815Sopenharmony_ci 1011425bb815Sopenharmony_ci scanner_literal_pool_t *new_literal_pool_p; 1012425bb815Sopenharmony_ci 1013425bb815Sopenharmony_ci new_literal_pool_p = (scanner_literal_pool_t *) scanner_malloc (context_p, sizeof (scanner_literal_pool_t)); 1014425bb815Sopenharmony_ci 1015425bb815Sopenharmony_ci new_literal_pool_p->prev_p = literal_pool_p; 1016425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p = new_literal_pool_p; 1017425bb815Sopenharmony_ci 1018425bb815Sopenharmony_ci *new_literal_pool_p = *literal_pool_p; 1019425bb815Sopenharmony_ci parser_list_init (&new_literal_pool_p->literal_pool, 1020425bb815Sopenharmony_ci sizeof (lexer_lit_location_t), 1021425bb815Sopenharmony_ci (uint32_t) ((128 - sizeof (void *)) / sizeof (lexer_lit_location_t))); 1022425bb815Sopenharmony_ci 1023425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 1024425bb815Sopenharmony_ci 1025425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1026425bb815Sopenharmony_ci /* Destructured args are placed after the other arguments because of register assignments. */ 1027425bb815Sopenharmony_ci bool has_destructured_arg = false; 1028425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1029425bb815Sopenharmony_ci 1030425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1031425bb815Sopenharmony_ci { 1032425bb815Sopenharmony_ci uint8_t type = literal_p->type; 1033425bb815Sopenharmony_ci 1034425bb815Sopenharmony_ci if ((type & SCANNER_LITERAL_IS_ARG) || (has_arguments && scanner_literal_is_arguments (literal_p))) 1035425bb815Sopenharmony_ci { 1036425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1037425bb815Sopenharmony_ci if (can_eval || (literal_p->type & SCANNER_LITERAL_EARLY_CREATE)) 1038425bb815Sopenharmony_ci { 1039425bb815Sopenharmony_ci type |= SCANNER_LITERAL_NO_REG | SCANNER_LITERAL_EARLY_CREATE; 1040425bb815Sopenharmony_ci literal_p->type = type; 1041425bb815Sopenharmony_ci } 1042425bb815Sopenharmony_ci 1043425bb815Sopenharmony_ci if (type & (SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG)) 1044425bb815Sopenharmony_ci { 1045425bb815Sopenharmony_ci has_destructured_arg = true; 1046425bb815Sopenharmony_ci 1047425bb815Sopenharmony_ci if (type & SCANNER_LITERAL_IS_DESTRUCTURED_ARG) 1048425bb815Sopenharmony_ci { 1049425bb815Sopenharmony_ci continue; 1050425bb815Sopenharmony_ci } 1051425bb815Sopenharmony_ci 1052425bb815Sopenharmony_ci type &= (uint8_t) ~SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG; 1053425bb815Sopenharmony_ci type |= SCANNER_LITERAL_IS_DESTRUCTURED_ARG; 1054425bb815Sopenharmony_ci 1055425bb815Sopenharmony_ci literal_p->type = type; 1056425bb815Sopenharmony_ci continue; 1057425bb815Sopenharmony_ci } 1058425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1059425bb815Sopenharmony_ci if (can_eval) 1060425bb815Sopenharmony_ci { 1061425bb815Sopenharmony_ci literal_p->type |= SCANNER_LITERAL_NO_REG; 1062425bb815Sopenharmony_ci } 1063425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1064425bb815Sopenharmony_ci 1065425bb815Sopenharmony_ci lexer_lit_location_t *new_literal_p; 1066425bb815Sopenharmony_ci new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool); 1067425bb815Sopenharmony_ci *new_literal_p = *literal_p; 1068425bb815Sopenharmony_ci } 1069425bb815Sopenharmony_ci else if (prev_literal_pool_p != NULL) 1070425bb815Sopenharmony_ci { 1071425bb815Sopenharmony_ci /* Propagate literal to upper level. */ 1072425bb815Sopenharmony_ci lexer_lit_location_t *literal_location_p = scanner_add_custom_literal (context_p, 1073425bb815Sopenharmony_ci prev_literal_pool_p, 1074425bb815Sopenharmony_ci literal_p); 1075425bb815Sopenharmony_ci type |= SCANNER_LITERAL_NO_REG; 1076425bb815Sopenharmony_ci 1077425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1078425bb815Sopenharmony_ci type |= SCANNER_LITERAL_IS_USED; 1079425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1080425bb815Sopenharmony_ci 1081425bb815Sopenharmony_ci literal_location_p->type |= type; 1082425bb815Sopenharmony_ci } 1083425bb815Sopenharmony_ci } 1084425bb815Sopenharmony_ci 1085425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1086425bb815Sopenharmony_ci if (has_destructured_arg) 1087425bb815Sopenharmony_ci { 1088425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 1089425bb815Sopenharmony_ci 1090425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1091425bb815Sopenharmony_ci { 1092425bb815Sopenharmony_ci const uint8_t expected_flags = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG; 1093425bb815Sopenharmony_ci 1094425bb815Sopenharmony_ci if ((literal_p->type & expected_flags) == expected_flags) 1095425bb815Sopenharmony_ci { 1096425bb815Sopenharmony_ci lexer_lit_location_t *new_literal_p; 1097425bb815Sopenharmony_ci new_literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &new_literal_pool_p->literal_pool); 1098425bb815Sopenharmony_ci *new_literal_p = *literal_p; 1099425bb815Sopenharmony_ci } 1100425bb815Sopenharmony_ci } 1101425bb815Sopenharmony_ci } 1102425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1103425bb815Sopenharmony_ci 1104425bb815Sopenharmony_ci new_literal_pool_p->prev_p = prev_literal_pool_p; 1105425bb815Sopenharmony_ci 1106425bb815Sopenharmony_ci parser_list_free (&literal_pool_p->literal_pool); 1107425bb815Sopenharmony_ci scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t)); 1108425bb815Sopenharmony_ci} /* scanner_filter_arguments */ 1109425bb815Sopenharmony_ci 1110425bb815Sopenharmony_ci/** 1111425bb815Sopenharmony_ci * Add any literal to the specified literal pool. 1112425bb815Sopenharmony_ci * 1113425bb815Sopenharmony_ci * @return pointer to the literal 1114425bb815Sopenharmony_ci */ 1115425bb815Sopenharmony_cilexer_lit_location_t * 1116425bb815Sopenharmony_ciscanner_add_custom_literal (parser_context_t *context_p, /**< context */ 1117425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p, /**< literal pool */ 1118425bb815Sopenharmony_ci const lexer_lit_location_t *literal_location_p) /**< literal */ 1119425bb815Sopenharmony_ci{ 1120425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 1121425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 1122425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 1123425bb815Sopenharmony_ci 1124425bb815Sopenharmony_ci const uint8_t *char_p = literal_location_p->char_p; 1125425bb815Sopenharmony_ci prop_length_t length = literal_location_p->length; 1126425bb815Sopenharmony_ci 1127425bb815Sopenharmony_ci if (JERRY_LIKELY (!literal_location_p->has_escape)) 1128425bb815Sopenharmony_ci { 1129425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1130425bb815Sopenharmony_ci { 1131425bb815Sopenharmony_ci if (literal_p->length == length) 1132425bb815Sopenharmony_ci { 1133425bb815Sopenharmony_ci if (JERRY_LIKELY (!literal_p->has_escape)) 1134425bb815Sopenharmony_ci { 1135425bb815Sopenharmony_ci if (memcmp (literal_p->char_p, char_p, length) == 0) 1136425bb815Sopenharmony_ci { 1137425bb815Sopenharmony_ci return literal_p; 1138425bb815Sopenharmony_ci } 1139425bb815Sopenharmony_ci } 1140425bb815Sopenharmony_ci else if (lexer_compare_identifier_to_string (literal_p, char_p, length)) 1141425bb815Sopenharmony_ci { 1142425bb815Sopenharmony_ci /* The non-escaped version is preferred. */ 1143425bb815Sopenharmony_ci literal_p->char_p = char_p; 1144425bb815Sopenharmony_ci literal_p->has_escape = 0; 1145425bb815Sopenharmony_ci return literal_p; 1146425bb815Sopenharmony_ci } 1147425bb815Sopenharmony_ci } 1148425bb815Sopenharmony_ci } 1149425bb815Sopenharmony_ci } 1150425bb815Sopenharmony_ci else 1151425bb815Sopenharmony_ci { 1152425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1153425bb815Sopenharmony_ci { 1154425bb815Sopenharmony_ci if (lexer_compare_identifiers (context_p, literal_p, literal_location_p)) 1155425bb815Sopenharmony_ci { 1156425bb815Sopenharmony_ci return literal_p; 1157425bb815Sopenharmony_ci } 1158425bb815Sopenharmony_ci } 1159425bb815Sopenharmony_ci } 1160425bb815Sopenharmony_ci 1161425bb815Sopenharmony_ci literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool); 1162425bb815Sopenharmony_ci *literal_p = *literal_location_p; 1163425bb815Sopenharmony_ci 1164425bb815Sopenharmony_ci literal_p->type = 0; 1165425bb815Sopenharmony_ci 1166425bb815Sopenharmony_ci return literal_p; 1167425bb815Sopenharmony_ci} /* scanner_add_custom_literal */ 1168425bb815Sopenharmony_ci 1169425bb815Sopenharmony_ci/** 1170425bb815Sopenharmony_ci * Add the current literal token to the current literal pool. 1171425bb815Sopenharmony_ci * 1172425bb815Sopenharmony_ci * @return pointer to the literal 1173425bb815Sopenharmony_ci */ 1174425bb815Sopenharmony_ciinline lexer_lit_location_t * JERRY_ATTR_ALWAYS_INLINE 1175425bb815Sopenharmony_ciscanner_add_literal (parser_context_t *context_p, /**< context */ 1176425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 1177425bb815Sopenharmony_ci{ 1178425bb815Sopenharmony_ci return scanner_add_custom_literal (context_p, 1179425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p, 1180425bb815Sopenharmony_ci &context_p->token.lit_location); 1181425bb815Sopenharmony_ci} /* scanner_add_literal */ 1182425bb815Sopenharmony_ci 1183425bb815Sopenharmony_ci/** 1184425bb815Sopenharmony_ci * Add the current literal token to the current literal pool and 1185425bb815Sopenharmony_ci * set SCANNER_LITERAL_NO_REG if it is inside a with statement. 1186425bb815Sopenharmony_ci * 1187425bb815Sopenharmony_ci * @return pointer to the literal 1188425bb815Sopenharmony_ci */ 1189425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 1190425bb815Sopenharmony_ciscanner_add_reference (parser_context_t *context_p, /**< context */ 1191425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 1192425bb815Sopenharmony_ci{ 1193425bb815Sopenharmony_ci lexer_lit_location_t *lit_location_p = scanner_add_custom_literal (context_p, 1194425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p, 1195425bb815Sopenharmony_ci &context_p->token.lit_location); 1196425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1197425bb815Sopenharmony_ci lit_location_p->type |= SCANNER_LITERAL_IS_USED; 1198425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1199425bb815Sopenharmony_ci 1200425bb815Sopenharmony_ci if (scanner_context_p->active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH) 1201425bb815Sopenharmony_ci { 1202425bb815Sopenharmony_ci lit_location_p->type |= SCANNER_LITERAL_NO_REG; 1203425bb815Sopenharmony_ci } 1204425bb815Sopenharmony_ci 1205425bb815Sopenharmony_ci scanner_detect_eval_call (context_p, scanner_context_p); 1206425bb815Sopenharmony_ci} /* scanner_add_reference */ 1207425bb815Sopenharmony_ci 1208425bb815Sopenharmony_ci/** 1209425bb815Sopenharmony_ci * Append an argument to the literal pool. If the argument is already present, make it a "hole". 1210425bb815Sopenharmony_ci * 1211425bb815Sopenharmony_ci * @return newly created literal 1212425bb815Sopenharmony_ci */ 1213425bb815Sopenharmony_cilexer_lit_location_t * 1214425bb815Sopenharmony_ciscanner_append_argument (parser_context_t *context_p, /**< context */ 1215425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 1216425bb815Sopenharmony_ci{ 1217425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; 1218425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 1219425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 1220425bb815Sopenharmony_ci lexer_lit_location_t *literal_location_p = &context_p->token.lit_location; 1221425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 1222425bb815Sopenharmony_ci 1223425bb815Sopenharmony_ci const uint8_t *char_p = literal_location_p->char_p; 1224425bb815Sopenharmony_ci prop_length_t length = literal_location_p->length; 1225425bb815Sopenharmony_ci 1226425bb815Sopenharmony_ci if (JERRY_LIKELY (!context_p->token.lit_location.has_escape)) 1227425bb815Sopenharmony_ci { 1228425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1229425bb815Sopenharmony_ci { 1230425bb815Sopenharmony_ci if (literal_p->length == length) 1231425bb815Sopenharmony_ci { 1232425bb815Sopenharmony_ci if (JERRY_LIKELY (!literal_p->has_escape)) 1233425bb815Sopenharmony_ci { 1234425bb815Sopenharmony_ci if (memcmp (literal_p->char_p, char_p, length) == 0) 1235425bb815Sopenharmony_ci { 1236425bb815Sopenharmony_ci break; 1237425bb815Sopenharmony_ci } 1238425bb815Sopenharmony_ci } 1239425bb815Sopenharmony_ci else if (lexer_compare_identifier_to_string (literal_p, char_p, length)) 1240425bb815Sopenharmony_ci { 1241425bb815Sopenharmony_ci break; 1242425bb815Sopenharmony_ci } 1243425bb815Sopenharmony_ci } 1244425bb815Sopenharmony_ci } 1245425bb815Sopenharmony_ci } 1246425bb815Sopenharmony_ci else 1247425bb815Sopenharmony_ci { 1248425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1249425bb815Sopenharmony_ci { 1250425bb815Sopenharmony_ci if (lexer_compare_identifiers (context_p, literal_p, literal_location_p)) 1251425bb815Sopenharmony_ci { 1252425bb815Sopenharmony_ci break; 1253425bb815Sopenharmony_ci } 1254425bb815Sopenharmony_ci } 1255425bb815Sopenharmony_ci } 1256425bb815Sopenharmony_ci 1257425bb815Sopenharmony_ci uint8_t literal_type = SCANNER_LITERAL_IS_ARG; 1258425bb815Sopenharmony_ci 1259425bb815Sopenharmony_ci if (literal_p != NULL) 1260425bb815Sopenharmony_ci { 1261425bb815Sopenharmony_ci literal_p->length = 0; 1262425bb815Sopenharmony_ci 1263425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1264425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_USED) 1265425bb815Sopenharmony_ci { 1266425bb815Sopenharmony_ci literal_type = SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_EARLY_CREATE; 1267425bb815Sopenharmony_ci } 1268425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1269425bb815Sopenharmony_ci } 1270425bb815Sopenharmony_ci 1271425bb815Sopenharmony_ci literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool); 1272425bb815Sopenharmony_ci 1273425bb815Sopenharmony_ci *literal_p = context_p->token.lit_location; 1274425bb815Sopenharmony_ci literal_p->type = literal_type; 1275425bb815Sopenharmony_ci 1276425bb815Sopenharmony_ci return literal_p; 1277425bb815Sopenharmony_ci} /* scanner_append_argument */ 1278425bb815Sopenharmony_ci 1279425bb815Sopenharmony_ci/** 1280425bb815Sopenharmony_ci * Check whether an eval call is performed and update the status flags accordingly. 1281425bb815Sopenharmony_ci */ 1282425bb815Sopenharmony_civoid 1283425bb815Sopenharmony_ciscanner_detect_eval_call (parser_context_t *context_p, /**< context */ 1284425bb815Sopenharmony_ci scanner_context_t *scanner_context_p) /**< scanner context */ 1285425bb815Sopenharmony_ci{ 1286425bb815Sopenharmony_ci if (context_p->token.keyword_type == LEXER_KEYW_EVAL 1287425bb815Sopenharmony_ci && lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)) 1288425bb815Sopenharmony_ci { 1289425bb815Sopenharmony_ci scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CAN_EVAL; 1290425bb815Sopenharmony_ci } 1291425bb815Sopenharmony_ci} /* scanner_detect_eval_call */ 1292425bb815Sopenharmony_ci 1293425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1294425bb815Sopenharmony_ci 1295425bb815Sopenharmony_ci/** 1296425bb815Sopenharmony_ci * Find a let/const declaration of a given literal. 1297425bb815Sopenharmony_ci * 1298425bb815Sopenharmony_ci * @return true - if the literal is found, false - otherwise 1299425bb815Sopenharmony_ci */ 1300425bb815Sopenharmony_cibool 1301425bb815Sopenharmony_ciscanner_scope_find_let_declaration (parser_context_t *context_p, /**< context */ 1302425bb815Sopenharmony_ci lexer_lit_location_t *literal_p) /**< literal */ 1303425bb815Sopenharmony_ci{ 1304425bb815Sopenharmony_ci ecma_string_t *name_p; 1305425bb815Sopenharmony_ci 1306425bb815Sopenharmony_ci if (JERRY_LIKELY (!literal_p->has_escape)) 1307425bb815Sopenharmony_ci { 1308425bb815Sopenharmony_ci name_p = ecma_new_ecma_string_from_utf8 (literal_p->char_p, literal_p->length); 1309425bb815Sopenharmony_ci } 1310425bb815Sopenharmony_ci else 1311425bb815Sopenharmony_ci { 1312425bb815Sopenharmony_ci uint8_t *destination_p = (uint8_t *) scanner_malloc (context_p, literal_p->length); 1313425bb815Sopenharmony_ci 1314425bb815Sopenharmony_ci lexer_convert_ident_to_cesu8 (destination_p, literal_p->char_p, literal_p->length); 1315425bb815Sopenharmony_ci 1316425bb815Sopenharmony_ci name_p = ecma_new_ecma_string_from_utf8 (destination_p, literal_p->length); 1317425bb815Sopenharmony_ci scanner_free (destination_p, literal_p->length); 1318425bb815Sopenharmony_ci } 1319425bb815Sopenharmony_ci 1320425bb815Sopenharmony_ci ecma_object_t *lex_env_p = JERRY_CONTEXT (vm_top_context_p)->lex_env_p; 1321425bb815Sopenharmony_ci 1322425bb815Sopenharmony_ci while (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1323425bb815Sopenharmony_ci { 1324425bb815Sopenharmony_ci if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1325425bb815Sopenharmony_ci { 1326425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1327425bb815Sopenharmony_ci 1328425bb815Sopenharmony_ci if (property_p != NULL && ecma_is_property_enumerable (*property_p)) 1329425bb815Sopenharmony_ci { 1330425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 1331425bb815Sopenharmony_ci return true; 1332425bb815Sopenharmony_ci } 1333425bb815Sopenharmony_ci } 1334425bb815Sopenharmony_ci 1335425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 1336425bb815Sopenharmony_ci lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1337425bb815Sopenharmony_ci } 1338425bb815Sopenharmony_ci 1339425bb815Sopenharmony_ci if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1340425bb815Sopenharmony_ci { 1341425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1342425bb815Sopenharmony_ci 1343425bb815Sopenharmony_ci if (property_p != NULL && ecma_is_property_enumerable (*property_p)) 1344425bb815Sopenharmony_ci { 1345425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 1346425bb815Sopenharmony_ci return true; 1347425bb815Sopenharmony_ci } 1348425bb815Sopenharmony_ci } 1349425bb815Sopenharmony_ci 1350425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 1351425bb815Sopenharmony_ci return false; 1352425bb815Sopenharmony_ci} /* scanner_scope_find_let_declaration */ 1353425bb815Sopenharmony_ci 1354425bb815Sopenharmony_ci/** 1355425bb815Sopenharmony_ci * Throws an error for invalid var statements. 1356425bb815Sopenharmony_ci */ 1357425bb815Sopenharmony_civoid 1358425bb815Sopenharmony_ciscanner_detect_invalid_var (parser_context_t *context_p, /**< context */ 1359425bb815Sopenharmony_ci scanner_context_t *scanner_context_p, /**< scanner context */ 1360425bb815Sopenharmony_ci lexer_lit_location_t *var_literal_p) /**< var literal */ 1361425bb815Sopenharmony_ci{ 1362425bb815Sopenharmony_ci if (var_literal_p->type & SCANNER_LITERAL_IS_LOCAL 1363425bb815Sopenharmony_ci && !(var_literal_p->type & (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_ARG)) 1364425bb815Sopenharmony_ci && (var_literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL) 1365425bb815Sopenharmony_ci { 1366425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1367425bb815Sopenharmony_ci } 1368425bb815Sopenharmony_ci 1369425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; 1370425bb815Sopenharmony_ci const uint8_t *char_p = var_literal_p->char_p; 1371425bb815Sopenharmony_ci prop_length_t length = var_literal_p->length; 1372425bb815Sopenharmony_ci 1373425bb815Sopenharmony_ci while (!(literal_pool_p->status_flags & SCANNER_LITERAL_POOL_FUNCTION)) 1374425bb815Sopenharmony_ci { 1375425bb815Sopenharmony_ci literal_pool_p = literal_pool_p->prev_p; 1376425bb815Sopenharmony_ci 1377425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 1378425bb815Sopenharmony_ci parser_list_iterator_init (&literal_pool_p->literal_pool, &literal_iterator); 1379425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 1380425bb815Sopenharmony_ci 1381425bb815Sopenharmony_ci if (JERRY_LIKELY (!context_p->token.lit_location.has_escape)) 1382425bb815Sopenharmony_ci { 1383425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1384425bb815Sopenharmony_ci { 1385425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_LOCAL 1386425bb815Sopenharmony_ci && !(literal_p->type & SCANNER_LITERAL_IS_ARG) 1387425bb815Sopenharmony_ci && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL 1388425bb815Sopenharmony_ci && literal_p->length == length) 1389425bb815Sopenharmony_ci { 1390425bb815Sopenharmony_ci if (JERRY_LIKELY (!literal_p->has_escape)) 1391425bb815Sopenharmony_ci { 1392425bb815Sopenharmony_ci if (memcmp (literal_p->char_p, char_p, length) == 0) 1393425bb815Sopenharmony_ci { 1394425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1395425bb815Sopenharmony_ci return; 1396425bb815Sopenharmony_ci } 1397425bb815Sopenharmony_ci } 1398425bb815Sopenharmony_ci else if (lexer_compare_identifier_to_string (literal_p, char_p, length)) 1399425bb815Sopenharmony_ci { 1400425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1401425bb815Sopenharmony_ci return; 1402425bb815Sopenharmony_ci } 1403425bb815Sopenharmony_ci } 1404425bb815Sopenharmony_ci } 1405425bb815Sopenharmony_ci } 1406425bb815Sopenharmony_ci else 1407425bb815Sopenharmony_ci { 1408425bb815Sopenharmony_ci while ((literal_p = (lexer_lit_location_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 1409425bb815Sopenharmony_ci { 1410425bb815Sopenharmony_ci if (literal_p->type & SCANNER_LITERAL_IS_LOCAL 1411425bb815Sopenharmony_ci && !(literal_p->type & SCANNER_LITERAL_IS_ARG) 1412425bb815Sopenharmony_ci && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL 1413425bb815Sopenharmony_ci && lexer_compare_identifiers (context_p, literal_p, var_literal_p)) 1414425bb815Sopenharmony_ci { 1415425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1416425bb815Sopenharmony_ci return; 1417425bb815Sopenharmony_ci } 1418425bb815Sopenharmony_ci } 1419425bb815Sopenharmony_ci } 1420425bb815Sopenharmony_ci } 1421425bb815Sopenharmony_ci 1422425bb815Sopenharmony_ci if ((context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL) 1423425bb815Sopenharmony_ci && scanner_scope_find_let_declaration (context_p, var_literal_p)) 1424425bb815Sopenharmony_ci { 1425425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1426425bb815Sopenharmony_ci } 1427425bb815Sopenharmony_ci} /* scanner_detect_invalid_var */ 1428425bb815Sopenharmony_ci 1429425bb815Sopenharmony_ci/** 1430425bb815Sopenharmony_ci * Throws an error for invalid let statements. 1431425bb815Sopenharmony_ci */ 1432425bb815Sopenharmony_civoid 1433425bb815Sopenharmony_ciscanner_detect_invalid_let (parser_context_t *context_p, /**< context */ 1434425bb815Sopenharmony_ci lexer_lit_location_t *let_literal_p) /**< let literal */ 1435425bb815Sopenharmony_ci{ 1436425bb815Sopenharmony_ci if (let_literal_p->type & (SCANNER_LITERAL_IS_ARG 1437425bb815Sopenharmony_ci | SCANNER_LITERAL_IS_VAR 1438425bb815Sopenharmony_ci | SCANNER_LITERAL_IS_LOCAL)) 1439425bb815Sopenharmony_ci { 1440425bb815Sopenharmony_ci scanner_raise_redeclaration_error (context_p); 1441425bb815Sopenharmony_ci } 1442425bb815Sopenharmony_ci 1443425bb815Sopenharmony_ci if (let_literal_p->type & SCANNER_LITERAL_IS_FUNC) 1444425bb815Sopenharmony_ci { 1445425bb815Sopenharmony_ci let_literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC; 1446425bb815Sopenharmony_ci } 1447425bb815Sopenharmony_ci} /* scanner_detect_invalid_let */ 1448425bb815Sopenharmony_ci 1449425bb815Sopenharmony_ci/** 1450425bb815Sopenharmony_ci * Push the values required for class declaration parsing. 1451425bb815Sopenharmony_ci */ 1452425bb815Sopenharmony_civoid 1453425bb815Sopenharmony_ciscanner_push_class_declaration (parser_context_t *context_p, /**< context */ 1454425bb815Sopenharmony_ci scanner_context_t *scanner_context_p, /* scanner context */ 1455425bb815Sopenharmony_ci uint8_t stack_mode) /**< stack mode */ 1456425bb815Sopenharmony_ci{ 1457425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS); 1458425bb815Sopenharmony_ci 1459425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, stack_mode); 1460425bb815Sopenharmony_ci scanner_source_start_t source_start; 1461425bb815Sopenharmony_ci source_start.source_p = context_p->source_p; 1462425bb815Sopenharmony_ci 1463425bb815Sopenharmony_ci parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t)); 1464425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR); 1465425bb815Sopenharmony_ci scanner_context_p->mode = SCAN_MODE_CLASS_DECLARATION; 1466425bb815Sopenharmony_ci 1467425bb815Sopenharmony_ci lexer_next_token (context_p); 1468425bb815Sopenharmony_ci} /* scanner_push_class_declaration */ 1469425bb815Sopenharmony_ci 1470425bb815Sopenharmony_ci/** 1471425bb815Sopenharmony_ci * Push the values required for destructuring assignment or binding parsing. 1472425bb815Sopenharmony_ci */ 1473425bb815Sopenharmony_civoid 1474425bb815Sopenharmony_ciscanner_push_destructuring_pattern (parser_context_t *context_p, /**< context */ 1475425bb815Sopenharmony_ci scanner_context_t *scanner_context_p, /**< scanner context */ 1476425bb815Sopenharmony_ci uint8_t binding_type, /**< type of destructuring binding pattern */ 1477425bb815Sopenharmony_ci bool is_nested) /**< nested declaration */ 1478425bb815Sopenharmony_ci{ 1479425bb815Sopenharmony_ci JERRY_ASSERT (binding_type != SCANNER_BINDING_NONE || !is_nested); 1480425bb815Sopenharmony_ci 1481425bb815Sopenharmony_ci scanner_source_start_t source_start; 1482425bb815Sopenharmony_ci source_start.source_p = context_p->source_p; 1483425bb815Sopenharmony_ci 1484425bb815Sopenharmony_ci parser_stack_push (context_p, &source_start, sizeof (scanner_source_start_t)); 1485425bb815Sopenharmony_ci parser_stack_push_uint8 (context_p, scanner_context_p->binding_type); 1486425bb815Sopenharmony_ci scanner_context_p->binding_type = binding_type; 1487425bb815Sopenharmony_ci 1488425bb815Sopenharmony_ci if (SCANNER_NEEDS_BINDING_LIST (binding_type)) 1489425bb815Sopenharmony_ci { 1490425bb815Sopenharmony_ci scanner_binding_list_t *binding_list_p; 1491425bb815Sopenharmony_ci binding_list_p = (scanner_binding_list_t *) scanner_malloc (context_p, sizeof (scanner_binding_list_t)); 1492425bb815Sopenharmony_ci 1493425bb815Sopenharmony_ci binding_list_p->prev_p = scanner_context_p->active_binding_list_p; 1494425bb815Sopenharmony_ci binding_list_p->items_p = NULL; 1495425bb815Sopenharmony_ci binding_list_p->is_nested = is_nested; 1496425bb815Sopenharmony_ci 1497425bb815Sopenharmony_ci scanner_context_p->active_binding_list_p = binding_list_p; 1498425bb815Sopenharmony_ci } 1499425bb815Sopenharmony_ci} /* scanner_push_destructuring_pattern */ 1500425bb815Sopenharmony_ci 1501425bb815Sopenharmony_ci/** 1502425bb815Sopenharmony_ci * Pop binding list. 1503425bb815Sopenharmony_ci */ 1504425bb815Sopenharmony_civoid 1505425bb815Sopenharmony_ciscanner_pop_binding_list (scanner_context_t *scanner_context_p) /**< scanner context */ 1506425bb815Sopenharmony_ci{ 1507425bb815Sopenharmony_ci scanner_binding_list_t *binding_list_p = scanner_context_p->active_binding_list_p; 1508425bb815Sopenharmony_ci scanner_binding_item_t *item_p = binding_list_p->items_p; 1509425bb815Sopenharmony_ci scanner_binding_list_t *prev_binding_list_p = binding_list_p->prev_p; 1510425bb815Sopenharmony_ci bool is_nested = binding_list_p->is_nested; 1511425bb815Sopenharmony_ci 1512425bb815Sopenharmony_ci scanner_free (binding_list_p, sizeof (scanner_binding_list_t)); 1513425bb815Sopenharmony_ci scanner_context_p->active_binding_list_p = prev_binding_list_p; 1514425bb815Sopenharmony_ci 1515425bb815Sopenharmony_ci JERRY_ASSERT (binding_list_p != NULL); 1516425bb815Sopenharmony_ci 1517425bb815Sopenharmony_ci if (!is_nested) 1518425bb815Sopenharmony_ci { 1519425bb815Sopenharmony_ci while (item_p != NULL) 1520425bb815Sopenharmony_ci { 1521425bb815Sopenharmony_ci scanner_binding_item_t *next_p = item_p->next_p; 1522425bb815Sopenharmony_ci 1523425bb815Sopenharmony_ci JERRY_ASSERT (item_p->literal_p->type & (SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_IS_ARG)); 1524425bb815Sopenharmony_ci 1525425bb815Sopenharmony_ci scanner_free (item_p, sizeof (scanner_binding_item_t)); 1526425bb815Sopenharmony_ci item_p = next_p; 1527425bb815Sopenharmony_ci } 1528425bb815Sopenharmony_ci return; 1529425bb815Sopenharmony_ci } 1530425bb815Sopenharmony_ci 1531425bb815Sopenharmony_ci JERRY_ASSERT (prev_binding_list_p != NULL); 1532425bb815Sopenharmony_ci 1533425bb815Sopenharmony_ci while (item_p != NULL) 1534425bb815Sopenharmony_ci { 1535425bb815Sopenharmony_ci scanner_binding_item_t *next_p = item_p->next_p; 1536425bb815Sopenharmony_ci 1537425bb815Sopenharmony_ci item_p->next_p = prev_binding_list_p->items_p; 1538425bb815Sopenharmony_ci prev_binding_list_p->items_p = item_p; 1539425bb815Sopenharmony_ci 1540425bb815Sopenharmony_ci item_p = next_p; 1541425bb815Sopenharmony_ci } 1542425bb815Sopenharmony_ci} /* scanner_pop_binding_list */ 1543425bb815Sopenharmony_ci 1544425bb815Sopenharmony_ci/** 1545425bb815Sopenharmony_ci * Append a hole into the literal pool. 1546425bb815Sopenharmony_ci */ 1547425bb815Sopenharmony_civoid 1548425bb815Sopenharmony_ciscanner_append_hole (parser_context_t *context_p, scanner_context_t *scanner_context_p) 1549425bb815Sopenharmony_ci{ 1550425bb815Sopenharmony_ci scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; 1551425bb815Sopenharmony_ci 1552425bb815Sopenharmony_ci lexer_lit_location_t *literal_p; 1553425bb815Sopenharmony_ci literal_p = (lexer_lit_location_t *) parser_list_append (context_p, &literal_pool_p->literal_pool); 1554425bb815Sopenharmony_ci 1555425bb815Sopenharmony_ci literal_p->char_p = NULL; 1556425bb815Sopenharmony_ci literal_p->length = 0; 1557425bb815Sopenharmony_ci literal_p->type = SCANNER_LITERAL_IS_ARG; 1558425bb815Sopenharmony_ci literal_p->has_escape = 0; 1559425bb815Sopenharmony_ci} /* scanner_append_hole */ 1560425bb815Sopenharmony_ci 1561425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1562425bb815Sopenharmony_ci 1563425bb815Sopenharmony_ci/** 1564425bb815Sopenharmony_ci * Reverse the scanner info chain after the scanning is completed. 1565425bb815Sopenharmony_ci */ 1566425bb815Sopenharmony_civoid 1567425bb815Sopenharmony_ciscanner_reverse_info_list (parser_context_t *context_p) /**< context */ 1568425bb815Sopenharmony_ci{ 1569425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = context_p->next_scanner_info_p; 1570425bb815Sopenharmony_ci scanner_info_t *last_scanner_info_p = NULL; 1571425bb815Sopenharmony_ci 1572425bb815Sopenharmony_ci if (scanner_info_p->type == SCANNER_TYPE_END) 1573425bb815Sopenharmony_ci { 1574425bb815Sopenharmony_ci return; 1575425bb815Sopenharmony_ci } 1576425bb815Sopenharmony_ci 1577425bb815Sopenharmony_ci do 1578425bb815Sopenharmony_ci { 1579425bb815Sopenharmony_ci scanner_info_t *next_scanner_info_p = scanner_info_p->next_p; 1580425bb815Sopenharmony_ci scanner_info_p->next_p = last_scanner_info_p; 1581425bb815Sopenharmony_ci 1582425bb815Sopenharmony_ci last_scanner_info_p = scanner_info_p; 1583425bb815Sopenharmony_ci scanner_info_p = next_scanner_info_p; 1584425bb815Sopenharmony_ci } 1585425bb815Sopenharmony_ci while (scanner_info_p->type != SCANNER_TYPE_END); 1586425bb815Sopenharmony_ci 1587425bb815Sopenharmony_ci context_p->next_scanner_info_p->next_p = scanner_info_p; 1588425bb815Sopenharmony_ci context_p->next_scanner_info_p = last_scanner_info_p; 1589425bb815Sopenharmony_ci} /* scanner_reverse_info_list */ 1590425bb815Sopenharmony_ci 1591425bb815Sopenharmony_ci/** 1592425bb815Sopenharmony_ci * Release unused scanner info blocks. 1593425bb815Sopenharmony_ci * This should happen only if an error is occured. 1594425bb815Sopenharmony_ci */ 1595425bb815Sopenharmony_civoid 1596425bb815Sopenharmony_ciscanner_cleanup (parser_context_t *context_p) /**< context */ 1597425bb815Sopenharmony_ci{ 1598425bb815Sopenharmony_ci if (context_p->skipped_scanner_info_p != NULL) 1599425bb815Sopenharmony_ci { 1600425bb815Sopenharmony_ci context_p->skipped_scanner_info_end_p->next_p = context_p->next_scanner_info_p; 1601425bb815Sopenharmony_ci context_p->next_scanner_info_p = context_p->skipped_scanner_info_p; 1602425bb815Sopenharmony_ci context_p->skipped_scanner_info_p = NULL; 1603425bb815Sopenharmony_ci } 1604425bb815Sopenharmony_ci 1605425bb815Sopenharmony_ci scanner_info_t *scanner_info_p = context_p->next_scanner_info_p; 1606425bb815Sopenharmony_ci 1607425bb815Sopenharmony_ci while (scanner_info_p != NULL) 1608425bb815Sopenharmony_ci { 1609425bb815Sopenharmony_ci scanner_info_t *next_scanner_info_p = scanner_info_p->next_p; 1610425bb815Sopenharmony_ci 1611425bb815Sopenharmony_ci size_t size = sizeof (scanner_info_t); 1612425bb815Sopenharmony_ci 1613425bb815Sopenharmony_ci switch (scanner_info_p->type) 1614425bb815Sopenharmony_ci { 1615425bb815Sopenharmony_ci case SCANNER_TYPE_END: 1616425bb815Sopenharmony_ci { 1617425bb815Sopenharmony_ci scanner_info_p = context_p->active_scanner_info_p; 1618425bb815Sopenharmony_ci continue; 1619425bb815Sopenharmony_ci } 1620425bb815Sopenharmony_ci case SCANNER_TYPE_FUNCTION: 1621425bb815Sopenharmony_ci case SCANNER_TYPE_BLOCK: 1622425bb815Sopenharmony_ci { 1623425bb815Sopenharmony_ci size = scanner_get_stream_size (scanner_info_p, sizeof (scanner_info_t)); 1624425bb815Sopenharmony_ci break; 1625425bb815Sopenharmony_ci } 1626425bb815Sopenharmony_ci case SCANNER_TYPE_WHILE: 1627425bb815Sopenharmony_ci case SCANNER_TYPE_FOR_IN: 1628425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1629425bb815Sopenharmony_ci case SCANNER_TYPE_FOR_OF: 1630425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1631425bb815Sopenharmony_ci case SCANNER_TYPE_CASE: 1632425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1633425bb815Sopenharmony_ci case SCANNER_TYPE_INITIALIZER: 1634425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1635425bb815Sopenharmony_ci { 1636425bb815Sopenharmony_ci size = sizeof (scanner_location_info_t); 1637425bb815Sopenharmony_ci break; 1638425bb815Sopenharmony_ci } 1639425bb815Sopenharmony_ci case SCANNER_TYPE_FOR: 1640425bb815Sopenharmony_ci { 1641425bb815Sopenharmony_ci size = sizeof (scanner_for_info_t); 1642425bb815Sopenharmony_ci break; 1643425bb815Sopenharmony_ci } 1644425bb815Sopenharmony_ci case SCANNER_TYPE_SWITCH: 1645425bb815Sopenharmony_ci { 1646425bb815Sopenharmony_ci scanner_release_switch_cases (((scanner_switch_info_t *) scanner_info_p)->case_p); 1647425bb815Sopenharmony_ci size = sizeof (scanner_switch_info_t); 1648425bb815Sopenharmony_ci break; 1649425bb815Sopenharmony_ci } 1650425bb815Sopenharmony_ci default: 1651425bb815Sopenharmony_ci { 1652425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1653425bb815Sopenharmony_ci JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS 1654425bb815Sopenharmony_ci || scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION 1655425bb815Sopenharmony_ci || scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR 1656425bb815Sopenharmony_ci || scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED 1657425bb815Sopenharmony_ci || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION); 1658425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1659425bb815Sopenharmony_ci JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS); 1660425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1661425bb815Sopenharmony_ci break; 1662425bb815Sopenharmony_ci } 1663425bb815Sopenharmony_ci } 1664425bb815Sopenharmony_ci 1665425bb815Sopenharmony_ci scanner_free (scanner_info_p, size); 1666425bb815Sopenharmony_ci scanner_info_p = next_scanner_info_p; 1667425bb815Sopenharmony_ci } 1668425bb815Sopenharmony_ci 1669425bb815Sopenharmony_ci context_p->next_scanner_info_p = NULL; 1670425bb815Sopenharmony_ci context_p->active_scanner_info_p = NULL; 1671425bb815Sopenharmony_ci} /* scanner_cleanup */ 1672425bb815Sopenharmony_ci 1673425bb815Sopenharmony_ci/** 1674425bb815Sopenharmony_ci * Checks whether a context needs to be created for a block. 1675425bb815Sopenharmony_ci * 1676425bb815Sopenharmony_ci * @return true - if context is needed, 1677425bb815Sopenharmony_ci * false - otherwise 1678425bb815Sopenharmony_ci */ 1679425bb815Sopenharmony_cibool 1680425bb815Sopenharmony_ciscanner_is_context_needed (parser_context_t *context_p, /**< context */ 1681425bb815Sopenharmony_ci parser_check_context_type_t check_type) /**< context type */ 1682425bb815Sopenharmony_ci{ 1683425bb815Sopenharmony_ci scanner_info_t *info_p = context_p->next_scanner_info_p; 1684425bb815Sopenharmony_ci const uint8_t *data_p = (const uint8_t *) (info_p + 1); 1685425bb815Sopenharmony_ci 1686425bb815Sopenharmony_ci JERRY_UNUSED (check_type); 1687425bb815Sopenharmony_ci 1688425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1689425bb815Sopenharmony_ci JERRY_ASSERT ((check_type == PARSER_CHECK_BLOCK_CONTEXT ? info_p->type == SCANNER_TYPE_BLOCK 1690425bb815Sopenharmony_ci : info_p->type == SCANNER_TYPE_FUNCTION)); 1691425bb815Sopenharmony_ci 1692425bb815Sopenharmony_ci uint32_t scope_stack_reg_top = (check_type != PARSER_CHECK_GLOBAL_CONTEXT ? context_p->scope_stack_reg_top 1693425bb815Sopenharmony_ci : 0); 1694425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1695425bb815Sopenharmony_ci JERRY_ASSERT (check_type == PARSER_CHECK_BLOCK_CONTEXT); 1696425bb815Sopenharmony_ci JERRY_ASSERT (info_p->type == SCANNER_TYPE_BLOCK); 1697425bb815Sopenharmony_ci 1698425bb815Sopenharmony_ci uint32_t scope_stack_reg_top = context_p->scope_stack_reg_top; 1699425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 1700425bb815Sopenharmony_ci 1701425bb815Sopenharmony_ci while (data_p[0] != SCANNER_STREAM_TYPE_END) 1702425bb815Sopenharmony_ci { 1703425bb815Sopenharmony_ci uint8_t data = data_p[0]; 1704425bb815Sopenharmony_ci 1705425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1706425bb815Sopenharmony_ci uint32_t type = data & SCANNER_STREAM_TYPE_MASK; 1707425bb815Sopenharmony_ci 1708425bb815Sopenharmony_ci if (JERRY_UNLIKELY (type == SCANNER_STREAM_TYPE_HOLE)) 1709425bb815Sopenharmony_ci { 1710425bb815Sopenharmony_ci JERRY_ASSERT (check_type == PARSER_CHECK_FUNCTION_CONTEXT); 1711425bb815Sopenharmony_ci data_p++; 1712425bb815Sopenharmony_ci continue; 1713425bb815Sopenharmony_ci } 1714425bb815Sopenharmony_ci 1715425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG 1716425bb815Sopenharmony_ci if (check_type == PARSER_CHECK_BLOCK_CONTEXT) 1717425bb815Sopenharmony_ci { 1718425bb815Sopenharmony_ci JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR 1719425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LET 1720425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_CONST 1721425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LOCAL 1722425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_FUNC); 1723425bb815Sopenharmony_ci } 1724425bb815Sopenharmony_ci else if (check_type == PARSER_CHECK_GLOBAL_CONTEXT) 1725425bb815Sopenharmony_ci { 1726425bb815Sopenharmony_ci /* FIXME: a private declarative lexical environment should always be present 1727425bb815Sopenharmony_ci * for modules. Remove SCANNER_STREAM_TYPE_IMPORT after it is implemented. */ 1728425bb815Sopenharmony_ci JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR 1729425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LET 1730425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_CONST 1731425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_FUNC 1732425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_IMPORT); 1733425bb815Sopenharmony_ci 1734425bb815Sopenharmony_ci /* Only let/const can be stored in registers */ 1735425bb815Sopenharmony_ci JERRY_ASSERT ((data & SCANNER_STREAM_NO_REG) 1736425bb815Sopenharmony_ci || (type == SCANNER_STREAM_TYPE_FUNC && (context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)) 1737425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LET 1738425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_CONST); 1739425bb815Sopenharmony_ci } 1740425bb815Sopenharmony_ci else 1741425bb815Sopenharmony_ci { 1742425bb815Sopenharmony_ci JERRY_ASSERT (check_type == PARSER_CHECK_FUNCTION_CONTEXT); 1743425bb815Sopenharmony_ci 1744425bb815Sopenharmony_ci JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR 1745425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LET 1746425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_CONST 1747425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_LOCAL 1748425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_ARG 1749425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_ARG_VAR 1750425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG 1751425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR 1752425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_ARG_FUNC 1753425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC 1754425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_FUNC); 1755425bb815Sopenharmony_ci } 1756425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 1757425bb815Sopenharmony_ci 1758425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1759425bb815Sopenharmony_ci JERRY_ASSERT ((data & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_VAR); 1760425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1761425bb815Sopenharmony_ci 1762425bb815Sopenharmony_ci if (!(data & SCANNER_STREAM_UINT16_DIFF)) 1763425bb815Sopenharmony_ci { 1764425bb815Sopenharmony_ci if (data_p[2] != 0) 1765425bb815Sopenharmony_ci { 1766425bb815Sopenharmony_ci data_p += 2 + 1; 1767425bb815Sopenharmony_ci } 1768425bb815Sopenharmony_ci else 1769425bb815Sopenharmony_ci { 1770425bb815Sopenharmony_ci data_p += 2 + 1 + sizeof (const uint8_t *); 1771425bb815Sopenharmony_ci } 1772425bb815Sopenharmony_ci } 1773425bb815Sopenharmony_ci else 1774425bb815Sopenharmony_ci { 1775425bb815Sopenharmony_ci data_p += 2 + 2; 1776425bb815Sopenharmony_ci } 1777425bb815Sopenharmony_ci 1778425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1779425bb815Sopenharmony_ci if (JERRY_UNLIKELY (check_type == PARSER_CHECK_GLOBAL_CONTEXT) 1780425bb815Sopenharmony_ci && (type == SCANNER_STREAM_TYPE_VAR 1781425bb815Sopenharmony_ci || (type == SCANNER_STREAM_TYPE_FUNC && !(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL)) 1782425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_IMPORT)) 1783425bb815Sopenharmony_ci { 1784425bb815Sopenharmony_ci continue; 1785425bb815Sopenharmony_ci } 1786425bb815Sopenharmony_ci 1787425bb815Sopenharmony_ci if (JERRY_UNLIKELY (check_type == PARSER_CHECK_FUNCTION_CONTEXT)) 1788425bb815Sopenharmony_ci { 1789425bb815Sopenharmony_ci if (SCANNER_STREAM_TYPE_IS_ARG_FUNC (type) 1790425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_ARG_VAR 1791425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR) 1792425bb815Sopenharmony_ci { 1793425bb815Sopenharmony_ci /* The return value is true, if the variable is stored in the lexical environment 1794425bb815Sopenharmony_ci * or all registers have already been used for function arguments. This can be 1795425bb815Sopenharmony_ci * inprecise in the latter case, but this is a very rare corner case. A more 1796425bb815Sopenharmony_ci * sophisticated check would require to decode the literal. */ 1797425bb815Sopenharmony_ci if ((data & SCANNER_STREAM_NO_REG) 1798425bb815Sopenharmony_ci || scope_stack_reg_top >= PARSER_MAXIMUM_NUMBER_OF_REGISTERS) 1799425bb815Sopenharmony_ci { 1800425bb815Sopenharmony_ci return true; 1801425bb815Sopenharmony_ci } 1802425bb815Sopenharmony_ci continue; 1803425bb815Sopenharmony_ci } 1804425bb815Sopenharmony_ci 1805425bb815Sopenharmony_ci if (SCANNER_STREAM_TYPE_IS_ARG (type)) 1806425bb815Sopenharmony_ci { 1807425bb815Sopenharmony_ci continue; 1808425bb815Sopenharmony_ci } 1809425bb815Sopenharmony_ci } 1810425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1811425bb815Sopenharmony_ci 1812425bb815Sopenharmony_ci if ((data & SCANNER_STREAM_NO_REG) 1813425bb815Sopenharmony_ci || scope_stack_reg_top >= PARSER_MAXIMUM_NUMBER_OF_REGISTERS) 1814425bb815Sopenharmony_ci { 1815425bb815Sopenharmony_ci return true; 1816425bb815Sopenharmony_ci } 1817425bb815Sopenharmony_ci 1818425bb815Sopenharmony_ci scope_stack_reg_top++; 1819425bb815Sopenharmony_ci } 1820425bb815Sopenharmony_ci 1821425bb815Sopenharmony_ci return false; 1822425bb815Sopenharmony_ci} /* scanner_is_context_needed */ 1823425bb815Sopenharmony_ci 1824425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1825425bb815Sopenharmony_ci 1826425bb815Sopenharmony_ci/** 1827425bb815Sopenharmony_ci * Try to scan/parse the ".target" part in the "new.target" expression. 1828425bb815Sopenharmony_ci * 1829425bb815Sopenharmony_ci * Upon exiting with "true" the current token will point to the "target" 1830425bb815Sopenharmony_ci * literal. 1831425bb815Sopenharmony_ci * 1832425bb815Sopenharmony_ci * If the "target" literal is not after the "new." then a scanner/parser 1833425bb815Sopenharmony_ci * error will be raised. 1834425bb815Sopenharmony_ci * 1835425bb815Sopenharmony_ci * @returns true if the ".target" part was found 1836425bb815Sopenharmony_ci * false if there is no "." after the new. 1837425bb815Sopenharmony_ci */ 1838425bb815Sopenharmony_cibool 1839425bb815Sopenharmony_ciscanner_try_scan_new_target (parser_context_t *context_p) /**< parser/scanner context */ 1840425bb815Sopenharmony_ci{ 1841425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_KEYW_NEW); 1842425bb815Sopenharmony_ci 1843425bb815Sopenharmony_ci if (lexer_check_next_character (context_p, LIT_CHAR_DOT)) 1844425bb815Sopenharmony_ci { 1845425bb815Sopenharmony_ci lexer_next_token (context_p); 1846425bb815Sopenharmony_ci if (context_p->token.type != LEXER_DOT) 1847425bb815Sopenharmony_ci { 1848425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_CHARACTER); 1849425bb815Sopenharmony_ci } 1850425bb815Sopenharmony_ci 1851425bb815Sopenharmony_ci lexer_next_token (context_p); 1852425bb815Sopenharmony_ci if (!lexer_token_is_identifier (context_p, "target", 6)) 1853425bb815Sopenharmony_ci { 1854425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_EXPECTED); 1855425bb815Sopenharmony_ci } 1856425bb815Sopenharmony_ci 1857425bb815Sopenharmony_ci return true; 1858425bb815Sopenharmony_ci } 1859425bb815Sopenharmony_ci return false; 1860425bb815Sopenharmony_ci} /* scanner_try_scan_new_target */ 1861425bb815Sopenharmony_ci 1862425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1863425bb815Sopenharmony_ci 1864425bb815Sopenharmony_ci/** 1865425bb815Sopenharmony_ci * Description of "arguments" literal string. 1866425bb815Sopenharmony_ci */ 1867425bb815Sopenharmony_ciconst lexer_lit_location_t lexer_arguments_literal = 1868425bb815Sopenharmony_ci{ 1869425bb815Sopenharmony_ci (const uint8_t *) "arguments", 9, LEXER_IDENT_LITERAL, false 1870425bb815Sopenharmony_ci}; 1871425bb815Sopenharmony_ci 1872425bb815Sopenharmony_ci/** 1873425bb815Sopenharmony_ci * Create an unused literal. 1874425bb815Sopenharmony_ci */ 1875425bb815Sopenharmony_cistatic void 1876425bb815Sopenharmony_ciscanner_create_unused_literal (parser_context_t *context_p, /**< context */ 1877425bb815Sopenharmony_ci uint8_t status_flags) /**< initial status flags */ 1878425bb815Sopenharmony_ci{ 1879425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)) 1880425bb815Sopenharmony_ci { 1881425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 1882425bb815Sopenharmony_ci } 1883425bb815Sopenharmony_ci 1884425bb815Sopenharmony_ci lexer_literal_t *literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 1885425bb815Sopenharmony_ci 1886425bb815Sopenharmony_ci literal_p->type = LEXER_UNUSED_LITERAL; 1887425bb815Sopenharmony_ci literal_p->status_flags = status_flags; 1888425bb815Sopenharmony_ci 1889425bb815Sopenharmony_ci context_p->literal_count++; 1890425bb815Sopenharmony_ci} /* scanner_create_unused_literal */ 1891425bb815Sopenharmony_ci 1892425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1893425bb815Sopenharmony_ci/** 1894425bb815Sopenharmony_ci * Emit checks for redeclared bindings in the global lexical scope. 1895425bb815Sopenharmony_ci */ 1896425bb815Sopenharmony_civoid 1897425bb815Sopenharmony_ciscanner_check_variables (parser_context_t *context_p) /**< context */ 1898425bb815Sopenharmony_ci{ 1899425bb815Sopenharmony_ci scanner_info_t *info_p = context_p->next_scanner_info_p; 1900425bb815Sopenharmony_ci const uint8_t *next_data_p = (const uint8_t *) (info_p + 1); 1901425bb815Sopenharmony_ci lexer_lit_location_t literal; 1902425bb815Sopenharmony_ci 1903425bb815Sopenharmony_ci JERRY_ASSERT (info_p->type == SCANNER_TYPE_FUNCTION); 1904425bb815Sopenharmony_ci 1905425bb815Sopenharmony_ci literal.char_p = info_p->source_p - 1; 1906425bb815Sopenharmony_ci 1907425bb815Sopenharmony_ci while (next_data_p[0] != SCANNER_STREAM_TYPE_END) 1908425bb815Sopenharmony_ci { 1909425bb815Sopenharmony_ci uint32_t type = next_data_p[0] & SCANNER_STREAM_TYPE_MASK; 1910425bb815Sopenharmony_ci const uint8_t *data_p = next_data_p; 1911425bb815Sopenharmony_ci 1912425bb815Sopenharmony_ci JERRY_ASSERT (type != SCANNER_STREAM_TYPE_HOLE 1913425bb815Sopenharmony_ci && !SCANNER_STREAM_TYPE_IS_ARG (type) 1914425bb815Sopenharmony_ci && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type)); 1915425bb815Sopenharmony_ci JERRY_ASSERT (data_p[0] & SCANNER_STREAM_NO_REG); 1916425bb815Sopenharmony_ci 1917425bb815Sopenharmony_ci if (!(data_p[0] & SCANNER_STREAM_UINT16_DIFF)) 1918425bb815Sopenharmony_ci { 1919425bb815Sopenharmony_ci if (data_p[2] != 0) 1920425bb815Sopenharmony_ci { 1921425bb815Sopenharmony_ci literal.char_p += data_p[2]; 1922425bb815Sopenharmony_ci next_data_p += 2 + 1; 1923425bb815Sopenharmony_ci } 1924425bb815Sopenharmony_ci else 1925425bb815Sopenharmony_ci { 1926425bb815Sopenharmony_ci memcpy (&literal.char_p, data_p + 2 + 1, sizeof (const uint8_t *)); 1927425bb815Sopenharmony_ci next_data_p += 2 + 1 + sizeof (const uint8_t *); 1928425bb815Sopenharmony_ci } 1929425bb815Sopenharmony_ci } 1930425bb815Sopenharmony_ci else 1931425bb815Sopenharmony_ci { 1932425bb815Sopenharmony_ci int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8; 1933425bb815Sopenharmony_ci 1934425bb815Sopenharmony_ci if (diff <= UINT8_MAX) 1935425bb815Sopenharmony_ci { 1936425bb815Sopenharmony_ci diff = -diff; 1937425bb815Sopenharmony_ci } 1938425bb815Sopenharmony_ci 1939425bb815Sopenharmony_ci literal.char_p += diff; 1940425bb815Sopenharmony_ci next_data_p += 2 + 2; 1941425bb815Sopenharmony_ci } 1942425bb815Sopenharmony_ci 1943425bb815Sopenharmony_ci literal.length = data_p[1]; 1944425bb815Sopenharmony_ci literal.type = LEXER_IDENT_LITERAL; 1945425bb815Sopenharmony_ci literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0; 1946425bb815Sopenharmony_ci 1947425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL); 1948425bb815Sopenharmony_ci literal.char_p += data_p[1]; 1949425bb815Sopenharmony_ci 1950425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 1951425bb815Sopenharmony_ci if (type == SCANNER_STREAM_TYPE_IMPORT) 1952425bb815Sopenharmony_ci { 1953425bb815Sopenharmony_ci continue; 1954425bb815Sopenharmony_ci } 1955425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 1956425bb815Sopenharmony_ci 1957425bb815Sopenharmony_ci context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED; 1958425bb815Sopenharmony_ci 1959425bb815Sopenharmony_ci uint16_t opcode; 1960425bb815Sopenharmony_ci if (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_FUNC) 1961425bb815Sopenharmony_ci { 1962425bb815Sopenharmony_ci opcode = CBC_CHECK_VAR; 1963425bb815Sopenharmony_ci } 1964425bb815Sopenharmony_ci else 1965425bb815Sopenharmony_ci { 1966425bb815Sopenharmony_ci opcode = CBC_CHECK_LET; 1967425bb815Sopenharmony_ci } 1968425bb815Sopenharmony_ci 1969425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, opcode, context_p->lit_object.index); 1970425bb815Sopenharmony_ci } 1971425bb815Sopenharmony_ci 1972425bb815Sopenharmony_ci parser_flush_cbc (context_p); 1973425bb815Sopenharmony_ci} /* scanner_check_variables */ 1974425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1975425bb815Sopenharmony_ci 1976425bb815Sopenharmony_ci/** 1977425bb815Sopenharmony_ci * Create and/or initialize var/let/const/function/etc. variables. 1978425bb815Sopenharmony_ci */ 1979425bb815Sopenharmony_civoid 1980425bb815Sopenharmony_ciscanner_create_variables (parser_context_t *context_p, /**< context */ 1981425bb815Sopenharmony_ci uint32_t option_flags) /**< combination of scanner_create_variables_flags_t bits */ 1982425bb815Sopenharmony_ci{ 1983425bb815Sopenharmony_ci scanner_info_t *info_p = context_p->next_scanner_info_p; 1984425bb815Sopenharmony_ci const uint8_t *next_data_p = (const uint8_t *) (info_p + 1); 1985425bb815Sopenharmony_ci uint8_t info_type = info_p->type; 1986425bb815Sopenharmony_ci uint8_t info_u8_arg = info_p->u8_arg; 1987425bb815Sopenharmony_ci lexer_lit_location_t literal; 1988425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_p; 1989425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_end_p; 1990425bb815Sopenharmony_ci 1991425bb815Sopenharmony_ci JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION || info_type == SCANNER_TYPE_BLOCK); 1992425bb815Sopenharmony_ci JERRY_ASSERT (!(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS) 1993425bb815Sopenharmony_ci || !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)); 1994425bb815Sopenharmony_ci JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION 1995425bb815Sopenharmony_ci || !(option_flags & (SCANNER_CREATE_VARS_IS_FUNCTION_ARGS | SCANNER_CREATE_VARS_IS_FUNCTION_BODY))); 1996425bb815Sopenharmony_ci 1997425bb815Sopenharmony_ci if (info_type == SCANNER_TYPE_FUNCTION && !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)) 1998425bb815Sopenharmony_ci { 1999425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_p == NULL); 2000425bb815Sopenharmony_ci 2001425bb815Sopenharmony_ci size_t stack_size = info_p->u16_arg * sizeof (parser_scope_stack_t); 2002425bb815Sopenharmony_ci context_p->scope_stack_size = info_p->u16_arg; 2003425bb815Sopenharmony_ci 2004425bb815Sopenharmony_ci scope_stack_p = NULL; 2005425bb815Sopenharmony_ci 2006425bb815Sopenharmony_ci if (stack_size > 0) 2007425bb815Sopenharmony_ci { 2008425bb815Sopenharmony_ci scope_stack_p = (parser_scope_stack_t *) parser_malloc (context_p, stack_size); 2009425bb815Sopenharmony_ci } 2010425bb815Sopenharmony_ci 2011425bb815Sopenharmony_ci context_p->scope_stack_p = scope_stack_p; 2012425bb815Sopenharmony_ci scope_stack_end_p = scope_stack_p + context_p->scope_stack_size; 2013425bb815Sopenharmony_ci } 2014425bb815Sopenharmony_ci else 2015425bb815Sopenharmony_ci { 2016425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_p != NULL || context_p->scope_stack_size == 0); 2017425bb815Sopenharmony_ci 2018425bb815Sopenharmony_ci scope_stack_p = context_p->scope_stack_p; 2019425bb815Sopenharmony_ci scope_stack_end_p = scope_stack_p + context_p->scope_stack_size; 2020425bb815Sopenharmony_ci scope_stack_p += context_p->scope_stack_top; 2021425bb815Sopenharmony_ci } 2022425bb815Sopenharmony_ci 2023425bb815Sopenharmony_ci uint32_t scope_stack_reg_top = context_p->scope_stack_reg_top; 2024425bb815Sopenharmony_ci 2025425bb815Sopenharmony_ci literal.char_p = info_p->source_p - 1; 2026425bb815Sopenharmony_ci 2027425bb815Sopenharmony_ci while (next_data_p[0] != SCANNER_STREAM_TYPE_END) 2028425bb815Sopenharmony_ci { 2029425bb815Sopenharmony_ci uint32_t type = next_data_p[0] & SCANNER_STREAM_TYPE_MASK; 2030425bb815Sopenharmony_ci const uint8_t *data_p = next_data_p; 2031425bb815Sopenharmony_ci 2032425bb815Sopenharmony_ci JERRY_ASSERT ((option_flags & (SCANNER_CREATE_VARS_IS_FUNCTION_BODY | SCANNER_CREATE_VARS_IS_FUNCTION_ARGS)) 2033425bb815Sopenharmony_ci || (type != SCANNER_STREAM_TYPE_HOLE 2034425bb815Sopenharmony_ci && !SCANNER_STREAM_TYPE_IS_ARG (type) 2035425bb815Sopenharmony_ci && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type))); 2036425bb815Sopenharmony_ci 2037425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 2038425bb815Sopenharmony_ci JERRY_ASSERT (type != SCANNER_STREAM_TYPE_IMPORT || (data_p[0] & SCANNER_STREAM_NO_REG)); 2039425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 2040425bb815Sopenharmony_ci 2041425bb815Sopenharmony_ci if (type == SCANNER_STREAM_TYPE_HOLE) 2042425bb815Sopenharmony_ci { 2043425bb815Sopenharmony_ci next_data_p++; 2044425bb815Sopenharmony_ci 2045425bb815Sopenharmony_ci if (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY) 2046425bb815Sopenharmony_ci { 2047425bb815Sopenharmony_ci continue; 2048425bb815Sopenharmony_ci } 2049425bb815Sopenharmony_ci 2050425bb815Sopenharmony_ci if (info_u8_arg & SCANNER_FUNCTION_MAPPED_ARGUMENTS) 2051425bb815Sopenharmony_ci { 2052425bb815Sopenharmony_ci scanner_create_unused_literal (context_p, LEXER_FLAG_FUNCTION_ARGUMENT); 2053425bb815Sopenharmony_ci } 2054425bb815Sopenharmony_ci 2055425bb815Sopenharmony_ci if (scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS) 2056425bb815Sopenharmony_ci { 2057425bb815Sopenharmony_ci scope_stack_reg_top++; 2058425bb815Sopenharmony_ci } 2059425bb815Sopenharmony_ci continue; 2060425bb815Sopenharmony_ci } 2061425bb815Sopenharmony_ci 2062425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_size != 0); 2063425bb815Sopenharmony_ci 2064425bb815Sopenharmony_ci if (!(data_p[0] & SCANNER_STREAM_UINT16_DIFF)) 2065425bb815Sopenharmony_ci { 2066425bb815Sopenharmony_ci if (data_p[2] != 0) 2067425bb815Sopenharmony_ci { 2068425bb815Sopenharmony_ci literal.char_p += data_p[2]; 2069425bb815Sopenharmony_ci next_data_p += 2 + 1; 2070425bb815Sopenharmony_ci } 2071425bb815Sopenharmony_ci else 2072425bb815Sopenharmony_ci { 2073425bb815Sopenharmony_ci memcpy (&literal.char_p, data_p + 2 + 1, sizeof (const uint8_t *)); 2074425bb815Sopenharmony_ci next_data_p += 2 + 1 + sizeof (const uint8_t *); 2075425bb815Sopenharmony_ci } 2076425bb815Sopenharmony_ci } 2077425bb815Sopenharmony_ci else 2078425bb815Sopenharmony_ci { 2079425bb815Sopenharmony_ci int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8; 2080425bb815Sopenharmony_ci 2081425bb815Sopenharmony_ci if (diff <= UINT8_MAX) 2082425bb815Sopenharmony_ci { 2083425bb815Sopenharmony_ci diff = -diff; 2084425bb815Sopenharmony_ci } 2085425bb815Sopenharmony_ci 2086425bb815Sopenharmony_ci literal.char_p += diff; 2087425bb815Sopenharmony_ci next_data_p += 2 + 2; 2088425bb815Sopenharmony_ci } 2089425bb815Sopenharmony_ci 2090425bb815Sopenharmony_ci if (SCANNER_STREAM_TYPE_IS_ARG (type)) 2091425bb815Sopenharmony_ci { 2092425bb815Sopenharmony_ci if (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY) 2093425bb815Sopenharmony_ci { 2094425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2095425bb815Sopenharmony_ci if ((context_p->status_flags & PARSER_LEXICAL_BLOCK_NEEDED) 2096425bb815Sopenharmony_ci && (type == SCANNER_STREAM_TYPE_ARG_VAR || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR)) 2097425bb815Sopenharmony_ci { 2098425bb815Sopenharmony_ci literal.length = data_p[1]; 2099425bb815Sopenharmony_ci literal.type = LEXER_IDENT_LITERAL; 2100425bb815Sopenharmony_ci literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0; 2101425bb815Sopenharmony_ci 2102425bb815Sopenharmony_ci /* Literal must be exists. */ 2103425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &literal, LEXER_IDENT_LITERAL); 2104425bb815Sopenharmony_ci 2105425bb815Sopenharmony_ci if (context_p->lit_object.index < PARSER_REGISTER_START) 2106425bb815Sopenharmony_ci { 2107425bb815Sopenharmony_ci parser_emit_cbc_ext_literal_from_token (context_p, CBC_EXT_COPY_FROM_ARG); 2108425bb815Sopenharmony_ci } 2109425bb815Sopenharmony_ci } 2110425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2111425bb815Sopenharmony_ci 2112425bb815Sopenharmony_ci literal.char_p += data_p[1]; 2113425bb815Sopenharmony_ci continue; 2114425bb815Sopenharmony_ci } 2115425bb815Sopenharmony_ci } 2116425bb815Sopenharmony_ci else if ((option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS) 2117425bb815Sopenharmony_ci && !SCANNER_STREAM_TYPE_IS_ARG_FUNC (type)) 2118425bb815Sopenharmony_ci { 2119425bb815Sopenharmony_ci /* Function arguments must come first. */ 2120425bb815Sopenharmony_ci break; 2121425bb815Sopenharmony_ci } 2122425bb815Sopenharmony_ci 2123425bb815Sopenharmony_ci literal.length = data_p[1]; 2124425bb815Sopenharmony_ci literal.type = LEXER_IDENT_LITERAL; 2125425bb815Sopenharmony_ci literal.has_escape = (data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? 1 : 0; 2126425bb815Sopenharmony_ci 2127425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL); 2128425bb815Sopenharmony_ci literal.char_p += data_p[1]; 2129425bb815Sopenharmony_ci 2130425bb815Sopenharmony_ci if (SCANNER_STREAM_TYPE_IS_ARG_FUNC (type) && (option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY)) 2131425bb815Sopenharmony_ci { 2132425bb815Sopenharmony_ci JERRY_ASSERT (scope_stack_p >= context_p->scope_stack_p + 2); 2133425bb815Sopenharmony_ci JERRY_ASSERT (context_p->status_flags & PARSER_IS_FUNCTION); 2134425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2135425bb815Sopenharmony_ci JERRY_ASSERT (!(context_p->status_flags & PARSER_FUNCTION_IS_PARSING_ARGS)); 2136425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2137425bb815Sopenharmony_ci 2138425bb815Sopenharmony_ci parser_scope_stack_t *function_map_p = scope_stack_p - 2; 2139425bb815Sopenharmony_ci uint16_t literal_index = context_p->lit_object.index; 2140425bb815Sopenharmony_ci 2141425bb815Sopenharmony_ci while (literal_index != function_map_p->map_from) 2142425bb815Sopenharmony_ci { 2143425bb815Sopenharmony_ci function_map_p--; 2144425bb815Sopenharmony_ci 2145425bb815Sopenharmony_ci JERRY_ASSERT (function_map_p >= context_p->scope_stack_p); 2146425bb815Sopenharmony_ci } 2147425bb815Sopenharmony_ci 2148425bb815Sopenharmony_ci JERRY_ASSERT (function_map_p[1].map_from == PARSER_SCOPE_STACK_FUNC); 2149425bb815Sopenharmony_ci 2150425bb815Sopenharmony_ci cbc_opcode_t opcode = CBC_SET_VAR_FUNC; 2151425bb815Sopenharmony_ci 2152425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2153425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->status_flags & PARSER_LEXICAL_BLOCK_NEEDED) 2154425bb815Sopenharmony_ci && (function_map_p[0].map_to & PARSER_SCOPE_STACK_REGISTER_MASK) == 0) 2155425bb815Sopenharmony_ci { 2156425bb815Sopenharmony_ci opcode = CBC_INIT_ARG_OR_FUNC; 2157425bb815Sopenharmony_ci } 2158425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2159425bb815Sopenharmony_ci 2160425bb815Sopenharmony_ci parser_emit_cbc_literal_value (context_p, 2161425bb815Sopenharmony_ci (uint16_t) opcode, 2162425bb815Sopenharmony_ci function_map_p[1].map_to, 2163425bb815Sopenharmony_ci scanner_decode_map_to (function_map_p)); 2164425bb815Sopenharmony_ci continue; 2165425bb815Sopenharmony_ci } 2166425bb815Sopenharmony_ci 2167425bb815Sopenharmony_ci if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p)) 2168425bb815Sopenharmony_ci { 2169425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK); 2170425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED); 2171425bb815Sopenharmony_ci } 2172425bb815Sopenharmony_ci 2173425bb815Sopenharmony_ci scope_stack_p->map_from = context_p->lit_object.index; 2174425bb815Sopenharmony_ci 2175425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2176425bb815Sopenharmony_ci if (info_type == SCANNER_TYPE_FUNCTION) 2177425bb815Sopenharmony_ci { 2178425bb815Sopenharmony_ci if (type != SCANNER_STREAM_TYPE_LET 2179425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 2180425bb815Sopenharmony_ci && type != SCANNER_STREAM_TYPE_IMPORT 2181425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 2182425bb815Sopenharmony_ci && type != SCANNER_STREAM_TYPE_CONST) 2183425bb815Sopenharmony_ci { 2184425bb815Sopenharmony_ci context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_GLOBAL; 2185425bb815Sopenharmony_ci } 2186425bb815Sopenharmony_ci } 2187425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2188425bb815Sopenharmony_ci 2189425bb815Sopenharmony_ci uint16_t map_to; 2190425bb815Sopenharmony_ci uint16_t func_init_opcode = CBC_INIT_ARG_OR_FUNC; 2191425bb815Sopenharmony_ci 2192425bb815Sopenharmony_ci if (!(data_p[0] & SCANNER_STREAM_NO_REG) 2193425bb815Sopenharmony_ci && scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS) 2194425bb815Sopenharmony_ci { 2195425bb815Sopenharmony_ci map_to = (uint16_t) (PARSER_REGISTER_START + scope_stack_reg_top); 2196425bb815Sopenharmony_ci 2197425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2198425bb815Sopenharmony_ci scope_stack_p->map_to = (uint16_t) (scope_stack_reg_top + 1); 2199425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2200425bb815Sopenharmony_ci scope_stack_p->map_to = map_to; 2201425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2202425bb815Sopenharmony_ci 2203425bb815Sopenharmony_ci scope_stack_reg_top++; 2204425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2205425bb815Sopenharmony_ci switch (type) 2206425bb815Sopenharmony_ci { 2207425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_CONST: 2208425bb815Sopenharmony_ci { 2209425bb815Sopenharmony_ci scope_stack_p->map_to |= PARSER_SCOPE_STACK_IS_CONST_REG; 2210425bb815Sopenharmony_ci /* FALLTHRU */ 2211425bb815Sopenharmony_ci } 2212425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LET: 2213425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG: 2214425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_VAR: 2215425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG: 2216425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR: 2217425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_FUNC: 2218425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC: 2219425bb815Sopenharmony_ci { 2220425bb815Sopenharmony_ci scope_stack_p->map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY; 2221425bb815Sopenharmony_ci break; 2222425bb815Sopenharmony_ci } 2223425bb815Sopenharmony_ci } 2224425bb815Sopenharmony_ci 2225425bb815Sopenharmony_ci func_init_opcode = CBC_SET_VAR_FUNC; 2226425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2227425bb815Sopenharmony_ci } 2228425bb815Sopenharmony_ci else 2229425bb815Sopenharmony_ci { 2230425bb815Sopenharmony_ci context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED; 2231425bb815Sopenharmony_ci map_to = context_p->lit_object.index; 2232425bb815Sopenharmony_ci 2233425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2234425bb815Sopenharmony_ci uint16_t scope_stack_map_to = 0; 2235425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2236425bb815Sopenharmony_ci scope_stack_p->map_to = map_to; 2237425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2238425bb815Sopenharmony_ci 2239425bb815Sopenharmony_ci if (info_type == SCANNER_TYPE_FUNCTION) 2240425bb815Sopenharmony_ci { 2241425bb815Sopenharmony_ci context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED; 2242425bb815Sopenharmony_ci } 2243425bb815Sopenharmony_ci 2244425bb815Sopenharmony_ci switch (type) 2245425bb815Sopenharmony_ci { 2246425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2247425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LET: 2248425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_CONST: 2249425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG: 2250425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR: 2251425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC: 2252425bb815Sopenharmony_ci { 2253425bb815Sopenharmony_ci scope_stack_map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY; 2254425bb815Sopenharmony_ci 2255425bb815Sopenharmony_ci if (!(data_p[0] & SCANNER_STREAM_EARLY_CREATE)) 2256425bb815Sopenharmony_ci { 2257425bb815Sopenharmony_ci break; 2258425bb815Sopenharmony_ci } 2259425bb815Sopenharmony_ci scope_stack_map_to |= PARSER_SCOPE_STACK_IS_LOCAL_CREATED; 2260425bb815Sopenharmony_ci /* FALLTHRU */ 2261425bb815Sopenharmony_ci } 2262425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LOCAL: 2263425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2264425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_VAR: 2265425bb815Sopenharmony_ci { 2266425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 2267425bb815Sopenharmony_ci context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p); 2268425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 2269425bb815Sopenharmony_ci 2270425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2271425bb815Sopenharmony_ci uint16_t opcode; 2272425bb815Sopenharmony_ci 2273425bb815Sopenharmony_ci switch (type) 2274425bb815Sopenharmony_ci { 2275425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_LET: 2276425bb815Sopenharmony_ci { 2277425bb815Sopenharmony_ci opcode = CBC_CREATE_LET; 2278425bb815Sopenharmony_ci break; 2279425bb815Sopenharmony_ci } 2280425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_CONST: 2281425bb815Sopenharmony_ci { 2282425bb815Sopenharmony_ci opcode = CBC_CREATE_CONST; 2283425bb815Sopenharmony_ci break; 2284425bb815Sopenharmony_ci } 2285425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_VAR: 2286425bb815Sopenharmony_ci { 2287425bb815Sopenharmony_ci opcode = CBC_CREATE_VAR; 2288425bb815Sopenharmony_ci 2289425bb815Sopenharmony_ci if (option_flags & SCANNER_CREATE_VARS_IS_SCRIPT) 2290425bb815Sopenharmony_ci { 2291425bb815Sopenharmony_ci opcode = CBC_CREATE_VAR_EVAL; 2292425bb815Sopenharmony_ci 2293425bb815Sopenharmony_ci if (context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT) 2294425bb815Sopenharmony_ci { 2295425bb815Sopenharmony_ci opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CREATE_VAR_EVAL); 2296425bb815Sopenharmony_ci } 2297425bb815Sopenharmony_ci } 2298425bb815Sopenharmony_ci break; 2299425bb815Sopenharmony_ci } 2300425bb815Sopenharmony_ci default: 2301425bb815Sopenharmony_ci { 2302425bb815Sopenharmony_ci JERRY_ASSERT (type == SCANNER_STREAM_TYPE_LOCAL 2303425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG 2304425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR 2305425bb815Sopenharmony_ci || type == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC); 2306425bb815Sopenharmony_ci 2307425bb815Sopenharmony_ci opcode = CBC_CREATE_LOCAL; 2308425bb815Sopenharmony_ci break; 2309425bb815Sopenharmony_ci } 2310425bb815Sopenharmony_ci } 2311425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2312425bb815Sopenharmony_ci uint16_t opcode = ((option_flags & SCANNER_CREATE_VARS_IS_SCRIPT) ? CBC_CREATE_VAR_EVAL 2313425bb815Sopenharmony_ci : CBC_CREATE_VAR); 2314425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2315425bb815Sopenharmony_ci 2316425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, opcode, map_to); 2317425bb815Sopenharmony_ci break; 2318425bb815Sopenharmony_ci } 2319425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG: 2320425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2321425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_VAR: 2322425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2323425bb815Sopenharmony_ci case SCANNER_STREAM_TYPE_ARG_FUNC: 2324425bb815Sopenharmony_ci { 2325425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 2326425bb815Sopenharmony_ci context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p); 2327425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 2328425bb815Sopenharmony_ci 2329425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2330425bb815Sopenharmony_ci scope_stack_map_to |= PARSER_SCOPE_STACK_NO_FUNCTION_COPY; 2331425bb815Sopenharmony_ci 2332425bb815Sopenharmony_ci /* Argument initializers of functions with mapped arguments (e.g. function f(a,b,a) {}) are 2333425bb815Sopenharmony_ci * generated here. The other initializers are handled by parser_parse_function_arguments(). */ 2334425bb815Sopenharmony_ci if (info_u8_arg & SCANNER_FUNCTION_MAPPED_ARGUMENTS) 2335425bb815Sopenharmony_ci { 2336425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2337425bb815Sopenharmony_ci parser_emit_cbc_literal_value (context_p, 2338425bb815Sopenharmony_ci CBC_INIT_ARG_OR_FUNC, 2339425bb815Sopenharmony_ci (uint16_t) (PARSER_REGISTER_START + scope_stack_reg_top), 2340425bb815Sopenharmony_ci map_to); 2341425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2342425bb815Sopenharmony_ci } 2343425bb815Sopenharmony_ci else if (data_p[0] & SCANNER_STREAM_EARLY_CREATE) 2344425bb815Sopenharmony_ci { 2345425bb815Sopenharmony_ci parser_emit_cbc_literal (context_p, CBC_CREATE_LOCAL, map_to); 2346425bb815Sopenharmony_ci scope_stack_map_to |= PARSER_SCOPE_STACK_IS_LOCAL_CREATED; 2347425bb815Sopenharmony_ci } 2348425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2349425bb815Sopenharmony_ci 2350425bb815Sopenharmony_ci if (scope_stack_reg_top < PARSER_MAXIMUM_NUMBER_OF_REGISTERS) 2351425bb815Sopenharmony_ci { 2352425bb815Sopenharmony_ci scope_stack_reg_top++; 2353425bb815Sopenharmony_ci } 2354425bb815Sopenharmony_ci break; 2355425bb815Sopenharmony_ci } 2356425bb815Sopenharmony_ci } 2357425bb815Sopenharmony_ci 2358425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2359425bb815Sopenharmony_ci scope_stack_p->map_to = scope_stack_map_to; 2360425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2361425bb815Sopenharmony_ci } 2362425bb815Sopenharmony_ci 2363425bb815Sopenharmony_ci scope_stack_p++; 2364425bb815Sopenharmony_ci 2365425bb815Sopenharmony_ci if (!SCANNER_STREAM_TYPE_IS_FUNCTION (type)) 2366425bb815Sopenharmony_ci { 2367425bb815Sopenharmony_ci continue; 2368425bb815Sopenharmony_ci } 2369425bb815Sopenharmony_ci 2370425bb815Sopenharmony_ci if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p)) 2371425bb815Sopenharmony_ci { 2372425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK); 2373425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED); 2374425bb815Sopenharmony_ci } 2375425bb815Sopenharmony_ci 2376425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 2377425bb815Sopenharmony_ci context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p); 2378425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 2379425bb815Sopenharmony_ci 2380425bb815Sopenharmony_ci if (!SCANNER_STREAM_TYPE_IS_ARG_FUNC (type)) 2381425bb815Sopenharmony_ci { 2382425bb815Sopenharmony_ci if (func_init_opcode == CBC_INIT_ARG_OR_FUNC && (option_flags & SCANNER_CREATE_VARS_IS_SCRIPT)) 2383425bb815Sopenharmony_ci { 2384425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2385425bb815Sopenharmony_ci literal.char_p -= data_p[1]; 2386425bb815Sopenharmony_ci if (!(context_p->global_status_flags & ECMA_PARSE_DIRECT_EVAL) 2387425bb815Sopenharmony_ci || !scanner_scope_find_let_declaration (context_p, &literal)) 2388425bb815Sopenharmony_ci { 2389425bb815Sopenharmony_ci func_init_opcode = CBC_CREATE_VAR_FUNC_EVAL; 2390425bb815Sopenharmony_ci 2391425bb815Sopenharmony_ci if (context_p->global_status_flags & ECMA_PARSE_FUNCTION_CONTEXT) 2392425bb815Sopenharmony_ci { 2393425bb815Sopenharmony_ci func_init_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CREATE_VAR_FUNC_EVAL); 2394425bb815Sopenharmony_ci } 2395425bb815Sopenharmony_ci } 2396425bb815Sopenharmony_ci literal.char_p += data_p[1]; 2397425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2398425bb815Sopenharmony_ci func_init_opcode = CBC_CREATE_VAR_FUNC_EVAL; 2399425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2400425bb815Sopenharmony_ci } 2401425bb815Sopenharmony_ci 2402425bb815Sopenharmony_ci parser_emit_cbc_literal_value (context_p, func_init_opcode, context_p->literal_count, map_to); 2403425bb815Sopenharmony_ci } 2404425bb815Sopenharmony_ci 2405425bb815Sopenharmony_ci scope_stack_p->map_from = PARSER_SCOPE_STACK_FUNC; 2406425bb815Sopenharmony_ci scope_stack_p->map_to = context_p->literal_count; 2407425bb815Sopenharmony_ci scope_stack_p++; 2408425bb815Sopenharmony_ci 2409425bb815Sopenharmony_ci scanner_create_unused_literal (context_p, 0); 2410425bb815Sopenharmony_ci } 2411425bb815Sopenharmony_ci 2412425bb815Sopenharmony_ci if (info_type == SCANNER_TYPE_FUNCTION 2413425bb815Sopenharmony_ci && !(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_BODY) 2414425bb815Sopenharmony_ci && (info_u8_arg & SCANNER_FUNCTION_ARGUMENTS_NEEDED)) 2415425bb815Sopenharmony_ci { 2416425bb815Sopenharmony_ci JERRY_ASSERT (info_type == SCANNER_TYPE_FUNCTION); 2417425bb815Sopenharmony_ci 2418425bb815Sopenharmony_ci if (JERRY_UNLIKELY (scope_stack_p >= scope_stack_end_p)) 2419425bb815Sopenharmony_ci { 2420425bb815Sopenharmony_ci JERRY_ASSERT (context_p->scope_stack_size == PARSER_MAXIMUM_DEPTH_OF_SCOPE_STACK); 2421425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_SCOPE_STACK_LIMIT_REACHED); 2422425bb815Sopenharmony_ci } 2423425bb815Sopenharmony_ci 2424425bb815Sopenharmony_ci context_p->status_flags |= PARSER_ARGUMENTS_NEEDED | PARSER_LEXICAL_ENV_NEEDED; 2425425bb815Sopenharmony_ci 2426425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &lexer_arguments_literal, lexer_arguments_literal.type); 2427425bb815Sopenharmony_ci 2428425bb815Sopenharmony_ci scope_stack_p->map_from = context_p->lit_object.index; 2429425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2430425bb815Sopenharmony_ci scope_stack_p->map_to = 0; 2431425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2432425bb815Sopenharmony_ci scope_stack_p->map_to = context_p->lit_object.index; 2433425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2434425bb815Sopenharmony_ci scope_stack_p++; 2435425bb815Sopenharmony_ci } 2436425bb815Sopenharmony_ci 2437425bb815Sopenharmony_ci context_p->scope_stack_top = (uint16_t) (scope_stack_p - context_p->scope_stack_p); 2438425bb815Sopenharmony_ci context_p->scope_stack_reg_top = (uint16_t) scope_stack_reg_top; 2439425bb815Sopenharmony_ci 2440425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2441425bb815Sopenharmony_ci if (info_type == SCANNER_TYPE_FUNCTION) 2442425bb815Sopenharmony_ci { 2443425bb815Sopenharmony_ci context_p->scope_stack_global_end = context_p->scope_stack_top; 2444425bb815Sopenharmony_ci } 2445425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2446425bb815Sopenharmony_ci 2447425bb815Sopenharmony_ci if (context_p->register_count < scope_stack_reg_top) 2448425bb815Sopenharmony_ci { 2449425bb815Sopenharmony_ci context_p->register_count = (uint16_t) scope_stack_reg_top; 2450425bb815Sopenharmony_ci } 2451425bb815Sopenharmony_ci 2452425bb815Sopenharmony_ci if (!(option_flags & SCANNER_CREATE_VARS_IS_FUNCTION_ARGS)) 2453425bb815Sopenharmony_ci { 2454425bb815Sopenharmony_ci scanner_release_next (context_p, (size_t) (next_data_p + 1 - ((const uint8_t *) info_p))); 2455425bb815Sopenharmony_ci } 2456425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2457425bb815Sopenharmony_ci} /* scanner_create_variables */ 2458425bb815Sopenharmony_ci 2459425bb815Sopenharmony_ci/** 2460425bb815Sopenharmony_ci * Get location from context. 2461425bb815Sopenharmony_ci */ 2462425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 2463425bb815Sopenharmony_ciscanner_get_location (scanner_location_t *location_p, /**< location */ 2464425bb815Sopenharmony_ci parser_context_t *context_p) /**< context */ 2465425bb815Sopenharmony_ci{ 2466425bb815Sopenharmony_ci location_p->source_p = context_p->source_p; 2467425bb815Sopenharmony_ci location_p->line = context_p->line; 2468425bb815Sopenharmony_ci location_p->column = context_p->column; 2469425bb815Sopenharmony_ci} /* scanner_get_location */ 2470425bb815Sopenharmony_ci 2471425bb815Sopenharmony_ci/** 2472425bb815Sopenharmony_ci * Set context location. 2473425bb815Sopenharmony_ci */ 2474425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 2475425bb815Sopenharmony_ciscanner_set_location (parser_context_t *context_p, /**< context */ 2476425bb815Sopenharmony_ci scanner_location_t *location_p) /**< location */ 2477425bb815Sopenharmony_ci{ 2478425bb815Sopenharmony_ci context_p->source_p = location_p->source_p; 2479425bb815Sopenharmony_ci context_p->line = location_p->line; 2480425bb815Sopenharmony_ci context_p->column = location_p->column; 2481425bb815Sopenharmony_ci} /* scanner_set_location */ 2482425bb815Sopenharmony_ci 2483425bb815Sopenharmony_ci/** 2484425bb815Sopenharmony_ci * Get the real map_to value. 2485425bb815Sopenharmony_ci */ 2486425bb815Sopenharmony_ciinline uint16_t JERRY_ATTR_ALWAYS_INLINE 2487425bb815Sopenharmony_ciscanner_decode_map_to (parser_scope_stack_t *stack_item_p) /**< scope stack item */ 2488425bb815Sopenharmony_ci{ 2489425bb815Sopenharmony_ci JERRY_ASSERT (stack_item_p->map_from != PARSER_SCOPE_STACK_FUNC); 2490425bb815Sopenharmony_ci 2491425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2492425bb815Sopenharmony_ci uint16_t value = (stack_item_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK); 2493425bb815Sopenharmony_ci return (value == 0) ? stack_item_p->map_from : (uint16_t) (value + (PARSER_REGISTER_START - 1)); 2494425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2495425bb815Sopenharmony_ci return stack_item_p->map_to; 2496425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2497425bb815Sopenharmony_ci} /* scanner_decode_map_to */ 2498425bb815Sopenharmony_ci 2499425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2500425bb815Sopenharmony_ci 2501425bb815Sopenharmony_ci/** 2502425bb815Sopenharmony_ci * Checks whether the literal is a const in the current scope. 2503425bb815Sopenharmony_ci * 2504425bb815Sopenharmony_ci * @return true if the literal is a const, false otherwise 2505425bb815Sopenharmony_ci */ 2506425bb815Sopenharmony_cibool 2507425bb815Sopenharmony_ciscanner_literal_is_const_reg (parser_context_t *context_p, /**< context */ 2508425bb815Sopenharmony_ci uint16_t literal_index) /**< literal index */ 2509425bb815Sopenharmony_ci{ 2510425bb815Sopenharmony_ci if (literal_index < PARSER_REGISTER_START) 2511425bb815Sopenharmony_ci { 2512425bb815Sopenharmony_ci /* Re-assignment of non-register const bindings are detected elsewhere. */ 2513425bb815Sopenharmony_ci return false; 2514425bb815Sopenharmony_ci } 2515425bb815Sopenharmony_ci 2516425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top; 2517425bb815Sopenharmony_ci 2518425bb815Sopenharmony_ci literal_index = (uint16_t) (literal_index - (PARSER_REGISTER_START - 1)); 2519425bb815Sopenharmony_ci 2520425bb815Sopenharmony_ci do 2521425bb815Sopenharmony_ci { 2522425bb815Sopenharmony_ci /* Registers must be found in the scope stack. */ 2523425bb815Sopenharmony_ci JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p); 2524425bb815Sopenharmony_ci scope_stack_p--; 2525425bb815Sopenharmony_ci } 2526425bb815Sopenharmony_ci while (literal_index != (scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK)); 2527425bb815Sopenharmony_ci 2528425bb815Sopenharmony_ci return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_CONST_REG) != 0; 2529425bb815Sopenharmony_ci} /* scanner_literal_is_const_reg */ 2530425bb815Sopenharmony_ci 2531425bb815Sopenharmony_ci/** 2532425bb815Sopenharmony_ci * Checks whether the literal is created before. 2533425bb815Sopenharmony_ci * 2534425bb815Sopenharmony_ci * @return true if the literal is created before, false otherwise 2535425bb815Sopenharmony_ci */ 2536425bb815Sopenharmony_cibool 2537425bb815Sopenharmony_ciscanner_literal_is_created (parser_context_t *context_p, /**< context */ 2538425bb815Sopenharmony_ci uint16_t literal_index) /**< literal index */ 2539425bb815Sopenharmony_ci{ 2540425bb815Sopenharmony_ci JERRY_ASSERT (literal_index < PARSER_REGISTER_START); 2541425bb815Sopenharmony_ci 2542425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top; 2543425bb815Sopenharmony_ci 2544425bb815Sopenharmony_ci do 2545425bb815Sopenharmony_ci { 2546425bb815Sopenharmony_ci /* These literals must be found in the scope stack. */ 2547425bb815Sopenharmony_ci JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p); 2548425bb815Sopenharmony_ci scope_stack_p--; 2549425bb815Sopenharmony_ci } 2550425bb815Sopenharmony_ci while (literal_index != scope_stack_p->map_from); 2551425bb815Sopenharmony_ci 2552425bb815Sopenharmony_ci JERRY_ASSERT ((scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK) == 0); 2553425bb815Sopenharmony_ci 2554425bb815Sopenharmony_ci return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_LOCAL_CREATED) != 0; 2555425bb815Sopenharmony_ci} /* scanner_literal_is_created */ 2556425bb815Sopenharmony_ci 2557425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2558425bb815Sopenharmony_ci 2559425bb815Sopenharmony_ci/** 2560425bb815Sopenharmony_ci * @} 2561425bb815Sopenharmony_ci * @} 2562425bb815Sopenharmony_ci * @} 2563425bb815Sopenharmony_ci */ 2564425bb815Sopenharmony_ci 2565425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER) */ 2566