fix & speed up variable modification fns

This commit is contained in:
dzaima 2021-11-18 01:10:30 +02:00
parent 3ba3558c93
commit 2baa9ac196
4 changed files with 38 additions and 37 deletions

View File

@ -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));

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}