From 740a968a1200ee93e7bc778d4bd8ec765033f6fe Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Fri, 23 Jan 2026 21:02:20 +0100 Subject: [PATCH] Fix some GC mistakes Objects could be cleaned up too early --- src/bytecode.c | 42 +++++++++++++++++++++++------------------- src/context.c | 10 ++++++---- src/eval.c | 3 +++ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/bytecode.c b/src/bytecode.c index e5fd7c0..f870283 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -194,10 +194,10 @@ apfl_instructions_deinit(struct apfl_allocator allocator, struct instruction_lis #define GET_ARGUMENT(ilist, i, arg) \ do { \ - if (i >= ilist->len) { \ + if (++i >= ilist->len) { \ return; \ } \ - arg = ilist->instructions[++i]; \ + arg = ilist->instructions[i]; \ } while (0) void @@ -691,22 +691,25 @@ unserialize_string( .cap = len, }; + if (!apfl_resizable_ensure_cap_for_more_elements( + unserializer->gc->allocator, + sizeof(struct apfl_string *), + (void **)&unserializer->strings, + unserializer->strings_len, + &unserializer->strings_cap, + 1 + )) { + FREE_BYTES(unserializer->gc->allocator, buf, len); + return false; + } + if ((*s = apfl_string_move_into_new_gc_string(unserializer->gc, &tmpstring)) == NULL) { FREE_BYTES(unserializer->gc->allocator, buf, len); return false; } - if (!apfl_resizable_append( - unserializer->gc->allocator, - sizeof(struct apfl_string *), - (void **)&unserializer->strings, - &unserializer->strings_len, - &unserializer->strings_cap, - &(*s), - 1 - )) { - return false; - } + unserializer->strings[unserializer->strings_len] = *s; + unserializer->strings_len++; return true; } @@ -800,6 +803,7 @@ unserialize_milist( case MINSN_ARGS_NAME: { struct apfl_string *name; FMT_TRY(unserialize_string(unserializer, &name)); + assert(name != NULL); FMT_TRY(APPEND_MATCHER_INS_OR_ARG(milist, string, name)); break; } @@ -879,8 +883,10 @@ set_ilist_nested( ) { (void)unserializer; - struct instruction_list **dst = opaque; - *dst = ilist; + struct instruction_list *dst_ilist = opaque; + + APPEND_INS_OR_ARG(dst_ilist, body, ilist); + return true; } @@ -893,7 +899,7 @@ unserialize_ilist( size_t line; FMT_TRY(unserialize_size(unserializer->r, &line)); - struct apfl_string *filename; + struct apfl_string *filename = NULL; FMT_TRY(unserialize_string(unserializer, &filename)); size_t tmproots = apfl_gc_tmproots_begin(unserializer->gc); @@ -968,9 +974,7 @@ unserialize_ilist( if (ilist->len >= ilist->cap) { return false; } - struct instruction_list **dst = &ilist->instructions[ilist->len].body; - ilist->len++; - FMT_TRY(unserialize_ilist(unserializer, set_ilist_nested, dst)); + FMT_TRY(unserialize_ilist(unserializer, set_ilist_nested, ilist)); break; } case INSN_ARGS_MATCHER: { diff --git a/src/context.c b/src/context.c index 8cd0bd8..e0f6354 100644 --- a/src/context.c +++ b/src/context.c @@ -703,10 +703,12 @@ visit_matcher_cse(struct matcher_call_stack_entry cse, gc_visitor visitor, void* visit_scopes(cse.scopes, visitor, opaque); for (size_t i = 0; i < cse.capture_count; i++) { apfl_value_visit_gc_object(cse.captures[i], visitor, opaque); - visitor( - opaque, - GC_OBJECT_FROM(cse.transfers[i].var, GC_TYPE_STRING) - ); + if (cse.transfers[i].var != NULL) { + visitor( + opaque, + GC_OBJECT_FROM(cse.transfers[i].var, GC_TYPE_STRING) + ); + } } } diff --git a/src/eval.c b/src/eval.c index 93e39bf..ab12356 100644 --- a/src/eval.c +++ b/src/eval.c @@ -16,6 +16,7 @@ static void evaluate(apfl_ctx ctx, struct func_call_stack_entry *cse); static void evaluate_matcher(apfl_ctx ctx, struct matcher_call_stack_entry *cse); static void dispatch(apfl_ctx ctx, struct call_stack_entry *cse); static void matcher_init_matching(apfl_ctx ctx, struct matcher *matcher, struct scopes scopes); +static void must_tmproot_add_value(apfl_ctx ctx, struct apfl_value value); static void stack_must_drop(apfl_ctx ctx, apfl_stackidx index) @@ -361,6 +362,8 @@ return_from_function_inner(apfl_ctx ctx) value = (struct apfl_value) { .type = VALUE_NIL }; } + must_tmproot_add_value(ctx, value); + call_stack_drop(ctx); apfl_stack_must_push(ctx, value);