• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #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