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 COMMON_H 17 #define COMMON_H 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <inttypes.h> 23 #include <setjmp.h> 24 25 /** \addtogroup parser Parser 26 * @{ 27 * 28 * \addtogroup jsparser JavaScript 29 * @{ 30 * 31 * \addtogroup jsparser_utils Utility 32 * @{ 33 */ 34 35 #include "config.h" 36 #include "ecma-globals.h" 37 #include "ecma-regexp-object.h" 38 #include "jmem.h" 39 40 /* Immediate management. */ 41 42 /** 43 * Literal types. 44 * 45 * The LEXER_UNUSED_LITERAL type is internal and 46 * used for various purposes. 47 */ 48 typedef enum 49 { 50 /* The LEXER_IS_IDENT_OR_STRING macro must be updated if the order is changed. */ 51 LEXER_IDENT_LITERAL = 0, /**< identifier literal */ 52 LEXER_STRING_LITERAL = 1, /**< string literal */ 53 LEXER_NUMBER_LITERAL = 2, /**< number literal */ 54 LEXER_FUNCTION_LITERAL = 3, /**< function literal */ 55 LEXER_REGEXP_LITERAL = 4, /**< regexp literal */ 56 LEXER_UNUSED_LITERAL = 5, /**< unused literal, can only be 57 used by the byte code generator. */ 58 LEXER_NEW_IDENT_LITERAL = 6, /**< new local variable, can only be 59 used by the byte code generator. */ 60 } lexer_literal_type_t; 61 62 /** 63 * Checks whether the literal type is identifier or string. 64 */ 65 #define LEXER_IS_IDENT_OR_STRING(literal_type) ((literal_type) <= LEXER_STRING_LITERAL) 66 67 /** 68 * Flag bits for status_flags member of lexer_literal_t. 69 */ 70 typedef enum 71 { 72 LEXER_FLAG_USED = (1 << 0), /**< this local identifier needs to be stored in the constant pool */ 73 LEXER_FLAG_FUNCTION_ARGUMENT = (1 << 1), /**< this local identifier is a function argument */ 74 LEXER_FLAG_SOURCE_PTR = (1 << 2), /**< the literal is directly referenced in the source code 75 * (no need to allocate memory) */ 76 LEXER_FLAG_LATE_INIT = (1 << 3), /**< initialize this variable after the byte code is freed */ 77 #if ENABLED (JERRY_ES2015) 78 LEXER_FLAG_GLOBAL = (1 << 4), /**< this local identifier is not a let or const declaration */ 79 #endif /* ENABLED (JERRY_ES2015) */ 80 } lexer_literal_status_flags_t; 81 82 /** 83 * Type of property length. 84 */ 85 #if ENABLED (JERRY_CPOINTER_32_BIT) 86 typedef uint32_t prop_length_t; 87 #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 88 typedef uint16_t prop_length_t; 89 #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 90 91 /** 92 * Literal data. 93 */ 94 typedef struct 95 { 96 union 97 { 98 ecma_value_t value; /**< literal value (not processed by the parser) */ 99 const uint8_t *char_p; /**< character value */ 100 ecma_compiled_code_t *bytecode_p; /**< compiled function or regexp pointer */ 101 uint32_t source_data; /**< encoded source literal */ 102 } u; 103 104 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 105 struct 106 #else /* !ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 107 union 108 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 109 { 110 prop_length_t length; /**< length of ident / string literal */ 111 uint16_t index; /**< real index during post processing */ 112 } prop; 113 114 uint8_t type; /**< type of the literal */ 115 uint8_t status_flags; /**< status flags */ 116 } lexer_literal_t; 117 118 void util_free_literal (lexer_literal_t *literal_p); 119 120 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 121 void util_print_literal (lexer_literal_t *); 122 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 123 124 /* TRY/CATCH block */ 125 126 #define PARSER_TRY_CONTEXT(context_name) \ 127 jmp_buf context_name 128 129 #define PARSER_THROW(context_name) \ 130 longjmp (context_name, 1); 131 132 #define PARSER_TRY(context_name) \ 133 { \ 134 if (!setjmp (context_name)) \ 135 { \ 136 137 #define PARSER_CATCH \ 138 } \ 139 else \ 140 { 141 142 #define PARSER_TRY_END \ 143 } \ 144 } 145 146 /** 147 * @} 148 * @} 149 * @} 150 */ 151 152 #endif /* !COMMON_H */ 153