Fix some GC mistakes

Objects could be cleaned up too early
This commit is contained in:
Laria 2026-01-23 21:02:20 +01:00
parent 279d2aaab8
commit 740a968a12
3 changed files with 32 additions and 23 deletions

View file

@ -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: {

View file

@ -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)
);
}
}
}

View file

@ -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);