From 6126b5094139309a9bf5245a98664ab7a4c06266 Mon Sep 17 00:00:00 2001 From: CPunch Date: Tue, 29 Aug 2023 16:48:38 -0500 Subject: [PATCH] cosmoV_throw() now resets the vm stack as well also a minor GC bug in cosmoO_newError was fixed. i'm going to try to phase out cosmoM_freezeGC & friends since that would cause hell with this new error handling solution. the only thing still using it is the GC. --- src/cbaselib.c | 7 ------- src/cobj.c | 7 ++++--- src/cparse.h | 3 +-- src/cstate.c | 3 ++- src/cstate.h | 2 ++ src/cvm.c | 7 +++++-- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/cbaselib.c b/src/cbaselib.c index 7cadc9b..e173938 100644 --- a/src/cbaselib.c +++ b/src/cbaselib.c @@ -948,16 +948,9 @@ int cosmoB_vnewindexBProto(CState *state, int nargs, CValue *args) // vm.collect() int cosmoB_vcollect(CState *state, int nargs, CValue *args) { - // first, unfreeze the state (we start frozen on entry to any C Function) - cosmoM_unfreezeGC(state); - // now force a garbage collection cosmoM_collectGarbage(state); - // and re-freeze the state - cosmoM_freezeGC(state); - - // the end! return 0; } diff --git a/src/cobj.c b/src/cobj.c index 2a30ab1..6badbdb 100644 --- a/src/cobj.c +++ b/src/cobj.c @@ -229,14 +229,13 @@ CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func) CObjError *cosmoO_newError(CState *state, CValue err) { + CCallFrame *frames = cosmoM_xmalloc(state, sizeof(CCallFrame) * state->frameCount); CObjError *cerror = (CObjError *)cosmoO_allocateBase(state, sizeof(CObjError), COBJ_ERROR); cerror->err = err; cerror->frameCount = state->frameCount; + cerror->frames = frames; cerror->parserError = false; - // allocate the callframe - cerror->frames = cosmoM_xmalloc(state, sizeof(CCallFrame) * cerror->frameCount); - // clone the call frame for (int i = 0; i < state->frameCount; i++) cerror->frames[i] = state->callFrame[i]; @@ -762,6 +761,8 @@ const char *cosmoO_typeStr(CObj *obj) return ""; case COBJ_CFUNCTION: return ""; + case COBJ_ERROR: + return ""; case COBJ_METHOD: return ""; case COBJ_CLOSURE: diff --git a/src/cparse.h b/src/cparse.h index 3c0da88..24e131f 100644 --- a/src/cparse.h +++ b/src/cparse.h @@ -4,8 +4,7 @@ #include "clex.h" #include "cosmo.h" -// compiles source into CChunk, if NULL is returned, a syntaxical error has occurred and pushed onto -// the stack +// compiles source into CChunk CObjFunction *cosmoP_compileString(CState *state, const char *source, const char *module); #endif diff --git a/src/cstate.c b/src/cstate.c index 08e3228..6233366 100644 --- a/src/cstate.c +++ b/src/cstate.c @@ -10,6 +10,8 @@ CPanic *cosmoV_newPanic(CState *state) { CPanic *panic = cosmoM_xmalloc(state, sizeof(CPanic)); + panic->top = state->top; + panic->frameCount = state->frameCount; panic->prev = state->panic; state->panic = panic; @@ -95,7 +97,6 @@ void cosmoV_freeState(CState *state) #ifdef GC_DEBUG printf("state %p is being free'd!\n", state); #endif - cosmoM_freezeGC(state); // frees all the objects CObj *objs = state->objects; diff --git a/src/cstate.h b/src/cstate.h index c6840c3..df79a86 100644 --- a/src/cstate.h +++ b/src/cstate.h @@ -43,6 +43,8 @@ typedef struct ArrayCObj typedef struct CPanic { jmp_buf jmp; + StkPtr top; + int frameCount; struct CPanic *prev; } CPanic; diff --git a/src/cvm.c b/src/cvm.c index c7bc95a..89d085e 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -118,11 +118,14 @@ void cosmoV_throw(CState *state) StkPtr temp = cosmoV_getTop(state, 0); CObjError *error = cosmoO_newError(state, *temp); - // replace the value on the stack with the error - *temp = cosmoV_newRef((CObj *)cosmoO_newError(state, *temp)); + CValue val = cosmoV_newRef((CObj *)cosmoO_newError(state, *temp)); if (state->panic) { + state->top = state->panic->top; + state->frameCount = state->panic->frameCount; + cosmoV_pushValue(state, val); longjmp(state->panic->jmp, 1); } else { + cosmoV_pushValue(state, val); fprintf(stderr, "Unhandled panic! "); cosmoV_printError(state, error); exit(1);