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