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.
This commit is contained in:
CPunch 2023-08-29 16:48:38 -05:00 committed by cpunch
parent 7fa7eb8d94
commit 6126b50941
6 changed files with 14 additions and 15 deletions

View File

@ -948,16 +948,9 @@ int cosmoB_vnewindexBProto(CState *state, int nargs, CValue *args)
// vm.collect() // vm.collect()
int cosmoB_vcollect(CState *state, int nargs, CValue *args) 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 // now force a garbage collection
cosmoM_collectGarbage(state); cosmoM_collectGarbage(state);
// and re-freeze the state
cosmoM_freezeGC(state);
// the end!
return 0; return 0;
} }

View File

@ -229,14 +229,13 @@ CObjCFunction *cosmoO_newCFunction(CState *state, CosmoCFunction func)
CObjError *cosmoO_newError(CState *state, CValue err) 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); CObjError *cerror = (CObjError *)cosmoO_allocateBase(state, sizeof(CObjError), COBJ_ERROR);
cerror->err = err; cerror->err = err;
cerror->frameCount = state->frameCount; cerror->frameCount = state->frameCount;
cerror->frames = frames;
cerror->parserError = false; cerror->parserError = false;
// allocate the callframe
cerror->frames = cosmoM_xmalloc(state, sizeof(CCallFrame) * cerror->frameCount);
// clone the call frame // clone the call frame
for (int i = 0; i < state->frameCount; i++) for (int i = 0; i < state->frameCount; i++)
cerror->frames[i] = state->callFrame[i]; cerror->frames[i] = state->callFrame[i];
@ -762,6 +761,8 @@ const char *cosmoO_typeStr(CObj *obj)
return "<function>"; return "<function>";
case COBJ_CFUNCTION: case COBJ_CFUNCTION:
return "<c function>"; return "<c function>";
case COBJ_ERROR:
return "<error>";
case COBJ_METHOD: case COBJ_METHOD:
return "<method>"; return "<method>";
case COBJ_CLOSURE: case COBJ_CLOSURE:

View File

@ -4,8 +4,7 @@
#include "clex.h" #include "clex.h"
#include "cosmo.h" #include "cosmo.h"
// compiles source into CChunk, if NULL is returned, a syntaxical error has occurred and pushed onto // compiles source into CChunk
// the stack
CObjFunction *cosmoP_compileString(CState *state, const char *source, const char *module); CObjFunction *cosmoP_compileString(CState *state, const char *source, const char *module);
#endif #endif

View File

@ -10,6 +10,8 @@
CPanic *cosmoV_newPanic(CState *state) CPanic *cosmoV_newPanic(CState *state)
{ {
CPanic *panic = cosmoM_xmalloc(state, sizeof(CPanic)); CPanic *panic = cosmoM_xmalloc(state, sizeof(CPanic));
panic->top = state->top;
panic->frameCount = state->frameCount;
panic->prev = state->panic; panic->prev = state->panic;
state->panic = panic; state->panic = panic;
@ -95,7 +97,6 @@ void cosmoV_freeState(CState *state)
#ifdef GC_DEBUG #ifdef GC_DEBUG
printf("state %p is being free'd!\n", state); printf("state %p is being free'd!\n", state);
#endif #endif
cosmoM_freezeGC(state);
// frees all the objects // frees all the objects
CObj *objs = state->objects; CObj *objs = state->objects;

View File

@ -43,6 +43,8 @@ typedef struct ArrayCObj
typedef struct CPanic typedef struct CPanic
{ {
jmp_buf jmp; jmp_buf jmp;
StkPtr top;
int frameCount;
struct CPanic *prev; struct CPanic *prev;
} CPanic; } CPanic;

View File

@ -118,11 +118,14 @@ void cosmoV_throw(CState *state)
StkPtr temp = cosmoV_getTop(state, 0); StkPtr temp = cosmoV_getTop(state, 0);
CObjError *error = cosmoO_newError(state, *temp); CObjError *error = cosmoO_newError(state, *temp);
// replace the value on the stack with the error CValue val = cosmoV_newRef((CObj *)cosmoO_newError(state, *temp));
*temp = cosmoV_newRef((CObj *)cosmoO_newError(state, *temp));
if (state->panic) { if (state->panic) {
state->top = state->panic->top;
state->frameCount = state->panic->frameCount;
cosmoV_pushValue(state, val);
longjmp(state->panic->jmp, 1); longjmp(state->panic->jmp, 1);
} else { } else {
cosmoV_pushValue(state, val);
fprintf(stderr, "Unhandled panic! "); fprintf(stderr, "Unhandled panic! ");
cosmoV_printError(state, error); cosmoV_printError(state, error);
exit(1); exit(1);