• 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 /*
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