Skip to content

Commit 21ea24b

Browse files
committed
Linked list for catchstack, attach to activation
Remove explicit catchstack. Make catchers a single linked list of duk_catcher structs, attached to a duk_activation.
1 parent c32aa3f commit 21ea24b

18 files changed

Lines changed: 408 additions & 571 deletions

src-input/duk_api_memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ DUK_EXTERNAL void duk_free(duk_context *ctx, void *ptr) {
4141

4242
DUK_ASSERT_CTX_VALID(ctx);
4343

44-
DUK_FREE(thr->heap, ptr);
44+
DUK_FREE_CHECKED(thr, ptr);
4545
}
4646

4747
DUK_EXTERNAL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size) {

src-input/duk_debug_vsnprintf.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,21 +534,30 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
534534
#endif
535535
} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {
536536
duk_hthread *t = (duk_hthread *) h;
537+
DUK__COMMA(); duk_fb_sprintf(fb, "__ptr_curr_pc:%p", (void *) t->ptr_curr_pc);
538+
DUK__COMMA(); duk_fb_sprintf(fb, "__heap:%p", (void *) t->heap);
537539
DUK__COMMA(); duk_fb_sprintf(fb, "__strict:%ld", (long) t->strict);
538540
DUK__COMMA(); duk_fb_sprintf(fb, "__state:%ld", (long) t->state);
539541
DUK__COMMA(); duk_fb_sprintf(fb, "__unused1:%ld", (long) t->unused1);
540542
DUK__COMMA(); duk_fb_sprintf(fb, "__unused2:%ld", (long) t->unused2);
541543
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_max:%ld", (long) t->valstack_max);
542544
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_max:%ld", (long) t->callstack_max);
543-
DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_max:%ld", (long) t->catchstack_max);
544545
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack:%p", (void *) t->valstack);
545546
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_end:%p/%ld", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));
546547
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_bottom:%p/%ld", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));
547548
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_top:%p/%ld", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));
548-
DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack:%p", (void *) t->catchstack);
549-
DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_size:%ld", (long) t->catchstack_size);
550-
DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_top:%ld", (long) t->catchstack_top);
549+
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack:%p", (void *) t->callstack);
550+
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_curr:%p", (void *) t->callstack_curr);
551+
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_size:%ld", (long) t->callstack_size);
552+
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_top:%ld", (long) t->callstack_top);
553+
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_preventcount:%ld", (long) t->callstack_preventcount);
551554
DUK__COMMA(); duk_fb_sprintf(fb, "__resumer:"); duk__print_hobject(st, (duk_hobject *) t->resumer);
555+
DUK__COMMA(); duk_fb_sprintf(fb, "__compile_ctx:%p", (void *) t->compile_ctx);
556+
#if defined(DUK_USE_INTERRUPT_COUNTER)
557+
DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_counter:%ld", (long) t->interrupt_counter);
558+
DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_init:%ld", (long) t->interrupt_init);
559+
#endif
560+
552561
/* XXX: print built-ins array? */
553562

554563
}

