diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-07-10 19:27:52 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-07-10 19:29:28 +0200 |
commit | dad8f3aed4ca5f2f93e2be6f1243632439dec541 (patch) | |
tree | c7ccb3813ad791cf3f912f61916b776cd022d6a9 /types.c | |
parent | 62dbd6470e2e1b049ba18669d21f91d60063e347 (diff) |
types: properly deal with circular data in GC mark phase
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 20 |
1 files changed, 12 insertions, 8 deletions
@@ -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: |