1 /*
2 * duk_hthread allocation and freeing.
3 */
4
5 #include "duk_internal.h"
6
7 /*
8 * Allocate initial stacks for a thread. Note that 'thr' must be reachable
9 * as a garbage collection may be triggered by the allocation attempts.
10 * Returns zero (without leaking memory) if init fails.
11 */
12
duk_hthread_init_stacks(duk_heap * heap,duk_hthread * thr)13 DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) {
14 duk_size_t alloc_size;
15 duk_size_t i;
16
17 DUK_ASSERT(heap != NULL);
18 DUK_ASSERT(thr != NULL);
19 DUK_ASSERT(thr->valstack == NULL);
20 DUK_ASSERT(thr->valstack_end == NULL);
21 DUK_ASSERT(thr->valstack_bottom == NULL);
22 DUK_ASSERT(thr->valstack_top == NULL);
23 DUK_ASSERT(thr->callstack == NULL);
24 DUK_ASSERT(thr->catchstack == NULL);
25
26 /* valstack */
27 alloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;
28 thr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);
29 if (!thr->valstack) {
30 goto fail;
31 }
32 DUK_MEMZERO(thr->valstack, alloc_size);
33 thr->valstack_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;
34 #if !defined(DUK_USE_PREFER_SIZE)
35 thr->valstack_size = DUK_VALSTACK_INITIAL_SIZE;
36 #endif
37 thr->valstack_bottom = thr->valstack;
38 thr->valstack_top = thr->valstack;
39
40 for (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {
41 DUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);
42 }
43
44 /* callstack */
45 alloc_size = sizeof(duk_activation) * DUK_CALLSTACK_INITIAL_SIZE;
46 thr->callstack = (duk_activation *) DUK_ALLOC(heap, alloc_size);
47 if (!thr->callstack) {
48 goto fail;
49 }
50 DUK_MEMZERO(thr->callstack, alloc_size);
51 thr->callstack_size = DUK_CALLSTACK_INITIAL_SIZE;
52 DUK_ASSERT(thr->callstack_top == 0);
53
54 /* catchstack */
55 alloc_size = sizeof(duk_catcher) * DUK_CATCHSTACK_INITIAL_SIZE;
56 thr->catchstack = (duk_catcher *) DUK_ALLOC(heap, alloc_size);
57 if (!thr->catchstack) {
58 goto fail;
59 }
60 DUK_MEMZERO(thr->catchstack, alloc_size);
61 thr->catchstack_size = DUK_CATCHSTACK_INITIAL_SIZE;
62 DUK_ASSERT(thr->catchstack_top == 0);
63
64 return 1;
65
66 fail:
67 DUK_FREE(heap, thr->valstack);
68 DUK_FREE(heap, thr->callstack);
69 DUK_FREE(heap, thr->catchstack);
70
71 thr->valstack = NULL;
72 thr->callstack = NULL;
73 thr->catchstack = NULL;
74 return 0;
75 }
76
77 /* For indirect allocs. */
78
duk_hthread_get_valstack_ptr(duk_heap * heap,void * ud)79 DUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {
80 duk_hthread *thr = (duk_hthread *) ud;
81 DUK_UNREF(heap);
82 return (void *) thr->valstack;
83 }
84
duk_hthread_get_callstack_ptr(duk_heap * heap,void * ud)85 DUK_INTERNAL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud) {
86 duk_hthread *thr = (duk_hthread *) ud;
87 DUK_UNREF(heap);
88 return (void *) thr->callstack;
89 }
90
duk_hthread_get_catchstack_ptr(duk_heap * heap,void * ud)91 DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud) {
92 duk_hthread *thr = (duk_hthread *) ud;
93 DUK_UNREF(heap);
94 return (void *) thr->catchstack;
95 }
96