diff options
| author | 2022-10-09 14:10:40 +0200 | |
|---|---|---|
| committer | 2022-10-09 14:10:40 +0200 | |
| commit | d0e41c59afbbae68e11e11aec589bf1806cdb084 (patch) | |
| tree | 122406fabe616ac46fe83ed1adae69be12da0faf /pez.c | |
| parent | dae9fadda69b858a7fbb5ce65eb72f28aea3fdf9 (diff) | |
fix closures GC bug
Diffstat (limited to 'pez.c')
| -rw-r--r-- | pez.c | 7 |
1 files changed, 6 insertions, 1 deletions
@@ -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]); + } } } |