GC+context: Fix GC reaching some invalid pointers / dead objects
This commit is contained in:
parent
7c63a6b189
commit
3fcf4f4c49
1 changed files with 45 additions and 10 deletions
|
|
@ -589,21 +589,22 @@ apfl_ctx_new(struct apfl_allocator base_allocator)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
apfl_gc_init(&ctx->gc, base_allocator, get_roots, ctx);
|
||||
|
||||
// It's important that we initialize all these before initializing the
|
||||
// garbage collector, otherwise it might try to follow invalid pointers.
|
||||
ctx->error_handler = NULL;
|
||||
ctx->panic_callback = NULL;
|
||||
ctx->panic_callback_data = NULL;
|
||||
ctx->toplevel_stack = apfl_stack_new();
|
||||
ctx->call_stack = call_stack_new();
|
||||
ctx->globals = NULL;
|
||||
ctx->iterative_runners = iterative_runners_list_new();
|
||||
|
||||
apfl_gc_init(&ctx->gc, base_allocator, get_roots, ctx);
|
||||
|
||||
if ((ctx->globals = apfl_scope_new(&ctx->gc)) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctx->error_handler = NULL;
|
||||
ctx->panic_callback = NULL;
|
||||
ctx->panic_callback_data = NULL;
|
||||
|
||||
ctx->iterative_runners = iterative_runners_list_new();
|
||||
|
||||
if (!init_globals(ctx)) {
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -663,9 +664,34 @@ find_iterative_runner(apfl_ctx ctx, apfl_iterative_runner runner, size_t *index)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_ctx_register_iterative_runner(apfl_ctx ctx, apfl_iterative_runner runner)
|
||||
struct iterative_runner_tmproot_data {
|
||||
struct gc *gc;
|
||||
bool ok;
|
||||
};
|
||||
|
||||
static void
|
||||
ctx_register_iterative_runner_tmproot(void *opaque, struct gc_object *object)
|
||||
{
|
||||
struct iterative_runner_tmproot_data *data = opaque;
|
||||
if (!data->ok) {
|
||||
return;
|
||||
}
|
||||
data->ok = apfl_gc_tmproot_add(data->gc, object);
|
||||
}
|
||||
|
||||
static bool
|
||||
ctx_register_iterative_runner_inner(apfl_ctx ctx, apfl_iterative_runner runner)
|
||||
{
|
||||
struct iterative_runner_tmproot_data data = {
|
||||
.gc = &ctx->gc,
|
||||
.ok = true
|
||||
};
|
||||
apfl_iterative_runner_visit_gc_objects(runner, ctx_register_iterative_runner_tmproot, &data);
|
||||
|
||||
if (!data.ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (find_iterative_runner(ctx, runner, NULL)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -681,6 +707,15 @@ apfl_ctx_register_iterative_runner(apfl_ctx ctx, apfl_iterative_runner runner)
|
|||
);
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_ctx_register_iterative_runner(apfl_ctx ctx, apfl_iterative_runner runner)
|
||||
{
|
||||
size_t tmproots = apfl_gc_tmproots_begin(&ctx->gc);
|
||||
bool out = ctx_register_iterative_runner_inner(ctx, runner);
|
||||
apfl_gc_tmproots_restore(&ctx->gc, tmproots);
|
||||
return out;
|
||||
}
|
||||
|
||||
void
|
||||
apfl_ctx_unregister_iterative_runner(apfl_ctx ctx, apfl_iterative_runner runner)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue