1 /* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef JS_SCANNER_INTERNAL_H 17 #define JS_SCANNER_INTERNAL_H 18 19 /* \addtogroup parser Parser 20 * @{ 21 * 22 * \addtogroup jsparser JavaScript 23 * @{ 24 * 25 * \addtogroup jsparser_scanner Scanner 26 * @{ 27 */ 28 29 /** 30 * Scan mode types. 31 */ 32 typedef enum 33 { 34 SCAN_MODE_PRIMARY_EXPRESSION, /**< scanning primary expression */ 35 SCAN_MODE_PRIMARY_EXPRESSION_AFTER_NEW, /**< scanning primary expression after new */ 36 SCAN_MODE_POST_PRIMARY_EXPRESSION, /**< scanning post primary expression */ 37 SCAN_MODE_PRIMARY_EXPRESSION_END, /**< scanning primary expression end */ 38 SCAN_MODE_STATEMENT, /**< scanning statement */ 39 SCAN_MODE_STATEMENT_OR_TERMINATOR, /**< scanning statement or statement end */ 40 SCAN_MODE_STATEMENT_END, /**< scanning statement end */ 41 SCAN_MODE_VAR_STATEMENT, /**< scanning var statement */ 42 SCAN_MODE_PROPERTY_NAME, /**< scanning property name */ 43 SCAN_MODE_FUNCTION_ARGUMENTS, /**< scanning function arguments */ 44 #if ENABLED (JERRY_ES2015) 45 SCAN_MODE_CONTINUE_FUNCTION_ARGUMENTS, /**< continue scanning function arguments */ 46 SCAN_MODE_BINDING, /**< array or object binding */ 47 SCAN_MODE_CLASS_DECLARATION, /**< scanning class declaration */ 48 SCAN_MODE_CLASS_METHOD, /**< scanning class method */ 49 #endif /* ENABLED (JERRY_ES2015) */ 50 } scan_modes_t; 51 52 /** 53 * Scan stack mode types. 54 */ 55 typedef enum 56 { 57 SCAN_STACK_SCRIPT, /**< script */ 58 SCAN_STACK_SCRIPT_FUNCTION, /**< script is a function body */ 59 SCAN_STACK_BLOCK_STATEMENT, /**< block statement group */ 60 SCAN_STACK_FUNCTION_STATEMENT, /**< function statement */ 61 SCAN_STACK_FUNCTION_EXPRESSION, /**< function expression */ 62 SCAN_STACK_FUNCTION_PROPERTY, /**< function expression in an object literal or class */ 63 #if ENABLED (JERRY_ES2015) 64 SCAN_STACK_FUNCTION_ARROW, /**< arrow function expression */ 65 #endif /* ENABLED (JERRY_ES2015) */ 66 SCAN_STACK_SWITCH_BLOCK, /**< block part of "switch" statement */ 67 SCAN_STACK_IF_STATEMENT, /**< statement part of "if" statements */ 68 SCAN_STACK_WITH_STATEMENT, /**< statement part of "with" statements */ 69 SCAN_STACK_WITH_EXPRESSION, /**< expression part of "with" statements */ 70 SCAN_STACK_DO_STATEMENT, /**< statement part of "do" statements */ 71 SCAN_STACK_DO_EXPRESSION, /**< expression part of "do" statements */ 72 SCAN_STACK_WHILE_EXPRESSION, /**< expression part of "while" iterator */ 73 SCAN_STACK_PAREN_EXPRESSION, /**< expression in brackets */ 74 SCAN_STACK_STATEMENT_WITH_EXPR, /**< statement which starts with expression enclosed in brackets */ 75 #if ENABLED (JERRY_ES2015) 76 SCAN_STACK_BINDING_INIT, /**< post processing after a single initializer */ 77 SCAN_STACK_BINDING_LIST_INIT, /**< post processing after an initializer list */ 78 SCAN_STACK_LET, /**< let statement */ 79 SCAN_STACK_CONST, /**< const statement */ 80 #endif /* ENABLED (JERRY_ES2015) */ 81 /* The SCANNER_IS_FOR_START macro needs to be updated when the following constants are reordered. */ 82 SCAN_STACK_VAR, /**< var statement */ 83 SCAN_STACK_FOR_VAR_START, /**< start of "for" iterator with var statement */ 84 #if ENABLED (JERRY_ES2015) 85 SCAN_STACK_FOR_LET_START, /**< start of "for" iterator with let statement */ 86 SCAN_STACK_FOR_CONST_START, /**< start of "for" iterator with const statement */ 87 #endif /* ENABLED (JERRY_ES2015) */ 88 SCAN_STACK_FOR_START, /**< start of "for" iterator */ 89 SCAN_STACK_FOR_CONDITION, /**< condition part of "for" iterator */ 90 SCAN_STACK_FOR_EXPRESSION, /**< expression part of "for" iterator */ 91 SCAN_STACK_SWITCH_EXPRESSION, /**< expression part of "switch" statement */ 92 SCAN_STACK_CASE_STATEMENT, /**< case statement inside a switch statement */ 93 SCAN_STACK_COLON_EXPRESSION, /**< expression between a question mark and colon */ 94 SCAN_STACK_TRY_STATEMENT, /**< try statement */ 95 SCAN_STACK_CATCH_STATEMENT, /**< catch statement */ 96 SCAN_STACK_ARRAY_LITERAL, /**< array literal or destructuring assignment or binding */ 97 SCAN_STACK_OBJECT_LITERAL, /**< object literal group */ 98 SCAN_STACK_PROPERTY_ACCESSOR, /**< property accessor in square brackets */ 99 #if ENABLED (JERRY_ES2015) 100 /* These four must be in this order. */ 101 SCAN_STACK_COMPUTED_PROPERTY, /**< computed property name */ 102 SCAN_STACK_COMPUTED_GENERATOR, /**< computed generator function */ 103 SCAN_STACK_COMPUTED_ASYNC, /**< computed async function */ 104 SCAN_STACK_COMPUTED_ASYNC_GENERATOR, /**< computed async function */ 105 SCAN_STACK_TEMPLATE_STRING, /**< template string */ 106 SCAN_STACK_TAGGED_TEMPLATE_LITERAL, /**< tagged template literal */ 107 SCAN_STACK_PRIVATE_BLOCK_EARLY, /**< private block for single statements (force early declarations) */ 108 SCAN_STACK_PRIVATE_BLOCK, /**< private block for single statements */ 109 SCAN_STACK_ARROW_ARGUMENTS, /**< might be arguments of an arrow function */ 110 SCAN_STACK_ARROW_EXPRESSION, /**< expression body of an arrow function */ 111 SCAN_STACK_EXPLICIT_CLASS_CONSTRUCTOR, /**< explicit class constructor */ 112 SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR, /**< implicit class constructor */ 113 SCAN_STACK_CLASS_STATEMENT, /**< class statement */ 114 SCAN_STACK_CLASS_EXPRESSION, /**< class expression */ 115 SCAN_STACK_CLASS_EXTENDS, /**< class extends expression */ 116 SCAN_STACK_FUNCTION_PARAMETERS, /**< function parameter initializer */ 117 SCAN_STACK_USE_ASYNC, /**< an "async" identifier is used */ 118 #endif /* ENABLED (JERRY_ES2015) */ 119 } scan_stack_modes_t; 120 121 /** 122 * Scanner context flag types. 123 */ 124 typedef enum 125 { 126 SCANNER_CONTEXT_NO_FLAGS = 0, /**< no flags are set */ 127 #if ENABLED (JERRY_ES2015) 128 SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION = (1 << 0), /**< throw async function error */ 129 #endif /* ENABLED (JERRY_ES2015) */ 130 #if ENABLED (JERRY_DEBUGGER) 131 SCANNER_CONTEXT_DEBUGGER_ENABLED = (1 << 1), /**< debugger is enabled */ 132 #endif /* ENABLED (JERRY_DEBUGGER) */ 133 } scanner_context_flags_t; 134 135 /** 136 * Checks whether the stack top is a for statement start. 137 */ 138 #define SCANNER_IS_FOR_START(stack_top) \ 139 ((stack_top) >= SCAN_STACK_FOR_VAR_START && (stack_top) <= SCAN_STACK_FOR_START) 140 141 /** 142 * Generic descriptor which stores only the start position. 143 */ 144 typedef struct 145 { 146 const uint8_t *source_p; /**< start source byte */ 147 } scanner_source_start_t; 148 149 /** 150 * Descriptor for storing a binding literal on stack. 151 */ 152 typedef struct 153 { 154 lexer_lit_location_t *literal_p; /**< binding literal */ 155 } scanner_binding_literal_t; 156 157 /** 158 * Flags for type member of lexer_lit_location_t structure in the literal pool. 159 */ 160 typedef enum 161 { 162 SCANNER_LITERAL_IS_ARG = (1 << 0), /**< literal is argument */ 163 SCANNER_LITERAL_IS_VAR = (1 << 1), /**< literal is var */ 164 #if ENABLED (JERRY_ES2015) 165 /** literal is a destructured argument binding of a possible arrow function */ 166 SCANNER_LITERAL_IS_ARROW_DESTRUCTURED_ARG = SCANNER_LITERAL_IS_VAR, 167 #endif /* ENABLED (JERRY_ES2015) */ 168 SCANNER_LITERAL_IS_FUNC = (1 << 2), /**< literal is function */ 169 SCANNER_LITERAL_NO_REG = (1 << 3), /**< literal cannot be stored in a register */ 170 SCANNER_LITERAL_IS_LET = (1 << 4), /**< literal is let */ 171 #if ENABLED (JERRY_ES2015) 172 /** literal is a function declared in this block (prevents declaring let/const with the same name) */ 173 SCANNER_LITERAL_IS_FUNC_DECLARATION = SCANNER_LITERAL_IS_LET, 174 #endif /* ENABLED (JERRY_ES2015) */ 175 SCANNER_LITERAL_IS_CONST = (1 << 5), /**< literal is const */ 176 #if ENABLED (JERRY_ES2015) 177 /** literal is a destructured argument binding */ 178 SCANNER_LITERAL_IS_DESTRUCTURED_ARG = SCANNER_LITERAL_IS_CONST, 179 SCANNER_LITERAL_IS_USED = (1 << 6), /**< literal is used */ 180 SCANNER_LITERAL_EARLY_CREATE = (1 << 7), /**< binding should be created early with ECMA_VALUE_UNINITIALIZED */ 181 #endif /* ENABLED (JERRY_ES2015) */ 182 } scanner_literal_type_flags_t; 183 184 /* 185 * Known combinations: 186 * 187 * SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION : 188 * function declared in this block 189 * SCANNER_LITERAL_IS_LOCAL : 190 * module import on global scope, catch block variable otherwise 191 * SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_FUNC : 192 * a function argument which is reassigned to a function later 193 * SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG : 194 * destructured binding argument 195 * SCANNER_LITERAL_IS_ARG | SCANNER_LITERAL_IS_DESTRUCTURED_ARG | SCANNER_LITERAL_IS_FUNC : 196 * destructured binding argument which is reassigned to a function later 197 */ 198 199 /** 200 * Literal is a local declration (let, const, catch variable, etc.) 201 */ 202 #define SCANNER_LITERAL_IS_LOCAL (SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_IS_CONST) 203 204 /** 205 * For statement descriptor. 206 */ 207 typedef struct 208 { 209 /** shared fields of for statements */ 210 union 211 { 212 const uint8_t *source_p; /**< start source byte */ 213 scanner_for_info_t *for_info_p; /**< for info */ 214 } u; 215 } scanner_for_statement_t; 216 217 /** 218 * Switch statement descriptor. 219 */ 220 typedef struct 221 { 222 scanner_case_info_t **last_case_p; /**< last case info */ 223 } scanner_switch_statement_t; 224 225 #if ENABLED (JERRY_ES2015) 226 227 /** 228 * Types of scanner destructuring bindings. 229 */ 230 typedef enum 231 { 232 /* Update SCANNER_NEEDS_BINDING_LIST after changing these values. */ 233 SCANNER_BINDING_NONE, /**< not a destructuring binding expression */ 234 SCANNER_BINDING_VAR, /**< destructuring var binding */ 235 SCANNER_BINDING_LET, /**< destructuring let binding */ 236 SCANNER_BINDING_CATCH, /**< destructuring catch binding */ 237 SCANNER_BINDING_CONST, /**< destructuring const binding */ 238 SCANNER_BINDING_ARG, /**< destructuring arg binding */ 239 SCANNER_BINDING_ARROW_ARG, /**< possible destructuring arg binding of an arrow function */ 240 } scanner_binding_type_t; 241 242 /** 243 * Check whether a binding list is needed for the binding pattern. 244 */ 245 #define SCANNER_NEEDS_BINDING_LIST(type) ((type) >= SCANNER_BINDING_LET) 246 247 /** 248 * Scanner binding items for destructuring binding patterns. 249 */ 250 typedef struct scanner_binding_item_t 251 { 252 struct scanner_binding_item_t *next_p; /**< next binding in the list */ 253 lexer_lit_location_t *literal_p; /**< binding literal */ 254 } scanner_binding_item_t; 255 256 /** 257 * Scanner binding lists for destructuring binding patterns. 258 */ 259 typedef struct scanner_binding_list_t 260 { 261 struct scanner_binding_list_t *prev_p; /**< prev list */ 262 scanner_binding_item_t *items_p; /**< list of bindings */ 263 bool is_nested; /**< is nested binding declaration */ 264 } scanner_binding_list_t; 265 266 #endif /* ENABLED (JERRY_ES2015) */ 267 268 /** 269 * Flags for scanner_literal_pool_t structure. 270 */ 271 typedef enum 272 { 273 SCANNER_LITERAL_POOL_FUNCTION = (1 << 0), /**< literal pool represents a function */ 274 SCANNER_LITERAL_POOL_BLOCK = (1 << 1), /**< literal pool represents a code block */ 275 SCANNER_LITERAL_POOL_IS_STRICT = (1 << 2), /**< literal pool represents a strict mode code block */ 276 SCANNER_LITERAL_POOL_CAN_EVAL = (1 << 3), /**< prepare for executing eval in this block */ 277 SCANNER_LITERAL_POOL_NO_ARGUMENTS = (1 << 4), /**< arguments object must not be constructed */ 278 #if ENABLED (JERRY_ES2015) 279 SCANNER_LITERAL_POOL_ARGUMENTS_UNMAPPED = (1 << 5), /**< arguments object should be unmapped */ 280 #endif /* ENABLED (JERRY_ES2015) */ 281 SCANNER_LITERAL_POOL_IN_WITH = (1 << 6), /**< literal pool is in a with statement */ 282 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 283 SCANNER_LITERAL_POOL_IN_EXPORT = (1 << 7), /**< the declared variables are exported by the module system */ 284 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 285 #if ENABLED (JERRY_ES2015) 286 SCANNER_LITERAL_POOL_FUNCTION_STATEMENT = (1 << 8), /**< function statement */ 287 SCANNER_LITERAL_POOL_GENERATOR = (1 << 9), /**< generator function */ 288 SCANNER_LITERAL_POOL_ASYNC = (1 << 10), /**< async function */ 289 SCANNER_LITERAL_POOL_ASYNC_ARROW = (1 << 11), /**< can be an async arrow function */ 290 #endif /* ENABLED (JERRY_ES2015) */ 291 } scanner_literal_pool_flags_t; 292 293 /** 294 * Define a function where no arguments are allowed. 295 */ 296 #define SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS \ 297 (SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_NO_ARGUMENTS) 298 299 /** 300 * Getting the generator and async properties of literal pool status flags. 301 */ 302 #define SCANNER_FROM_LITERAL_POOL_TO_COMPUTED(status_flags) \ 303 ((uint8_t) ((((status_flags) >> 9) & 0x3) + SCAN_STACK_COMPUTED_PROPERTY)) 304 305 /** 306 * Setting the generator and async properties of literal pool status flags. 307 */ 308 #define SCANNER_FROM_COMPUTED_TO_LITERAL_POOL(mode) \ 309 (((mode) - SCAN_STACK_COMPUTED_PROPERTY) << 9) 310 311 /** 312 * Local literal pool. 313 */ 314 typedef struct scanner_literal_pool_t 315 { 316 struct scanner_literal_pool_t *prev_p; /**< previous literal pool */ 317 const uint8_t *source_p; /**< source position where the final data needs to be inserted */ 318 parser_list_t literal_pool; /**< list of literal */ 319 uint16_t status_flags; /**< combination of scanner_literal_pool_flags_t flags */ 320 uint16_t no_declarations; /**< size of scope stack required during parsing */ 321 } scanner_literal_pool_t; 322 323 /** 324 * Scanner context. 325 */ 326 struct scanner_context_t 327 { 328 uint32_t context_status_flags; /**< original status flags of the context */ 329 uint8_t mode; /**< scanner mode */ 330 #if ENABLED (JERRY_ES2015) 331 uint8_t binding_type; /**< current destructuring binding type */ 332 #endif /* ENABLED (JERRY_ES2015) */ 333 uint16_t status_flags; /**< scanner status flags */ 334 #if ENABLED (JERRY_ES2015) 335 scanner_binding_list_t *active_binding_list_p; /**< currently active binding list */ 336 #endif /* ENABLED (JERRY_ES2015) */ 337 scanner_literal_pool_t *active_literal_pool_p; /**< currently active literal pool */ 338 scanner_switch_statement_t active_switch_statement; /**< currently active switch statement */ 339 scanner_info_t *end_arguments_p; /**< position of end arguments */ 340 #if ENABLED (JERRY_ES2015) 341 const uint8_t *async_source_p; /**< source position for async functions */ 342 #endif /* ENABLED (JERRY_ES2015) */ 343 }; 344 345 /* Scanner utils. */ 346 347 void scanner_raise_error (parser_context_t *context_p); 348 #if ENABLED (JERRY_ES2015) 349 void scanner_raise_redeclaration_error (parser_context_t *context_p); 350 #endif /* ENABLED (JERRY_ES2015) */ 351 352 void *scanner_malloc (parser_context_t *context_p, size_t size); 353 void scanner_free (void *ptr, size_t size); 354 355 size_t scanner_get_stream_size (scanner_info_t *info_p, size_t size); 356 scanner_info_t *scanner_insert_info (parser_context_t *context_p, const uint8_t *source_p, size_t size); 357 scanner_info_t *scanner_insert_info_before (parser_context_t *context_p, const uint8_t *source_p, 358 scanner_info_t *start_info_p, size_t size); 359 scanner_literal_pool_t *scanner_push_literal_pool (parser_context_t *context_p, scanner_context_t *scanner_context_p, 360 uint16_t status_flags); 361 void scanner_pop_literal_pool (parser_context_t *context_p, scanner_context_t *scanner_context_p); 362 #if ENABLED (JERRY_ES2015) 363 void scanner_construct_global_block (parser_context_t *context_p, scanner_context_t *scanner_context_p); 364 #endif /* ENABLED (JERRY_ES2015) */ 365 void scanner_filter_arguments (parser_context_t *context_p, scanner_context_t *scanner_context_p); 366 lexer_lit_location_t *scanner_add_custom_literal (parser_context_t *context_p, scanner_literal_pool_t *literal_pool_p, 367 const lexer_lit_location_t *literal_location_p); 368 lexer_lit_location_t *scanner_add_literal (parser_context_t *context_p, scanner_context_t *scanner_context_p); 369 void scanner_add_reference (parser_context_t *context_p, scanner_context_t *scanner_context_p); 370 lexer_lit_location_t *scanner_append_argument (parser_context_t *context_p, scanner_context_t *scanner_context_p); 371 #if ENABLED (JERRY_ES2015) 372 void scanner_detect_invalid_var (parser_context_t *context_p, scanner_context_t *scanner_context_p, 373 lexer_lit_location_t *var_literal_p); 374 void scanner_detect_invalid_let (parser_context_t *context_p, lexer_lit_location_t *let_literal_p); 375 #endif /* ENABLED (JERRY_ES2015) */ 376 void scanner_detect_eval_call (parser_context_t *context_p, scanner_context_t *scanner_context_p); 377 378 #if ENABLED (JERRY_ES2015) 379 void scanner_push_class_declaration (parser_context_t *context_p, scanner_context_t *scanner_context_p, 380 uint8_t stack_mode); 381 void scanner_push_destructuring_pattern (parser_context_t *context_p, scanner_context_t *scanner_context_p, 382 uint8_t binding_type, bool is_nested); 383 void scanner_pop_binding_list (scanner_context_t *scanner_context_p); 384 void scanner_append_hole (parser_context_t *context_p, scanner_context_t *scanner_context_p); 385 #endif /* ENABLED (JERRY_ES2015) */ 386 387 /* Scanner operations. */ 388 389 #if ENABLED (JERRY_ES2015) 390 void scanner_add_async_literal (parser_context_t *context_p, scanner_context_t *scanner_context_p); 391 void scanner_check_arrow (parser_context_t *context_p, scanner_context_t *scanner_context_p); 392 void scanner_scan_simple_arrow (parser_context_t *context_p, scanner_context_t *scanner_context_p, 393 const uint8_t *source_p); 394 void scanner_check_arrow_arg (parser_context_t *context_p, scanner_context_t *scanner_context_p); 395 bool scanner_check_async_function (parser_context_t *context_p, scanner_context_t *scanner_context_p); 396 void scanner_check_function_after_if (parser_context_t *context_p, scanner_context_t *scanner_context_p); 397 #endif /* ENABLED (JERRY_ES2015) */ 398 void scanner_scan_bracket (parser_context_t *context_p, scanner_context_t *scanner_context_p); 399 void scanner_check_directives (parser_context_t *context_p, scanner_context_t *scanner_context_p); 400 401 /** 402 * @} 403 * @} 404 * @} 405 */ 406 407 #endif /* !JS_SCANNER_INTERNAL_H */ 408