diff --git a/src/cbaselib.c b/src/cbaselib.c index e173938..3e3e076 100644 --- a/src/cbaselib.c +++ b/src/cbaselib.c @@ -30,7 +30,6 @@ int cosmoB_assert(CState *state, int nargs, CValue *args) { if (nargs < 1 || nargs > 2) { cosmoV_error(state, "assert() expected 1 or 2 arguments, got %d!", nargs); - return 0; // nothing pushed onto the stack to return } if (!IS_BOOLEAN(args[0]) || (nargs == 2 && !IS_STRING(args[1]))) { @@ -40,7 +39,6 @@ int cosmoB_assert(CState *state, int nargs, CValue *args) } else { cosmoV_typeError(state, "assert()", "", "%s", cosmoV_typeStr(args[0])); } - return 0; } if (!cosmoV_readBoolean(args[0])) // expression passed was false, error! @@ -53,7 +51,6 @@ int cosmoB_type(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "type() expected 1 argument, got %d!", nargs); - return 0; } // push the type string to the stack @@ -65,7 +62,6 @@ int cosmoB_pcall(CState *state, int nargs, CValue *args) { if (nargs < 1) { cosmoV_error(state, "pcall() expected at least 1 argument!"); - return 0; } // call the passed callable, the passed arguments are already in the @@ -81,7 +77,6 @@ int cosmoB_tonumber(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "tonumber() expected 1 argument, got %d!", nargs); - return 0; } cosmoV_pushNumber(state, cosmoV_toNumber(state, args[0])); @@ -90,10 +85,8 @@ int cosmoB_tonumber(CState *state, int nargs, CValue *args) int cosmoB_tostring(CState *state, int nargs, CValue *args) { - if (nargs != 1) { + if (nargs != 1) cosmoV_error(state, "tostring() expected 1 argument, got %d!", nargs); - return 0; - } cosmoV_pushRef(state, (CObj *)cosmoV_toString(state, args[0])); return 1; @@ -103,12 +96,10 @@ int cosmoB_loadstring(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "loadstring() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "loadstring()", "", "%s", cosmoV_typeStr(args[0])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -122,12 +113,10 @@ int cosmoB_error(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "error() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "error()", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_error(state, "%s", cosmoV_readCString(args[0])); @@ -176,10 +165,8 @@ int cosmoB_osetProto(CState *state, int nargs, CValue *args) int cosmoB_ogetProto(CState *state, int nargs, CValue *args) { - if (nargs != 1) { + if (nargs != 1) cosmoV_error(state, "Expected 1 argument, got %d!", nargs); - return 0; - } cosmoV_pushRef(state, (CObj *)cosmoV_readObject(args[0])->_obj.proto); // just return the proto @@ -190,13 +177,11 @@ int cosmoB_oisChild(CState *state, int nargs, CValue *args) { if (nargs != 2) { cosmoV_error(state, "object.ischild() expected 2 arguments, got %d!", nargs); - return 0; } if (!IS_REF(args[0]) || !IS_OBJECT(args[1])) { cosmoV_typeError(state, "object.ischild()", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } CObj *obj = cosmoV_readRef(args[0]); @@ -255,12 +240,10 @@ int cosmoB_osRead(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "os.read() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "os.read()", "", "%s", cosmoV_typeStr(args[0])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -301,7 +284,6 @@ int cosmoB_osTime(CState *state, int nargs, CValue *args) struct timeval time; if (nargs > 0) { cosmoV_error(state, "os.time() expected no arguments, got %d!", nargs); - return 0; } gettimeofday(&time, NULL); @@ -314,12 +296,10 @@ int cosmoB_osSystem(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "os.system() expects 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "os.system()", "", "%s", cosmoV_typeStr(args[0])); - return 0; } // run the command and return the exit code @@ -354,7 +334,6 @@ int cosmoB_sSub(CState *state, int nargs, CValue *args) if (!IS_STRING(args[0]) || !IS_NUMBER(args[1])) { cosmoV_typeError(state, "string.sub()", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -364,7 +343,6 @@ int cosmoB_sSub(CState *state, int nargs, CValue *args) if (indx < 0 || indx >= str->length) { cosmoV_error(state, "string.sub() expected index to be 0-%d, got %d!", str->length - 1, indx); - return 0; } cosmoV_pushLString(state, str->str + ((int)indx), str->length - ((int)indx)); @@ -373,7 +351,6 @@ int cosmoB_sSub(CState *state, int nargs, CValue *args) cosmoV_typeError(state, "string.sub()", ", , ", "%s, %s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]), cosmoV_typeStr(args[2])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -385,13 +362,11 @@ int cosmoB_sSub(CState *state, int nargs, CValue *args) cosmoV_error( state, "string.sub() expected subbed string goes out of bounds, max length is %d!", str->length); - return 0; } cosmoV_pushLString(state, str->str + ((int)indx), ((int)length)); } else { cosmoV_error(state, "string.sub() expected 2 or 3 arguments, got %d!", nargs); - return 0; } return 1; @@ -404,7 +379,6 @@ int cosmoB_sFind(CState *state, int nargs, CValue *args) if (!IS_STRING(args[0]) || !IS_STRING(args[1])) { cosmoV_typeError(state, "string.find()", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -425,7 +399,6 @@ int cosmoB_sFind(CState *state, int nargs, CValue *args) cosmoV_typeError(state, "string.find()", ", , ", "%s, %s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]), cosmoV_typeStr(args[2])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -444,7 +417,6 @@ int cosmoB_sFind(CState *state, int nargs, CValue *args) cosmoV_pushNumber(state, (cosmo_Number)(indx - str->str)); } else { cosmoV_error(state, "string.find() expected 2 or 3 arguments, got %d!", nargs); - return 0; } return 1; @@ -455,13 +427,11 @@ int cosmoB_sSplit(CState *state, int nargs, CValue *args) { if (nargs != 2) { cosmoV_error(state, "string.split() expected 2 arguments, got %d!", nargs); - return 0; } if (!IS_STRING(args[0]) || !IS_STRING(args[1])) { cosmoV_typeError(state, "string.split()", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -492,12 +462,10 @@ int cosmoB_sByte(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "string.byte() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "string.byte", "", "%s", cosmoV_typeStr(args[0])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -518,12 +486,10 @@ int cosmoB_sChar(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "string.char() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "string.char", "", "%s", cosmoV_typeStr(args[0])); - return 0; } // small side effect of truncating the number, but ignoring the decimal instead of throwing an @@ -533,7 +499,6 @@ int cosmoB_sChar(CState *state, int nargs, CValue *args) if (num > 255 || num < 0) { cosmoV_error(state, "Character expected to be in range 0-255, got %d!", num); - return 0; } // basically, treat the character value on the C stack as an """"array"""" with a length of 1 @@ -545,12 +510,10 @@ int cosmoB_sLen(CState *state, int nargs, CValue *args) { if (nargs < 1) { cosmoV_error(state, "string.len() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_STRING(args[0])) { cosmoV_typeError(state, "string.len", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, (cosmo_Number)strlen(cosmoV_readCString(args[0]))); @@ -562,14 +525,12 @@ int cosmoB_sRep(CState *state, int nargs, CValue *args) { if (nargs != 2) { cosmoV_error(state, "string.rep() expected 2 arguments, got %d!", nargs); - return 0; } // expects , if (!IS_STRING(args[0]) || !IS_NUMBER(args[1])) { cosmoV_typeError(state, "string.rep", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } CObjString *str = cosmoV_readString(args[0]); @@ -627,12 +588,10 @@ int cosmoB_mAbs(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.abs() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.abs", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, fabs(cosmoV_readNumber(args[0]))); @@ -644,12 +603,10 @@ int cosmoB_mFloor(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.floor() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.floor", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, (int)cosmoV_readNumber(args[0])); @@ -661,12 +618,10 @@ int cosmoB_mCeil(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.ceil() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.ceil", "", "%s", cosmoV_typeStr(args[0])); - return 0; } int roundedDown = (int)cosmoV_readNumber(args[0]); @@ -685,12 +640,10 @@ int cosmoB_mSin(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.sin() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.sin", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, sin(cosmoV_readNumber(args[0]))); @@ -701,12 +654,10 @@ int cosmoB_mCos(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.cos() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.cos", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, cos(cosmoV_readNumber(args[0]))); @@ -717,12 +668,10 @@ int cosmoB_mTan(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.tan() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.tan", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, tan(cosmoV_readNumber(args[0]))); @@ -733,12 +682,10 @@ int cosmoB_mASin(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.asin() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.asin", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, asin(cosmoV_readNumber(args[0]))); @@ -749,12 +696,10 @@ int cosmoB_mACos(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.acos() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.acos", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, acos(cosmoV_readNumber(args[0]))); @@ -765,12 +710,10 @@ int cosmoB_mATan(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.atan() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.atan", "", "%s", cosmoV_typeStr(args[0])); - return 0; } cosmoV_pushNumber(state, atan(cosmoV_readNumber(args[0]))); @@ -781,12 +724,10 @@ int cosmoB_mRad(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.rad() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.rad", "", "%s", cosmoV_typeStr(args[0])); - return 0; } // convert the degree to radians @@ -798,12 +739,10 @@ int cosmoB_mDeg(CState *state, int nargs, CValue *args) { if (nargs != 1) { cosmoV_error(state, "math.deg() expected 1 argument, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[0])) { cosmoV_typeError(state, "math.deg", "", "%s", cosmoV_typeStr(args[0])); - return 0; } // convert the degree to radians @@ -852,13 +791,11 @@ int cosmoB_vsetGlobal(CState *state, int nargs, CValue *args) { if (nargs != 2) { cosmoV_error(state, "Expected 2 argumenst, got %d!", nargs); - return 0; } if (!IS_TABLE(args[1])) { cosmoV_typeError(state, "vm.__setter[\"globals\"]", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } // this makes me very nervous ngl @@ -874,13 +811,11 @@ int cosmoB_vdisassemble(CState *state, int nargs, CValue *args) if (nargs != 1) { cosmoV_error(state, "Expected 1 argument, got %d!", nargs); - return 0; } // get the closure if (!IS_CLOSURE(args[0])) { cosmoV_typeError(state, "vm.disassemble", "", "%s", cosmoV_typeStr(args[0])); - return 0; } closure = cosmoV_readClosure(args[0]); @@ -895,13 +830,11 @@ int cosmoB_vindexBProto(CState *state, int nargs, CValue *args) { if (nargs != 2) { cosmoV_error(state, "Expected 2 arguments, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[1])) { cosmoV_typeError(state, "baseProtos.__index", ", ", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1])); - return 0; } int indx = (int)cosmoV_readNumber(args[1]); @@ -923,14 +856,12 @@ int cosmoB_vnewindexBProto(CState *state, int nargs, CValue *args) { if (nargs != 3) { cosmoV_error(state, "Expected 3 arguments, got %d!", nargs); - return 0; } if (!IS_NUMBER(args[1]) || !IS_OBJECT(args[2])) { cosmoV_typeError(state, "baseProtos.__newindex", ", , ", "%s, %s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]), cosmoV_typeStr(args[2])); - return 0; } int indx = (int)cosmoV_readNumber(args[1]); @@ -938,7 +869,6 @@ int cosmoB_vnewindexBProto(CState *state, int nargs, CValue *args) if (indx >= COBJ_MAX || indx < 0) { cosmoV_error(state, "index out of range! expected 0 - %d, got %d!", COBJ_MAX, indx); - return 0; } cosmoV_registerProtoObject(state, indx, proto); diff --git a/src/clex.c b/src/clex.c index e2993df..ed8360e 100644 --- a/src/clex.c +++ b/src/clex.c @@ -90,7 +90,7 @@ static char *cutBuffer(CLexState *state, int *length) resetBuffer(state); // shrink the buffer to only use what we need - return cosmoM_reallocate(state->cstate, buf, cap, count, true); + return cosmoM_reallocate(state->cstate, buf, cap, count); } static CToken makeToken(CLexState *state, CTokenType type) diff --git a/src/cmem.c b/src/cmem.c index 491fc96..20d8e41 100644 --- a/src/cmem.c +++ b/src/cmem.c @@ -8,7 +8,7 @@ #include "cvalue.h" // realloc wrapper -void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize, bool isGC) +void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize) { if (buf == NULL) oldSize = 0; @@ -34,20 +34,18 @@ void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize return NULL; } - if (isGC) { #ifdef GC_STRESS - if (!(cosmoM_isFrozen(state)) && newSize > oldSize) { - cosmoM_collectGarbage(state); - } + if (!(cosmoM_isFrozen(state)) && newSize > oldSize) { + cosmoM_collectGarbage(state); + } # ifdef GC_DEBUG - else { - printf("GC event ignored! state frozen! [%d]\n", state->freezeGC); - } + else { + printf("GC event ignored! state frozen! [%d]\n", state->freezeGC); + } # endif #else - cosmoM_checkGarbage(state, 0); + cosmoM_checkGarbage(state, 0); #endif - } // if NULL is passed, realloc() acts like malloc() void *newBuf = realloc(buf, newSize); @@ -208,8 +206,8 @@ static void markObject(CState *state, CObj *obj) return; // we can use cosmoM_growarray because we lock the GC when we entered in cosmoM_collectGarbage - cosmoM_growArrayNonGC(state, CObj *, state->grayStack.array, state->grayStack.count, - state->grayStack.capacity); + cosmoM_growArray(state, CObj *, state->grayStack.array, state->grayStack.count, + state->grayStack.capacity); state->grayStack.array[state->grayStack.count++] = obj; } @@ -298,6 +296,7 @@ static void markRoots(CState *state) COSMO_API void cosmoM_collectGarbage(CState *state) { + cosmoM_freezeGC(state); #ifdef GC_DEBUG printf("-- GC start\n"); size_t start = state->allocatedBytes; @@ -317,6 +316,7 @@ COSMO_API void cosmoM_collectGarbage(CState *state) "scheduled at %ld bytes\n", start - state->allocatedBytes, start, state->allocatedBytes, state->nextGC); #endif + cosmoM_unfreezeGC(state); } COSMO_API void cosmoM_updateThreshhold(CState *state) diff --git a/src/cmem.h b/src/cmem.h index ba38087..0063892 100644 --- a/src/cmem.h +++ b/src/cmem.h @@ -15,38 +15,30 @@ # define cosmoM_freeArray(state, type, buf, capacity) \ printf("freeing array %p [size %lu] at %s:%d\n", buf, sizeof(type) * capacity, __FILE__, \ __LINE__); \ - cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0, true) + cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0) #else # define cosmoM_freeArray(state, type, buf, capacity) \ - cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0, true) + cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0) #endif #define cosmoM_growArray(state, type, buf, count, capacity) \ if (count >= capacity || buf == NULL) { \ int old = capacity; \ capacity = old * GROW_FACTOR; \ - buf = (type *)cosmoM_reallocate(state, buf, sizeof(type) * old, sizeof(type) * capacity, \ - true); \ - } - -#define cosmoM_growArrayNonGC(state, type, buf, count, capacity) \ - if (count >= capacity || buf == NULL) { \ - int old = capacity; \ - capacity = old * GROW_FACTOR; \ - buf = (type *)cosmoM_reallocate(state, buf, sizeof(type) * old, sizeof(type) * capacity, \ - false); \ + buf = (type *)cosmoM_reallocate(state, buf, sizeof(type) * old, sizeof(type) * capacity); \ } #ifdef GC_DEBUG # define cosmoM_free(state, type, x) \ printf("freeing %p [size %lu] at %s:%d\n", x, sizeof(type), __FILE__, __LINE__); \ - cosmoM_reallocate(state, x, sizeof(type), 0, true) + cosmoM_reallocate(state, x, sizeof(type), 0) #else -# define cosmoM_free(state, type, x) cosmoM_reallocate(state, x, sizeof(type), 0, true) +# define cosmoM_free(state, type, x) cosmoM_reallocate(state, x, sizeof(type), 0) #endif #define cosmoM_isFrozen(state) (state->freezeGC > 0) +// cosmoM_freezeGC should only be used in the garbage collector ! // if debugging, print the locations of when the state is frozen/unfrozen #ifdef GC_DEBUG # define cosmoM_freezeGC(state) \ @@ -69,8 +61,7 @@ #endif -COSMO_API void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize, - bool isGC); +COSMO_API void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize); COSMO_API bool cosmoM_checkGarbage(CState *state, size_t needed); // returns true if GC event was triggered COSMO_API void cosmoM_collectGarbage(CState *state); @@ -86,7 +77,7 @@ COSMO_API void cosmoM_removeRoot(CState *state, CObj *oldRoot); // wrapper for cosmoM_reallocate so we can track our memory usage static inline void *cosmoM_xmalloc(CState *state, size_t sz) { - return cosmoM_reallocate(state, NULL, 0, sz, true); + return cosmoM_reallocate(state, NULL, 0, sz); } #endif diff --git a/src/cstate.h b/src/cstate.h index f895957..f000672 100644 --- a/src/cstate.h +++ b/src/cstate.h @@ -44,33 +44,32 @@ typedef struct CPanic { jmp_buf jmp; StkPtr top; - int frameCount; struct CPanic *prev; + int frameCount; } CPanic; struct CState { - int freezeGC; // when > 0, GC events will be ignored (for internal use) - int frameCount; - CPanic *panic; + CCallFrame callFrame[FRAME_MAX]; // call frames + CValue stack[STACK_MAX]; // stack + CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto] + CObjString *iStrings[ISTRING_MAX]; // strings used internally by the VM, eg. __init, __index + CTable strings; + ArrayCObj grayStack; // keeps track of which objects *haven't yet* been traversed in our GC, but + // *have been* found + CObjUpval *openUpvalues; // tracks all of our still open (meaning still on the stack) upvalues + CObjTable *globals; + CValue *top; // top of the stack CObj *objects; // tracks all of our allocated objects CObj *userRoots; // user definable roots, this holds CObjs that should be considered "roots", // lets the VM know you are holding a reference to a CObj in your code - ArrayCObj grayStack; // keeps track of which objects *haven't yet* been traversed in our GC, but - // *have been* found + CPanic *panic; + + int freezeGC; // when > 0, GC events will be ignored (for internal use) + int frameCount; size_t allocatedBytes; size_t nextGC; // when allocatedBytes reaches this threshhold, trigger a GC event - - CObjUpval *openUpvalues; // tracks all of our still open (meaning still on the stack) upvalues - CTable strings; - CObjTable *globals; - - CValue *top; // top of the stack - CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto] - CObjString *iStrings[ISTRING_MAX]; // strings used internally by the VM, eg. __init, __index - CCallFrame callFrame[FRAME_MAX]; // call frames - CValue stack[STACK_MAX]; // stack }; CPanic *cosmoV_newPanic(CState *state);