diff --git a/src/jit/nvm.c b/src/jit/nvm.c index cb826b82..75829a3d 100644 --- a/src/jit/nvm.c +++ b/src/jit/nvm.c @@ -52,7 +52,7 @@ static void* mmX_allocN(usz sz, u8 type) { assert(sz>=16); return mmX_allocL(BSZ #endif #define P(N) B N=GSP; #if VM_POS - #define POS_UPD (envCurr-1)->bcL = bc; + #define POS_UPD envCurr->bcL = bc; #else #define POS_UPD #endif diff --git a/src/main.c b/src/main.c index b5d2cfff..592f21ff 100644 --- a/src/main.c +++ b/src/main.c @@ -142,7 +142,7 @@ int main(int argc, char* argv[]) { repl_init(); while (CATCH) { printf("Error: "); print(catchMessage); putchar('\n'); - vm_pst(envCurr, envStart+envPrevHeight); + vm_pst(envCurr+1, envStart+envPrevHeight); dec(catchMessage); #ifdef HEAP_VERIFY heapVerify(); diff --git a/src/vm.c b/src/vm.c index 8d7b6bfd..6c6667cc 100644 --- a/src/vm.c +++ b/src/vm.c @@ -85,7 +85,7 @@ void printBC(u32* p) { B catchMessage; u64 envPrevHeight; -Env* envCurr; +Env* envCurr; // pointer to current environment; included to make for simpler current position updating Env* envStart; Env* envEnd; @@ -386,7 +386,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume #endif #define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; }) #if VM_POS - #define POS_UPD (envCurr-1)->bcL = bc-1; + #define POS_UPD envCurr->bcL = bc-1; #else #define POS_UPD #endif @@ -776,6 +776,7 @@ void comp_init() { allocStack((void**)&gStack, (void**)&gStackStart, (void**)&gStackEnd, sizeof(B), GS_SIZE); #endif allocStack((void**)&envCurr, (void**)&envStart, (void**)&envEnd, sizeof(Env), ENV_SIZE); + envCurr--; } @@ -802,7 +803,7 @@ jmp_buf* prepareCatch() { // in the case of returning false, must call popCatch( } cf->cfDepth = cf-cfStart; cf->gsDepth = gStack-gStackStart; - cf->envDepth = envCurr-envStart; + cf->envDepth = (envCurr+1)-envStart; return &(cf++)->jmp; } void popCatch() { @@ -838,7 +839,7 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) { } } -NOINLINE void vm_pst(Env* s, Env* e) { +NOINLINE void vm_pst(Env* s, Env* e) { // e not included assert(s<=e); i64 l = e-s; i64 i = l-1; @@ -849,20 +850,20 @@ NOINLINE void vm_pst(Env* s, Env* e) { i = 10; } Comp* comp = c->sc->body->comp; - i32 bcPos = c>=envStart && csc->body, c->bcL) : c->bcV; + i32 bcPos = c>=envStart && c<=envCurr? BCPOS(c->sc->body, c->bcL) : c->bcV; vm_printPos(comp, bcPos, i); i--; } } NOINLINE void vm_pstLive() { - vm_pst(envStart, envCurr); + vm_pst(envStart, envCurr+1); } -static void unwindEnv(Env* envNew) { +static void unwindEnv(Env* envNew) { // envNew==envStart-1 for emptying the env stack assert(envNew<=envCurr); while (envCurr!=envNew) { - envCurr--; envCurr->bcV = BCPOS(envCurr->sc->body, envCurr->bcL); + envCurr--; } } @@ -876,8 +877,8 @@ NOINLINE NORETURN void thr(B msg) { B* gStackNew = gStackStart + cf->gsDepth; assert(gStackNew<=gStack); while (gStack!=gStackNew) dec(*--gStack); - envPrevHeight = envCurr-envStart; - unwindEnv(envStart + cf->envDepth); + envPrevHeight = envCurr-envStart + 1; + unwindEnv(envStart + cf->envDepth - 1); if (cfStart+cf->cfDepth > cf) err("bad catch cfDepth"); @@ -885,10 +886,10 @@ NOINLINE NORETURN void thr(B msg) { longjmp(cf->jmp, 1); } assert(cf==cfStart); - printf("Error: "); print(msg); putchar('\n'); - Env* envPrev = envCurr; - unwindEnv(envStart); - vm_pst(envCurr, envPrev); + printf("Error: "); print(msg); putchar('\n'); fflush(stdout); + Env* envEnd = envCurr+1; + unwindEnv(envStart-1); + vm_pst(envCurr+1, envEnd); #ifdef DEBUG __builtin_trap(); #else diff --git a/src/vm.h b/src/vm.h index 3d7ff4b9..5857d5d9 100644 --- a/src/vm.h +++ b/src/vm.h @@ -147,14 +147,15 @@ typedef struct Env { extern Env* envCurr; extern Env* envStart; extern Env* envEnd; +extern u64 envPrevHeight; // envStart+prevEnvHeight gives envCurr+1 from before the error static inline void pushEnv(Scope* sc, u32* bc) { + envCurr++; if (envCurr==envEnd) thrM("Stack overflow"); envCurr->sc = sc; envCurr->bcL = bc; - envCurr++; } static inline void popEnv() { - assert(envCurr>envStart); + assert(envCurr>=envStart); envCurr--; } void vm_pst(Env* s, Env* e);