From 38ab8ecf96c08da2fcedac7fc4d84f7ddb2183f0 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 15 Apr 2021 02:10:30 +0300 Subject: [PATCH] error catching option --- src/gc.c | 6 +++++- src/h.h | 13 +++++++++++-- src/heap.c | 6 ++++++ src/main.c | 5 +++-- src/vm.c | 19 ++++++++++++------- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/gc.c b/src/gc.c index 12e888da..2eccc3f6 100644 --- a/src/gc.c +++ b/src/gc.c @@ -55,13 +55,17 @@ void mm_visitP(void* xp) { } void gc_tryFree(Value* v) { u8 t = v->type; - #ifdef DEBUG + #if defined(DEBUG) && !defined(CATCH_ERRORS) if (t==t_freed) err("GC found t_freed\n"); #endif if (t!=t_empty & (v->mmInfo&0x80)==gc_tagCurr) { if (t==t_shape) return; #ifdef DONT_FREE v->flags = t; + #else + #ifdef CATCH_ERRORS + if (t==t_freed) { mm_free(v); return; } + #endif #endif #ifdef LOG_GC gc_freedBytes+= mm_size(v); gc_freedCount++; diff --git a/src/h.h b/src/h.h index 3dc65dec..763bf76e 100644 --- a/src/h.h +++ b/src/h.h @@ -202,7 +202,12 @@ B m_v4(B a, B b, B c, B d); B m_str32(u32* s); NORETURN void thr(B b); NORETURN void thrM(char* s); -jmp_buf* prepareCatch(); // use with `if (setjmp(prepareCatch())) { /*catch*/ } /*regular execution*/` +jmp_buf* prepareCatch(); +#ifdef CATCH_ERRORS +#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error; dec(catchMessage);*/ } /*regular execution*/ popCatch();` +#else +#define CATCH false +#endif void popCatch(); B catchMessage; @@ -357,7 +362,11 @@ void do_nothing(B x) { } void empty_free(B x) { err("FREEING EMPTY\n"); } void builtin_free(B x) { err("FREEING BUILTIN\n"); } void def_visit(B x) { printf("(no visit for %d=%s)\n", v(x)->type, format_type(v(x)->type)); } -void freeed_visit(B x) { err("visiting t_freed\n"); } +void freeed_visit(B x) { + #ifndef CATCH_ERRORS + err("visiting t_freed\n"); + #endif +} void def_print(B x) { printf("(%d=%s)", v(x)->type, format_type(v(x)->type)); } B def_get (B x, usz n) { return inc(x); } B def_getU(B x, usz n) { return x; } diff --git a/src/heap.c b/src/heap.c index 966fe6db..cdf3ac1f 100644 --- a/src/heap.c +++ b/src/heap.c @@ -50,7 +50,13 @@ void heap_getReferents(Value* v) { if (ti[v->type].isArr && rnk(tag(v,ARR_TAG))>1) heapVerify_visitP(shObj(tag(v,ARR_TAG))); ti[v->type].visit(tag(v,OBJ_TAG)); } +#ifdef CATCH_ERRORS +bool heapVerify_msg; +#endif void heapVerify() { + #ifdef CATCH_ERRORS + if(!heapVerify_msg) { printf("note: heapVerify() will give garbage in combination with CATCH_ERRORS\n"); heapVerify_msg=true; } + #endif heap_observed = 0; heapVerify_mode=0; mm_forHeap(heapVerify_callVisit); gc_visitRoots(); mm_forHeap(heapVerify_checkFn); diff --git a/src/main.c b/src/main.c index d216fb98..fcdbaf7d 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ // #define DEBUG_VM #endif +#define CATCH_ERRORS // whether to allow catching errors; currently means refcounts won't be accurate and can't be tested for // #define HEAP_VERIFY // enable usage of heapVerify() // #define ALLOC_STAT // store basic allocation statistics // #define ALLOC_SIZES // store per-type allocation size statistics @@ -167,7 +168,7 @@ int main() { // comp = m_funBlock(cbc_b, 0); // free(c_src); // } - while (setjmp(*prepareCatch())) { + while (CATCH) { printf("caught: "); print(catchMessage); puts(""); @@ -204,7 +205,7 @@ int main() { #ifdef DEBUG #endif } - + popCatch(); CTR_FOR(CTR_PRINT) // printf("done\n");fflush(stdout); while(1); printAllocStats(); diff --git a/src/vm.c b/src/vm.c index 55d1c4f4..e6b3982f 100644 --- a/src/vm.c +++ b/src/vm.c @@ -544,19 +544,21 @@ jmp_buf* prepareCatch() { // in the case of returning false, must call popCatch( return &(cf++)->jmp; } void popCatch() { - assert(cf>cfStart); - cf--; + #ifdef CATCH_ERRORS + assert(cf>cfStart); + cf--; + #endif } -NORETURN void thr(B msg) { +void thr(B msg) { if (cf>cfStart) { catchMessage = msg; cf--; B* gStackNew = gStackStart + cf->gStackDepth; if (gStackNew>gStack) err("bad catch gStack"); - // while (gStack!=gStackNew) dec(*--gStack); - gStack = gStackNew; + while (gStack!=gStackNew) dec(*--gStack); + // gStack = gStackNew; cf = cfStart + cf->cfDepth; longjmp(cf->jmp, 1); @@ -566,10 +568,13 @@ NORETURN void thr(B msg) { printf("Error: "); print(msg); puts(""); - // exit(1); + #ifdef DEBUG __builtin_trap(); + #else + exit(1); + #endif } -NORETURN void thrM(char* s) { +void thrM(char* s) { thr(fromUTF8(s, strlen(s))); } \ No newline at end of file