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 */
94typedef struct jmem_heap_t jmem_heap_t;
95#endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
96
97/**
98 * User context item
99 */
100typedef 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 */
120struct 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 */
253extern 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
264struct 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 */
283extern 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
307struct 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 */
316extern 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
327void
328jcontext_set_exception_flag (bool is_exception);
329
330void
331jcontext_set_abort_flag (bool is_abort);
332
333bool
334jcontext_has_pending_exception (void);
335
336bool
337jcontext_has_pending_abort (void);
338
339void
340jcontext_raise_exception (ecma_value_t error);
341
342void
343jcontext_release_exception (void);
344
345ecma_value_t
346jcontext_take_exception (void);
347
348/**
349 * @}
350 */
351
352#endif /* !JCONTEXT_H */
353