summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-10-09 14:10:40 +0200
committerlemon <lsof@mailbox.org>2022-10-09 14:10:40 +0200
commitd0e41c59afbbae68e11e11aec589bf1806cdb084 (patch)
tree122406fabe616ac46fe83ed1adae69be12da0faf
parentdae9fadda69b858a7fbb5ce65eb72f28aea3fdf9 (diff)
fix closures GC bug
-rw-r--r--pez.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/pez.c b/pez.c
index b2e590c..1611770 100644
--- a/pez.c
+++ b/pez.c
@@ -494,6 +494,7 @@ newfn(PezContext *cx, Proto *pr, Val *args, Val *locals, Fn *parent)
{
Fn *fn = newobj(cx, PEZ_TFn, sizeof *fn + pr->nupval * sizeof(struct Upval *));
if (fn) {
+ TRY(push(cx, box_obj(fn))); // gc keep
fn->proto = pr;
fn->nupval = pr->nupval;
for (int i = 0; i < pr->nupval; ++i) {
@@ -510,6 +511,7 @@ newfn(PezContext *cx, Proto *pr, Val *args, Val *locals, Fn *parent)
up = newobj(cx, PEZ_TUpval, sizeof *up);
if (!up) {
cxfree(cx, fn, sizeoffn(fn));
+ pop(cx);
return NULL;
}
up->ptr = &vals[upinfo->idx];
@@ -522,6 +524,7 @@ newfn(PezContext *cx, Proto *pr, Val *args, Val *locals, Fn *parent)
fn->upval[i] = parent->upval[upinfo->idx];
}
}
+ pop(cx);
}
return fn;
}
@@ -772,7 +775,9 @@ markfn(PezContext *cx, Fn *fn)
{
gcmark(cx, (Obj *)fn->proto);
for (int i = 0; i < fn->nupval; ++i) {
- gcmark(cx, (Obj *)fn->upval[i]);
+ if (fn->upval[i]) {
+ gcmark(cx, (Obj *)fn->upval[i]);
+ }
}
}