namespaces

This commit is contained in:
dzaima 2021-05-09 16:00:02 +03:00
parent 8ed4019edf
commit 0dede67d2a
7 changed files with 218 additions and 43 deletions

View File

@ -69,9 +69,10 @@ enum Type {
/*18*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, t_f64slice, /*18*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, t_f64slice,
/*22*/ t_comp, t_block, t_body, t_scope, /*22*/ t_comp, t_block, t_body, t_scope,
/*26*/ t_freed, t_harrPartial, /*26*/ t_ns, t_nsDesc,
/*27*/ t_freed, t_harrPartial,
#ifdef RT_PERF #ifdef RT_PERF
/*28*/ t_funPerf, t_md1Perf, t_md2Perf, /*29*/ t_funPerf, t_md1Perf, t_md2Perf,
#endif #endif
t_COUNT t_COUNT
}; };
@ -346,6 +347,7 @@ i32 o2cu (B x) { return (u32)x.u; }
usz o2su (B x) { return (usz)x.f; } usz o2su (B x) { return (usz)x.f; }
f64 o2fu (B x) { return x.f; } f64 o2fu (B x) { return x.f; }
i64 o2i64u(B x) { return (i64)x.f; } i64 o2i64u(B x) { return (i64)x.f; }
bool o2b (B x) { usz t=o2s(x); if(t!=0&t!=1)thrM("Expected boolean"); return t; }
bool q_i32(B x) { return isI32(x) | (isF64(x) && x.f==(f64)(i32)x.f); } bool q_i32(B x) { return isI32(x) | (isF64(x) && x.f==(f64)(i32)x.f); }
bool q_f64(B x) { return isF64(x) || isI32(x); } bool q_f64(B x) { return isF64(x) || isI32(x); }

View File

@ -50,6 +50,7 @@
#include "md1.c" #include "md1.c"
#include "md2.c" #include "md2.c"
#include "vm.c" #include "vm.c"
#include "ns.c"
#include "rtPerf.c" #include "rtPerf.c"
void pr(char* a, B b) { void pr(char* a, B b) {
@ -60,12 +61,15 @@ void pr(char* a, B b) {
fflush(stdout); fflush(stdout);
} }
Block* ca3(B x) { Block* compB(B x) {
B* xp = harr_ptr(x); BS2B xget = TI(x).get;
Block* r = compile(inc(xp[0]),inc(xp[1]),inc(xp[2])); Block* r = compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4));
dec(x); dec(x);
return r; return r;
} }
Block* compile3(B bc, B objs, B blocks) {
return compile(bc, objs, blocks, bi_N, bi_N);
}
int main() { int main() {
@ -99,14 +103,14 @@ int main() {
#ifndef ALL_R0 #ifndef ALL_R0
B runtime_0[] = {bi_floor,bi_ceil,bi_stile,bi_lt,bi_gt,bi_ne,bi_ge,bi_rtack,bi_ltack,bi_join,bi_take,bi_drop,bi_select,bi_const,bi_swap,bi_each,bi_fold,bi_atop,bi_over,bi_before,bi_after,bi_cond,bi_repeat}; B runtime_0[] = {bi_floor,bi_ceil,bi_stile,bi_lt,bi_gt,bi_ne,bi_ge,bi_rtack,bi_ltack,bi_join,bi_take,bi_drop,bi_select,bi_const,bi_swap,bi_each,bi_fold,bi_atop,bi_over,bi_before,bi_after,bi_cond,bi_repeat};
#else #else
Block* runtime0_b = compile( Block* runtime0_b = compile3(
#include "runtime0" #include "runtime0"
); );
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b); B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
B* runtime_0 = toHArr(r0r)->a; B* runtime_0 = toHArr(r0r)->a;
#endif #endif
Block* runtime_b = compile( Block* runtime_b = compile3(
#include "runtime1" #include "runtime1"
); );
@ -153,14 +157,14 @@ int main() {
// uncomment to use src/interp; needed for test.bqn // uncomment to use src/interp; needed for test.bqn
// Block* c = ca3( // Block* c = compB(
// #include "interp" // #include "interp"
// ); // );
// B interp = m_funBlock(c, 0); ptr_dec(c); // B interp = m_funBlock(c, 0); ptr_dec(c);
// pr("result: ", interp); // pr("result: ", interp);
// exit(0); // exit(0);
Block* comp_b = compile( Block* comp_b = compile3(
#include "compiler" #include "compiler"
); );
B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b); B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
@ -168,7 +172,7 @@ int main() {
#ifdef FORMATTER #ifdef FORMATTER
Block* fmt_b = compile( Block* fmt_b = compile3(
#include "formatter" #include "formatter"
); );
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b); B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
@ -195,7 +199,7 @@ int main() {
// } // }
// if (c_src) { // if (c_src) {
// B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len)); // B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len));
// Block* cbc_b = ca3(cbc); // Block* cbc_b = compB(cbc);
// comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b); // comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b);
// gc_add(comp); // gc_add(comp);
// free(c_src); // free(c_src);
@ -215,7 +219,7 @@ int main() {
if (ln[0]==0 || ln[0]==10) break; if (ln[0]==0 || ln[0]==10) break;
B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln))); B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln)));
free(ln); free(ln);
Block* cbc_b = ca3(cbc); Block* cbc_b = compB(cbc);
#ifdef TIME #ifdef TIME
u64 sns = nsTime(); u64 sns = nsTime();

