SETC
This commit is contained in:
parent
4f0841c95e
commit
084eaaecbd
@ -127,6 +127,12 @@ INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
v_set(pscs, s, r, true); 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 r = c1(f,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
return r;
|
||||
}
|
||||
INS B i_SETH(B s, B x, Scope** pscs, u32* bc, Body* v1, Body* v2) { POS_UPD;
|
||||
bool ok = v_seth(pscs, s, x); dec(x); dec(s);
|
||||
if (ok) return bi_okHdr;
|
||||
@ -143,9 +149,11 @@ INS B i_SETH(B s, B x, Scope** pscs, u32* bc, Body* v1, Body* v2) { POS_UPD;
|
||||
INS B i_SETNi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; 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, u32* bc) { POS_UPD; 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_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));
|
||||
@ -297,7 +305,7 @@ static OptRes opt(u32* bc0) {
|
||||
stk[TSSIZE(stk)-1] = SREF(d, pos);
|
||||
break;
|
||||
}
|
||||
case SETN: case SETU: case SETM: { S(s,0)
|
||||
case SETN: case SETU: case SETM: case SETC: { S(s,0)
|
||||
if (!isVar(s.v)) goto defIns;
|
||||
cact = 2; RM(s.p);
|
||||
TSADD(data, s.v.u);
|
||||
@ -356,15 +364,15 @@ static OptRes opt(u32* bc0) {
|
||||
u64 psz = TSSIZE(rbc);
|
||||
#define A64(X) { u64 a64=(X); TSADD(rbc, (u32)a64); TSADD(rbc, a64>>32); }
|
||||
switch (ctype) { default: UD;
|
||||
case 2: { assert(v==SETN|v==SETU|v==SETM);
|
||||
TSADD(rbc, v==SETN? SETNi : v==SETU? SETUi : SETMi);
|
||||
case 2: { assert(v==SETN|v==SETU|v==SETM|v==SETC);
|
||||
TSADD(rbc, v==SETN? SETNi : v==SETU? SETUi : v==SETC? SETCi : SETMi);
|
||||
u64 d = data[dpos++];
|
||||
TSADD(rbc, (u16)(d>>32));
|
||||
TSADD(rbc, (u32)d);
|
||||
break;
|
||||
}
|
||||
case 7: { assert(v==SETN|v==SETU|v==SETM);
|
||||
TSADD(rbc, v==SETN? SETNv : v==SETU? SETUv : SETMv);
|
||||
case 7: { assert(v==SETN|v==SETU|v==SETM|v==SETC);
|
||||
TSADD(rbc, v==SETN? SETNv : v==SETU? SETUv : v==SETC? SETCv : SETMv);
|
||||
u64 d = data[dpos++];
|
||||
TSADD(rbc, (u16)(d>>32));
|
||||
TSADD(rbc, (u32)d);
|
||||
@ -597,13 +605,16 @@ Nvm_res m_nvm(Body* body) {
|
||||
case SETN: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETN); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
case SETU: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETU); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
case SETM: TOPp; GET(R_A1,1,1); GET(R_A2,2,1); LEAi(R_A3,R_SP,VAR(pscs,0)); IMM(R_A4,off); CCALL(i_SETM); break; // (B s, B f, B x, Scope** pscs, u32* bc)
|
||||
case SETC: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETC); break; // (B s, B f, Scope** pscs, u32* bc)
|
||||
// TODO SETNi doesn't really need to update gStack
|
||||
case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETMi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMi); break; } // (B f, B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETCi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETCi); break; } // (B f, Scope* sc, u32 p, u32* bc)
|
||||
case SETNv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNv); NORES(1); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUv); NORES(1); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETMv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMv); NORES(2); break; } // (B f, B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETCv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETCv); NORES(1); break; } // (B f, Scope* sc, u32 p, u32* bc)
|
||||
case FLDO: TOPp; GET(R_A1,0,2); IMM(R_A1,*bc++); MOV(R_A2,r_SC); CCALL(i_FLDO); break; // (B, u32 p, Scope* sc)
|
||||
case ALIM: TOPp; IMM(R_A1,*bc++); CCALL(i_ALIM); break; // (B, u32 l)
|
||||
case VFYM: TOPp; CCALL(i_VFYM); break; // (B)
|
||||
@ -611,7 +622,7 @@ Nvm_res m_nvm(Body* body) {
|
||||
case RETD: if (lGPos!=0) GS_SET(r_CS); MOV(R_A0,r_SC); CCALL(i_RETD); ret=true; break; // (Scope* sc)
|
||||
case RETN: if (lGPos!=0) GS_SET(r_CS); ret=true; break;
|
||||
case FAIL: TOPs; IMM(R_A0,off); MOV(R_A1,r_SC); INV(2,0,i_FAIL); ret=true; break;
|
||||
default: thrF("JIT: Unsupported bytecode %i/%S", *s, nameBC(s));
|
||||
default: thrF("JIT: Unsupported bytecode %i/%S", *s, bc_repr(s));
|
||||
}
|
||||
#undef GET
|
||||
#undef GS_SET
|
||||
|
||||
22
src/vm.c
22
src/vm.c
@ -11,10 +11,10 @@
|
||||
#endif
|
||||
|
||||
#define FOR_BC(F) F(PUSH) F(DYNO) F(DYNM) F(ARRO) F(ARRM) F(FN1C) F(FN2C) F(MD1C) F(MD2C) F(TR2D) \
|
||||
F(TR3D) F(SETN) F(SETU) F(SETM) F(POPS) F(DFND) F(FN1O) F(FN2O) F(CHKV) F(TR3O) \
|
||||
F(TR3D) F(SETN) F(SETU) F(SETM) F(SETC) F(POPS) F(DFND) F(FN1O) F(FN2O) F(CHKV) F(TR3O) \
|
||||
F(MD2R) F(VARO) F(VARM) F(VFYM) F(SETH) F(RETN) F(FLDO) F(FLDM) F(ALIM) F(RETD) F(SYSV) F(VARU) \
|
||||
F(EXTO) F(EXTM) F(EXTU) F(ADDI) F(ADDU) F(FN1Ci)F(FN1Oi)F(FN2Ci)F(FN2Oi) \
|
||||
F(SETNi)F(SETUi)F(SETMi)F(SETNv)F(SETUv)F(SETMv)F(FAIL)
|
||||
F(SETNi)F(SETUi)F(SETMi)F(SETCi)F(SETNv)F(SETUv)F(SETMv)F(SETCv)F(FAIL)
|
||||
|
||||
u32* nextBC(u32* p) {
|
||||
i32 off;
|
||||
@ -22,7 +22,7 @@ u32* nextBC(u32* p) {
|
||||
case FN1C: case FN2C: case FN1O: case FN2O:
|
||||
case MD1C: case MD2C: case MD2R:
|
||||
case TR2D: case TR3D: case TR3O:
|
||||
case SETN: case SETU: case SETM: case SETH:
|
||||
case SETN: case SETU: case SETM: case SETH: case SETC:
|
||||
case POPS: case CHKV: case VFYM: case RETN: case RETD:
|
||||
case FAIL:
|
||||
off = 1; break;
|
||||
@ -34,7 +34,8 @@ u32* nextBC(u32* p) {
|
||||
case EXTO: case EXTM: case EXTU:
|
||||
case ADDI: case ADDU:
|
||||
case FN1Ci: case FN1Oi: case FN2Ci: case DFND0: case DFND1: case DFND2:
|
||||
case SETNi: case SETUi: case SETMi: case SETNv: case SETUv: case SETMv:
|
||||
case SETNi: case SETUi: case SETMi: case SETCi:
|
||||
case SETNv: case SETUv: case SETMv: case SETCv:
|
||||
off = 3; break;
|
||||
case FN2Oi: case SETHi:
|
||||
off = 5; break;
|
||||
@ -52,6 +53,7 @@ i32 stackDiff(u32* p) {
|
||||
|
||||
case SETN: return -1; case SETNi:return 0; case SETNv:return -1;
|
||||
case SETU: return -1; case SETUi:return 0; case SETUv:return -1;
|
||||
case SETC: return -1; case SETCi:return 0; case SETCv:return -1;
|
||||
case SETM: return -2; case SETMi:return -1; case SETMv:return -2;
|
||||
case FAIL: return 0;
|
||||
}
|
||||
@ -68,6 +70,7 @@ i32 stackConsumed(u32* p) {
|
||||
|
||||
case SETN: return 2; case SETNi: case SETNv: return 1;
|
||||
case SETU: return 2; case SETUi: case SETUv: return 1;
|
||||
case SETC: return 2; case SETCi: case SETCv: return 1;
|
||||
case SETM: return 3; case SETMi: case SETMv: return 2;
|
||||
case FAIL: return 0;
|
||||
}
|
||||
@ -76,7 +79,7 @@ i32 stackAdded(u32* p) {
|
||||
if (*p==ARRO|*p==ARRM) return 1;
|
||||
return stackDiff(p)+stackConsumed(p);
|
||||
}
|
||||
char* nameBC(u32* p) {
|
||||
char* bc_repr(u32* p) {
|
||||
switch(*p) { default: return "(unknown)";
|
||||
#define F(X) case X: return #X;
|
||||
FOR_BC(F)
|
||||
@ -84,7 +87,7 @@ char* nameBC(u32* p) {
|
||||
}
|
||||
}
|
||||
void printBC(u32* p) {
|
||||
printf("%s", nameBC(p));
|
||||
printf("%s", bc_repr(p));
|
||||
u32* n = nextBC(p);
|
||||
p++;
|
||||
i64 am = n-p;
|
||||
@ -692,6 +695,13 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
|
||||
B x = v_get(pscs, s);
|
||||
B r = c1(f,x); dec(f);
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
case SETHi:{ P(s) P(x) GS_UPD; POS_UPD; u64 v1 = L64; u64 v2 = L64;
|
||||
bool ok = v_seth(pscs, s, x); dec(x); dec(s);
|
||||
if (!ok) {
|
||||
|
||||
7
src/vm.h
7
src/vm.h
@ -46,14 +46,15 @@ enum {
|
||||
SETN = 0x30, // set new; _ ←_; ⟨…,x, mut⟩ → mut←x
|
||||
SETU = 0x31, // set upd; _ ↩_; ⟨…,x, mut⟩ → mut↩x
|
||||
SETM = 0x32, // set mod; _ F↩_; ⟨…,x,F,mut⟩ → mut F↩x
|
||||
SETC = 0x33, // set call; _ F↩; (…, F,mut) → mut F↩
|
||||
FLDO = 0x40, // N; get field nameList[N] from ToS
|
||||
FLDM = 0x41, // N; get mutable field nameList[N] from ToS
|
||||
ALIM = 0x42, // N; replace ToS with one with a namespace field alias N
|
||||
EXTO, EXTM, EXTU, // alternate versions of VAR_ for extended variables
|
||||
ADDI, ADDU, // separate PUSH for refcounting needed/not needed (stores the object inline as 2 u32s, instead of reading from `objs`)
|
||||
FN1Ci, FN1Oi, FN2Ci, FN2Oi, // FN__ alternatives that don't take the function from the stack, but instead as an 2×u32 immediate in the bytecode
|
||||
SETNi, SETUi, SETMi, // SET_ alternatives that expect the set variable as a depth-position pair like VAR_
|
||||
SETNv, SETUv, SETMv, // SET_i alternatives that also don't return the result
|
||||
SETNi, SETUi, SETMi, SETCi, // SET_ alternatives that expect the set variable as a depth-position pair like VAR_
|
||||
SETNv, SETUv, SETMv, SETCv, // SET_i alternatives that also don't return the result
|
||||
SETHi, // internal version of SETH, with 2×u64 arguments specifying bodies to jump to on fail (or NULL if is last)
|
||||
DFND0, DFND1, DFND2, // internal versions of DFND with a specific type, and a u64 argument representing the block pointer
|
||||
FAIL, // this body cannot be called monadically/dyadically
|
||||
@ -165,7 +166,7 @@ u32* nextBC(u32* p);
|
||||
i32 stackDiff(u32* p);
|
||||
i32 stackConsumed(u32* p);
|
||||
i32 stackAdded(u32* p);
|
||||
char* nameBC(u32* p);
|
||||
char* bc_repr(u32* p);
|
||||
|
||||
|
||||
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user