fix & speed up variable modification fns
This commit is contained in:
parent
3ba3558c93
commit
2baa9ac196
@ -146,18 +146,18 @@ INS B i_EXTU(u32 p, Scope* sc) {
|
||||
vars[p] = bi_optOut;
|
||||
return r;
|
||||
}
|
||||
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false); dec(s); return x; }
|
||||
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true ); dec(s); return x; }
|
||||
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false, true); dec(s); return x; }
|
||||
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true, true); dec(s); return x; }
|
||||
INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
B w = v_get(pscs, s);
|
||||
B w = v_get(pscs, s, true);
|
||||
B r = c2(f,w,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
v_set(pscs, s, r, true, false); dec(s);
|
||||
return r;
|
||||
}
|
||||
INS B i_SETC(B s, B f, Scope** pscs, u32* bc) { POS_UPD;
|
||||
B x = v_get(pscs, s);
|
||||
B x = v_get(pscs, s, true);
|
||||
B r = c1(f,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
v_set(pscs, s, r, true, false); dec(s);
|
||||
return r;
|
||||
}
|
||||
FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {
|
||||
@ -182,14 +182,14 @@ INS B i_PRED2(B x, Scope* sc, u32* bc, Body* v1, Body* v2) { POS_UPD;
|
||||
if (o2b(x)) return bi_okHdr;
|
||||
return gotoNextBodyJIT(sc, q_N(sc->vars[2])? v1 : v2);
|
||||
}
|
||||
INS B i_SETNi( B x, Scope* sc, u32 p ) { v_setI(sc, p, inc(x), false); return x; }
|
||||
INS B i_SETUi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), true ); return x; }
|
||||
INS B i_SETMi(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p),x); dec(f); v_setI(sc, p, inc(r), true); return r; }
|
||||
INS B i_SETCi(B f, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c1(f,v_getI(sc, p) ); dec(f); v_setI(sc, p, inc(r), true); return r; }
|
||||
INS void i_SETNv(B x, Scope* sc, u32 p ) { v_setI(sc, p, x, false); }
|
||||
INS void i_SETUv(B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, x, true ); }
|
||||
INS void i_SETMv(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p),x); dec(f); v_setI(sc, p, r, true); }
|
||||
INS void i_SETCv(B f, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c1(f,v_getI(sc, p) ); dec(f); v_setI(sc, p, r, true); }
|
||||
INS B i_SETNi( B x, Scope* sc, u32 p ) { v_setI(sc, p, inc(x), false, false); return x; }
|
||||
INS B i_SETUi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), true, false); return x; }
|
||||
INS B i_SETMi(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p, false),x); dec(f); v_setI(sc, p, inc(r), true, false); return r; }
|
||||
INS B i_SETCi(B f, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c1(f,v_getI(sc, p, false) ); dec(f); v_setI(sc, p, inc(r), true, false); return r; }
|
||||
INS void i_SETNv(B x, Scope* sc, u32 p ) { v_setI(sc, p, x, false, false); }
|
||||
INS void i_SETUv(B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, x, true, false); }
|
||||
INS void i_SETMv(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p, false),x); dec(f); v_setI(sc, p, r, true, false); }
|
||||
INS void i_SETCv(B f, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c1(f,v_getI(sc, p, false) ); dec(f); v_setI(sc, p, r, true, false); }
|
||||
INS B i_FLDO(B ns, u32 p, Scope* sc) {
|
||||
if (!isNsp(ns)) thrM("Trying to read a field from non-namespace");
|
||||
B r = inc(ns_getU(ns, sc->body->nsDesc->nameList, p));
|
||||
|
||||
@ -210,8 +210,7 @@ static NOINLINE void asm_write(u8* P, u64 SZ) {
|
||||
// #define POP(O,I) {REX4(O,0),0x58+((O)&7)}
|
||||
|
||||
// #define BYTES4(I) ((UC)(I)),((UC)((I)>>8)),((UC)((I)>>16)),((UC)((I)>>24))
|
||||
// #define BYTES8(I) BYTES4(I) ,((UC)((I)>>32)),((UC)((I)>>40)) \
|
||||
// ,((UC)((I)>>48)),((UC)((I)>>56))
|
||||
// #define BYTES8(I) BYTES4(I) ,((UC)((I)>>32)),((UC)((I)>>40)),((UC)((I)>>48)),((UC)((I)>>56))
|
||||
|
||||
// #define MOV_MR(O,I,OFF) {REX8(O,I),0x89,0x40+A_0REG(O,I),OFF}
|
||||
// #define MOV_MR0(O,I) {REX8(O,I),0x89,A_0REG(O,I)} // TODO is broken on (12,14)
|
||||
|
||||
23
src/vm.c
23
src/vm.c
@ -438,21 +438,21 @@ NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) {
|
||||
if (isVar(c)) {
|
||||
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||
i32 nameID = sc->body->varIDs[(u32)c.u];
|
||||
v_set(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID), upd);
|
||||
v_set(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID), upd, true);
|
||||
} else if (isExt(c)) {
|
||||
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
|
||||
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd);
|
||||
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd, true);
|
||||
} else if (isObj(c)) {
|
||||
assert(v(c)->type == t_fldAlias);
|
||||
Scope* sc = pscs[0];
|
||||
FldAlias* cf = c(FldAlias,c);
|
||||
v_set(pscs, cf->obj, ns_getU(x, sc->body->nsDesc->nameList, cf->p), upd);
|
||||
v_set(pscs, cf->obj, ns_getU(x, sc->body->nsDesc->nameList, cf->p), upd, true);
|
||||
} else thrM("Assignment: extracting non-name from namespace");
|
||||
}
|
||||
return;
|
||||
}
|
||||
SGetU(x)
|
||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd);
|
||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd, true);
|
||||
}
|
||||
}
|
||||
NOINLINE bool v_sethR(Scope* pscs[], B s, B x) {
|
||||
@ -491,6 +491,7 @@ NOINLINE B v_getR(Scope* pscs[], B s) {
|
||||
if (isExt(s)) {
|
||||
Scope* sc = pscs[(u16)(s.u>>32)];
|
||||
B r = sc->ext->vars[(u32)s.u];
|
||||
if (r.u==bi_noVar.u) thrM("↩: Reading variable that hasn't been set");
|
||||
sc->ext->vars[(u32)s.u] = bi_optOut;
|
||||
return r;
|
||||
} else {
|
||||
@ -498,7 +499,7 @@ NOINLINE B v_getR(Scope* pscs[], B s) {
|
||||
usz ia = a(s)->ia;
|
||||
B* sp = harr_ptr(s);
|
||||
HArr_p r = m_harrUv(ia);
|
||||
for (u64 i = 0; i < ia; i++) r.a[i] = v_get(pscs, sp[i]);
|
||||
for (u64 i = 0; i < ia; i++) r.a[i] = v_get(pscs, sp[i], true);
|
||||
return r.b;
|
||||
}
|
||||
}
|
||||
@ -679,19 +680,19 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
|
||||
vars[p] = bi_optOut;
|
||||
break;
|
||||
}
|
||||
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false); dec(s); ADD(x); break; }
|
||||
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true ); dec(s); ADD(x); break; }
|
||||
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true); dec(s); ADD(x); break; }
|
||||
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true, true); dec(s); ADD(x); break; }
|
||||
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
|
||||
B w = v_get(pscs, s);
|
||||
B w = v_get(pscs, s, true);
|
||||
B r = c2(f,w,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
v_set(pscs, s, r, true, false); dec(s);
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
|
||||
B x = v_get(pscs, s);
|
||||
B x = v_get(pscs, s, true);
|
||||
B r = c1(f,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
v_set(pscs, s, r, true, false); dec(s);
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
|
||||
21
src/vm.h
21
src/vm.h
@ -251,33 +251,34 @@ typedef struct VfyObj {
|
||||
|
||||
|
||||
NOINLINE B v_getR(Scope* pscs[], B s); // doesn't consume
|
||||
static inline B v_getI(Scope* sc, u32 p) {
|
||||
FORCE_INLINE B v_getI(Scope* sc, u32 p, bool chk) {
|
||||
B r = sc->vars[p];
|
||||
if (chk && r.u==bi_noVar.u) thrM("↩: Reading variable that hasn't been set");
|
||||
sc->vars[p] = bi_optOut;
|
||||
return r;
|
||||
}
|
||||
static inline B v_get(Scope* pscs[], B s) { // get value representing s, replacing with bi_optOut; doesn't consume
|
||||
FORCE_INLINE B v_get(Scope* pscs[], B s, bool chk) { // get value representing s, replacing with bi_optOut; doesn't consume; if chk is false, content variables _may_ not be checked to be set
|
||||
if (RARE(!isVar(s))) return v_getR(pscs, s);
|
||||
return v_getI(pscs[(u16)(s.u>>32)], (u32)s.u);
|
||||
return v_getI(pscs[(u16)(s.u>>32)], (u32)s.u, chk);
|
||||
}
|
||||
|
||||
NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd); // doesn't consume
|
||||
NOINLINE bool v_sethR(Scope* pscs[], B s, B x); // doesn't consume
|
||||
static inline void v_setI(Scope* sc, u32 p, B x, bool upd) { // consumes x
|
||||
B prev = sc->vars[p];
|
||||
FORCE_INLINE void v_setI(Scope* sc, u32 p, B x, bool upd, bool chk) { // consumes x
|
||||
if (upd) {
|
||||
if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable");
|
||||
B prev = sc->vars[p];
|
||||
if (chk && prev.u==bi_noVar.u) thrM("↩: Updating variable that hasn't been set");
|
||||
dec(prev);
|
||||
}
|
||||
sc->vars[p] = x;
|
||||
}
|
||||
static inline void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume
|
||||
FORCE_INLINE void v_set(Scope* pscs[], B s, B x, bool upd, bool chk) { // doesn't consume; if chk is false, content variables _may_ not be checked to be set
|
||||
if (RARE(!isVar(s))) v_setR(pscs, s, x, upd);
|
||||
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd);
|
||||
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd, chk);
|
||||
}
|
||||
|
||||
static inline bool v_seth(Scope* pscs[], B s, B x) { // doesn't consume; s cannot contain extended variables
|
||||
FORCE_INLINE bool v_seth(Scope* pscs[], B s, B x) { // doesn't consume; s cannot contain extended variables
|
||||
if (RARE(!isVar(s))) return v_sethR(pscs, s, x);
|
||||
v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), false);
|
||||
v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), false, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user