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 /* 17 * Engine context for JerryScript 18 */ 19 #ifndef JCONTEXT_H 20 #define JCONTEXT_H 21 22 #include "debugger.h" 23 #include "ecma-builtins.h" 24 #include "ecma-helpers.h" 25 #include "ecma-jobqueue.h" 26 #include "jerryscript-port.h" 27 #include "jmem.h" 28 #include "re-bytecode.h" 29 #include "vm-defines.h" 30 #include "jerryscript.h" 31 #include "jerryscript-debugger-transport.h" 32 #include "js-parser-internal.h" 33 #ifdef JERRY_FOR_IAR_CONFIG 34 #include "jerryscript-port-default.h" 35 #endif 36 37 /** \addtogroup context Context 38 * @{ 39 */ 40 41 /** 42 * Advanced allocator configurations. 43 */ 44 /** 45 * Maximum global heap size in bytes 46 */ 47 #define CONFIG_MEM_HEAP_SIZE (JERRY_GLOBAL_HEAP_SIZE * 1024) 48 49 /** 50 * Maximum stack usage size in bytes 51 */ 52 #define CONFIG_MEM_STACK_LIMIT (JERRY_STACK_LIMIT * 1024) 53 54 /** 55 * Max heap usage limit 56 */ 57 #define CONFIG_MAX_GC_LIMIT 8192 58 59 /** 60 * Allowed heap usage limit until next garbage collection 61 * 62 * Whenever the total allocated memory size reaches the current heap limit, garbage collection will be triggered 63 * to try and reduce clutter from unreachable objects. If the allocated memory can't be reduced below the limit, 64 * then the current limit will be incremented by CONFIG_MEM_HEAP_LIMIT. 65 */ 66 #if defined (JERRY_GC_LIMIT) && (JERRY_GC_LIMIT != 0) 67 #define CONFIG_GC_LIMIT JERRY_GC_LIMIT 68 #else 69 #define CONFIG_GC_LIMIT (JERRY_MIN (CONFIG_MEM_HEAP_SIZE / 32, CONFIG_MAX_GC_LIMIT)) 70 #endif 71 72 /** 73 * Amount of newly allocated objects since the last GC run, represented as a fraction of all allocated objects, 74 * which when reached will trigger garbage collection to run with a low pressure setting. 75 * 76 * The fraction is calculated as: 77 * 1.0 / CONFIG_ECMA_GC_NEW_OBJECTS_FRACTION 78 */ 79 #define CONFIG_ECMA_GC_NEW_OBJECTS_FRACTION (16) 80 81 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 82 /** 83 * Heap structure 84 * 85 * Memory blocks returned by the allocator must not start from the 86 * beginning of the heap area because offset 0 is reserved for 87 * JMEM_CP_NULL. This special constant is used in several places, 88 * e.g. it marks the end of the property chain list, so it cannot 89 * be eliminated from the project. Although the allocator cannot 90 * use the first 8 bytes of the heap, nothing prevents to use it 91 * for other purposes. Currently the free region start is stored 92 * there. 93 */ 94 typedef struct jmem_heap_t jmem_heap_t; 95 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 96 97 /** 98 * User context item 99 */ 100 typedef struct jerry_context_data_header 101 { 102 struct jerry_context_data_header *next_p; /**< pointer to next context item */ 103 const jerry_context_data_manager_t *manager_p; /**< manager responsible for deleting this item */ 104 } jerry_context_data_header_t; 105 106 #define JERRY_CONTEXT_DATA_HEADER_USER_DATA(item_p) \ 107 ((uint8_t *) (item_p + 1)) 108 109 /** 110 * First non-external member of the jerry context 111 */ 112 #define JERRY_CONTEXT_FIRST_MEMBER ecma_builtin_objects 113 114 /** 115 * JerryScript context 116 * 117 * The purpose of this header is storing 118 * all global variables for Jerry 119 */ 120 struct jerry_context_t 121 { 122 /* The value of external context members must be preserved across initializations and cleanups. */ 123 #if ENABLED (JERRY_EXTERNAL_CONTEXT) 124 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 125 jmem_heap_t *heap_p; /**< point to the heap aligned to JMEM_ALIGNMENT. */ 126 uint32_t heap_size; /**< size of the heap */ 127 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 128 #endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */ 129 130 /* Update JERRY_CONTEXT_FIRST_MEMBER if the first non-external member changes */ 131 jmem_cpointer_t ecma_builtin_objects[ECMA_BUILTIN_ID__COUNT]; /**< pointer to instances of built-in objects */ 132 #if ENABLED (JERRY_BUILTIN_REGEXP) 133 re_compiled_code_t *re_cache[RE_CACHE_SIZE]; /**< regex cache */ 134 #endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 135 jmem_cpointer_t ecma_gc_objects_cp; /**< List of currently alive objects. */ 136 jmem_heap_free_t *jmem_heap_list_skip_p; /**< This is used to speed up deallocation. */ 137 jmem_pools_chunk_t *jmem_free_8_byte_chunk_p; /**< list of free eight byte pool chunks */ 138 #if ENABLED (JERRY_CPOINTER_32_BIT) 139 jmem_pools_chunk_t *jmem_free_16_byte_chunk_p; /**< list of free sixteen byte pool chunks */ 140 #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 141 const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */ 142 const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */ 143 jmem_cpointer_t string_list_first_cp; /**< first item of the literal string list */ 144 #if ENABLED (JERRY_ES2015) 145 jmem_cpointer_t symbol_list_first_cp; /**< first item of the global symbol list */ 146 #endif /* ENABLED (JERRY_ES2015) */ 147 jmem_cpointer_t number_list_first_cp; /**< first item of the literal number list */ 148 jmem_cpointer_t ecma_global_env_cp; /**< global lexical environment */ 149 #if ENABLED (JERRY_ES2015) 150 jmem_cpointer_t ecma_global_scope_cp; /**< global lexical scope */ 151 #endif /* ENABLED (JERRY_ES2015) */ 152 153 #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 154 ecma_module_t *ecma_modules_p; /**< list of referenced modules */ 155 ecma_module_context_t *module_top_context_p; /**< top (current) module parser context */ 156 #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 157 158 vm_frame_ctx_t *vm_top_context_p; /**< top (current) interpreter context */ 159 jerry_context_data_header_t *context_data_p; /**< linked list of user-provided context-specific pointers */ 160 size_t ecma_gc_objects_number; /**< number of currently allocated objects */ 161 size_t ecma_gc_new_objects; /**< number of newly allocated objects since last GC session */ 162 size_t jmem_heap_allocated_size; /**< size of allocated regions */ 163 size_t jmem_heap_limit; /**< current limit of heap usage, that is upon being reached, 164 * causes call of "try give memory back" callbacks */ 165 ecma_value_t error_value; /**< currently thrown error value */ 166 uint32_t lit_magic_string_ex_count; /**< external magic strings count */ 167 uint32_t jerry_init_flags; /**< run-time configuration flags */ 168 uint32_t status_flags; /**< run-time flags (the top 8 bits are used for passing class parsing options) */ 169 #if (JERRY_GC_MARK_LIMIT != 0) 170 uint32_t ecma_gc_mark_recursion_limit; /**< GC mark recursion limit */ 171 #endif /* (JERRY_GC_MARK_LIMIT != 0) */ 172 173 #if ENABLED (JERRY_PROPRETY_HASHMAP) 174 uint8_t ecma_prop_hashmap_alloc_state; /**< property hashmap allocation state: 0-4, 175 * if !0 property hashmap allocation is disabled */ 176 #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 177 178 #if ENABLED (JERRY_BUILTIN_REGEXP) 179 uint8_t re_cache_idx; /**< evicted item index when regex cache is full (round-robin) */ 180 #endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 181 182 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 183 ecma_job_queue_item_t *job_queue_head_p; /**< points to the head item of the job queue */ 184 ecma_job_queue_item_t *job_queue_tail_p; /**< points to the tail item of the job queue */ 185 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 186 187 #if ENABLED (JERRY_VM_EXEC_STOP) 188 uint32_t vm_exec_stop_frequency; /**< reset value for vm_exec_stop_counter */ 189 uint32_t vm_exec_stop_counter; /**< down counter for reducing the calls of vm_exec_stop_cb */ 190 void *vm_exec_stop_user_p; /**< user pointer for vm_exec_stop_cb */ 191 ecma_vm_exec_stop_callback_t vm_exec_stop_cb; /**< user function which returns whether the 192 * ECMAScript execution should be stopped */ 193 #endif /* ENABLED (JERRY_VM_EXEC_STOP) */ 194 195 #if (JERRY_STACK_LIMIT != 0) 196 uintptr_t stack_base; /**< stack base marker */ 197 #endif /* (JERRY_STACK_LIMIT != 0) */ 198 199 #if ENABLED (JERRY_DEBUGGER) 200 uint8_t debugger_send_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for sending messages */ 201 uint8_t debugger_receive_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for receiving messages */ 202 jerry_debugger_transport_header_t *debugger_transport_header_p; /**< head of transport protocol chain */ 203 uint8_t *debugger_send_buffer_payload_p; /**< start where the outgoing message can be written */ 204 vm_frame_ctx_t *debugger_stop_context; /**< stop only if the current context is equal to this context */ 205 const uint8_t *debugger_exception_byte_code_p; /**< Location of the currently executed byte code if an 206 * error occours while the vm_loop is suspended */ 207 jmem_cpointer_t debugger_byte_code_free_head; /**< head of byte code free linked list */ 208 jmem_cpointer_t debugger_byte_code_free_tail; /**< tail of byte code free linked list */ 209 uint32_t debugger_flags; /**< debugger flags */ 210 uint16_t debugger_received_length; /**< length of currently received bytes */ 211 uint8_t debugger_message_delay; /**< call receive message when reaches zero */ 212 uint8_t debugger_max_send_size; /**< maximum amount of data that can be sent */ 213 uint8_t debugger_max_receive_size; /**< maximum amount of data that can be received */ 214 #endif /* ENABLED (JERRY_DEBUGGER) */ 215 216 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 217 ecma_value_t resource_name; /**< resource name (usually a file name) */ 218 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 219 220 #if ENABLED (JERRY_MEM_STATS) 221 jmem_heap_stats_t jmem_heap_stats; /**< heap's memory usage statistics */ 222 #endif /* ENABLED (JERRY_MEM_STATS) */ 223 224 /* This must be at the end of the context for performance reasons */ 225 #if ENABLED (JERRY_LCACHE) 226 /** hash table for caching the last access of properties */ 227 ecma_lcache_hash_entry_t lcache[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH]; 228 #endif /* ENABLED (JERRY_LCACHE) */ 229 230 #if ENABLED (JERRY_ES2015) 231 /** 232 * Allowed values and it's meaning: 233 * * NULL (0x0): the current "new.target" is undefined, that is the execution is inside a normal method. 234 * * Any other valid function object pointer: the current "new.target" is valid and it is constructor call. 235 */ 236 ecma_object_t *current_new_target; 237 ecma_object_t *current_function_obj_p; /** currently invoked function object 238 (Note: currently used only in generator functions) */ 239 #endif /* ENABLED (JERRY_ES2015) */ 240 241 #ifdef JERRY_FOR_IAR_CONFIG 242 #if ENABLED (JERRY_EXTERNAL_CONTEXT) 243 fatal_handler_t jerry_fatal_handler; /* js task fatal handler */ 244 #endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */ 245 #endif // not defined JERRY_FOR_IAR_CONFIG 246 }; 247 248 #if ENABLED (JERRY_EXTERNAL_CONTEXT) 249 250 /* 251 * This part is for JerryScript which uses external context. 252 */ 253 extern jerry_context_t *jerry_dynamic_global_context_p; 254 255 #define JERRY_CONTEXT_STRUCT (*jerry_dynamic_global_context_p) 256 #define JERRY_CONTEXT(field) (jerry_dynamic_global_context_p->field) 257 258 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 259 260 #define JMEM_HEAP_SIZE (JERRY_CONTEXT (heap_size)) 261 262 #define JMEM_HEAP_AREA_SIZE (JMEM_HEAP_SIZE - JMEM_ALIGNMENT) 263 264 struct jmem_heap_t 265 { 266 jmem_heap_free_t first; /**< first node in free region list */ 267 uint8_t area[]; /**< heap area */ 268 }; 269 270 #define JERRY_HEAP_CONTEXT(field) (JERRY_CONTEXT (heap_p)->field) 271 272 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 273 274 #else /* !ENABLED (JERRY_EXTERNAL_CONTEXT) */ 275 276 /* 277 * This part is for JerryScript which uses default context. 278 */ 279 280 /** 281 * Global context. 282 */ 283 extern jerry_context_t jerry_global_context; 284 285 /** 286 * Config-independent name for context. 287 */ 288 #define JERRY_CONTEXT_STRUCT (jerry_global_context) 289 290 /** 291 * Provides a reference to a field in the current context. 292 */ 293 #define JERRY_CONTEXT(field) (jerry_global_context.field) 294 295 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 296 297 /** 298 * Size of heap 299 */ 300 #define JMEM_HEAP_SIZE ((size_t) (CONFIG_MEM_HEAP_SIZE)) 301 302 /** 303 * Calculate heap area size, leaving space for a pointer to the free list 304 */ 305 #define JMEM_HEAP_AREA_SIZE (JMEM_HEAP_SIZE - JMEM_ALIGNMENT) 306 307 struct jmem_heap_t 308 { 309 jmem_heap_free_t first; /**< first node in free region list */ 310 uint8_t area[JMEM_HEAP_AREA_SIZE]; /**< heap area */ 311 }; 312 313 /** 314 * Global heap. 315 */ 316 extern jmem_heap_t jerry_global_heap; 317 318 /** 319 * Provides a reference to a field of the heap. 320 */ 321 #define JERRY_HEAP_CONTEXT(field) (jerry_global_heap.field) 322 323 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 324 325 #endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */ 326 327 void 328 jcontext_set_exception_flag (bool is_exception); 329 330 void 331 jcontext_set_abort_flag (bool is_abort); 332 333 bool 334 jcontext_has_pending_exception (void); 335 336 bool 337 jcontext_has_pending_abort (void); 338 339 void 340 jcontext_raise_exception (ecma_value_t error); 341 342 void 343 jcontext_release_exception (void); 344 345 ecma_value_t 346 jcontext_take_exception (void); 347 348 /** 349 * @} 350 */ 351 352 #endif /* !JCONTEXT_H */ 353