diff --git a/Makefile b/Makefile index 90b9034..1742be2 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # make clean && make && ./bin/cosmo CC=clang -CFLAGS=-fPIE -O3 -LDFLAGS=#-fsanitize=address +CFLAGS=-fPIE -g3 #-O3 +LDFLAGS=-fsanitize=address OUT=bin/cosmo CHDR=\ diff --git a/src/cmem.c b/src/cmem.c index 7724ddd..6a0cc13 100644 --- a/src/cmem.c +++ b/src/cmem.c @@ -208,7 +208,10 @@ void markRoots(CState *state) { } markTable(state, &state->globals); - markObject(state, (CObj*)state->initString); + + // mark all internal strings + for (int i = 0; i < INTERNALSTRING_MAX; i++) + markObject(state, (CObj*)state->internalStrings[i]); traceGrays(state); } diff --git a/src/cstate.c b/src/cstate.c index 8ae081e..116708a 100644 --- a/src/cstate.c +++ b/src/cstate.c @@ -34,8 +34,12 @@ CState *cosmoV_newState() { cosmoT_initTable(state, &state->strings, 8); // init string table cosmoT_initTable(state, &state->globals, 8); // init global table - state->initString = NULL; - state->initString = cosmoO_copyString(state, "__init", 6); + // first, set all strings to NULL so our GC doesn't read garbage data + for (int i = 0; i < INTERNALSTRING_MAX; i++) + state->internalStrings[i] = NULL; + + // setup all strings used by the VM + state->internalStrings[INTERNALSTRING_INIT] = cosmoO_copyString(state, "__init", 6); return state; } @@ -51,11 +55,14 @@ void cosmoV_freeState(CState *state) { objs = next; } - // free our string & global table - state->initString = NULL; + // mark our internal VM strings NULL + for (int i = 0; i < INTERNALSTRING_MAX; i++) + state->internalStrings[i] = NULL; + + // free our string & global table (the string table includes the internal VM strings) cosmoT_clearTable(state, &state->strings); cosmoT_clearTable(state, &state->globals); - + // free our gray stack & finally free the state structure free(state->grayStack); free(state); diff --git a/src/cstate.h b/src/cstate.h index abeb1c6..2b4f3b8 100644 --- a/src/cstate.h +++ b/src/cstate.h @@ -12,6 +12,12 @@ typedef struct CCallFrame { CValue* base; } CCallFrame; +typedef enum { + INTERNALSTRING_INIT, // __init + INTERNALSTRING_EQUAL, // __equal + INTERNALSTRING_MAX +} InternalStringEnum; + typedef struct CState { bool panic; int freezeGC; // when > 0, GC events will be ignored (for internal use) @@ -31,7 +37,7 @@ typedef struct CState { CCallFrame callFrame[FRAME_MAX]; // call frames int frameCount; - CObjString *initString; + CObjString *internalStrings[INTERNALSTRING_MAX]; // strings used internally by the VM, eg. __init } CState; COSMO_API CState *cosmoV_newState(); diff --git a/src/cvm.c b/src/cvm.c index 4a267a9..b3c694f 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -187,7 +187,7 @@ COSMOVMRESULT cosmoV_call(CState *state, int args) { CValue ret; // check if they defined an initalizer - if (cosmoO_getObject(state, metaObj, cosmoV_newObj(state->initString), &ret) && IS_CLOSURE(ret)) { + if (cosmoO_getObject(state, metaObj, cosmoV_newObj(state->internalStrings[INTERNALSTRING_INIT]), &ret) && IS_CLOSURE(ret)) { CObjClosure *closure = cosmoV_readClosure(ret); if (args+1 != closure->function->args) { @@ -202,8 +202,8 @@ COSMOVMRESULT cosmoV_call(CState *state, int args) { if (!cosmoV_execute(state)) return COSMOVM_RUNTIME_ERR; - // we throw away the return result, it's unused - // pop the callframe and return result :) + // we throw away the return result, it's ignored + // pop the callframe and return the new object :) popCallFrame(state); state->top++; // adjust stack back into place } else {