/* Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef JS_SCANNER_H #define JS_SCANNER_H /** \addtogroup parser Parser * @{ * * \addtogroup jsparser JavaScript * @{ * * \addtogroup jsparser_scanner Scanner * @{ */ /** * Allowed types for scanner_info_t structures. */ typedef enum { SCANNER_TYPE_END, /**< mark the last info block */ SCANNER_TYPE_END_ARGUMENTS, /**< mark the end of function arguments * (only present if a function script is parsed) */ SCANNER_TYPE_FUNCTION, /**< declarations in a function */ SCANNER_TYPE_BLOCK, /**< declarations in a code block (usually enclosed in {}) */ SCANNER_TYPE_WHILE, /**< while statement */ SCANNER_TYPE_FOR, /**< for statement */ SCANNER_TYPE_FOR_IN, /**< for-in statement */ #if ENABLED (JERRY_ES2015) SCANNER_TYPE_FOR_OF, /**< for-of statement */ #endif /* ENABLED (JERRY_ES2015) */ SCANNER_TYPE_SWITCH, /**< switch statement */ SCANNER_TYPE_CASE, /**< case statement */ #if ENABLED (JERRY_ES2015) SCANNER_TYPE_INITIALIZER, /**< destructuring binding or assignment pattern with initializer */ SCANNER_TYPE_CLASS_CONSTRUCTOR, /**< class constructor */ SCANNER_TYPE_LET_EXPRESSION, /**< let expression */ SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */ SCANNER_TYPE_ERR_ASYNC_FUNCTION, /**< an invalid async function follows */ #endif /* ENABLED (JERRY_ES2015) */ } scanner_info_type_t; /** * Source code location which can be used to change the position of parsing. */ typedef struct { const uint8_t *source_p; /**< next source byte */ parser_line_counter_t line; /**< token start line */ parser_line_counter_t column; /**< token start column */ } scanner_location_t; /** * Scanner info blocks which provides information for the parser. */ typedef struct scanner_info_t { struct scanner_info_t *next_p; /**< next info structure */ const uint8_t *source_p; /**< triggering position of this scanner info */ uint8_t type; /**< type of the scanner info */ uint8_t u8_arg; /**< custom 8-bit value */ uint16_t u16_arg; /**< custom 16-bit value */ } scanner_info_t; /** * Scanner info extended with a location. */ typedef struct { scanner_info_t info; /**< header */ scanner_location_t location; /**< location */ } scanner_location_info_t; /** * Scanner info for "for" statements. */ typedef struct { scanner_info_t info; /**< header */ scanner_location_t expression_location; /**< location of expression start */ scanner_location_t end_location; /**< location of expression end */ } scanner_for_info_t; /** * Case statement list for scanner_switch_info_t structure. */ typedef struct scanner_case_info_t { struct scanner_case_info_t *next_p; /**< next case statement info */ scanner_location_t location; /**< location of case statement */ } scanner_case_info_t; /** * Scanner info for "switch" statements. */ typedef struct { scanner_info_t info; /**< header */ scanner_case_info_t *case_p; /**< list of switch cases */ } scanner_switch_info_t; /* * Description of compressed streams. * * The stream is a sequence of commands which encoded as bytes. The first byte * contains the type of the command (see scanner_function_compressed_stream_types_t). * * The variable declaration commands has two arguments: * - The first represents the length of the declared identifier * - The second contains the relative distance from the end of the previous declaration * Usually the distance is between 1 and 255, and represented as a single byte * Distances between -256 and 65535 are encoded as two bytes * Larger distances are encoded as pointers */ /** * Constants for compressed streams. */ typedef enum { SCANNER_STREAM_UINT16_DIFF = (1 << 7), /**< relative distance is between -256 and 65535 */ SCANNER_STREAM_HAS_ESCAPE = (1 << 6), /**< binding has escape */ SCANNER_STREAM_NO_REG = (1 << 5), /**< binding cannot be stored in register */ SCANNER_STREAM_EARLY_CREATE = (1 << 4), /**< binding must be created with ECMA_VALUE_UNINITIALIZED */ /* Update SCANNER_STREAM_TYPE_MASK macro if more bits are added. */ } scanner_compressed_stream_flags_t; /** * Types for compressed streams. */ typedef enum { SCANNER_STREAM_TYPE_END, /**< end of scanner data */ SCANNER_STREAM_TYPE_HOLE, /**< no name is assigned to this argument */ SCANNER_STREAM_TYPE_VAR, /**< var declaration */ #if ENABLED (JERRY_ES2015) SCANNER_STREAM_TYPE_LET, /**< let declaration */ SCANNER_STREAM_TYPE_CONST, /**< const declaration */ SCANNER_STREAM_TYPE_LOCAL, /**< local declaration (e.g. catch block) */ #endif /* ENABLED (JERRY_ES2015) */ #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) SCANNER_STREAM_TYPE_IMPORT, /**< module import */ #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ /* The next four types must be in this order (see SCANNER_STREAM_TYPE_IS_ARG). */ SCANNER_STREAM_TYPE_ARG, /**< argument declaration */ #if ENABLED (JERRY_ES2015) SCANNER_STREAM_TYPE_ARG_VAR, /**< argument declaration which is later copied * into a variable declared by var statement */ SCANNER_STREAM_TYPE_DESTRUCTURED_ARG, /**< destructuring argument declaration */ SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR, /**< destructuring argument declaration which is later * copied into a variable declared by var statement */ #endif /* ENABLED (JERRY_ES2015) */ /* Function types should be at the end. See the SCANNER_STREAM_TYPE_IS_FUNCTION macro. */ SCANNER_STREAM_TYPE_ARG_FUNC, /**< argument declaration which * is later initialized with a function */ #if ENABLED (JERRY_ES2015) SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC, /**< destructuring argument declaration which * is later initialized with a function */ #endif /* ENABLED (JERRY_ES2015) */ SCANNER_STREAM_TYPE_FUNC, /**< function declaration */ } scanner_compressed_stream_types_t; /** * Mask for decoding the type from the compressed stream. */ #define SCANNER_STREAM_TYPE_MASK 0xf /** * Checks whether the decoded type represents a function declaration. */ #define SCANNER_STREAM_TYPE_IS_FUNCTION(type) ((type) >= SCANNER_STREAM_TYPE_ARG_FUNC) #if ENABLED (JERRY_ES2015) /** * Checks whether the decoded type represents a function argument. */ #define SCANNER_STREAM_TYPE_IS_ARG(type) \ ((type) >= SCANNER_STREAM_TYPE_ARG && (type) <= SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_VAR) /** * Checks whether the decoded type represents both a function argument and a function declaration. */ #define SCANNER_STREAM_TYPE_IS_ARG_FUNC(type) \ ((type) == SCANNER_STREAM_TYPE_ARG_FUNC || (type) == SCANNER_STREAM_TYPE_DESTRUCTURED_ARG_FUNC) #else /* !ENABLED (JERRY_ES2015) */ /** * Checks whether the decoded type represents a function argument. */ #define SCANNER_STREAM_TYPE_IS_ARG(type) ((type) == SCANNER_STREAM_TYPE_ARG) /** * Checks whether the decoded type represents both a function argument and a function declaration. */ #define SCANNER_STREAM_TYPE_IS_ARG_FUNC(type) ((type) == SCANNER_STREAM_TYPE_ARG_FUNC) #endif /* ENABLED (JERRY_ES2015) */ /** * Constants for u8_arg flags in scanner_function_info_t. */ typedef enum { SCANNER_FUNCTION_ARGUMENTS_NEEDED = (1 << 0), /**< arguments object needs to be created */ SCANNER_FUNCTION_MAPPED_ARGUMENTS = (1 << 1), /**< arguments object should be mapped */ #if ENABLED (JERRY_ES2015) SCANNER_FUNCTION_LEXICAL_ENV_NEEDED = (1 << 2), /**< lexical environment is needed for the function body */ SCANNER_FUNCTION_STATEMENT = (1 << 3), /**< function is function statement (not arrow expression) * this flag must be combined with the type of function (e.g. async) */ SCANNER_FUNCTION_ASYNC = (1 << 4), /**< function is async function */ #endif /* ENABLED (JERRY_ES2015) */ } scanner_function_flags_t; /** * Option bits for scanner_create_variables function. */ typedef enum { SCANNER_CREATE_VARS_NO_OPTS = 0, /**< no options */ SCANNER_CREATE_VARS_IS_SCRIPT = (1 << 0), /**< create variables for script or direct eval */ SCANNER_CREATE_VARS_IS_FUNCTION_ARGS = (1 << 1), /**< create variables for function arguments */ SCANNER_CREATE_VARS_IS_FUNCTION_BODY = (1 << 2), /**< create variables for function body */ } scanner_create_variables_flags_t; /** * @} * @} * @} */ #endif /* !JS_SCANNER_H */