From dad8f3aed4ca5f2f93e2be6f1243632439dec541 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 10 Jul 2021 19:27:52 +0200 Subject: types: properly deal with circular data in GC mark phase Signed-off-by: Jo-Philipp Wich --- types.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'types.c') diff --git a/types.c b/types.c index 54bc50e..d0f23f9 100644 --- a/types.c +++ b/types.c @@ -126,30 +126,34 @@ ucv_gc_mark(uc_value_t *uv) struct lh_entry *entry; size_t i; + if (ucv_is_marked(uv)) + return; + switch (ucv_type(uv)) { case UC_ARRAY: array = (uc_array_t *)uv; + if (array->ref.next) + ucv_set_mark(uv); + ucv_gc_mark(array->proto); for (i = 0; i < array->count; i++) ucv_gc_mark(array->entries[i]); - if (array->ref.next) - ucv_set_mark(uv); - break; case UC_OBJECT: object = (uc_object_t *)uv; + if (object->ref.next) + ucv_set_mark(uv); + ucv_gc_mark(object->proto); lh_foreach(object->table, entry) ucv_gc_mark((uc_value_t *)lh_entry_v(entry)); - if (object->ref.next) - ucv_set_mark(uv); break; @@ -157,14 +161,14 @@ ucv_gc_mark(uc_value_t *uv) closure = (uc_closure_t *)uv; function = closure->function; + if (closure->ref.next) + ucv_set_mark(uv); + for (i = 0; i < function->nupvals; i++) ucv_gc_mark((uc_value_t *)closure->upvals[i]); ucv_gc_mark((uc_value_t *)function); - if (closure->ref.next) - ucv_set_mark(uv); - break; case UC_UPVALUE: -- cgit v1.2.3