4 * Provides primitive allocation functions for all object types (plain object,
5 * compiled function, native function, thread). The object return is not yet
6 * in "heap allocated" list and has a refcount of zero, so caller must careful.
9 #include "duk_internal.h"
11 DUK_LOCAL
void duk__init_object_parts(duk_heap
*heap
, duk_hobject
*obj
, duk_uint_t hobject_flags
) {
12 #ifdef DUK_USE_EXPLICIT_NULL_INIT
13 DUK_HOBJECT_SET_PROPS(heap
, obj
, NULL
);
16 /* XXX: macro? sets both heaphdr and object flags */
17 obj
->hdr
.h_flags
= hobject_flags
;
18 DUK_HEAPHDR_SET_TYPE(&obj
->hdr
, DUK_HTYPE_OBJECT
); /* also goes into flags */
20 #if defined(DUK_USE_HEAPPTR16)
21 /* Zero encoded pointer is required to match NULL */
22 DUK_HEAPHDR_SET_NEXT(heap
, &obj
->hdr
, NULL
);
23 #if defined(DUK_USE_DOUBLE_LINKED_HEAP)
24 DUK_HEAPHDR_SET_PREV(heap
, &obj
->hdr
, NULL
);
27 DUK_ASSERT_HEAPHDR_LINKS(heap
, &obj
->hdr
);
28 DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap
, &obj
->hdr
);
31 * obj->props is intentionally left as NULL, and duk_hobject_props.c must deal
32 * with this properly. This is intentional: empty objects consume a minimum
33 * amount of memory. Further, an initial allocation might fail and cause
34 * 'obj' to "leak" (require a mark-and-sweep) since it is not reachable yet.
39 * Allocate an duk_hobject.
41 * The allocated object has no allocation for properties; the caller may
42 * want to force a resize if a desired size is known.
44 * The allocated object has zero reference count and is not reachable.
45 * The caller MUST make the object reachable and increase its reference
46 * count before invoking any operation that might require memory allocation.
49 DUK_INTERNAL duk_hobject
*duk_hobject_alloc(duk_heap
*heap
, duk_uint_t hobject_flags
) {
52 DUK_ASSERT(heap
!= NULL
);
54 /* different memory layout, alloc size, and init */
55 DUK_ASSERT((hobject_flags
& DUK_HOBJECT_FLAG_COMPILEDFUNCTION
) == 0);
56 DUK_ASSERT((hobject_flags
& DUK_HOBJECT_FLAG_NATIVEFUNCTION
) == 0);
57 DUK_ASSERT((hobject_flags
& DUK_HOBJECT_FLAG_THREAD
) == 0);
59 res
= (duk_hobject
*) DUK_ALLOC(heap
, sizeof(duk_hobject
));
63 DUK_MEMZERO(res
, sizeof(duk_hobject
));
65 duk__init_object_parts(heap
, res
, hobject_flags
);
70 DUK_INTERNAL duk_hcompiledfunction
*duk_hcompiledfunction_alloc(duk_heap
*heap
, duk_uint_t hobject_flags
) {
71 duk_hcompiledfunction
*res
;
73 res
= (duk_hcompiledfunction
*) DUK_ALLOC(heap
, sizeof(duk_hcompiledfunction
));
77 DUK_MEMZERO(res
, sizeof(duk_hcompiledfunction
));
79 duk__init_object_parts(heap
, &res
->obj
, hobject_flags
);
81 #ifdef DUK_USE_EXPLICIT_NULL_INIT
82 #ifdef DUK_USE_HEAPPTR16
83 /* NULL pointer is required to encode to zero, so memset is enough. */
94 DUK_INTERNAL duk_hnativefunction
*duk_hnativefunction_alloc(duk_heap
*heap
, duk_uint_t hobject_flags
) {
95 duk_hnativefunction
*res
;
97 res
= (duk_hnativefunction
*) DUK_ALLOC(heap
, sizeof(duk_hnativefunction
));
101 DUK_MEMZERO(res
, sizeof(duk_hnativefunction
));
103 duk__init_object_parts(heap
, &res
->obj
, hobject_flags
);
105 #ifdef DUK_USE_EXPLICIT_NULL_INIT
112 DUK_INTERNAL duk_hbufferobject
*duk_hbufferobject_alloc(duk_heap
*heap
, duk_uint_t hobject_flags
) {
113 duk_hbufferobject
*res
;
115 res
= (duk_hbufferobject
*) DUK_ALLOC(heap
, sizeof(duk_hbufferobject
));
119 DUK_MEMZERO(res
, sizeof(duk_hbufferobject
));
121 duk__init_object_parts(heap
, &res
->obj
, hobject_flags
);
123 #ifdef DUK_USE_EXPLICIT_NULL_INIT
127 DUK_ASSERT_HBUFFEROBJECT_VALID(res
);
132 * Allocate a new thread.
134 * Leaves the built-ins array uninitialized. The caller must either
135 * initialize a new global context or share existing built-ins from
139 DUK_INTERNAL duk_hthread
*duk_hthread_alloc(duk_heap
*heap
, duk_uint_t hobject_flags
) {
142 res
= (duk_hthread
*) DUK_ALLOC(heap
, sizeof(duk_hthread
));
146 DUK_MEMZERO(res
, sizeof(duk_hthread
));
148 duk__init_object_parts(heap
, &res
->obj
, hobject_flags
);
150 #ifdef DUK_USE_EXPLICIT_NULL_INIT
151 res
->ptr_curr_pc
= NULL
;
153 res
->valstack
= NULL
;
154 res
->valstack_end
= NULL
;
155 res
->valstack_bottom
= NULL
;
156 res
->valstack_top
= NULL
;
157 res
->callstack
= NULL
;
158 res
->catchstack
= NULL
;
160 res
->compile_ctx
= NULL
,
161 #ifdef DUK_USE_HEAPPTR16
168 for (i
= 0; i
< DUK_NUM_BUILTINS
; i
++) {
169 res
->builtins
[i
] = NULL
;
173 /* when nothing is running, API calls are in non-strict mode */
174 DUK_ASSERT(res
->strict
== 0);
177 res
->valstack_max
= DUK_VALSTACK_DEFAULT_MAX
;
178 res
->callstack_max
= DUK_CALLSTACK_DEFAULT_MAX
;
179 res
->catchstack_max
= DUK_CATCHSTACK_DEFAULT_MAX
;
184 #if 0 /* unused now */
185 DUK_INTERNAL duk_hobject
*duk_hobject_alloc_checked(duk_hthread
*thr
, duk_uint_t hobject_flags
) {
186 duk_hobject
*res
= duk_hobject_alloc(thr
->heap
, hobject_flags
);
188 DUK_ERROR_ALLOC_DEFMSG(thr
);