From 6b52c2069f5dc20b4de7fa2c63ca89fa90edcd5e Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 27 Aug 2021 12:35:23 +0300 Subject: [PATCH] compile-time separated DFND --- src/README.md | 4 ++-- src/builtins/sysfn.c | 6 +++++- src/jit/nvm_x86_64.c | 5 ++--- src/vm.c | 40 +++++++++++++++++++++++----------------- src/vm.h | 1 + 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/README.md b/src/README.md index 332d3417..e76c37c0 100644 --- a/src/README.md +++ b/src/README.md @@ -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`): ``` -%i decimal i32 +%i decimal i32 (also for i8/i16/ur) %l decimal i64 -%ui decimal u32 +%ui decimal u32 (also for u8/u16) %ul decimal u64 %xi hex u32 %xl hex u64 diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index a5a4cee9..96115963 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -185,7 +185,11 @@ B casrt_c2(B t, B w, 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) { #if FORMATTER B fmt = bqn_fmt(inc(x)); diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index 46a9f7f6..aaaa86cd 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -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); } u32* origBC = body->bc; OptRes optRes = opt(origBC); - Block** blocks = body->bl->blocks; i32 depth = 0; u32* bc = optRes.bc; 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) else { TOPs; CCALL(i_ARR_0); } // unused with optimizations break; - case DFND: TOPs; // (u32* bc, Scope* sc, Block* bl) - Block* bl = blocks[*bc++]; + 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); if (fn==0) thrM("JIT: Bad DFND argument"); GET(R_A3,-1,2); diff --git a/src/vm.c b/src/vm.c index fc6e48fb..08273b1b 100644 --- a/src/vm.c +++ b/src/vm.c @@ -33,7 +33,8 @@ u32* nextBC(u32* p) { case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: 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; case FN2Oi: case SETHi: off = 5; break; @@ -44,7 +45,8 @@ u32* nextBC(u32* p) { i32 stackDiff(u32* p) { if (*p==ARRO|*p==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 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; @@ -58,7 +60,8 @@ i32 stackDiff(u32* p) { i32 stackConsumed(u32* p) { if (*p==ARRO|*p==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 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; @@ -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 (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places"); bDone[id] = true; - TSADD(newBC, DFND); - TSADD(newBC, TSSIZE(usedBlocks)); - TSADD(usedBlocks, compileBlock(TI(allBlocks,getU)(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1)); + Block* bl = compileBlock(TI(allBlocks,getU)(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1); + TSADD(newBC, bl->ty==0? DFND0 : bl->ty==1? DFND1 : DFND2); + A64((u64)bl); + TSADD(usedBlocks, bl); break; } 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"); #endif B* objs = bl->comp->objs->a; - Block** blocks = bl->blocks; u32* bc = b->bc; pushEnv(sc, bc); gsReserve(b->maxStack); @@ -626,16 +629,19 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume } break; } - case DFND: { - GS_UPD;POS_UPD; - Block* cbl = blocks[*bc++]; - switch(cbl->ty) { default: UD; - case 0: ADD(m_funBlock(cbl, sc)); break; - case 1: ADD(m_md1Block(cbl, sc)); break; - case 2: ADD(m_md2Block(cbl, sc)); break; - } - break; - } + case DFND0: { GS_UPD;POS_UPD; ADD(m_funBlock((Block*)L64, sc)); break; } + case DFND1: { GS_UPD;POS_UPD; ADD(m_md1Block((Block*)L64, sc)); break; } + case DFND2: { GS_UPD;POS_UPD; ADD(m_md2Block((Block*)L64, sc)); break; } + // case DFND: { + // GS_UPD;POS_UPD; + // Block* cbl = blocks[*bc++]; + // switch(cbl->ty) { default: UD; + // case 0: ADD(m_funBlock(cbl, sc)); 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 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; } diff --git a/src/vm.h b/src/vm.h index b9387c80..b8611626 100644 --- a/src/vm.h +++ b/src/vm.h @@ -49,6 +49,7 @@ enum { 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 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 BC_SIZE };