src-input/duk_error_misc.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,25 @@
1212
#if defined(DUK_USE_DEBUGGER_SUPPORT) && \
1313
(defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT))
1414
DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {
15-
/*
16-
* XXX: As noted above, a protected API call won't be counted as a
17-
* catcher. This is usually convenient, e.g. in the case of a top-
18-
* level duk_pcall(), but may not always be desirable. Perhaps add an
19-
* argument to treat them as catchers?
15+
/* As noted above, a protected API call won't be counted as a
16+
* catcher. This is usually convenient, e.g. in the case of a top-
17+
* level duk_pcall(), but may not always be desirable. Perhaps add
18+
* an argument to treat them as catchers?
2019
*/
2120

2221
duk_size_t i;
22+
duk_activation *act;
23+
duk_catcher *cat;
2324

2425
DUK_ASSERT(thr != NULL);
2526

2627
while (thr != NULL) {
27-
for (i = 0; i < thr->catchstack_top; i++) {
28-
duk_catcher *cat = thr->catchstack + i;
29-
if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
30-
return 1; /* all we need to know */
28+
for (i = 0; i < thr->callstack_top; i++) {
29+
act = thr->callstack + i;
30+
for (cat = act->cat; cat != NULL; cat = cat->parent) {
31+
if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
32+
return 1; /* all we need to know */
33+
}
3134
}
3235
}
3336
thr = thr->resumer;

src-input/duk_heap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,14 @@ typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
220220

221221
/*
222222
* Checked allocation, relative to a thread
223+
*
224+
* DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument
225+
* for convenience.
223226
*/
224227

225228
#define DUK_ALLOC_CHECKED(thr,size) duk_heap_mem_alloc_checked((thr), (size))
226229
#define DUK_ALLOC_CHECKED_ZEROED(thr,size) duk_heap_mem_alloc_checked_zeroed((thr), (size))
230+
#define DUK_FREE_CHECKED(thr,ptr) duk_heap_mem_free((thr)->heap, (ptr))
227231

228232
/*
229233
* Memory constants

src-input/duk_heap_alloc.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,27 @@ DUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {
3434
/* Currently nothing to free */
3535
} else if (DUK_HOBJECT_IS_THREAD(h)) {
3636
duk_hthread *t = (duk_hthread *) h;
37+
duk_activation *act;
38+
duk_catcher *cat;
39+
duk_size_t i;
40+
3741
DUK_FREE(heap, t->valstack);
38-
DUK_FREE(heap, t->callstack);
39-
DUK_FREE(heap, t->catchstack);
42+
4043
/* Don't free h->resumer because it exists in the heap.
4144
* Callstack entries also contain function pointers which
4245
* are not freed for the same reason.
4346
*/
47+
for (i = t->callstack_top; i > 0; i--) {
48+
act = t->callstack + i;
49+
for (cat = act->cat; cat != NULL;) {
50+
duk_catcher *cat_next;
51+
52+
cat_next = cat->parent;
53+
DUK_FREE(heap, (void *) cat);
54+
cat = cat_next;
55+
}
56+
}
57+
DUK_FREE(heap, t->callstack);
4458

4559
/* XXX: with 'caller' property the callstack would need
4660
* to be unwound to update the 'caller' properties of

src-input/duk_heap_finalize.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_context *ctx) {
1717
/* Require a lot of stack to force a value stack grow/shrink. */
1818
duk_require_stack(ctx, 100000);
1919

20-
/* Force a reallocation with pointer change for value, call, and
21-
* catch stacks to maximize side effects.
20+
/* Force a reallocation with pointer change for value and call
21+
* stacks to maximize side effects.
2222
*/
2323
duk_hthread_valstack_torture_realloc((duk_hthread *) ctx);
2424
duk_hthread_callstack_torture_realloc((duk_hthread *) ctx);
25-
duk_hthread_catchstack_torture_realloc((duk_hthread *) ctx);
2625

2726
/* Inner function call, error throw. */
2827
duk_eval_string_noresult(ctx,
@@ -145,7 +144,6 @@ DUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {
145144
DUK_ASSERT(heap->heap_thread != NULL);
146145
DUK_ASSERT(heap->heap_thread->valstack != NULL);
147146
DUK_ASSERT(heap->heap_thread->callstack != NULL);
148-
DUK_ASSERT(heap->heap_thread->catchstack != NULL);
149147
#if defined(DUK_USE_REFERENCE_COUNTING)
150148
DUK_ASSERT(heap->refzero_list == NULL);
151149
#endif

src-input/duk_heap_markandsweep.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,11 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
125125
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
126126
duk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);
127127
#endif
128-
}
129-
130128
#if 0 /* nothing now */
131-
for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
132-
duk_catcher *cat = t->catchstack + i;
133-
}
129+
for (cat = act->cat; cat != NULL; cat = cat->parent) {
130+
}
134131
#endif
132+
}
135133

136134
duk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);
137135

@@ -749,7 +747,7 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
749747

750748
DUK_LOCAL int duk__protected_compact_object(duk_context *ctx, void *udata) {
751749
duk_hobject *obj;
752-
/* XXX: for threads, compact value stack, call stack, catch stack? */
750+
/* XXX: for threads, compact stacks? */
753751

754752
DUK_UNREF(udata);
755753
obj = duk_known_hobject(ctx, -1);
@@ -1018,7 +1016,6 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
10181016
DUK_ASSERT(heap->heap_thread != NULL);
10191017
DUK_ASSERT(heap->heap_thread->valstack != NULL);
10201018
DUK_ASSERT(heap->heap_thread->callstack != NULL);
1021-
DUK_ASSERT(heap->heap_thread->catchstack != NULL);
10221019

10231020
DUK_D(DUK_DPRINT("garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx",
10241021
(unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));

src-input/duk_heap_refcount.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,12 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
174174
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
175175
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);
176176
#endif
177-
}
178-
179177
#if 0 /* nothing now */
180-
for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
181-
duk_catcher *cat = t->catchstack + i;
182-
}
178+
for (cat = act->cat; cat != NULL; cat = cat->parent) {
179+
}
183180
#endif
181+
}
182+
184183

185184
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
186185
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);

src-input/duk_hobject_alloc.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t
163163
res->valstack_top = NULL;
164164
res->callstack = NULL;
165165
res->callstack_curr = NULL;
166-
res->catchstack = NULL;
167166
res->resumer = NULL;
168167
res->compile_ctx = NULL,
169168
#if defined(DUK_USE_HEAPPTR16)
@@ -184,7 +183,6 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t
184183
res->heap = heap;
185184
res->valstack_max = DUK_VALSTACK_DEFAULT_MAX;
186185
res->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;
187-
res->catchstack_max = DUK_CATCHSTACK_DEFAULT_MAX;
188186

189187
return res;
190188
}

src-input/duk_hobject_props.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
927927
* All done, switch properties ('p') allocation to new one.
928928
*/
929929

930-
DUK_FREE(thr->heap, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */
930+
DUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */
931931
DUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);
932932
DUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);
933933
DUK_HOBJECT_SET_ENEXT(obj, new_e_next);
@@ -970,7 +970,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
970970
alloc_failed:
971971
DUK_D(DUK_DPRINT("object property table resize failed"));
972972

973-
DUK_FREE(thr->heap, new_p); /* OK for NULL. */
973+
DUK_FREE_CHECKED(thr, new_p); /* OK for NULL. */
974974

975975
thr->heap->pf_prevent_count--;
976976
thr->heap->ms_base_flags = prev_ms_base_flags;

0 commit comments

Comments
 (0)