View File

@ -78,7 +78,7 @@ B repeat_replace(B g, B* q) { // doesn't consume
if (min) { \ if (min) { \
B x2 = inc(x); \ B x2 = inc(x); \
B fi = m1_d(inc(rt_undo), inc(f)); \ B fi = m1_d(inc(rt_undo), inc(f)); \
for (u64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \ for (i64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \
dec(x2); \ dec(x2); \
dec(fi); \ dec(fi); \
} \ } \

115
src/ns.c Normal file
View File

@ -0,0 +1,115 @@
#include "ns.h"
typedef struct NSDesc {
struct Value;
B nameList;
i32 varAm; // number of items in expIDs (currently equal to sc->varAm/body->varAm)
i32 expIDs[]; // each item is an index in nameList (or -1), and its position is the corresponding position in sc->vars
} NSDesc;
typedef struct NS {
struct Value;
B nameList; // copy of desc->nameList for quick checking; isn't owned
NSDesc* desc;
Scope* sc;
} NS;
void m_nsDesc(Body* body, bool imm, u8 ty, B nameList, B varIDs, B exported) { // consumes nameList
if (!isArr(varIDs) || !isArr(exported)) thrM("Bad namespace description information");
usz ia = a(varIDs)->ia;
if (ia!=a(exported)->ia) thrM("Bad namespace description information");
i32 off = (ty==0?0:ty==1?2:3) + (imm?0:3);
i32 vam = ia+off;
if (vam != body->varAm) thrM("Bad namespace description information");
NSDesc* rc = c(NSDesc, mm_alloc(fsizeof(NSDesc, expIDs, i32, vam), t_nsDesc, ftag(OBJ_TAG)));
rc->nameList = nameList;
rc->varAm = vam;
BS2B getIDU = TI(varIDs).getU;
BS2B getOnU = TI(exported).getU;
for (i32 i = 0; i < off; i++) {
body->varIDs[i] = -1;
rc ->expIDs[i] = -1;
}
for (usz i = 0; i < ia; i++) {
i32 cid = o2i(getIDU(varIDs, i));
bool cexp = o2b(getOnU(exported, i));
body->varIDs[i+off] = cid;
rc->expIDs[i+off] = cexp? cid : -1;
}
// printf("def %p:\n", rc);
// for (usz i = 0; i < vam; i++) printf(" %d: %d %d\n", i, body->varIDs[i], rc->expIDs[i]);
body->nsDesc = rc;
}
B m_ns(Scope* sc, NSDesc* desc) { // consumes both
B r = mm_alloc(sizeof(NS), t_ns, ftag(NSP_TAG));
NS* rc = c(NS,r);
rc->desc = desc;
rc->nameList = rc->desc->nameList;
rc->sc = sc;
return r;
}
B ns_getU(B ns, B nameList, i32 nameID) {
NS* n = c(NS, ns);
NSDesc* d = n->desc;
if (n->nameList.u != nameList.u) thrM("TODO cross-program namespace access");
i32 varAm = d->varAm;
// printf("getting from %p with vam=%d\n", d, d->varAm);
assert(nameID<a(nameList)->ia && nameID>=0);
for (i32 i = 0; i < varAm; i++) {
if (d->expIDs[i]==nameID) return n->sc->vars[i];
}
thrM("No key found");
}
B ns_nameList(NSDesc* d) {
return d->nameList;
}
void ns_free(B x) {
NS* c = c(NS, x);
ptr_decR(c->desc);
ptr_decR(c->sc);
}
void ns_visit(B x) {
NS* c = c(NS, x);
mm_visitP(c->desc);
mm_visitP(c->sc);
}
void ns_print(B x) {
putchar('{');
NSDesc* desc = c(NS,x)->desc;
Scope* sc = c(NS,x)->sc;
i32 am = desc->varAm;
BS2B getNameU = TI(desc->nameList).getU;
bool first = true;
for (i32 i = 0; i < am; i++) {
i32 id = desc->expIDs[i];
if (id>=0) {
if (first) first=false;
else printf("");
printRaw(getNameU(desc->nameList, id));
printf("");
print(sc->vars[i]);
}
}
putchar('}');
}
void nsDesc_free(B x) {
decR(c(NSDesc,x)->nameList);
}
void nsDesc_visit(B x) {
mm_visit(c(NSDesc,x)->nameList);
}
void nsDesc_print(B x) {
printf("(namespace description)");
}
static inline void ns_init() {
ti[t_ns].free = ns_free; ti[t_nsDesc].free = nsDesc_free;
ti[t_ns].visit = ns_visit; ti[t_nsDesc].visit = nsDesc_visit;
ti[t_ns].print = ns_print; ti[t_nsDesc].print = nsDesc_print;
}

9
src/ns.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "h.h"
typedef struct Scope Scope;
typedef struct Body Body;
typedef struct NSDesc NSDesc;
void m_nsDesc(Body* body, bool imm, u8 ty, B nameList, B varIDs, B exported); // consumes nameList
B m_ns(Scope* sc, NSDesc* desc); // consumes both
B ns_getU(B ns, B nameList, i32 nameID); // doesn't consume anything, doesn't increment result
B ns_nameList(NSDesc* d);

View File

@ -320,7 +320,7 @@ void printAllocStats() {
#endif #endif
} }
#define FOR_INIT(F) F(hdr) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(arith) F(fns) F(sfns) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf) #define FOR_INIT(F) F(hdr) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(arith) F(fns) F(sfns) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf) F(ns)
#define F(X) static inline void X##_init(); #define F(X) static inline void X##_init();
FOR_INIT(F) FOR_INIT(F)
#undef F #undef F

103
src/vm.c
View File

@ -1,4 +1,5 @@
#include "h.h" #include "h.h"
#include "ns.h"
// #define GS_REALLOC // whether to dynamically realloc gStack // #define GS_REALLOC // whether to dynamically realloc gStack
#ifndef GS_SIZE #ifndef GS_SIZE
@ -114,14 +115,15 @@ typedef struct Comp {
Block* blocks[]; Block* blocks[];
} Comp; } Comp;
typedef struct Block { struct Block {
struct Value; struct Value;
bool imm; bool imm;
u8 ty; u8 ty;
Body* body; Body* body;
} Block; };
typedef struct Body { typedef struct NSDesc NSDesc;
struct Body {
struct Value; struct Value;
Comp* comp; Comp* comp;
// B* objs; // B* objs;
@ -129,25 +131,29 @@ typedef struct Body {
u32 maxStack; u32 maxStack;
u16 maxPSC; u16 maxPSC;
u16 varAm; u16 varAm;
u32 endStack;
NSDesc* nsDesc;
i32 varIDs[];
// HArr* vNames; // HArr* vNames;
} Body; };
typedef struct Scope { struct Scope {
struct Value; struct Value;
Scope* psc; Scope* psc;
Body* body;
u16 varAm; u16 varAm;
#ifdef DEBUG #ifdef DEBUG
u64 bcInd; // DEBUG: place of this in bytecode array u64 bcInd; // DEBUG: place of this in bytecode array
#endif #endif
B vars[]; B vars[];
} Scope; };
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock; typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block; typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block; typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block;
Block* compile(B bcq, B objs, B blocksq) { // consumes all Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo) { // consumes all
HArr* blocksH = toHArr(blocksq); HArr* blocksH = toHArr(blocksq);
usz bam = blocksH->ia; usz bam = blocksH->ia;
@ -162,22 +168,31 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
comp->objs = toHArr(objs); comp->objs = toHArr(objs);
comp->blockAm = bam; comp->blockAm = bam;
B* blockDefs = blocksH->a; B* blockDefs = blocksH->a;
dec(indices);
B nameList;
if (isNothing(tokenInfo)) {
nameList = bi_emptyHVec;
} else {
B t = TI(tokenInfo).getU(tokenInfo,2);
nameList = TI(t).getU(t,0);
}
for (usz i = 0; i < bam; i++) { for (usz i = 0; i < bam; i++) {
B cbld = blockDefs[i]; B cbld = blockDefs[i];
usz cbia = a(cbld)->ia; usz cbia = a(cbld)->ia;
if (cbia!=4 && cbia!=6) thrM("bad compile block"); if (cbia!=4 && cbia!=6) thrM("bad compile block");
BS2B bget = TI(cbld).get; BS2B bgetU = TI(cbld).getU;
usz ty = o2s(bget(cbld,0)); if (ty>2) thrM("bad block type"); usz ty = o2s(bgetU(cbld,0)); if (ty>2) thrM("bad block type");
bool imm = o2s(bget(cbld,1)); // todo o2b or something bool imm = o2s(bgetU(cbld,1)); // todo o2b or something
usz idx = o2s(bget(cbld,2)); if (idx>=bcl) thrM("oob bytecode index"); usz idx = o2s(bgetU(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
usz vam = o2s(bget(cbld,3)); if (vam!=(u16)vam) thrM("too many variables"); usz vam = o2s(bgetU(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
i32* cbc = bc+idx; i32* cbc = bc+idx;
i32* scan = cbc; i32* scan = cbc;
i32 ssz = 0, mssz=0; i32 ssz = 0, mssz=0;
i32 mpsc = 0; i32 mpsc = 0;
while (*scan!=RETN & *scan!=RETD) { while (true) {
if (*scan==RETN) { if(ssz!=1)thrM("Wrong stack size before RETN"); break; }
if (*scan==RETD) { if(ssz!=1&ssz!=0)thrM("Wrong stack size before RETN"); break; }
ssz+= stackDiff(scan); ssz+= stackDiff(scan);
if (ssz>mssz) mssz = ssz; if (ssz>mssz) mssz = ssz;
if (*scan==LOCO | *scan==LOCM | *scan==LOCU) { if (*scan==LOCO | *scan==LOCM | *scan==LOCU) {
@ -188,12 +203,17 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
} }
if (mpsc>U16_MAX) thrM("LOC_ too deep"); if (mpsc>U16_MAX) thrM("LOC_ too deep");
Body* body = mm_allocN(sizeof(Body), t_body); Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body);
body->comp = comp; body->comp = comp;
body->bc = cbc; body->bc = cbc;
body->maxStack = mssz; body->maxStack = mssz;
body->maxPSC = (u16)mpsc; body->maxPSC = (u16)mpsc;
body->endStack = ssz;
body->varAm = (u16)vam; body->varAm = (u16)vam;
if (cbia==4) {
body->nsDesc = NULL;
for (i32 i = 0; i < vam; i++) body->varIDs[i] = -1;
} else m_nsDesc(body, imm, ty, inc(nameList), bgetU(cbld,4), bgetU(cbld,5));
ptr_inc(comp); ptr_inc(comp);
Block* bl = mm_allocN(sizeof(Block), t_block); Block* bl = mm_allocN(sizeof(Block), t_block);
@ -208,6 +228,7 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
// for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]); // for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]);
ptr_dec(comp); ptr_dec(comp);
ptr_dec(blocksH); ptr_dec(blocksH);
dec(tokenInfo);
return ret; return ret;
} }
@ -219,14 +240,26 @@ void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume
if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable"); if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable");
dec(prev); dec(prev);
} else { } else {
if (prev.u!=bi_noVar.u) thrM("←: redefining variable"); if (prev.u!=bi_noVar.u) thrM("←: Redefining variable");
} }
sc->vars[(u32)s.u] = inc(x); sc->vars[(u32)s.u] = inc(x);
} else { } else {
VT(s, t_harr); VT(s, t_harr);
if (isAtm(x) || !eqShape(s, x)) thrM("Assignment: Mismatched shape for spread assignment");
usz ia = a(x)->ia;
B* sp = harr_ptr(s); B* sp = harr_ptr(s);
usz ia = a(s)->ia;
if (isAtm(x) || !eqShape(s, x)) {
if (isNsp(x)) {
for (u64 i = 0; i < ia; i++) {
B c = sp[i];
if (!isVar(c)) thrM("Assignment: extracting non-name from namespace");
Scope* sc = pscs[(u16)(c.u>>32)];
i32 nameID = sc->body->varIDs[(u32)c.u];
v_set(pscs, c, ns_getU(x, ns_nameList(sc->body->nsDesc), nameID), upd);
}
return;
}
thrM("Assignment: Mismatched shape for spread assignment");
}
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd); for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd);
} }
@ -409,7 +442,9 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
break; break;
} }
case LOCO: { i32 d = *bc++; i32 p = *bc++; case LOCO: { i32 d = *bc++; i32 p = *bc++;
ADD(inc(pscs[d]->vars[p])); B l = pscs[d]->vars[p];
if(l.u==bi_noVar.u) thrM("Reading variable before its defined");
ADD(inc(l));
break; break;
} }
case LOCU: { i32 d = *bc++; i32 p = *bc++; case LOCU: { i32 d = *bc++; i32 p = *bc++;
@ -427,14 +462,21 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
ADD(r); ADD(r);
break; break;
} }
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM RETD SYSV case RETD: {
if (b->endStack) dec(POP);
ptr_inc(sc);
ptr_inc(b->nsDesc);
ADD(m_ns(sc, b->nsDesc));
goto end;
}
case RETN: goto end;
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM SYSV
default: default:
#ifdef DEBUG #ifdef DEBUG
printf("todo %d\n", bc[-1]); bc++; break; printf("todo %d\n", bc[-1]); bc++; break;
#else #else
UD; UD;
#endif #endif
case RETN: goto end;
} }
#ifdef DEBUG_VM #ifdef DEBUG_VM
for(i32 i = 0; i < bcDepth; i++) printf(" "); for(i32 i = 0; i < bcDepth; i++) printf(" ");
@ -456,18 +498,19 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
} }
B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
Body* bdy = bl->body; Body* body = bl->body;
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope); Scope* sc = mm_allocN(fsizeof(Scope, vars, B, body->varAm), t_scope);
sc->body = body; ptr_inc(body);
sc->psc = psc; if(psc) ptr_inc(psc); sc->psc = psc; if(psc) ptr_inc(psc);
u16 varAm = sc->varAm = bdy->varAm; u16 varAm = sc->varAm = body->varAm;
assert(varAm>=ga); assert(varAm>=ga);
#ifdef DEBUG #ifdef DEBUG
sc->bcInd = bdy->bc-c(I32Arr,bdy->comp->bc)->a; sc->bcInd = body->bc-c(I32Arr,body->comp->bc)->a;
#endif #endif
i32 i = 0; i32 i = 0;
while (i<ga) { sc->vars[i] = svar[i]; i++; } while (i<ga) { sc->vars[i] = svar[i]; i++; }
while (i<varAm) sc->vars[i++] = bi_noVar; while (i<varAm) sc->vars[i++] = bi_noVar;
B r = evalBC(bdy, sc); B r = evalBC(body, sc);
ptr_dec(sc); ptr_dec(sc);
return r; return r;
} }
@ -505,7 +548,7 @@ B m_md2Block(Block* bl, Scope* psc) {
} }
void comp_free(B x) { void comp_free(B x) {
Comp* c = c(Comp ,x); Comp* c = c(Comp, x);
ptr_decR(c->objs); ptr_decR(c->objs);
decR(c->bc); decR(c->bc);
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]); u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]);
@ -513,10 +556,11 @@ void comp_free(B x) {
void scope_free(B x) { void scope_free(B x) {
Scope* c = c(Scope,x); Scope* c = c(Scope,x);
if (c->psc) ptr_decR(c->psc); if (c->psc) ptr_decR(c->psc);
ptr_decR(c->body);
u16 am = c->varAm; u16 am = c->varAm;
for (u32 i = 0; i < am; i++) dec(c->vars[i]); for (u32 i = 0; i < am; i++) dec(c->vars[i]);
} }
void body_free(B x) { Body* c = c(Body ,x); ptr_decR(c->comp); } void body_free(B x) { Body* c = c(Body ,x); ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); }
void block_free(B x) { Block* c = c(Block,x); ptr_decR(c->body); } void block_free(B x) { Block* c = c(Block,x); ptr_decR(c->body); }
void funBl_free(B x) { FunBlock* c = c(FunBlock,x); ptr_decR(c->sc); ptr_decR(c->bl); } void funBl_free(B x) { FunBlock* c = c(FunBlock,x); ptr_decR(c->sc); ptr_decR(c->bl); }
void md1Bl_free(B x) { Md1Block* c = c(Md1Block,x); ptr_decR(c->sc); ptr_decR(c->bl); } void md1Bl_free(B x) { Md1Block* c = c(Md1Block,x); ptr_decR(c->sc); ptr_decR(c->bl); }
@ -530,10 +574,11 @@ void comp_visit(B x) {
void scope_visit(B x) { void scope_visit(B x) {
Scope* c = c(Scope,x); Scope* c = c(Scope,x);
if (c->psc) mm_visitP(c->psc); if (c->psc) mm_visitP(c->psc);
mm_visitP(c->body);
u16 am = c->varAm; u16 am = c->varAm;
for (u32 i = 0; i < am; i++) mm_visit(c->vars[i]); for (u32 i = 0; i < am; i++) mm_visit(c->vars[i]);
} }
void body_visit(B x) { Body* c = c(Body ,x); mm_visitP(c->comp); } void body_visit(B x) { Body* c = c(Body ,x); mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); }
void block_visit(B x) { Block* c = c(Block,x); mm_visitP(c->body); } void block_visit(B x) { Block* c = c(Block,x); mm_visitP(c->body); }
void funBl_visit(B x) { FunBlock* c = c(FunBlock,x); mm_visitP(c->sc); mm_visitP(c->bl); } void funBl_visit(B x) { FunBlock* c = c(FunBlock,x); mm_visitP(c->sc); mm_visitP(c->bl); }
void md1Bl_visit(B x) { Md1Block* c = c(Md1Block,x); mm_visitP(c->sc); mm_visitP(c->bl); } void md1Bl_visit(B x) { Md1Block* c = c(Md1Block,x); mm_visitP(c->sc); mm_visitP(c->bl); }