1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #ifndef _NJS_VM_H_INCLUDED_ 8 #define _NJS_VM_H_INCLUDED_ 9 10 11 #define NJS_MAX_STACK_SIZE (256 * 1024) 12 13 14 /* 15 * NJS_PROPERTY_QUERY_GET must be less to NJS_PROPERTY_QUERY_SET 16 * and NJS_PROPERTY_QUERY_DELETE. 17 */ 18 #define NJS_PROPERTY_QUERY_GET 0 19 #define NJS_PROPERTY_QUERY_SET 1 20 #define NJS_PROPERTY_QUERY_DELETE 2 21 22 23 typedef struct njs_frame_s njs_frame_t; 24 typedef struct njs_native_frame_s njs_native_frame_t; 25 typedef struct njs_parser_s njs_parser_t; 26 typedef struct njs_parser_scope_s njs_parser_scope_t; 27 typedef struct njs_parser_node_s njs_parser_node_t; 28 typedef struct njs_generator_s njs_generator_t; 29 30 31 typedef enum { 32 NJS_SCOPE_GLOBAL = 0, 33 NJS_SCOPE_FUNCTION, 34 NJS_SCOPE_BLOCK 35 } njs_scope_t; 36 37 38 typedef enum { 39 NJS_OBJ_TYPE_OBJECT = 0, 40 NJS_OBJ_TYPE_ARRAY, 41 NJS_OBJ_TYPE_BOOLEAN, 42 NJS_OBJ_TYPE_NUMBER, 43 NJS_OBJ_TYPE_SYMBOL, 44 NJS_OBJ_TYPE_STRING, 45 NJS_OBJ_TYPE_FUNCTION, 46 NJS_OBJ_TYPE_ASYNC_FUNCTION, 47 NJS_OBJ_TYPE_REGEXP, 48 NJS_OBJ_TYPE_DATE, 49 NJS_OBJ_TYPE_PROMISE, 50 NJS_OBJ_TYPE_ARRAY_BUFFER, 51 NJS_OBJ_TYPE_DATA_VIEW, 52 NJS_OBJ_TYPE_TEXT_DECODER, 53 NJS_OBJ_TYPE_TEXT_ENCODER, 54 NJS_OBJ_TYPE_BUFFER, 55 56 #define NJS_OBJ_TYPE_HIDDEN_MIN (NJS_OBJ_TYPE_ITERATOR) 57 NJS_OBJ_TYPE_ITERATOR, 58 NJS_OBJ_TYPE_ARRAY_ITERATOR, 59 NJS_OBJ_TYPE_TYPED_ARRAY, 60 #define NJS_OBJ_TYPE_HIDDEN_MAX (NJS_OBJ_TYPE_TYPED_ARRAY + 1) 61 #define NJS_OBJ_TYPE_NORMAL_MAX (NJS_OBJ_TYPE_HIDDEN_MAX) 62 63 #define NJS_OBJ_TYPE_TYPED_ARRAY_MIN (NJS_OBJ_TYPE_UINT8_ARRAY) 64 #define njs_typed_array_index(type) (type - NJS_OBJ_TYPE_TYPED_ARRAY_MIN) 65 NJS_OBJ_TYPE_UINT8_ARRAY, 66 NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY, 67 NJS_OBJ_TYPE_INT8_ARRAY, 68 NJS_OBJ_TYPE_UINT16_ARRAY, 69 NJS_OBJ_TYPE_INT16_ARRAY, 70 NJS_OBJ_TYPE_UINT32_ARRAY, 71 NJS_OBJ_TYPE_INT32_ARRAY, 72 NJS_OBJ_TYPE_FLOAT32_ARRAY, 73 NJS_OBJ_TYPE_FLOAT64_ARRAY, 74 #define NJS_OBJ_TYPE_TYPED_ARRAY_MAX (NJS_OBJ_TYPE_FLOAT64_ARRAY + 1) 75 #define NJS_OBJ_TYPE_TYPED_ARRAY_SIZE (NJS_OBJ_TYPE_TYPED_ARRAY_MAX \ 76 - NJS_OBJ_TYPE_TYPED_ARRAY_MIN) 77 78 NJS_OBJ_TYPE_ERROR, 79 NJS_OBJ_TYPE_EVAL_ERROR, 80 NJS_OBJ_TYPE_INTERNAL_ERROR, 81 NJS_OBJ_TYPE_RANGE_ERROR, 82 NJS_OBJ_TYPE_REF_ERROR, 83 NJS_OBJ_TYPE_SYNTAX_ERROR, 84 NJS_OBJ_TYPE_TYPE_ERROR, 85 NJS_OBJ_TYPE_URI_ERROR, 86 NJS_OBJ_TYPE_MEMORY_ERROR, 87 NJS_OBJ_TYPE_AGGREGATE_ERROR, 88 89 NJS_OBJ_TYPE_MAX, 90 } njs_object_type_t; 91 92 93 #define njs_primitive_prototype_index(type) \ 94 (NJS_OBJ_TYPE_BOOLEAN + ((type) - NJS_BOOLEAN)) 95 96 97 #define njs_prototype_type(index) \ 98 (index + NJS_OBJECT) 99 100 101 enum njs_object_e { 102 NJS_OBJECT_THIS = 0, 103 NJS_OBJECT_NJS, 104 NJS_OBJECT_PROCESS, 105 NJS_OBJECT_MATH, 106 NJS_OBJECT_JSON, 107 #ifdef NJS_TEST262 108 NJS_OBJECT_262, 109 #endif 110 NJS_OBJECT_MAX 111 }; 112 113 114 enum njs_hook_e { 115 NJS_HOOK_EXIT = 0, 116 NJS_HOOK_MAX 117 }; 118 119 120 typedef enum { 121 NJS_LEVEL_LOCAL = 0, 122 NJS_LEVEL_CLOSURE, 123 NJS_LEVEL_GLOBAL, 124 NJS_LEVEL_STATIC, 125 NJS_LEVEL_TEMP, 126 NJS_LEVEL_MAX 127 } njs_level_type_t; 128 129 130 struct njs_vm_s { 131 /* njs_vm_t must be aligned to njs_value_t due to scratch value. */ 132 njs_value_t retval; 133 134 njs_arr_t *paths; 135 njs_arr_t *protos; 136 137 njs_arr_t *scope_absolute; 138 njs_value_t **levels[NJS_LEVEL_MAX]; 139 size_t global_items; 140 141 njs_external_ptr_t external; 142 143 njs_native_frame_t *top_frame; 144 njs_frame_t *active_frame; 145 146 njs_rbtree_t *variables_hash; 147 njs_lvlhsh_t keywords_hash; 148 njs_lvlhsh_t values_hash; 149 150 njs_arr_t *modules; 151 njs_lvlhsh_t modules_hash; 152 153 uint32_t event_id; 154 njs_lvlhsh_t events_hash; 155 njs_queue_t posted_events; 156 njs_queue_t promise_events; 157 158 njs_vm_opt_t options; 159 160 /* 161 * The prototypes and constructors arrays must be together because 162 * they are copied from njs_vm_shared_t by single memcpy() 163 * in njs_builtin_objects_clone(). 164 */ 165 njs_object_prototype_t prototypes[NJS_OBJ_TYPE_MAX]; 166 njs_function_t constructors[NJS_OBJ_TYPE_MAX]; 167 168 njs_function_t *hooks[NJS_HOOK_MAX]; 169 170 njs_mp_t *mem_pool; 171 172 u_char *start; 173 size_t stack_size; 174 175 njs_vm_shared_t *shared; 176 177 njs_regex_generic_ctx_t *regex_generic_ctx; 178 njs_regex_compile_ctx_t *regex_compile_ctx; 179 njs_regex_match_data_t *single_match_data; 180 181 njs_array_t *promise_reason; 182 183 njs_parser_scope_t *global_scope; 184 185 /* 186 * MemoryError is statically allocated immutable Error object 187 * with the InternalError prototype. 188 */ 189 njs_object_t memory_error_object; 190 191 njs_object_t string_object; 192 njs_object_t global_object; 193 njs_value_t global_value; 194 195 njs_arr_t *codes; /* of njs_vm_code_t */ 196 njs_arr_t *functions_name_cache; 197 198 njs_trace_t trace; 199 njs_random_t random; 200 201 uint64_t symbol_generator; 202 }; 203 204 205 typedef struct { 206 uint32_t offset; 207 uint32_t line; 208 } njs_vm_line_num_t; 209 210 211 typedef struct { 212 u_char *start; 213 u_char *end; 214 njs_str_t file; 215 njs_str_t name; 216 njs_arr_t *lines; /* of njs_vm_line_num_t */ 217 } njs_vm_code_t; 218 219 220 struct njs_vm_shared_s { 221 njs_lvlhsh_t keywords_hash; 222 njs_lvlhsh_t values_hash; 223 224 njs_lvlhsh_t array_instance_hash; 225 njs_lvlhsh_t string_instance_hash; 226 njs_lvlhsh_t function_instance_hash; 227 njs_lvlhsh_t async_function_instance_hash; 228 njs_lvlhsh_t arrow_instance_hash; 229 njs_lvlhsh_t arguments_object_instance_hash; 230 njs_lvlhsh_t regexp_instance_hash; 231 232 njs_lvlhsh_t modules_hash; 233 234 njs_lvlhsh_t env_hash; 235 236 njs_object_t string_object; 237 njs_object_t objects[NJS_OBJECT_MAX]; 238 239 njs_exotic_slots_t global_slots; 240 241 /* 242 * The prototypes and constructors arrays must be togther because they are 243 * copied to njs_vm_t by single memcpy() in njs_builtin_objects_clone(). 244 */ 245 njs_object_prototype_t prototypes[NJS_OBJ_TYPE_MAX]; 246 njs_function_t constructors[NJS_OBJ_TYPE_MAX]; 247 248 njs_regexp_pattern_t *empty_regexp_pattern; 249 }; 250 251 252 void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame, 253 njs_native_frame_t *previous); 254 255 njs_int_t njs_builtin_objects_create(njs_vm_t *vm); 256 njs_int_t njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global); 257 njs_int_t njs_builtin_match_native_function(njs_vm_t *vm, 258 njs_function_t *function, njs_str_t *name); 259 260 njs_arr_t *njs_vm_completions(njs_vm_t *vm, njs_str_t *expression); 261 262 void *njs_lvlhsh_alloc(void *data, size_t size); 263 void njs_lvlhsh_free(void *data, void *p, size_t size); 264 265 266 extern const njs_str_t njs_entry_main; 267 extern const njs_str_t njs_entry_module; 268 extern const njs_str_t njs_entry_native; 269 extern const njs_str_t njs_entry_unknown; 270 extern const njs_str_t njs_entry_anonymous; 271 272 extern const njs_lvlhsh_proto_t njs_object_hash_proto; 273 274 275 #endif /* _NJS_VM_H_INCLUDED_ */ 276