From 7bf3b4be501c7c4f733c3ef8d647fa53ef21de58 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 26 May 2021 14:24:15 +0300 Subject: [PATCH] store directly needed blocks in bodies --- precompiled.bqn | 2 +- src/core/stuff.c | 4 +- src/core/stuff.h | 23 ++++++- src/h.h | 11 +-- src/load.c | 158 +++++++++++++++++++++++-------------------- src/vm.c | 171 ++++++++++++++++++++++++----------------------- src/vm.h | 22 +++++- 7 files changed, 223 insertions(+), 168 deletions(-) diff --git a/precompiled.bqn b/precompiled.bqn index 219a8d8e..be266ca6 100755 --- a/precompiled.bqn +++ b/precompiled.bqn @@ -14,7 +14,7 @@ tests ← •FLines path∾"/test/cases/prim.bqn" '%'⊸∊◶{𝕤 •Out 𝕩 "src/gen/interp" •FChars ⟨1,path,𝕩⟩ •Import "cc.bqn" - (×⊑)◶@‿{𝕤⋄•Out "############ Failed to compile! ############" ⋄ •Out¨1↓𝕩}{env⇐<"PATH="∾envP}•SH"./debugBuild"‿"-DNO_COMP" + (×⊑)◶@‿{𝕤⋄•Out "############ Failed to compile! ############" ⋄ •Out¨1↓𝕩}{env⇐<"PATH="∾envP}•SH"./debugBuild"‿"-DPRECOMP" code‿out‿err←•SH"./BQN" •Out out {𝕤⋄•Out"exit code "∾(⍕code) ⋄ •Out err}⍟(×code) err diff --git a/src/core/stuff.c b/src/core/stuff.c index 9be0fa37..fb4209e2 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -337,7 +337,7 @@ char* format_type(u8 u) { case t_md1D:return"md1D"; case t_md2D:return"md2D"; case t_md2H:return"md2H"; case t_harr :return"harr" ; case t_i8arr :return"i8arr" ; case t_i32arr :return"i32arr" ; case t_fillarr :return"fillarr" ; case t_c32arr :return"c32arr" ; case t_f64arr :return"f64arr" ; case t_hslice:return"hslice"; case t_i8slice:return"i8slice"; case t_i32slice:return"i32slice"; case t_fillslice:return"fillslice"; case t_c32slice:return"c32slice"; case t_f64slice:return"f64slice"; - case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope"; + case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope"; case t_blBlocks: return "block list"; case t_ns:return"ns"; case t_nsDesc:return"nsDesc"; case t_fldAlias:return"alias"; case t_hashmap:return"hashmap"; case t_temp:return"temporary"; case t_freed:return"(freed by GC)"; case t_harrPartial:return"partHarr"; #ifdef RT_WRAP @@ -457,7 +457,7 @@ B bqn_merge(B x) { // consumes NOINLINE void printAllocStats() { #ifdef ALLOC_STAT printf("total ever allocated: %lu\n", talloc); - printf("allocated heap size: %ld\n", mm_heapAllocated()); + printf("allocated heap size: %ld\n", mm_heapAlloc); printf("used heap size: %ld\n", mm_heapUsed()); ctr_a[t_harr]+= ctr_a[t_harrPartial]; ctr_a[t_harrPartial] = 0; diff --git a/src/core/stuff.h b/src/core/stuff.h index 4fcda69c..128c8438 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -8,7 +8,6 @@ static void mm_free(Value* x); static u64 mm_size(Value* x); static void mm_visit(B x); static void mm_visitP(void* x); -static u64 mm_heapAllocated(); u64 mm_heapUsed(); void printAllocStats(); static B mm_alloc(usz sz, u8 type, u64 tag) { @@ -31,7 +30,7 @@ typedef struct TAlloc { #define TFREE(N) mm_free((Value*)TOBJ(N)); #define TREALLOC(N, AM) talloc_realloc(TOBJ(N), AM) #define TSIZE(N) (mm_size(TOBJ(N))-TOFF) -static inline void* talloc_realloc(TAlloc* t, u64 am) { +static inline void* talloc_realloc(TAlloc* t, u64 am) { // TODO maybe shouldn't be inline? u64 stored = mm_size((Value*)t)-TOFF; if (stored > am) return t->data; TALLOC(u8,r,am); @@ -40,6 +39,26 @@ static inline void* talloc_realloc(TAlloc* t, u64 am) { return r; } +typedef struct TStack { + struct Value; + usz size; + usz cap; + u8 data[]; +} TStack; +#define TSALLOC(T,N) u32 N##_e=sizeof(T); TStack* N##_o = (TStack*)mm_allocN(sizeof(TStack)+N##_e*2, t_temp); N##_o->size=0; N##_o->cap=2; T* N = (T*)N##_o->data; +#define TSFREE(N) mm_free((Value*)N##_o); +#define TSADD(N,X) { if (N##_o->size==N##_o->cap) { N##_o = tstack_ext(N##_o, N##_e); N = (void*)N##_o->data; } N[N##_o->size++] = X; } +#define TSSIZE(N) (N##_o->size) +static NOINLINE TStack* tstack_ext(TStack* o, u32 elsz) { + usz ncap = o->cap*2; + TStack* n = (TStack*)mm_allocN(sizeof(TStack) + elsz*ncap, t_temp); + memcpy(n->data, o->data, o->cap*elsz); + n->cap = ncap; + n->size = o->size; + mm_free((Value*)o); + return n; +} + // shape mess typedef struct ShArr { diff --git a/src/h.h b/src/h.h index 4fdbace5..bc18ff2f 100644 --- a/src/h.h +++ b/src/h.h @@ -28,7 +28,8 @@ // #define TIME // output runtime of every expression // #define RT_PERF // time runtime primitives // #define RT_VERIFY // compare native and runtime versions of primitives -// #define NO_COMP // don't load the compiler, instead execute src/interp; needed for ./precompiled.bqn +// #define NO_RT // whether to completely disable self-hosted runtime loading +// #define PRECOMP // execute just precompiled code at src/gen/interp #include @@ -133,11 +134,11 @@ enum Type { /*13*/ t_harr , t_i8arr , t_i32arr , t_fillarr , t_c32arr , t_f64arr , /*19*/ t_hslice, t_i8slice, t_i32slice, t_fillslice, t_c32slice, t_f64slice, - /*25*/ t_comp, t_block, t_body, t_scope, - /*29*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp, - /*34*/ t_freed, t_harrPartial, + /*25*/ t_comp, t_block, t_body, t_scope, t_blBlocks, + /*30*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp, + /*35*/ t_freed, t_harrPartial, #ifdef RT_WRAP - /*36*/ t_funWrap, t_md1Wrap, t_md2Wrap, + /*37*/ t_funWrap, t_md1Wrap, t_md2Wrap, #endif t_COUNT }; diff --git a/src/load.c b/src/load.c index c089ce44..1a596ac6 100644 --- a/src/load.c +++ b/src/load.c @@ -30,19 +30,19 @@ Block* load_compObj(B x, B src) { // consumes BS2B xget = TI(x).get; usz xia = a(x)->ia; if (xia!=5 & xia!=3) thrM("load_compObj: bad item count"); - Block* r = xia==5? compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4), src) - : compile(xget(x,0),xget(x,1),xget(x,2),bi_N, bi_N, src); + Block* r = xia==5? compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4), src, NULL) + : compile(xget(x,0),xget(x,1),xget(x,2),bi_N, bi_N, src, NULL); dec(x); return r; } #include "gen/src" #if RT_SRC Block* load_compImport(B bc, B objs, B blocks, B inds, B src) { // consumes all - return compile(bc, objs, blocks, inds, bi_N, src); + return compile(bc, objs, blocks, inds, bi_N, src, NULL); } #else Block* load_compImport(B bc, B objs, B blocks) { // consumes all - return compile(bc, objs, blocks, bi_N, bi_N, bi_N); + return compile(bc, objs, blocks, bi_N, bi_N, bi_N, NULL); } #endif @@ -110,82 +110,86 @@ static inline void load_init() { // very last init function for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]); B frtObj = m_caB(rtLen, fruntime); - B provide[] = {bi_type,bi_fill,bi_log,bi_grLen,bi_grOrd,bi_asrt,bi_add,bi_sub,bi_mul,bi_div,bi_pow,bi_floor,bi_eq,bi_le,bi_fne,bi_shape,bi_pick,bi_ud,bi_tbl,bi_scan,bi_fillBy,bi_val,bi_catch}; - - #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}; - #else - Block* runtime0_b = load_compImport( - #include "gen/runtime0" - ); - B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b); - B* runtime_0 = toHArr(r0r)->a; - #endif - - Block* runtime_b = load_compImport( - #include "gen/runtime1" - ); - - #ifdef ALL_R0 - dec(r0r); - #endif - - B rtRes = m_funBlock(runtime_b, 0); ptr_dec(runtime_b); - B rtObjRaw = TI(rtRes).get(rtRes,0); - B rtFinish = TI(rtRes).get(rtRes,1); - dec(rtRes); - - if (c(Arr,rtObjRaw)->ia != rtLen) err("incorrectly defined rtLen!"); - HArr_p runtimeH = m_harrUc(rtObjRaw); - BS2B rtObjGet = TI(rtObjRaw).get; - - rt_sortDsc = rtObjGet(rtObjRaw, 11); gc_add(rt_sortDsc); - rt_merge = rtObjGet(rtObjRaw, 13); gc_add(rt_merge); - rt_undo = rtObjGet(rtObjRaw, 48); gc_add(rt_undo); - rt_select = rtObjGet(rtObjRaw, 35); gc_add(rt_select); - rt_slash = rtObjGet(rtObjRaw, 32); gc_add(rt_slash); - rt_join = rtObjGet(rtObjRaw, 23); gc_add(rt_join); - rt_ud = rtObjGet(rtObjRaw, 27); gc_add(rt_ud); - rt_pick = rtObjGet(rtObjRaw, 36); gc_add(rt_pick); - rt_take = rtObjGet(rtObjRaw, 25); gc_add(rt_take); - rt_drop = rtObjGet(rtObjRaw, 26); gc_add(rt_drop); - rt_group = rtObjGet(rtObjRaw, 41); gc_add(rt_group); - rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under); - rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse); - rt_indexOf = rtObjGet(rtObjRaw, 37); gc_add(rt_indexOf); - rt_count = rtObjGet(rtObjRaw, 38); gc_add(rt_count); - rt_memberOf= rtObjGet(rtObjRaw, 39); gc_add(rt_memberOf); - rt_find = rtObjGet(rtObjRaw, 40); gc_add(rt_find); - rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell); - - for (usz i = 0; i < rtLen; i++) { - #ifdef RT_WRAP - r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]); - #endif - #ifdef ALL_R1 - B r = rtObjGet(rtObjRaw, i); + #ifndef NO_RT + B provide[] = {bi_type,bi_fill,bi_log,bi_grLen,bi_grOrd,bi_asrt,bi_add,bi_sub,bi_mul,bi_div,bi_pow,bi_floor,bi_eq,bi_le,bi_fne,bi_shape,bi_pick,bi_ud,bi_tbl,bi_scan,bi_fillBy,bi_val,bi_catch}; + + #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}; #else - B r = rtComplete[i]? inc(fruntime[i]) : rtObjGet(rtObjRaw, i); + Block* runtime0_b = load_compImport( + #include "gen/runtime0" + ); + B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b); + B* runtime_0 = toHArr(r0r)->a; #endif - if (isNothing(r)) { printf("· in runtime!\n"); exit(1); } - if (isVal(r)) v(r)->flags|= i+1; - #ifdef RT_WRAP - r = rtWrap_wrap(r); + + Block* runtime_b = load_compImport( + #include "gen/runtime1" + ); + + #ifdef ALL_R0 + dec(r0r); + #endif + + B rtRes = m_funBlock(runtime_b, 0); ptr_dec(runtime_b); + B rtObjRaw = TI(rtRes).get(rtRes,0); + B rtFinish = TI(rtRes).get(rtRes,1); + dec(rtRes); + + if (c(Arr,rtObjRaw)->ia != rtLen) err("incorrectly defined rtLen!"); + HArr_p runtimeH = m_harrUc(rtObjRaw); + BS2B rtObjGet = TI(rtObjRaw).get; + + rt_sortDsc = rtObjGet(rtObjRaw, 11); gc_add(rt_sortDsc); + rt_merge = rtObjGet(rtObjRaw, 13); gc_add(rt_merge); + rt_undo = rtObjGet(rtObjRaw, 48); gc_add(rt_undo); + rt_select = rtObjGet(rtObjRaw, 35); gc_add(rt_select); + rt_slash = rtObjGet(rtObjRaw, 32); gc_add(rt_slash); + rt_join = rtObjGet(rtObjRaw, 23); gc_add(rt_join); + rt_ud = rtObjGet(rtObjRaw, 27); gc_add(rt_ud); + rt_pick = rtObjGet(rtObjRaw, 36); gc_add(rt_pick); + rt_take = rtObjGet(rtObjRaw, 25); gc_add(rt_take); + rt_drop = rtObjGet(rtObjRaw, 26); gc_add(rt_drop); + rt_group = rtObjGet(rtObjRaw, 41); gc_add(rt_group); + rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under); + rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse); + rt_indexOf = rtObjGet(rtObjRaw, 37); gc_add(rt_indexOf); + rt_count = rtObjGet(rtObjRaw, 38); gc_add(rt_count); + rt_memberOf= rtObjGet(rtObjRaw, 39); gc_add(rt_memberOf); + rt_find = rtObjGet(rtObjRaw, 40); gc_add(rt_find); + rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell); + + for (usz i = 0; i < rtLen; i++) { + #ifdef RT_WRAP + r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]); + #endif + #ifdef ALL_R1 + B r = rtObjGet(rtObjRaw, i); + #else + B r = rtComplete[i]? inc(fruntime[i]) : rtObjGet(rtObjRaw, i); + #endif + if (isNothing(r)) { printf("· in runtime!\n"); exit(1); } if (isVal(r)) v(r)->flags|= i+1; - #endif - runtimeH.a[i] = r; - } - dec(rtObjRaw); - B* runtime = runtimeH.a; - B rtObj = runtimeH.b; - dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish); + #ifdef RT_WRAP + r = rtWrap_wrap(r); + if (isVal(r)) v(r)->flags|= i+1; + #endif + runtimeH.a[i] = r; + } + dec(rtObjRaw); + B* runtime = runtimeH.a; + B rtObj = runtimeH.b; + dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish); + load_compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj); + gc_add(load_compArg); + #else + B* runtime = fruntime; + #endif - load_compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj); - gc_add(load_compArg); - #ifdef NO_COMP + #ifdef PRECOMP Block* c = load_compObj( #include "gen/interp" , bi_N @@ -194,6 +198,12 @@ static inline void load_init() { // very last init function print(interp); printf("\n"); dec(interp); + #ifdef HEAP_VERIFY + heapVerify(); + #endif + rtWrap_print(); + CTR_FOR(CTR_PRINT) + printAllocStats(); exit(0); #else // use compiler Block* comp_b = load_compImport( @@ -216,7 +226,7 @@ static inline void load_init() { // very last init function dec(fmtM); #endif gc_enable(); - #endif // NO_COMP + #endif // PRECOMP } B bqn_execFile(B path, B args) { // consumes both diff --git a/src/vm.c b/src/vm.c index 4b3e36bc..b605ac79 100644 --- a/src/vm.c +++ b/src/vm.c @@ -119,26 +119,86 @@ void gsPrint() { } } - - - -NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src) { // consumes all - HArr* blocksH = toHArr(blocksq); - usz bam = blocksH->ia; +Block* compileBlock(B block, Comp* comp, bool* bDone, i32* bc, usz bcIA, B blocks, B nameList, Scope* sc, i32 depth) { + usz cIA = a(block)->ia; + if (cIA!=4 && cIA!=6) thrM("VM compiler: Bad block info size"); + BS2B bgetU = TI(block).getU; + usz ty = o2s(bgetU(block,0)); if (ty>2) thrM("VM compiler: Bad type"); + bool imm = o2b(bgetU(block,1)); + usz idx = o2s(bgetU(block,2)); if (idx>=bcIA) thrM("VM compiler: Bytecode index out of bounds"); + usz vam = o2s(bgetU(block,3)); if (vam!=(u16)vam) thrM("VM compiler: >2⋆16 variables not supported"); // TODO any reason for this? 2⋆32 vars should just work, no? + i32* thisBC = bc+idx; + i32 h = 0; // stack height + i32 hM = 0; // max stack height + i32 mpsc = 0; + i32* c = thisBC; + TSALLOC(Block*,nBlT); + while (true) { + i32* n = nextBC(c); + if (n-thisBC-1 >= bcIA) thrM("VM compiler: No RETN/RETD found before end of bytecode"); + switch (*c) { + case RETN: if(h!=1) thrM("VM compiler: Wrong stack size before RETN"); + goto returned; + case RETD: if(h!=1&h!=0) thrM("VM compiler: Wrong stack size before RETD"); + goto returned; + case DFND: + u32 id = c[1]; + if ((u32)id >= a(blocks)->ia) thrM("VM compiler: DFND index out-of-bounds"); + if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places"); + bDone[id] = true; + c[1] = TSSIZE(nBlT); + TSADD(nBlT, compileBlock(TI(blocks).getU(blocks,id), comp, bDone, bc, bcIA, blocks, nameList, sc, depth+1)); + break; + case LOCO: case LOCM: case LOCU: + if (c[1]>mpsc) mpsc = c[1]; + break; + default: + break; + } + h+= stackDiff(c); + if (h<0) thrM("VM compiler: Stack size goes negative"); + if (h>hM) hM = h; + c = n; + } returned:; + u64 blC = TSSIZE(nBlT); + BlBlocks* nBl = mm_allocN(fsizeof(BlBlocks,a,Block*,blC), t_blBlocks); + nBl->am = blC; + memcpy(nBl->a, nBlT, blC*sizeof(Block*)); + TSFREE(nBlT); + if (mpsc>U16_MAX) thrM("VM compiler: LOC_ too deep"); - // B* objPtr = harr_ptr(objs); usz objIA = a(objs)->ia; - // for (usz i = 0; i < objIA; i++) objPtr[i] = c2(bi_fill, c1(bi_pick, inc(objPtr[i])), objPtr[i]); + Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body); + body->comp = comp; ptr_inc(comp); + body->bc = thisBC; + body->blocks = nBl; + body->maxStack = hM; + body->maxPSC = (u16)mpsc; + body->endStack = h; + body->varAm = (u16)vam; + if (cIA==4) { + body->nsDesc = NULL; + for (i32 i = 0; i < vam; i++) body->varIDs[i] = -1; + } else m_nsDesc(body, imm, ty, inc(nameList), bgetU(block,4), bgetU(block,5)); + + Block* bl = mm_allocN(sizeof(Block), t_block); + bl->body = body; + bl->imm = imm; + bl->ty = (u8)ty; + return bl; +} + +NOINLINE Block* compile(B bcq, B objs, B blocks, B indices, B tokenInfo, B src, Scope* sc) { // consumes all; assumes arguments are valid (verifies some stuff, but definitely not everything) + usz bIA = a(blocks)->ia; I32Arr* bca = toI32Arr(bcq); i32* bc = bca->a; - usz bcl = bca->ia; - Comp* comp = mm_allocN(fsizeof(Comp,blocks,Block*,bam), t_comp); + usz bcIA = bca->ia; + Comp* comp = mm_allocN(sizeof(Comp), t_comp); comp->bc = tag(bca, ARR_TAG); comp->indices = indices; comp->src = src; comp->objs = toHArr(objs); - comp->blockAm = bam; - B* blockDefs = blocksH->a; + comp->blockAm = 0; B nameList; if (isNothing(tokenInfo)) { nameList = bi_emptyHVec; @@ -147,68 +207,19 @@ NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src) nameList = TI(t).getU(t,0); } if (!isNothing(src) && !isNothing(indices)) { - if (isAtm(indices) || rnk(indices)!=1 || a(indices)->ia!=2) thrM("compile: bad indices"); + if (isAtm(indices) || rnk(indices)!=1 || a(indices)->ia!=2) thrM("VM compiler: Bad indices"); for (i32 i = 0; i < 2; i++) { B ind = TI(indices).getU(indices,i); - if (isAtm(ind) || rnk(ind)!=1 || a(ind)->ia!=bcl) thrM("compile: bad indices"); + if (isAtm(ind) || rnk(ind)!=1 || a(ind)->ia!=bcIA) thrM("VM compiler: Bad indices"); BS2B indGetU = TI(ind).getU; - for (usz j = 0; j < bcl; j++) o2i(indGetU(ind,j)); + for (usz j = 0; j < bcIA; j++) o2i(indGetU(ind,j)); } } - - for (usz i = 0; i < bam; i++) { - B cbld = blockDefs[i]; - usz cbia = a(cbld)->ia; - if (cbia!=4 && cbia!=6) thrM("bad compile block"); - BS2B bgetU = TI(cbld).getU; - usz ty = o2s(bgetU(cbld,0)); if (ty>2) thrM("bad block type"); - bool imm = o2s(bgetU(cbld,1)); // todo o2b or something - usz idx = o2s(bgetU(cbld,2)); if (idx>=bcl) thrM("oob bytecode index"); - usz vam = o2s(bgetU(cbld,3)); if (vam!=(u16)vam) thrM("too many variables"); - i32* cbc = bc+idx; - i32* scan = cbc; - i32 ssz = 0, mssz=0; - i32 mpsc = 0; - 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); - if (ssz < 0) thrM("Invalid bytecode: stack size goes negative"); - if (ssz>mssz) mssz = ssz; - if (*scan==LOCO | *scan==LOCM | *scan==LOCU) { - if (scan[1]>mpsc) mpsc = scan[1]; - } - scan = nextBC(scan); - if (scan-bc >= bcl) thrM("no RETN/RETD found at end of bytecode"); - } - if (mpsc>U16_MAX) thrM("LOC_ too deep"); - - Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body); - body->comp = comp; - body->bc = cbc; - body->maxStack = mssz; - body->maxPSC = (u16)mpsc; - body->endStack = ssz; - 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); - - Block* bl = mm_allocN(sizeof(Block), t_block); - bl->body = body; - bl->imm = imm; - bl->ty = (u8)ty; - comp->blocks[i] = bl; - } - - Block* ret = c(Block,inc(tag(comp->blocks[0], OBJ_TAG))); - // TODO store blocks in each body, then decrement each of comp->blocks; also then move temp block list out of Comp as it's useless then - // for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]); - ptr_dec(comp); - ptr_dec(blocksH); - dec(tokenInfo); + TALLOC(bool,bDone,bIA); + for (usz i = 0; i < bIA; i++) bDone[i] = false; + Block* ret = compileBlock(TI(blocks).getU(blocks, 0), comp, bDone, bc, bcIA, blocks, nameList, sc, 0); + TFREE(bDone); + ptr_dec(comp); dec(blocks); dec(tokenInfo); return ret; } @@ -290,7 +301,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume printf("new eval\n"); #endif B* objs = b->comp->objs->a; - Block** blocks = b->comp->blocks; + Block** blocks = b->blocks->a; // b->comp->blocks; i32* bc = b->bc; pushEnv(sc, bc); gsReserve(b->maxStack); @@ -527,11 +538,6 @@ B m_md2Block(Block* bl, Scope* psc) { return r; } -void comp_free(Value* x) { - Comp* c = (Comp*)x; - ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices); - u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]); -} void scope_free(Value* x) { Scope* c = (Scope*)x; if (c->psc) ptr_decR(c->psc); @@ -539,18 +545,15 @@ void scope_free(Value* x) { u16 am = c->varAm; for (u32 i = 0; i < am; i++) dec(c->vars[i]); } -void body_free(Value* x) { Body* c = (Body *)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); } +void comp_free(Value* x) { Comp* c = (Comp *)x; ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices); } +void body_free(Value* x) { Body* c = (Body *)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); ptr_decR(c->blocks); } void block_free(Value* x) { Block* c = (Block *)x; ptr_decR(c->body); } void funBl_free(Value* x) { FunBlock* c = (FunBlock*)x; ptr_decR(c->sc); ptr_decR(c->bl); } void md1Bl_free(Value* x) { Md1Block* c = (Md1Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); } void md2Bl_free(Value* x) { Md2Block* c = (Md2Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); } void alias_free(Value* x) { dec(((FldAlias*)x)->obj); } +void bBlks_free(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (u32 i = 0; i < am; i++) ptr_dec(c->a[i]); } -void comp_visit(Value* x) { - Comp* c = (Comp*)x; - mm_visitP(c->objs); mm_visit(c->bc); mm_visit(c->src); mm_visit(c->indices); - u32 am = c->blockAm; for(u32 i = 0; i < am; i++) mm_visitP(c->blocks[i]); -} void scope_visit(Value* x) { Scope* c = (Scope*)x; if (c->psc) mm_visitP(c->psc); @@ -558,18 +561,21 @@ void scope_visit(Value* x) { u16 am = c->varAm; for (u32 i = 0; i < am; i++) mm_visit(c->vars[i]); } -void body_visit(Value* x) { Body* c = (Body *)x; mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); } +void comp_visit(Value* x) { Comp* c = (Comp *)x; mm_visitP(c->objs); mm_visit(c->bc); mm_visit(c->src); mm_visit(c->indices); } +void body_visit(Value* x) { Body* c = (Body *)x; mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); mm_visitP(c->blocks); } void block_visit(Value* x) { Block* c = (Block *)x; mm_visitP(c->body); } void funBl_visit(Value* x) { FunBlock* c = (FunBlock*)x; mm_visitP(c->sc); mm_visitP(c->bl); } void md1Bl_visit(Value* x) { Md1Block* c = (Md1Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); } void md2Bl_visit(Value* x) { Md2Block* c = (Md2Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); } void alias_visit(Value* x) { mm_visit(((FldAlias*)x)->obj); } +void bBlks_visit(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (u32 i = 0; i < am; i++) mm_visitP(c->a[i]); } void comp_print (B x) { printf("(%p: comp)",v(x)); } void body_print (B x) { printf("(%p: body varam=%d)",v(x),c(Body,x)->varAm); } void block_print(B x) { printf("(%p: block for %p)",v(x),c(Block,x)->body); } void scope_print(B x) { printf("(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;ivarAm;i++){printf(" ");print(sc->vars[i]);}printf(")"); } void alias_print(B x) { printf("(alias %d of ", c(FldAlias,x)->p); print(c(FldAlias,x)->obj); printf(")"); } +void bBlks_print(B x) { printf("(block list)"); } // void funBl_print(B x) { printf("(%p: function"" block bl=%p sc=%p)",v(x),c(FunBlock,x)->bl,c(FunBlock,x)->sc); } // void md1Bl_print(B x) { printf("(%p: 1-modifier block bl=%p sc=%p)",v(x),c(Md1Block,x)->bl,c(Md1Block,x)->sc); } @@ -609,6 +615,7 @@ void comp_init() { ti[t_body ].free = body_free; ti[t_body ].visit = body_visit; ti[t_body ].print = body_print; ti[t_block ].free = block_free; ti[t_block ].visit = block_visit; ti[t_block ].print = block_print; ti[t_scope ].free = scope_free; ti[t_scope ].visit = scope_visit; ti[t_scope ].print = scope_print; + ti[t_blBlocks ].free = bBlks_free; ti[t_blBlocks ].visit = bBlks_visit; ti[t_blBlocks ].print = bBlks_print; ti[t_fldAlias ].free = alias_free; ti[t_fldAlias ].visit = alias_visit; ti[t_fldAlias ].print = alias_print; ti[t_fun_block].free = funBl_free; ti[t_fun_block].visit = funBl_visit; ti[t_fun_block].print = funBl_print; ti[t_fun_block].decompose = block_decompose; ti[t_md1_block].free = md1Bl_free; ti[t_md1_block].visit = md1Bl_visit; ti[t_md1_block].print = md1Bl_print; ti[t_md1_block].decompose = block_decompose; ti[t_md1_block].m1_d=bl_m1d; diff --git a/src/vm.h b/src/vm.h index f595c72d..2c1b6389 100644 --- a/src/vm.h +++ b/src/vm.h @@ -1,7 +1,10 @@ #pragma once +typedef struct Comp Comp; +typedef struct BlBlocks BlBlocks; typedef struct Block Block; typedef struct Body Body; typedef struct Scope Scope; +typedef struct ScopeExt ScopeExt; typedef struct Comp { struct Value; @@ -10,9 +13,14 @@ typedef struct Comp { B indices; HArr* objs; u32 blockAm; - Block* blocks[]; } Comp; +struct BlBlocks { + struct Value; + u32 am; + Block* a[]; +}; + struct Block { struct Value; bool imm; @@ -24,6 +32,7 @@ typedef struct NSDesc NSDesc; struct Body { struct Value; Comp* comp; + BlBlocks* blocks; // B* objs; i32* bc; // pointer in comp->bc u32 maxStack; @@ -34,20 +43,29 @@ struct Body { i32 varIDs[]; }; +struct ScopeExt { + u16 varAm; + B vars[]; +}; + struct Scope { struct Value; Scope* psc; Body* body; u16 varAm; + ScopeExt* ext; B vars[]; }; + +Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc); + + typedef struct Env { Scope* sc; union { i32* bcL; i32 bcV; }; } Env; -Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src); void vm_pst(Env* s, Env* e); void vm_pstLive();