make evalBC consume the scope
This commit is contained in:
parent
0abb24821d
commit
7d43d74b28
@ -631,7 +631,7 @@ B evalJIT(Body* b, Scope* sc, u8* ptr) { // doesn't consume
|
|||||||
// B* sp = gStack;
|
// B* sp = gStack;
|
||||||
B r = ((JITFn*)ptr)(gStack, sc);
|
B r = ((JITFn*)ptr)(gStack, sc);
|
||||||
// if (sp!=gStack) thrM("uh oh");
|
// if (sp!=gStack) thrM("uh oh");
|
||||||
|
scope_dec(sc);
|
||||||
popEnv();
|
popEnv();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/vm.c
27
src/vm.c
@ -712,6 +712,7 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
|
|||||||
B r = POP;
|
B r = POP;
|
||||||
GS_UPD;
|
GS_UPD;
|
||||||
popEnv();
|
popEnv();
|
||||||
|
scope_dec(sc);
|
||||||
return r;
|
return r;
|
||||||
#undef L64
|
#undef L64
|
||||||
#undef P
|
#undef P
|
||||||
@ -732,29 +733,8 @@ Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars) {
|
|||||||
while (i<varAm) sc->vars[i++] = bi_noVar;
|
while (i<varAm) sc->vars[i++] = bi_noVar;
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
static void scope_dec(Scope* sc) {
|
|
||||||
i32 varAm = sc->varAm;
|
|
||||||
if (sc->refc>1) {
|
|
||||||
i32 innerRef = 1;
|
|
||||||
for (i32 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr_dec(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE B execBodyInlineI(Block* block, Body* body, Scope* sc) {
|
FORCE_INLINE B execBodyInlineI(Block* block, Body* body, Scope* sc) { // consumes sc, unlike execBlockInline
|
||||||
#if JIT_START != -1
|
#if JIT_START != -1
|
||||||
if (body->nvm) { toJIT: return evalJIT(body, sc, body->nvm); }
|
if (body->nvm) { toJIT: return evalJIT(body, sc, body->nvm); }
|
||||||
bool jit = true;
|
bool jit = true;
|
||||||
@ -771,14 +751,13 @@ FORCE_INLINE B execBodyInlineI(Block* block, Body* body, Scope* sc) {
|
|||||||
#endif
|
#endif
|
||||||
return evalBC(block, body, sc);
|
return evalBC(block, body, sc);
|
||||||
}
|
}
|
||||||
B execBlockInline(Block* block, Scope* sc) { return execBodyInlineI(block, block->bodies[0], sc); }
|
B execBlockInline(Block* block, Scope* sc) { ptr_inc(sc); return execBodyInlineI(block, block->bodies[0], sc); }
|
||||||
|
|
||||||
FORCE_INLINE B execBlock(Block* block, Body* body, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
FORCE_INLINE B execBlock(Block* block, Body* body, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
||||||
u16 varAm = body->varAm;
|
u16 varAm = body->varAm;
|
||||||
assert(varAm>=ga);
|
assert(varAm>=ga);
|
||||||
Scope* sc = m_scope(body, psc, varAm, ga, svar);
|
Scope* sc = m_scope(body, psc, varAm, ga, svar);
|
||||||
B r = execBodyInlineI(block, body, sc);
|
B r = execBodyInlineI(block, body, sc);
|
||||||
scope_dec(sc);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
src/vm.h
21
src/vm.h
@ -167,6 +167,27 @@ static inline void popEnv() {
|
|||||||
assert(envCurr>=envStart);
|
assert(envCurr>=envStart);
|
||||||
envCurr--;
|
envCurr--;
|
||||||
}
|
}
|
||||||
|
FORCE_INLINE void scope_dec(Scope* sc) { // version of ptr_dec for scopes, that tries to also free trivial cycles
|
||||||
|
i32 varAm = sc->varAm;
|
||||||
|
if (sc->refc>1) {
|
||||||
|
i32 innerRef = 1;
|
||||||
|
for (i32 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr_dec(sc);
|
||||||
|
}
|
||||||
void vm_pst(Env* s, Env* e);
|
void vm_pst(Env* s, Env* e);
|
||||||
void vm_pstLive(void);
|
void vm_pstLive(void);
|
||||||
void vm_printPos(Comp* comp, i32 bcPos, i64 pos);
|
void vm_printPos(Comp* comp, i32 bcPos, i64 pos);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user