ARMO & ARMM

This commit is contained in:
dzaima 2022-06-14 02:09:41 +03:00
parent 8a84726e6e
commit 5e0bda6a28
4 changed files with 106 additions and 30 deletions

View File

@ -223,7 +223,7 @@ typedef union B {
/*31*/ F(bitarr) \
\
/*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) F(arbObj) F(ffiType) \
/*40*/ F(ns) F(nsDesc) F(fldAlias) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \
/*40*/ F(ns) F(nsDesc) F(fldAlias) F(arrMerge) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \
/*48*/ F(freed) F(harrPartial) F(customObj) F(mmapH) \
\
/*51*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap))

View File

@ -121,6 +121,22 @@ INS B i_ARR_p(B el0, i64 sz, B* cStack) { assert(sz>0);
if (allNum) return num_squeeze(r.b);
return r.b;
}
INS B i_ARMO(B el0, i64 sz, B* cStack) { assert(sz>0);
HArr_p r = m_harrUv(sz);
r.a[sz-1] = el0;
for (i64 i = 1; i < sz; i++) r.a[sz-i-1] = GSP;
GS_UPD;
return bqn_merge(r.b);
}
INS B i_ARMM(B el0, i64 sz, B* cStack) { assert(sz>0);
HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated
r.a[sz-1] = el0;
for (i64 i = 1; i < sz; i++) r.a[sz-i-1] = GSP;
GS_UPD;
WrappedObj* a = mm_alloc(sizeof(WrappedObj), t_arrMerge);
a->obj = r.b;
return tag(a,OBJ_TAG);
}
INS B i_DFND_0(u32* bc, Scope* sc, Block* bl) { POS_UPD; return evalFunBlock(bl, sc); }
INS B i_DFND_1(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_md1Block(bl, sc); } // TODO these only fail on oom, so no need to update pos
INS B i_DFND_2(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_md2Block(bl, sc); }
@ -200,7 +216,7 @@ INS B i_FLDO(B ns, u32 p, Scope* sc) {
return r;
}
INS B i_VFYM(B o) { // TODO this and ALIM allocate and thus can error on OOM
VfyObj* a = mm_alloc(sizeof(VfyObj), t_vfyObj);
WrappedObj* a = mm_alloc(sizeof(WrappedObj), t_vfyObj);
a->obj = o;
return tag(a,OBJ_TAG);
}
@ -597,13 +613,15 @@ Nvm_res m_nvm(Body* body) {
case FN2Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,1,1); CCALL(fn); } break;
case FN1Oi:TOPp; GET(R_A1,0,2); IMM(R_A1,L64); IMM(R_A2,off); CCALL(i_FN1Oi); break; // ( B x, BB2B fm, u32* bc)
case FN2Oi:TOPp; GET(R_A1,1,1); IMM(R_A2,L64); IMM(R_A3, L64); IMM(R_A4,off); CCALL(i_FN2Oi); break; // (B w, B x, BB2B fm, BBB2B fd, u32* bc)
case ARRM: case ARRO:; bool o = *(bc-1) == ARRO;
case ARRM: case ARRO:; { bool o = *(bc-1) == ARRO;
u32 sz = *bc++;
if (sz==0 ) { TOPs; CCALL(i_ARR_0); } // unused with optimizations
else if (sz==1 && o) { TOPp; GET(R_A3,0,2); CCALL(m_vec1); } // (B a)
else if (sz==2 && o) { TOPpR(R_A1); GET(R_A0,1,1); CCALL(m_vec2); } // (B a, B b)
else { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B a, i64 sz, S)
break;
} break;
case ARMO: { u32 sz = *bc++; TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARMO); break; }
case ARMM: { u32 sz = *bc++; TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARMM); break; }
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
Block* bl = (Block*)L64;
u64 fn = (u64)(bl->ty==0? i_DFND_0 : bl->ty==1? i_DFND_1 : bl->ty==2? i_DFND_2 : NULL);
@ -654,7 +672,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: print_fmt("JIT: Unsupported bytecode %i/%S", *s, bc_repr(*s)); err("");
default: print_fmt("JIT: Unsupported bytecode %i/%S\n", *s, bc_repr(*s)); err("");
}
#undef GET
#undef GS_SET

View File

@ -11,7 +11,7 @@
#define UNWIND_COMPILER 1
#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) \
#define FOR_BC(F) F(PUSH) F(DYNO) F(DYNM) F(ARRO) F(ARRM) F(ARMO) F(ARMM) F(FN1C) F(FN2C) F(MD1C) F(MD2C) F(TR2D) \
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(MD2L) F(VARO) F(VARM) F(VFYM) F(SETH) F(RETN) F(FLDO) F(FLDM) F(ALIM) F(NOTM) F(RETD) F(SYSV) F(VARU) F(PRED) \
F(EXTO) F(EXTM) F(EXTU) F(ADDI) F(ADDU) F(FN1Ci)F(FN1Oi)F(FN2Ci)F(FN2Oi) \
@ -473,6 +473,38 @@ NOINLINE Block* compile(B bcq, B objs, B allBlocks, B allBodies, B indices, B to
FORCE_INLINE bool v_merge(Scope* pscs[], B s, B x, bool upd, bool hdr) {
B o = c(WrappedObj,s)->obj;
if (!isArr(x) || rnk(x)==0) thrF("[…]%S𝕩: 𝕩 cannot have rank 0", upd? "" : "");
B* op = harr_ptr(o);
usz oia = a(o)->ia;
if (a(x)->sh[0] != oia) {
if (hdr) return false;
else thrF("[…]%S𝕩: Target length & leading axis of 𝕩 didn't match", upd? "" : "");
}
if (rnk(x)==1) {
SGet(x)
for (usz i = 0; i < oia; i++) {
B cx = m_unit(Get(x,i));
if (!hdr) v_set (pscs, op[i], cx, upd, true);
else if (!v_seth(pscs, op[i], cx)) { dec(cx); return false; }
dec(cx);
}
return true;
} else {
B cells = toCells(inc(x));
B* xp = harr_ptr(cells);
for (usz i = 0; i < oia; i++) {
if (!hdr) v_set (pscs, op[i], xp[i], upd, true);
else if (!v_seth(pscs, op[i], xp[i])) { dec(cells); return false; }
}
dec(cells);
return true;
}
}
NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
if (isArr(s)) { VTY(s, t_harr);
@ -500,6 +532,8 @@ NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd, true);
} else if (s.u == bi_N.u) {
return;
} else if (isObj(s)) {
v_merge(pscs, s, x, upd, false);
} else { assert(isExt(s));
Scope* sc = pscs[(u16)(s.u>>32)];
B prev = sc->ext->vars[(u32)s.u];
@ -511,7 +545,8 @@ NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
}
}
NOINLINE bool v_sethF(Scope* pscs[], B s, B x) {
if (v(s)->type==t_vfyObj) return equal(c(VfyObj,s)->obj,x);
if (v(s)->type==t_vfyObj) return equal(c(WrappedObj,s)->obj,x);
if (v(s)->type==t_arrMerge) return v_merge(pscs, s, x, false, true);
VTY(s, t_harr);
B* sp = harr_ptr(s);
usz ia = a(s)->ia;
@ -813,12 +848,30 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
break;
}
case VFYM: { P(o) GS_UPD;
VfyObj* a = mm_alloc(sizeof(VfyObj), t_vfyObj);
WrappedObj* a = mm_alloc(sizeof(WrappedObj), t_vfyObj);
a->obj = o;
ADD(tag(a,OBJ_TAG));
break;
}
case FAIL: thrM(q_N(sc->vars[2])? "This block cannot be called monadically" : "This block cannot be called dyadically");
case ARMO: {
u32 sz = *bc++;
assert(sz>0);
HArr_p r = m_harrUv(sz);
for (i64 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
ADD(bqn_merge(r.b));
break;
}
case ARMM: {
u32 sz = *bc++;
assert(sz>0);
HArr_p r = m_harrUv(sz);
for (i64 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
WrappedObj* a = mm_alloc(sizeof(WrappedObj), t_arrMerge);
a->obj = r.b;
ADD(tag(a,OBJ_TAG));
break;
}
case RETD: { GS_UPD;
ADD(m_ns(ptr_inc(sc), ptr_inc(b->nsDesc)));
@ -979,8 +1032,8 @@ DEF_FREE(comp) { Comp* c = (Comp *)x; if (c->objs!=NULL) ptr_decR(c->obj
DEF_FREE(funBl) { FunBlock* c = (FunBlock*)x; ptr_dec(c->sc); ptr_decR(c->bl); }
DEF_FREE(md1Bl) { Md1Block* c = (Md1Block*)x; ptr_dec(c->sc); ptr_decR(c->bl); }
DEF_FREE(md2Bl) { Md2Block* c = (Md2Block*)x; ptr_dec(c->sc); ptr_decR(c->bl); }
DEF_FREE(alias) { dec(((FldAlias*)x)->obj); }
DEF_FREE(vfymO) { dec(((VfyObj* )x)->obj); }
DEF_FREE(alias) { dec(((FldAlias* )x)->obj); }
DEF_FREE(wrobj) { dec(((WrappedObj*)x)->obj); }
DEF_FREE(bBlks) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (i32 i = 0; i < am; i++) ptr_dec(c->a[i]); }
DEF_FREE(scExt) { ScopeExt* c = (ScopeExt*)x; u16 am = c->varAm*2; for (i32 i = 0; i < am; i++) dec(c->vars[i]); }
@ -1013,8 +1066,8 @@ void comp_visit(Value* x) { Comp* c = (Comp *)x; mm_visitP(c->objs); mm_
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); }
void md2Bl_visit(Value* x) { Md2Block* c = (Md2Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
void alias_visit(Value* x) { mm_visit(((FldAlias*)x)->obj); }
void vfymO_visit(Value* x) { mm_visit(((VfyObj* )x)->obj); }
void alias_visit(Value* x) { mm_visit(((FldAlias* )x)->obj); }
void wrobj_visit(Value* x) { mm_visit(((WrappedObj*)x)->obj); }
void bBlks_visit(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (i32 i = 0; i < am; i++) mm_visitP(c->a[i]); }
void scExt_visit(Value* x) { ScopeExt* c = (ScopeExt*)x; u16 am = c->varAm*2; for (i32 i = 0; i < am; i++) mm_visit(c->vars[i]); }
@ -1024,6 +1077,7 @@ void block_print(FILE* f, B x) { fprintf(f,"(%p: block)",v(x)); }
void scope_print(FILE* f, B x) { fprintf(f,"(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;i<sc->varAm;i++){fprintf(f," ");fprint(f,sc->vars[i]);}fprintf(f,")"); }
void alias_print(FILE* f, B x) { fprintf(f,"(alias %d of ", c(FldAlias,x)->p); fprint(f,c(FldAlias,x)->obj); fprintf(f,")"); }
void vfymO_print(FILE* f, B x) { fprint(f,c(FldAlias,x)->obj); }
void marrO_print(FILE* f, B x) { fprintf(f,"["); fprint(f,c(FldAlias,x)->obj); fprintf(f,"]"); }
void bBlks_print(FILE* f, B x) { fprintf(f,"(block list)"); }
void scExt_print(FILE* f, B x) { fprintf(f,"(scope extension with %d vars)", c(ScopeExt,x)->varAm); }
@ -1071,17 +1125,18 @@ void print_vmStack() {
B oomMessage;
void comp_init() {
TIi(t_comp ,freeO) = comp_freeO; TIi(t_comp ,freeF) = comp_freeF; TIi(t_comp ,visit) = comp_visit; TIi(t_comp ,print) = comp_print;
TIi(t_body ,freeO) = body_freeO; TIi(t_body ,freeF) = body_freeF; TIi(t_body ,visit) = body_visit; TIi(t_body ,print) = body_print;
TIi(t_block ,freeO) = block_freeO; TIi(t_block ,freeF) = block_freeF; TIi(t_block ,visit) = block_visit; TIi(t_block ,print) = block_print;
TIi(t_scope ,freeO) = scope_freeO; TIi(t_scope ,freeF) = scope_freeF; TIi(t_scope ,visit) = scope_visit; TIi(t_scope ,print) = scope_print;
TIi(t_scopeExt ,freeO) = scExt_freeO; TIi(t_scopeExt,freeF) = scExt_freeF; TIi(t_scopeExt,visit) = scExt_visit; TIi(t_scopeExt,print) = scExt_print;
TIi(t_blBlocks ,freeO) = bBlks_freeO; TIi(t_blBlocks,freeF) = bBlks_freeF; TIi(t_blBlocks,visit) = bBlks_visit; TIi(t_blBlocks,print) = bBlks_print;
TIi(t_fldAlias ,freeO) = alias_freeO; TIi(t_fldAlias,freeF) = alias_freeF; TIi(t_fldAlias,visit) = alias_visit; TIi(t_fldAlias,print) = alias_print;
TIi(t_vfyObj ,freeO) = vfymO_freeO; TIi(t_vfyObj ,freeF) = vfymO_freeF; TIi(t_vfyObj ,visit) = vfymO_visit; TIi(t_vfyObj ,print) = vfymO_print;
TIi(t_funBl ,freeO) = funBl_freeO; TIi(t_funBl ,freeF) = funBl_freeF; TIi(t_funBl ,visit) = funBl_visit; TIi(t_funBl ,print) = funBl_print; TIi(t_funBl,decompose) = block_decompose;
TIi(t_md1Bl ,freeO) = md1Bl_freeO; TIi(t_md1Bl ,freeF) = md1Bl_freeF; TIi(t_md1Bl ,visit) = md1Bl_visit; TIi(t_md1Bl ,print) = md1Bl_print; TIi(t_md1Bl,decompose) = block_decompose; TIi(t_md1Bl,m1_d)=md1Bl_d;
TIi(t_md2Bl ,freeO) = md2Bl_freeO; TIi(t_md2Bl ,freeF) = md2Bl_freeF; TIi(t_md2Bl ,visit) = md2Bl_visit; TIi(t_md2Bl ,print) = md2Bl_print; TIi(t_md2Bl,decompose) = block_decompose; TIi(t_md2Bl,m2_d)=md2Bl_d;
TIi(t_comp ,freeO) = comp_freeO; TIi(t_comp ,freeF) = comp_freeF; TIi(t_comp ,visit) = comp_visit; TIi(t_comp ,print) = comp_print;
TIi(t_body ,freeO) = body_freeO; TIi(t_body ,freeF) = body_freeF; TIi(t_body ,visit) = body_visit; TIi(t_body ,print) = body_print;
TIi(t_block ,freeO) = block_freeO; TIi(t_block ,freeF) = block_freeF; TIi(t_block ,visit) = block_visit; TIi(t_block ,print) = block_print;
TIi(t_scope ,freeO) = scope_freeO; TIi(t_scope ,freeF) = scope_freeF; TIi(t_scope ,visit) = scope_visit; TIi(t_scope ,print) = scope_print;
TIi(t_scopeExt,freeO) = scExt_freeO; TIi(t_scopeExt,freeF) = scExt_freeF; TIi(t_scopeExt,visit) = scExt_visit; TIi(t_scopeExt,print) = scExt_print;
TIi(t_blBlocks,freeO) = bBlks_freeO; TIi(t_blBlocks,freeF) = bBlks_freeF; TIi(t_blBlocks,visit) = bBlks_visit; TIi(t_blBlocks,print) = bBlks_print;
TIi(t_fldAlias,freeO) = alias_freeO; TIi(t_fldAlias,freeF) = alias_freeF; TIi(t_fldAlias,visit) = alias_visit; TIi(t_fldAlias,print) = alias_print;
TIi(t_vfyObj ,freeO) = wrobj_freeO; TIi(t_vfyObj ,freeF) = wrobj_freeF; TIi(t_vfyObj ,visit) = wrobj_visit; TIi(t_vfyObj ,print) = vfymO_print;
TIi(t_arrMerge,freeO) = wrobj_freeO; TIi(t_arrMerge,freeF) = wrobj_freeF; TIi(t_arrMerge,visit) = wrobj_visit; TIi(t_arrMerge,print) = marrO_print;
TIi(t_funBl ,freeO) = funBl_freeO; TIi(t_funBl ,freeF) = funBl_freeF; TIi(t_funBl ,visit) = funBl_visit; TIi(t_funBl ,print) = funBl_print; TIi(t_funBl,decompose) = block_decompose;
TIi(t_md1Bl ,freeO) = md1Bl_freeO; TIi(t_md1Bl ,freeF) = md1Bl_freeF; TIi(t_md1Bl ,visit) = md1Bl_visit; TIi(t_md1Bl ,print) = md1Bl_print; TIi(t_md1Bl,decompose) = block_decompose; TIi(t_md1Bl,m1_d)=md1Bl_d;
TIi(t_md2Bl ,freeO) = md2Bl_freeO; TIi(t_md2Bl ,freeF) = md2Bl_freeF; TIi(t_md2Bl ,visit) = md2Bl_visit; TIi(t_md2Bl ,print) = md2Bl_print; TIi(t_md2Bl,decompose) = block_decompose; TIi(t_md2Bl,m2_d)=md2Bl_d;
TIi(t_funBl,fn_im) = funBl_im; TIi(t_md1Bl,m1_im) = md1Bl_im; TIi(t_md2Bl,m2_im) = md2Bl_im;
TIi(t_funBl,fn_iw) = funBl_iw; TIi(t_md1Bl,m1_iw) = md1Bl_iw; TIi(t_md2Bl,m2_iw) = md2Bl_iw;
@ -1105,7 +1160,7 @@ void comp_init() {
bL_m[POPS]=1; bL_m[CHKV]=1; bL_m[VFYM]=1; bL_m[NOTM]=1; bL_m[RETN]=1; bL_m[RETD]=1;
bL_m[FAIL]=1; bL_m[PRED]=1;
bL_m[PUSH]=2; bL_m[DFND]=2; bL_m[ARRO]=2; bL_m[ARRM]=2;
bL_m[PUSH]=2; bL_m[DFND]=2; bL_m[ARRO]=2; bL_m[ARRM]=2; bL_m[ARMO]=2; bL_m[ARMM]=2;
bL_m[DYNO]=2; bL_m[DYNM]=2; bL_m[FLDO]=2; bL_m[FLDM]=2;
bL_m[SYSV]=2; bL_m[ALIM]=2;
@ -1150,8 +1205,8 @@ void comp_init() {
// stack added map
for (i32 i = 0; i < BC_SIZE; i++) sA_m[i] = sD_m[i] + sC_m[i];
sA_m[ARRO]=1;
sA_m[ARRM]=1;
sA_m[ARRO]=1; sA_m[ARMO]=1;
sA_m[ARRM]=1; sA_m[ARMM]=1;
}

View File

@ -25,6 +25,8 @@ enum {
RETD = 0x08, // return a namespace of exported items
ARRO = 0x0B, // N; create a vector of top N items
ARRM = 0x0C, // N; create a mutable vector of top N items
ARMO = 0x0D, // push `>ToS`
ARMM = 0x0E, // push a mutable version of `>ToS` that unpacks cells of what its assigned to
FN1C = 0x10, // monadic function call ⟨…,x,f ⟩ → F x
FN2C = 0x11, // dyadic function call ⟨…,x,f,w⟩ → w F x
@ -57,6 +59,7 @@ enum {
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
@ -190,8 +193,8 @@ extern i32 sC_m[BC_SIZE];
extern i32 sA_m[BC_SIZE];
static u32* nextBC (u32* p) { return p + bL_m[*p]; }
static i32 stackAdded (u32* p) { return sA_m[*p]; }
static i32 stackDiff (u32* p) { if (*p==ARRO|*p==ARRM) return 1-p[1]; return sD_m[*p]; }
static i32 stackConsumed(u32* p) { if (*p==ARRO|*p==ARRM) return p[1]; return sC_m[*p]; }
static i32 stackDiff (u32* p) { if (*p==ARRO|*p==ARRM|*p==ARMO|*p==ARMM) return 1-p[1]; return sD_m[*p]; }
static i32 stackConsumed(u32* p) { if (*p==ARRO|*p==ARRM|*p==ARMO|*p==ARMM) return p[1]; return sC_m[*p]; }
char* bc_repr(u32 p);
@ -281,10 +284,10 @@ typedef struct FldAlias {
B obj;
i32 p;
} FldAlias;
typedef struct VfyObj {
typedef struct WrappedObj {
struct Value;
B obj;
} VfyObj;
} WrappedObj;
NOINLINE B v_getF(Scope* pscs[], B s); // doesn't consume