From af9fbb7dc3be01d09d2f39a778082d173866d0c1 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 19 May 2021 00:28:46 +0300 Subject: [PATCH] free simple scope-block reference cycles on bytecode exit --- src/sfns.c | 2 +- src/vm.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/sfns.c b/src/sfns.c index f521ba03..e3da5ccb 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -387,7 +387,7 @@ B slash_c2(B t, B w, B x) { } B slicev(B x, usz s, usz ia) { - usz xia = a(x)->ia; if (s+ia>xia) thrM("↑/↓: NYI fills"); + usz xia = a(x)->ia; assert(s+ia <= xia); B r = TI(x).slice(x, s); arr_shVec(r, ia); return r; diff --git a/src/vm.c b/src/vm.c index 7b61da8f..e4c031e4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -525,6 +525,23 @@ B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents while (ivars[i] = svar[i]; i++; } while (ivars[i++] = bi_noVar; B r = evalBC(body, sc); + if (sc->refc>1) { + usz innerRef = 1; + for (i = 0; i < varAm; i++) { + B c = sc->vars[i]; + if (isVal(c) && v(c)->refc==1) { + u8 t = v(c)->type; + if (t==t_fun_block && c(FunBlock,c)->sc==sc) innerRef++; + else if (t==t_md1_block && c(Md1Block,c)->sc==sc) innerRef++; + else if (t==t_md2_block && c(Md2Block,c)->sc==sc) innerRef++; + } + } + assert(innerRef<=sc->refc); + if (innerRef==sc->refc) { + value_free((Value*)sc); + return r; + } + } ptr_dec(sc); return r; }