proper bytecode rewriting

This commit is contained in:
dzaima 2021-05-26 16:34:36 +03:00
parent 7bf3b4be50
commit 48229571ba
4 changed files with 53 additions and 28 deletions

View File

@ -45,7 +45,7 @@ typedef struct TStack {
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 TSALLOC(T,N,I) usz N##_dc=(I); u32 N##_e=sizeof(T); TStack* N##_o = (TStack*)mm_allocN(sizeof(TStack)+N##_e*N##_dc, t_temp); N##_o->size=0; N##_o->cap=N##_dc; 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)

View File

@ -81,6 +81,7 @@
#define AUTO __auto_type
#define LIKELY(X) __builtin_expect(X,1)
#define RARE(X) __builtin_expect(X,0)
#define RFLD(X,T,F) ((T*)((char*)(X) - offsetof(T,F))) // reverse-read field: `T* x = …; E v = x->f; x == RFLD(v, T, f)`
typedef u32 usz;
typedef u8 ur;

View File

@ -127,53 +127,77 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, i32* bc, usz bcIA, B block
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);
TSALLOC(Block*, nBlT, 2);
TSALLOC(i32, nBCT, 20);
TSALLOC(i32, mapT, 20);
i32* c = bc+idx;
while (true) {
i32* n = nextBC(c);
if (n-thisBC-1 >= bcIA) thrM("VM compiler: No RETN/RETD found before end of bytecode");
if (n-bc-1 >= bcIA) thrM("VM compiler: No RETN/RETD found before end of bytecode");
bool ret = false;
switch (*c) {
case RETN: if(h!=1) thrM("VM compiler: Wrong stack size before RETN");
goto returned;
TSADD(nBCT, RETN);
ret = true;
break;
case RETD: if(h!=1&h!=0) thrM("VM compiler: Wrong stack size before RETD");
goto returned;
case DFND:
if (h==1) TSADD(nBCT, POPS);
TSADD(nBCT, RETD);
ret = true;
break;
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(nBCT, DFND);
TSADD(nBCT, 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:
}
case LOCO: case LOCM: case LOCU: {
if (c[1]>mpsc) mpsc = c[1];
TSADD(nBCT, c[0]);
TSADD(nBCT, c[1]);
TSADD(nBCT, c[2]);
break;
default:
}
default: {
i32* ccpy = c;
while (ccpy!=n) TSADD(nBCT, *ccpy++);
break;
}
}
usz nlen = TSSIZE(nBCT)-TSSIZE(mapT);
for (usz i = 0; i < nlen; i++) TSADD(mapT, c-bc);
h+= stackDiff(c);
if (h<0) thrM("VM compiler: Stack size goes negative");
if (h>hM) hM = h;
if (ret) break;
c = n;
} returned:;
u64 blC = TSSIZE(nBlT);
}
if (mpsc>U16_MAX) thrM("VM compiler: LOC_ too deep");
usz 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");
usz nbcC = TSSIZE(nBCT); i32* nbc; m_i32arrv(&nbc, nbcC); memcpy(nbc, nBCT, nbcC*4); TSFREE(nBCT);
usz mapC = TSSIZE(mapT); i32* map; m_i32arrv(&map, mapC); memcpy(map, mapT, mapC*4); TSFREE(mapT);
Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body);
body->comp = comp; ptr_inc(comp);
body->bc = thisBC;
body->bc = nbc;
body->map = map;
body->blocks = nBl;
body->maxStack = hM;
body->maxPSC = (u16)mpsc;
body->endStack = h;
body->varAm = (u16)vam;
if (cIA==4) {
body->nsDesc = NULL;
@ -292,6 +316,7 @@ i32 bcDepth=-2;
i32* vmStack;
i32 bcCtr = 0;
#endif
#define BCPOS(B,P) (B->map[P-B->bc])
B evalBC(Body* b, Scope* sc) { // doesn't consume
#ifdef DEBUG_VM
bcDepth+= 2;
@ -329,7 +354,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
while(true) {
#ifdef DEBUG_VM
i32* sbc = bc;
i32 bcPos = sbc-c(I32Arr,b->comp->bc)->a;
i32 bcPos = BCPOS(b,sbc);
vmStack[stackNum] = bcPos;
for(i32 i = 0; i < bcDepth; i++) printf(" ");
printBC(sbc); printf("@%d << ", bcPos);
@ -432,7 +457,6 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
break;
}
case RETD: {
if (b->endStack) dec(POP);
ptr_inc(sc);
ptr_inc(b->nsDesc);
ADD(m_ns(sc, b->nsDesc));
@ -456,7 +480,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
}
#ifdef DEBUG_VM
for(i32 i = 0; i < bcDepth; i++) printf(" ");
printBC(sbc); printf("@%ld: ", sbc-c(I32Arr,b->comp->bc)->a);
printBC(sbc); printf("@%ld: ", BCPOS(b, sbc));
for (i32 i = 0; i < b->maxStack; i++) { if(i)printf(""); print(gStack[i]); } putchar('\n'); fflush(stdout);
#endif
}
@ -546,7 +570,7 @@ void scope_free(Value* x) {
for (u32 i = 0; i < am; i++) dec(c->vars[i]);
}
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 body_free(Value* x) { Body* c = (Body *)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); ptr_decR(c->blocks); ptr_decR(RFLD(c->bc,I32Arr,a)); ptr_decR(RFLD(c->map,I32Arr,a)); }
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); }
@ -562,7 +586,7 @@ void scope_visit(Value* x) {
for (u32 i = 0; i < am; i++) mm_visit(c->vars[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); }
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 body_visit(Value* x) { Body* c = (Body *)x; mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); mm_visitP(c->blocks); mm_visitP(RFLD(c->bc,I32Arr,a)); mm_visitP(RFLD(c->map,I32Arr,a)); }
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); }
@ -580,9 +604,9 @@ 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); }
// void md2Bl_print(B x) { printf("(%p: 2-modifier block bl=%p sc=%p)",v(x),c(Md2Block,x)->bl,c(Md2Block,x)->sc); }
void funBl_print(B x) { printf("(function"" block @%ld)",c(FunBlock,x)->bl->body->bc-c(I32Arr,c(FunBlock,x)->bl->body->comp->bc)->a); }
void md1Bl_print(B x) { printf("(1-modifier block @%ld)",c(Md1Block,x)->bl->body->bc-c(I32Arr,c(Md1Block,x)->bl->body->comp->bc)->a); }
void md2Bl_print(B x) { printf("(2-modifier block @%ld)",c(Md2Block,x)->bl->body->bc-c(I32Arr,c(Md2Block,x)->bl->body->comp->bc)->a); }
void funBl_print(B x) { printf("(function"" block @%d)",c(FunBlock,x)->bl->body->map[0]); }
void md1Bl_print(B x) { printf("(1-modifier block @%d)",c(Md1Block,x)->bl->body->map[0]); }
void md2Bl_print(B x) { printf("(2-modifier block @%d)",c(Md2Block,x)->bl->body->map[0]); }
// void funBl_print(B x) { printf("{function""}"); }
// void md1Bl_print(B x) { printf("{1-modifier}"); }
// void md2Bl_print(B x) { printf("{2-modifier}"); }
@ -697,7 +721,7 @@ NOINLINE void vm_pst(Env* s, Env* e) {
i = 10;
}
Comp* comp = c->sc->body->comp;
i32 bcPos = c>=envStart && c<envCurr? c->bcL - i32arr_ptr(comp->bc) : c->bcV;
i32 bcPos = c>=envStart && c<envCurr? BCPOS(c->sc->body, c->bcL) : c->bcV;
vm_printPos(comp, bcPos, i);
i--;
}
@ -710,7 +734,7 @@ static void unwindEnv(Env* envNew) {
assert(envNew<=envCurr);
while (envCurr!=envNew) {
envCurr--;
envCurr->bcV = envCurr->bcL - i32arr_ptr(envCurr->sc->body->comp->bc);
envCurr->bcV = BCPOS(envCurr->sc->body, envCurr->bcL);
}
}

View File

@ -34,11 +34,11 @@ struct Body {
Comp* comp;
BlBlocks* blocks;
// B* objs;
i32* bc; // pointer in comp->bc
i32* bc; // pointer in an owned I32Arr
i32* map; // pointer in an owned I32Arr
u32 maxStack;
u16 maxPSC;
u16 varAm;
u32 endStack;
NSDesc* nsDesc;
i32 varIDs[];
};