error catching option

This commit is contained in:
dzaima 2021-04-15 02:10:30 +03:00
parent 4bd3a526d0
commit 38ab8ecf96
5 changed files with 37 additions and 12 deletions

View File

@ -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++;

13
src/h.h
View File

@ -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; }

View File

@ -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);

View File

@ -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();

View File

@ -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)));
}