compile-time separated DFND

This commit is contained in:
dzaima 2021-08-27 12:35:23 +03:00
parent 305f578707
commit 6b52c2069f
5 changed files with 33 additions and 23 deletions

View File

@ -213,9 +213,9 @@ Throw an error with `thrM("some message")` or `thr(some B instance)` or `thrOOM(
A fancier message can be created with `thrF(message, …)` with printf-like (but different!!) varargs (source in `do_fmt`): A fancier message can be created with `thrF(message, …)` with printf-like (but different!!) varargs (source in `do_fmt`):
``` ```
%i decimal i32 %i decimal i32 (also for i8/i16/ur)
%l decimal i64 %l decimal i64
%ui decimal u32 %ui decimal u32 (also for u8/u16)
%ul decimal u64 %ul decimal u64
%xi hex u32 %xi hex u32
%xl hex u64 %xl hex u64

View File

@ -185,7 +185,11 @@ B casrt_c2(B t, B w, B x) {
} }
B sys_c1(B t, B x); B sys_c1(B t, B x);
B out_c1(B t, B x) { printRaw(x); putchar('\n'); return x; } B out_c1(B t, B x) {
if (isArr(x) && rnk(x)>1) thrF("•Out: Argument cannot have rank %i", rnk(x));
printRaw(x); putchar('\n');
return x;
}
B show_c1(B t, B x) { B show_c1(B t, B x) {
#if FORMATTER #if FORMATTER
B fmt = bqn_fmt(inc(x)); B fmt = bqn_fmt(inc(x));

View File

@ -506,7 +506,6 @@ Nvm_res m_nvm(Body* body) {
#define CCALL(F) { u64 f=(u64)(F); if(f>I32_MAX)thrM("JIT: Function address too large for call"); CALLi(f); } #define CCALL(F) { u64 f=(u64)(F); if(f>I32_MAX)thrM("JIT: Function address too large for call"); CALLi(f); }
u32* origBC = body->bc; u32* origBC = body->bc;
OptRes optRes = opt(origBC); OptRes optRes = opt(origBC);
Block** blocks = body->bl->blocks;
i32 depth = 0; i32 depth = 0;
u32* bc = optRes.bc; u32* bc = optRes.bc;
i32 lGPos = 0; // last updated gStack offset i32 lGPos = 0; // last updated gStack offset
@ -559,8 +558,8 @@ Nvm_res m_nvm(Body* body) {
if (sz) { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B, i64 sz, S) if (sz) { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B, i64 sz, S)
else { TOPs; CCALL(i_ARR_0); } // unused with optimizations else { TOPs; CCALL(i_ARR_0); } // unused with optimizations
break; break;
case DFND: TOPs; // (u32* bc, Scope* sc, Block* bl) case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
Block* bl = blocks[*bc++]; 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); u64 fn = (u64)(bl->ty==0? i_DFND_0 : bl->ty==1? i_DFND_1 : bl->ty==2? i_DFND_2 : NULL);
if (fn==0) thrM("JIT: Bad DFND argument"); if (fn==0) thrM("JIT: Bad DFND argument");
GET(R_A3,-1,2); GET(R_A3,-1,2);

View File

@ -33,7 +33,8 @@ u32* nextBC(u32* p) {
case LOCO: case LOCM: case LOCU: case LOCO: case LOCM: case LOCU:
case EXTO: case EXTM: case EXTU: case EXTO: case EXTM: case EXTU:
case ADDI: case ADDU: case ADDI: case ADDU:
case FN1Ci: case FN1Oi: case FN2Ci: case SETNi: case SETUi: case SETMi: case SETNv: case SETUv: case SETMv: case FN1Ci: case FN1Oi: case FN2Ci: case DFND0: case DFND1: case DFND2:
case SETNi: case SETUi: case SETMi: case SETNv: case SETUv: case SETMv:
off = 3; break; off = 3; break;
case FN2Oi: case SETHi: case FN2Oi: case SETHi:
off = 5; break; off = 5; break;
@ -44,7 +45,8 @@ u32* nextBC(u32* p) {
i32 stackDiff(u32* p) { i32 stackDiff(u32* p) {
if (*p==ARRO|*p==ARRM) return 1-p[1]; if (*p==ARRO|*p==ARRM) return 1-p[1];
switch(*p) { default: UD; // case ARRO: case ARRM: return 1-p[1]; switch(*p) { default: UD; // case ARRO: case ARRM: return 1-p[1];
case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 1; case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case DFND0:case DFND1:case DFND2:
case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 1;
case FN1Ci:case FN1Oi:case CHKV: case VFYM: case FLDO: case FLDM: case RETD: case NSPM: return 0; case FN1Ci:case FN1Oi:case CHKV: case VFYM: case FLDO: case FLDM: case RETD: case NSPM: return 0;
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case POPS: case OP2H: case RETN: return -1; case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case POPS: case OP2H: case RETN: return -1;
case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: case SETH: case SETHi:return -2; case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: case SETH: case SETHi:return -2;
@ -58,7 +60,8 @@ i32 stackDiff(u32* p) {
i32 stackConsumed(u32* p) { i32 stackConsumed(u32* p) {
if (*p==ARRO|*p==ARRM) return p[1]; if (*p==ARRO|*p==ARRM) return p[1];
switch(*p) { default: UD; // case ARRO: case ARRM: return -p[1]; switch(*p) { default: UD; // case ARRO: case ARRM: return -p[1];
case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 0; case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM:
case EXTU: case SYSV: case ADDI: case ADDU: case DFND0:case DFND1:case DFND2:return 0;
case CHKV: case RETD: return 0; case CHKV: case RETD: return 0;
case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: case VFYM: return 1; case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: case VFYM: return 1;
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case OP2H: case SETH: case SETHi:return 2; case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case OP2H: case SETH: case SETHi:return 2;
@ -278,9 +281,10 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl
if ((u32)id >= a(allBlocks)->ia) thrM("VM compiler: DFND index out-of-bounds"); if ((u32)id >= a(allBlocks)->ia) thrM("VM compiler: DFND index out-of-bounds");
if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places"); if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places");
bDone[id] = true; bDone[id] = true;
TSADD(newBC, DFND); Block* bl = compileBlock(TI(allBlocks,getU)(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1);
TSADD(newBC, TSSIZE(usedBlocks)); TSADD(newBC, bl->ty==0? DFND0 : bl->ty==1? DFND1 : DFND2);
TSADD(usedBlocks, compileBlock(TI(allBlocks,getU)(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1)); A64((u64)bl);
TSADD(usedBlocks, bl);
break; break;
} }
case LOCO: case LOCM: case LOCU: { case LOCO: case LOCM: case LOCU: {
@ -532,7 +536,6 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
printf("new eval\n"); printf("new eval\n");
#endif #endif
B* objs = bl->comp->objs->a; B* objs = bl->comp->objs->a;
Block** blocks = bl->blocks;
u32* bc = b->bc; u32* bc = b->bc;
pushEnv(sc, bc); pushEnv(sc, bc);
gsReserve(b->maxStack); gsReserve(b->maxStack);
@ -626,16 +629,19 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
} }
break; break;
} }
case DFND: { case DFND0: { GS_UPD;POS_UPD; ADD(m_funBlock((Block*)L64, sc)); break; }
GS_UPD;POS_UPD; case DFND1: { GS_UPD;POS_UPD; ADD(m_md1Block((Block*)L64, sc)); break; }
Block* cbl = blocks[*bc++]; case DFND2: { GS_UPD;POS_UPD; ADD(m_md2Block((Block*)L64, sc)); break; }
switch(cbl->ty) { default: UD; // case DFND: {
case 0: ADD(m_funBlock(cbl, sc)); break; // GS_UPD;POS_UPD;
case 1: ADD(m_md1Block(cbl, sc)); break; // Block* cbl = blocks[*bc++];
case 2: ADD(m_md2Block(cbl, sc)); break; // switch(cbl->ty) { default: UD;
} // case 0: ADD(m_funBlock(cbl, sc)); break;
break; // case 1: ADD(m_md1Block(cbl, sc)); break;
} // case 2: ADD(m_md2Block(cbl, sc)); break;
// }
// break;
// }
case OP1D: { P(f)P(m) GS_UPD;POS_UPD; ADD(m1_d (m,f )); break; } case OP1D: { P(f)P(m) GS_UPD;POS_UPD; ADD(m1_d (m,f )); break; }
case OP2D: { P(f)P(m)P(g) GS_UPD;POS_UPD; ADD(m2_d (m,f,g)); break; } case OP2D: { P(f)P(m)P(g) GS_UPD;POS_UPD; ADD(m2_d (m,f,g)); break; }
case OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; } case OP2H: { P(m)P(g) ADD(m2_h (m, g)); break; }

View File

@ -49,6 +49,7 @@ enum {
SETNi, SETUi, SETMi, // SET_ alternatives that expect the set variable as a depth-position pair like LOC_ SETNi, SETUi, SETMi, // SET_ alternatives that expect the set variable as a depth-position pair like LOC_
SETNv, SETUv, SETMv, // SET_i alternatives that also don't return the result SETNv, SETUv, SETMv, // 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) 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 FAIL, // this body cannot be called monadically/dyadically
BC_SIZE BC_SIZE
}; };