ahead-of-time computed scope parents
not much of a difference in performance, but whatever
This commit is contained in:
parent
db7b0cc323
commit
3ebdb16571
42
src/vm.c
42
src/vm.c
@ -122,6 +122,7 @@ typedef struct Body {
|
|||||||
// B* objs;
|
// B* objs;
|
||||||
i32* bc; // pointer in comp->bc
|
i32* bc; // pointer in comp->bc
|
||||||
u32 maxStack;
|
u32 maxStack;
|
||||||
|
u16 maxPSC;
|
||||||
u16 varAm;
|
u16 varAm;
|
||||||
// HArr* vNames;
|
// HArr* vNames;
|
||||||
} Body;
|
} Body;
|
||||||
@ -169,20 +170,23 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
|||||||
|
|
||||||
i32* scan = cbc;
|
i32* scan = cbc;
|
||||||
i32 ssz = 0, mssz=0;
|
i32 ssz = 0, mssz=0;
|
||||||
|
i32 mpsc = 0;
|
||||||
while (*scan!=RETN & *scan!=RETD) {
|
while (*scan!=RETN & *scan!=RETD) {
|
||||||
ssz+= stackDiff(scan);
|
ssz+= stackDiff(scan);
|
||||||
if (ssz>mssz) mssz = ssz;
|
if (ssz>mssz) mssz = ssz;
|
||||||
if (*scan==LOCO | *scan==LOCM) {
|
if (*scan==LOCO | *scan==LOCM | *scan==LOCU) {
|
||||||
if (scan[1]>U16_MAX) return c(Block,err("LOC_ too deep"));
|
if (scan[1]>mpsc) mpsc = scan[1];
|
||||||
}
|
}
|
||||||
scan = nextBC(scan);
|
scan = nextBC(scan);
|
||||||
if (scan-bc >= bcl) return c(Block,err("no RETN/RETD found at end of bytecode"));
|
if (scan-bc >= bcl) return c(Block,err("no RETN/RETD found at end of bytecode"));
|
||||||
}
|
}
|
||||||
|
if (mpsc>U16_MAX) thrM("LOC_ too deep");
|
||||||
|
|
||||||
Body* body = mm_allocN(sizeof(Body), t_body);
|
Body* body = mm_allocN(sizeof(Body), t_body);
|
||||||
body->comp = comp;
|
body->comp = comp;
|
||||||
body->bc = cbc;
|
body->bc = cbc;
|
||||||
body->maxStack = mssz;
|
body->maxStack = mssz;
|
||||||
|
body->maxPSC = mpsc;
|
||||||
body->varAm = vam;
|
body->varAm = vam;
|
||||||
ptr_inc(comp);
|
ptr_inc(comp);
|
||||||
|
|
||||||
@ -201,14 +205,9 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope* scd(Scope* sc, u16 d) {
|
void v_set(Scope* pscs[], B s, B x, bool upd) { // frees s, doesn't consume x
|
||||||
for (i32 i = 0; i < d; i++) sc = sc->psc;
|
|
||||||
return sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void v_set(Scope* sc, B s, B x, bool upd) { // frees s, doesn't consume x
|
|
||||||
if (isVar(s)) {
|
if (isVar(s)) {
|
||||||
sc = scd(sc, (u16)(s.u>>32));
|
Scope* sc = pscs[(u16)(s.u>>32)];
|
||||||
B prev = sc->vars[(u32)s.u];
|
B prev = sc->vars[(u32)s.u];
|
||||||
if (upd) {
|
if (upd) {
|
||||||
if (prev.u==bi_noVar.u) err("updating undefined variable");
|
if (prev.u==bi_noVar.u) err("updating undefined variable");
|
||||||
@ -224,14 +223,14 @@ void v_set(Scope* sc, B s, B x, bool upd) { // frees s, doesn't consume x
|
|||||||
B* sp = harr_ptr(s);
|
B* sp = harr_ptr(s);
|
||||||
BS2B xgetU = TI(x).getU;
|
BS2B xgetU = TI(x).getU;
|
||||||
for (u64 i = 0; i < ia; i++) {
|
for (u64 i = 0; i < ia; i++) {
|
||||||
v_set(sc, sp[i], xgetU(x,i), upd);
|
v_set(pscs, sp[i], xgetU(x,i), upd);
|
||||||
}
|
}
|
||||||
dec(s);
|
dec(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut; doesn't consume
|
B v_get(Scope* pscs[], B s) { // get value representing s, replacing with bi_optOut; doesn't consume
|
||||||
if (isVar(s)) {
|
if (isVar(s)) {
|
||||||
sc = scd(sc, (u16)(s.u>>32));
|
Scope* sc = pscs[(u16)(s.u>>32)];
|
||||||
B r = sc->vars[(u32)s.u];
|
B r = sc->vars[(u32)s.u];
|
||||||
sc->vars[(u32)s.u] = bi_optOut;
|
sc->vars[(u32)s.u] = bi_optOut;
|
||||||
return r;
|
return r;
|
||||||
@ -240,7 +239,7 @@ B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut;
|
|||||||
usz ia = a(s)->ia;
|
usz ia = a(s)->ia;
|
||||||
B* sp = harr_ptr(s);
|
B* sp = harr_ptr(s);
|
||||||
HArr_p r = m_harrUv(ia);
|
HArr_p r = m_harrUv(ia);
|
||||||
for (u64 i = 0; i < ia; i++) r.a[i] = v_get(sc, sp[i]);
|
for (u64 i = 0; i < ia; i++) r.a[i] = v_get(pscs, sp[i]);
|
||||||
return r.b;
|
return r.b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +276,6 @@ void gsAdd(B x) {
|
|||||||
B gsPop() {
|
B gsPop() {
|
||||||
return *--gStack;
|
return *--gStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
B evalBC(Body* b, Scope* sc) { // doesn't consume
|
B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
bcDepth+= 2;
|
bcDepth+= 2;
|
||||||
@ -290,6 +288,10 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
Block** blocks = b->comp->blocks;
|
Block** blocks = b->comp->blocks;
|
||||||
i32* bc = b->bc;
|
i32* bc = b->bc;
|
||||||
gsReserve(b->maxStack);
|
gsReserve(b->maxStack);
|
||||||
|
Scope* pscs[b->maxPSC+1];
|
||||||
|
pscs[0] = sc;
|
||||||
|
for (i32 i = 0; i < b->maxPSC; i++) pscs[i+1] = pscs[i]->psc;
|
||||||
|
|
||||||
#define POP (*--gStack)
|
#define POP (*--gStack)
|
||||||
#define P(N) B N=POP;
|
#define P(N) B N=POP;
|
||||||
#define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed
|
#define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed
|
||||||
@ -361,21 +363,21 @@ 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(scd(sc,d)->vars[p]));
|
ADD(inc(pscs[d]->vars[p]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCU: { i32 d = *bc++; i32 p = *bc++;
|
case LOCU: { i32 d = *bc++; i32 p = *bc++;
|
||||||
B* vars = scd(sc,d)->vars;
|
B* vars = pscs[d]->vars;
|
||||||
ADD(vars[p]);
|
ADD(vars[p]);
|
||||||
vars[p] = bi_optOut;
|
vars[p] = bi_optOut;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SETN: { P(s) P(x) v_set(sc, s, x, false); ADD(x); break; }
|
case SETN: { P(s) P(x) v_set(pscs, s, x, false); ADD(x); break; }
|
||||||
case SETU: { P(s) P(x) v_set(sc, s, x, true ); ADD(x); break; }
|
case SETU: { P(s) P(x) v_set(pscs, s, x, true ); ADD(x); break; }
|
||||||
case SETM: { P(s)P(f)P(x)
|
case SETM: { P(s)P(f)P(x)
|
||||||
B w = v_get(sc, s);
|
B w = v_get(pscs, s);
|
||||||
B r = c2(f,w,x); dec(f);
|
B r = c2(f,w,x); dec(f);
|
||||||
v_set(sc, s, r, true);
|
v_set(pscs, s, r, true);
|
||||||
ADD(r);
|
ADD(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user