From 5cde913c78e4e00e265b26ea3d65965cab22f2c7 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 8 Jan 2022 21:55:19 +0200 Subject: [PATCH] =?UTF-8?q?=E2=80=A2CurrentError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins.h | 2 +- src/builtins/md1.c | 4 ++-- src/builtins/md2.c | 44 ++++++++++++++++++++++++++++++++++++++++---- src/builtins/sysfn.c | 19 +++++++++++++++++++ src/h.h | 13 +++++++------ src/main.c | 4 ++-- src/opt/mm_malloc.h | 6 +++--- src/utils/each.h | 2 +- src/utils/file.h | 2 +- src/vm.c | 9 +++++++-- src/vm.h | 2 +- 11 files changed, 84 insertions(+), 23 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index bb29e570..04c4b35a 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -9,7 +9,7 @@ /* sort.c*/A(gradeUp,"⍋") A(gradeDown,"⍒") \ /* everything before the definition of •Type is defined to be pure, and everything after is not */ \ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•GroupOrd") \ -/* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") A(bqn,"•BQN") A(sh,"•SH") M(fromUtf8,"•FromUTF8") \ +/* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") A(bqn,"•BQN") A(sh,"•SH") M(fromUtf8,"•FromUTF8") M(currentError,"•CurrentError") \ /* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(unixTime,"•UnixTime") M(monoTime,"•MonoTime") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \ /* inverse.c*/M(setInvReg, "(SetInvReg)") M(setInvSwap, "(SetInvSwap)") M(nativeInvReg, "(NativeInvReg)") M(nativeInvSwap, "(NativeInvSwap)") \ /*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ diff --git a/src/builtins/md1.c b/src/builtins/md1.c index 8942a76d..f5d3c7e9 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -13,7 +13,7 @@ static B homFil1(B f, B r, B xf) { if (f.u==bi_eq.u || f.u==bi_ne.u || f.u==bi_feq.u) { dec(xf); return toI32Any(r); } // ≠ may return ≥2⋆31, but whatever, this thing is stupid anyway if (f.u==bi_fne.u) { dec(xf); return withFill(r, m_harrUv(0).b); } if (!noFill(xf)) { - if (CATCH) { dec(catchMessage); return r; } + if (CATCH) { freeThrown(); return r; } B rf = asFill(c1(f, xf)); popCatch(); return withFill(r, rf); @@ -27,7 +27,7 @@ static B homFil2(B f, B r, B wf, B xf) { if (isPureFn(f)) { if (f.u==bi_feq.u || f.u==bi_fne.u) { dec(wf); dec(xf); return toI32Any(r); } if (!noFill(wf) && !noFill(xf)) { - if (CATCH) { dec(catchMessage); return r; } + if (CATCH) { freeThrown(); return r; } B rf = asFill(c2(f, wf, xf)); popCatch(); return withFill(r, rf); diff --git a/src/builtins/md2.c b/src/builtins/md2.c index 0cc31ed9..0eaaa305 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -11,12 +11,30 @@ B val_c1(Md2D* d, B x) { return c1(d->f, x); } B val_c2(Md2D* d, B w, B x) { return c2(d->g, w,x); } +typedef struct CustomObj { + struct Value; + V2v visit; + V2v freeO; +} CustomObj; +void* customObj(u64 size, V2v visit, V2v freeO) { + CustomObj* r = mm_alloc(size, t_customObj); + r->visit = visit; + r->freeO = freeO; + return r; +} +void customObj_visit(Value* v) { ((CustomObj*)v)->visit(v); } +void customObj_freeO(Value* v) { ((CustomObj*)v)->freeO(v); } +void customObj_freeF(Value* v) { ((CustomObj*)v)->freeO(v); mm_free(v); } + + #if CATCH_ERRORS +extern B lastErrMsg; // sysfn.c + B fillBy_c1(Md2D* d, B x) { B xf=getFillQ(x); B r = c1(d->f, x); if(isAtm(r) || noFill(xf)) { dec(xf); return r; } - if (CATCH) { dec(catchMessage); return r; } + if (CATCH) { freeThrown(); return r; } B fill = asFill(c1(d->g, xf)); popCatch(); return withFill(r, fill); @@ -25,14 +43,29 @@ B fillBy_c2(Md2D* d, B w, B x) { B wf=getFillQ(w); B xf=getFillQ(x); B r = c2(d->f, w,x); if(isAtm(r) || noFill(xf)) { dec(xf); dec(wf); return r; } - if (CATCH) { dec(catchMessage); return r; } + if (CATCH) { freeThrown(); return r; } if (noFill(wf)) wf = incG(bi_asrt); B fill = asFill(c2(d->g, wf, xf)); popCatch(); return withFill(r, fill); } -B catch_c1(Md2D* d, B x) { if(CATCH) { dec(catchMessage); return c1(d->g, x); } inc(x); B r = c1(d->f, x); popCatch(); dec(x); return r; } -B catch_c2(Md2D* d, B w, B x) { if(CATCH) { dec(catchMessage); return c2(d->g, w,x); } inc(w); inc(x); B r = c2(d->f, w,x); popCatch(); dec(w); dec(x); return r; } + +typedef struct ReObj { + struct CustomObj; + B msg; +} ReObj; +void re_visit(Value* v) { mm_visit(((ReObj*)v)->msg); } +void re_freeO(Value* v) { dec(lastErrMsg); lastErrMsg = ((ReObj*)v)->msg; } +void pushRe() { + ReObj* o = customObj(sizeof(ReObj), re_visit, re_freeO); + o->msg = lastErrMsg; + gsAdd(tag(o,OBJ_TAG)); + + lastErrMsg = inc(thrownMsg); + freeThrown(); +} +B catch_c1(Md2D* d, B x) { if(CATCH) { pushRe(); B r = c1(d->g, x); dec(gsPop()); return r; } inc(x); B r = c1(d->f, x); popCatch(); dec(x); return r; } +B catch_c2(Md2D* d, B w, B x) { if(CATCH) { pushRe(); B r = c2(d->g, w,x); dec(gsPop()); return r; } inc(w); inc(x); B r = c2(d->f, w,x); popCatch(); dec(w); dec(x); return r; } #else B fillBy_c1(Md2D* d, B x) { return c1(d->f, x); } B fillBy_c2(Md2D* d, B w, B x) { return c2(d->f, w,x); } @@ -265,5 +298,8 @@ void md2_init() { TIi(t_md2BI,print) = print_md2BI; TIi(t_md2BI,m2_uc1) = md2BI_uc1; TIi(t_md2BI,m2_ucw) = md2BI_ucw; + TIi(t_customObj,freeO) = customObj_freeO; + TIi(t_customObj,freeF) = customObj_freeF; + TIi(t_customObj,visit) = customObj_visit; c(BMd2,bi_before)->uc1 = before_uc1; } diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index b1ddb0e0..6ddf8ce8 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -555,6 +555,17 @@ B repl_c1(B t, B x) { return repl_c2(t, emptyHVec(), x); } +#if CATCH_ERRORS +B lastErrMsg; +B currentError_c1(B t, B x) { + dec(x); + if (q_N(lastErrMsg)) thrM("•CurrentError: Not currently within any ⎊"); + return inc(lastErrMsg); +} +#else +B currentError_c1(B t, B x) { thrM("•CurrentError: No errors as error catching has been disabled"); } +#endif + static NFnDesc* fileAtDesc; B fileAt_c1(B d, B x) { return path_rel(nfn_objU(d), x); @@ -654,6 +665,10 @@ B import_c1(B d, B x) { static void sys_gcFn() { mm_visit(importKeyList); mm_visit(importValList); + mm_visit(thrownMsg); + #if CATCH_ERRORS + mm_visit(lastErrMsg); + #endif } @@ -857,6 +872,7 @@ B sys_c1(B t, B x) { else if (eqStr(c, U"fbytes")) cr = m_nfn(fBytesDesc, inc(REQ_PATH)); else if (eqStr(c, U"flines")) cr = m_nfn(fLinesDesc, inc(REQ_PATH)); else if (eqStr(c, U"import")) cr = m_nfn(importDesc, inc(REQ_PATH)); + else if (eqStr(c, U"currenterror")) cr = inc(bi_currentError); else if (eqStr(c, U"state")) { if (q_N(comp_currArgs)) thrM("No arguments present for •state"); cr = m_hVec3(inc(REQ_PATH), inc(REQ_NAME), inc(comp_currArgs)); @@ -876,6 +892,9 @@ B sys_c1(B t, B x) { B cdPath; void sysfn_init() { + #if CATCH_ERRORS + lastErrMsg = bi_N; + #endif cdPath = m_str8(1, "."); gc_add(cdPath); gc_addFn(sys_gcFn); fCharsDesc = registerNFn(m_str8l("(file).Chars"), fchars_c1, fchars_c2); fileAtDesc = registerNFn(m_str8l("(file).At"), fileAt_c1, fileAt_c2); diff --git a/src/h.h b/src/h.h index fefa4f15..69e93d37 100644 --- a/src/h.h +++ b/src/h.h @@ -203,11 +203,11 @@ typedef union B { \ /*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) \ /*38*/ F(ns) F(nsDesc) F(fldAlias) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \ - /*46*/ F(freed) F(harrPartial) \ - /*48*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \ - /*51*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \ + /*46*/ F(freed) F(harrPartial) F(customObj) \ + /*49*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \ + /*52*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \ \ - /*54*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) + /*55*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) enum Type { #define F(X) t_##X, @@ -332,12 +332,13 @@ NOINLINE NORETURN void thrF(char* s, ...); NOINLINE NORETURN void thrOOM(void); jmp_buf* prepareCatch(void); #if CATCH_ERRORS -#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ dec(catchMessage); return; } /*potentially erroring thing*/ popCatch(); /*no errors yay*/` +#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ freeThrown(); return; } /*potentially erroring thing*/ popCatch(); /*no errors yay*/` #else // note: popCatch() must always be called if no error was caught, so no returns before it! #define CATCH false #endif void popCatch(void); -extern B catchMessage; +extern B thrownMsg; +void freeThrown(void); diff --git a/src/main.c b/src/main.c index cabccd4f..b25bf590 100644 --- a/src/main.c +++ b/src/main.c @@ -152,9 +152,9 @@ int main(int argc, char* argv[]) { if (startREPL) { repl_init(); while (CATCH) { - printf("Error: "); printErrMsg(catchMessage); putchar('\n'); + printf("Error: "); printErrMsg(thrownMsg); putchar('\n'); vm_pst(envCurr+1, envStart+envPrevHeight); - dec(catchMessage); + freeThrown(); #ifdef HEAP_VERIFY heapVerify(); #endif diff --git a/src/opt/mm_malloc.h b/src/opt/mm_malloc.h index b5e2a33d..e5bc8e88 100644 --- a/src/opt/mm_malloc.h +++ b/src/opt/mm_malloc.h @@ -26,9 +26,9 @@ static void mm_visitP(void* x) { } void gc_add(B x); void gc_addFn(vfn f); -void gc_maybeGC(); -void gc_forceGC(); -void gc_visitRoots(); +void gc_maybeGC(void); +void gc_forceGC(void); +void gc_visitRoots(void); void mm_forHeap(V2v f); static u64 mm_round(usz x) { return x; } diff --git a/src/utils/each.h b/src/utils/each.h index dc9943b4..414568d1 100644 --- a/src/utils/each.h +++ b/src/utils/each.h @@ -28,7 +28,7 @@ static inline B arith_recd(BBB2B f, B w, B x) { B fw = getFillQ(w); B r = eachd_fn(f, bi_N, w, x); if (noFill(fw)) return r; - if (CATCH) { dec(catchMessage); return r; } + if (CATCH) { freeThrown(); return r; } B fr = f(bi_N, fw, fx); popCatch(); return withFill(r, asFill(fr)); diff --git a/src/utils/file.h b/src/utils/file.h index bcd7dcee..dfa85960 100644 --- a/src/utils/file.h +++ b/src/utils/file.h @@ -11,7 +11,7 @@ I8Arr* file_bytes(B path); // consumes B file_chars(B path); // consumes B file_lines(B path); // consumes -I8Arr* stream_bytes(); +I8Arr* stream_bytes(FILE* f); void file_wChars(B path, B x); // consumes path void file_wBytes(B path, B x); // consumes path diff --git a/src/vm.c b/src/vm.c index 0c5bca87..50b95818 100644 --- a/src/vm.c +++ b/src/vm.c @@ -59,7 +59,7 @@ void print_BCStream(u32* p) { } -B catchMessage; +B thrownMsg; u64 envPrevHeight; Env* envCurr; // pointer to current environment; included to make for simpler current position updating @@ -1217,7 +1217,7 @@ NOINLINE NORETURN void thr(B msg) { // while (c>gStackStart) { print(*--c); putchar('\n'); } printf("gStack printed\n"); if (cf>cfStart) { // something wants to catch errors - catchMessage = msg; + thrownMsg = msg; cf--; B* gStackNew = gStackStart + cf->gsDepth; @@ -1244,6 +1244,11 @@ NOINLINE NORETURN void thr(B msg) { } } +NOINLINE void freeThrown() { + dec(thrownMsg); + thrownMsg = bi_N; +} + NOINLINE NORETURN void thrM(char* s) { thr(fromUTF8(s, strlen(s))); } diff --git a/src/vm.h b/src/vm.h index 11270cd4..6c601949 100644 --- a/src/vm.h +++ b/src/vm.h @@ -228,7 +228,7 @@ NOINLINE B vm_fmtPoint(B src, B prepend, B path, usz cs, usz ce); // consumes pr NOINLINE void printErrMsg(B msg); NOINLINE void unwindEnv(Env* envNew); // envNew==envStart-1 for emptying the env stack NOINLINE void unwindCompiler(void); // unwind to the env of the invocation of the compiler; UB when not in compiler! -usz getPageSize(); +usz getPageSize(void);