]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_api_heap.c
import 12.2.13 release
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.5.2 / src-separate / duk_api_heap.c
1 /*
2 * Heap creation and destruction
3 */
4
5 #include "duk_internal.h"
6
7 DUK_EXTERNAL
8 duk_context *duk_create_heap(duk_alloc_function alloc_func,
9 duk_realloc_function realloc_func,
10 duk_free_function free_func,
11 void *heap_udata,
12 duk_fatal_function fatal_handler) {
13 duk_heap *heap = NULL;
14 duk_context *ctx;
15
16 /* Assume that either all memory funcs are NULL or non-NULL, mixed
17 * cases will now be unsafe.
18 */
19
20 /* XXX: just assert non-NULL values here and make caller arguments
21 * do the defaulting to the default implementations (smaller code)?
22 */
23
24 if (!alloc_func) {
25 DUK_ASSERT(realloc_func == NULL);
26 DUK_ASSERT(free_func == NULL);
27 #if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)
28 alloc_func = duk_default_alloc_function;
29 realloc_func = duk_default_realloc_function;
30 free_func = duk_default_free_function;
31 #else
32 DUK_D(DUK_DPRINT("no allocation functions given and no default providers"));
33 return NULL;
34 #endif
35 } else {
36 DUK_ASSERT(realloc_func != NULL);
37 DUK_ASSERT(free_func != NULL);
38 }
39
40 if (!fatal_handler) {
41 fatal_handler = duk_default_fatal_handler;
42 }
43
44 DUK_ASSERT(alloc_func != NULL);
45 DUK_ASSERT(realloc_func != NULL);
46 DUK_ASSERT(free_func != NULL);
47 DUK_ASSERT(fatal_handler != NULL);
48
49 heap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler);
50 if (!heap) {
51 return NULL;
52 }
53 ctx = (duk_context *) heap->heap_thread;
54 DUK_ASSERT(ctx != NULL);
55 DUK_ASSERT(((duk_hthread *) ctx)->heap != NULL);
56 return ctx;
57 }
58
59 DUK_EXTERNAL void duk_destroy_heap(duk_context *ctx) {
60 duk_hthread *thr = (duk_hthread *) ctx;
61 duk_heap *heap;
62
63 if (!ctx) {
64 return;
65 }
66 heap = thr->heap;
67 DUK_ASSERT(heap != NULL);
68
69 duk_heap_free(heap);
70 }
71
72 /* XXX: better place for this */
73 DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
74 duk_hthread *thr = (duk_hthread *) ctx;
75 duk_hobject *h_glob;
76 duk_hobject *h_prev_glob;
77 duk_hobject *h_env;
78 duk_hobject *h_prev_env;
79
80 DUK_D(DUK_DPRINT("replace global object with: %!T", duk_get_tval(ctx, -1)));
81
82 h_glob = duk_require_hobject(ctx, -1);
83 DUK_ASSERT(h_glob != NULL);
84
85 /*
86 * Replace global object.
87 */
88
89 h_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];
90 DUK_UNREF(h_prev_glob);
91 thr->builtins[DUK_BIDX_GLOBAL] = h_glob;
92 DUK_HOBJECT_INCREF(thr, h_glob);
93 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob); /* side effects, in theory (referenced by global env) */
94
95 /*
96 * Replace lexical environment for global scope
97 *
98 * Create a new object environment for the global lexical scope.
99 * We can't just reset the _Target property of the current one,
100 * because the lexical scope is shared by other threads with the
101 * same (initial) built-ins.
102 */
103
104 (void) duk_push_object_helper(ctx,
105 DUK_HOBJECT_FLAG_EXTENSIBLE |
106 DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV),
107 -1); /* no prototype, updated below */
108
109 duk_dup(ctx, -2);
110 duk_dup(ctx, -3);
111
112 /* [ ... new_glob new_env new_glob new_glob ] */
113
114 duk_xdef_prop_stridx(thr, -3, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);
115 duk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE);
116
117 /* [ ... new_glob new_env ] */
118
119 h_env = duk_get_hobject(ctx, -1);
120 DUK_ASSERT(h_env != NULL);
121
122 h_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];
123 thr->builtins[DUK_BIDX_GLOBAL_ENV] = h_env;
124 DUK_HOBJECT_INCREF(thr, h_env);
125 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env); /* side effects */
126 DUK_UNREF(h_env); /* without refcounts */
127 DUK_UNREF(h_prev_env);
128
129 /* [ ... new_glob new_env ] */
130
131 duk_pop_2(ctx);
132
133 /* [ ... ] */
134 }