+++ /dev/null
-/*
- * Hobject allocation.
- *
- * Provides primitive allocation functions for all object types (plain object,
- * compiled function, native function, thread). The object return is not yet
- * in "heap allocated" list and has a refcount of zero, so caller must careful.
- */
-
-#include "duk_internal.h"
-
-DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_hobject *obj, duk_uint_t hobject_flags) {
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
- DUK_HOBJECT_SET_PROPS(heap, obj, NULL);
-#endif
-
- /* XXX: macro? sets both heaphdr and object flags */
- obj->hdr.h_flags = hobject_flags;
- DUK_HEAPHDR_SET_TYPE(&obj->hdr, DUK_HTYPE_OBJECT); /* also goes into flags */
-
-#if defined(DUK_USE_HEAPPTR16)
- /* Zero encoded pointer is required to match NULL */
- DUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);
-#if defined(DUK_USE_DOUBLE_LINKED_HEAP)
- DUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);
-#endif
-#endif
- DUK_ASSERT_HEAPHDR_LINKS(heap, &obj->hdr);
- DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);
-
- /*
- * obj->props is intentionally left as NULL, and duk_hobject_props.c must deal
- * with this properly. This is intentional: empty objects consume a minimum
- * amount of memory. Further, an initial allocation might fail and cause
- * 'obj' to "leak" (require a mark-and-sweep) since it is not reachable yet.
- */
-}
-
-/*
- * Allocate an duk_hobject.
- *
- * The allocated object has no allocation for properties; the caller may
- * want to force a resize if a desired size is known.
- *
- * The allocated object has zero reference count and is not reachable.
- * The caller MUST make the object reachable and increase its reference
- * count before invoking any operation that might require memory allocation.
- */
-
-DUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
- duk_hobject *res;
-
- DUK_ASSERT(heap != NULL);
-
- /* different memory layout, alloc size, and init */
- DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPILEDFUNCTION) == 0);
- DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATIVEFUNCTION) == 0);
- DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_THREAD) == 0);
-
- res = (duk_hobject *) DUK_ALLOC(heap, sizeof(duk_hobject));
- if (!res) {
- return NULL;
- }
- DUK_MEMZERO(res, sizeof(duk_hobject));
-
- duk__init_object_parts(heap, res, hobject_flags);
-
- return res;
-}
-
-DUK_INTERNAL duk_hcompiledfunction *duk_hcompiledfunction_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
- duk_hcompiledfunction *res;
-
- res = (duk_hcompiledfunction *) DUK_ALLOC(heap, sizeof(duk_hcompiledfunction));
- if (!res) {
- return NULL;
- }
- DUK_MEMZERO(res, sizeof(duk_hcompiledfunction));
-
- duk__init_object_parts(heap, &res->obj, hobject_flags);
-
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
-#ifdef DUK_USE_HEAPPTR16
- /* NULL pointer is required to encode to zero, so memset is enough. */
-#else
- res->data = NULL;
- res->funcs = NULL;
- res->bytecode = NULL;
-#endif
-#endif
-
- return res;
-}
-
-DUK_INTERNAL duk_hnativefunction *duk_hnativefunction_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
- duk_hnativefunction *res;
-
- res = (duk_hnativefunction *) DUK_ALLOC(heap, sizeof(duk_hnativefunction));
- if (!res) {
- return NULL;
- }
- DUK_MEMZERO(res, sizeof(duk_hnativefunction));
-
- duk__init_object_parts(heap, &res->obj, hobject_flags);
-
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
- res->func = NULL;
-#endif
-
- return res;
-}
-
-DUK_INTERNAL duk_hbufferobject *duk_hbufferobject_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
- duk_hbufferobject *res;
-
- res = (duk_hbufferobject *) DUK_ALLOC(heap, sizeof(duk_hbufferobject));
- if (!res) {
- return NULL;
- }
- DUK_MEMZERO(res, sizeof(duk_hbufferobject));
-
- duk__init_object_parts(heap, &res->obj, hobject_flags);
-
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
- res->buf = NULL;
-#endif
-
- DUK_ASSERT_HBUFFEROBJECT_VALID(res);
- return res;
-}
-
-/*
- * Allocate a new thread.
- *
- * Leaves the built-ins array uninitialized. The caller must either
- * initialize a new global context or share existing built-ins from
- * another thread.
- */
-
-DUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
- duk_hthread *res;
-
- res = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));
- if (!res) {
- return NULL;
- }
- DUK_MEMZERO(res, sizeof(duk_hthread));
-
- duk__init_object_parts(heap, &res->obj, hobject_flags);
-
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
- res->ptr_curr_pc = NULL;
- res->heap = NULL;
- res->valstack = NULL;
- res->valstack_end = NULL;
- res->valstack_bottom = NULL;
- res->valstack_top = NULL;
- res->callstack = NULL;
- res->catchstack = NULL;
- res->resumer = NULL;
- res->compile_ctx = NULL,
-#ifdef DUK_USE_HEAPPTR16
- res->strs16 = NULL;
-#else
- res->strs = NULL;
-#endif
- {
- int i;
- for (i = 0; i < DUK_NUM_BUILTINS; i++) {
- res->builtins[i] = NULL;
- }
- }
-#endif
- /* when nothing is running, API calls are in non-strict mode */
- DUK_ASSERT(res->strict == 0);
-
- res->heap = heap;
- res->valstack_max = DUK_VALSTACK_DEFAULT_MAX;
- res->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;
- res->catchstack_max = DUK_CATCHSTACK_DEFAULT_MAX;
-
- return res;
-}
-
-#if 0 /* unused now */
-DUK_INTERNAL duk_hobject *duk_hobject_alloc_checked(duk_hthread *thr, duk_uint_t hobject_flags) {
- duk_hobject *res = duk_hobject_alloc(thr->heap, hobject_flags);
- if (!res) {
- DUK_ERROR_ALLOC_DEFMSG(thr);
- }
- return res;
-}
-#endif