mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-12-04 22:46:31 +00:00
Compare commits
5 Commits
37e42eb60b
...
37e4653d40
Author | SHA1 | Date | |
---|---|---|---|
37e4653d40 | |||
1ae473383d | |||
6ed5589513 | |||
1408a07b23 | |||
27818b3788 |
@ -6,7 +6,7 @@ end
|
|||||||
// instance of test
|
// instance of test
|
||||||
let obj = test()
|
let obj = test()
|
||||||
|
|
||||||
test.__index = function(self, key)
|
test.__index = func(self, key)
|
||||||
print("__index called!")
|
print("__index called!")
|
||||||
if (key == "lol") then
|
if (key == "lol") then
|
||||||
return 9001
|
return 9001
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ void initChunk(CState *state, CChunk *chunk, size_t startCapacity)
|
|||||||
void cleanChunk(CState *state, CChunk *chunk)
|
void cleanChunk(CState *state, CChunk *chunk)
|
||||||
{
|
{
|
||||||
// first, free the chunk buffer
|
// first, free the chunk buffer
|
||||||
cosmoM_freearray(state, INSTRUCTION, chunk->buf, chunk->capacity);
|
cosmoM_freeArray(state, INSTRUCTION, chunk->buf, chunk->capacity);
|
||||||
// then the line info
|
// then the line info
|
||||||
cosmoM_freearray(state, int, chunk->lineInfo, chunk->capacity);
|
cosmoM_freeArray(state, int, chunk->lineInfo, chunk->capacity);
|
||||||
// free the constants
|
// free the constants
|
||||||
cleanValArray(state, &chunk->constants);
|
cleanValArray(state, &chunk->constants);
|
||||||
}
|
}
|
||||||
@ -61,8 +61,8 @@ int addConstant(CState *state, CChunk *chunk, CValue value)
|
|||||||
void writeu8Chunk(CState *state, CChunk *chunk, INSTRUCTION i, int line)
|
void writeu8Chunk(CState *state, CChunk *chunk, INSTRUCTION i, int line)
|
||||||
{
|
{
|
||||||
// does the buffer need to be reallocated?
|
// does the buffer need to be reallocated?
|
||||||
cosmoM_growarray(state, INSTRUCTION, chunk->buf, chunk->count, chunk->capacity);
|
cosmoM_growArray(state, INSTRUCTION, chunk->buf, chunk->count, chunk->capacity);
|
||||||
cosmoM_growarray(state, int, chunk->lineInfo, chunk->count, chunk->lineCapacity);
|
cosmoM_growArray(state, int, chunk->lineInfo, chunk->count, chunk->lineCapacity);
|
||||||
|
|
||||||
// write data to the chunk :)
|
// write data to the chunk :)
|
||||||
chunk->lineInfo[chunk->count] = line;
|
chunk->lineInfo[chunk->count] = line;
|
||||||
|
@ -54,7 +54,7 @@ static void resetBuffer(CLexState *state)
|
|||||||
// cancels the token heap buffer and frees it
|
// cancels the token heap buffer and frees it
|
||||||
static void freeBuffer(CLexState *state)
|
static void freeBuffer(CLexState *state)
|
||||||
{
|
{
|
||||||
cosmoM_freearray(state->cstate, char, state->buffer, state->bufCap);
|
cosmoM_freeArray(state->cstate, char, state->buffer, state->bufCap);
|
||||||
|
|
||||||
resetBuffer(state);
|
resetBuffer(state);
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ static void freeBuffer(CLexState *state)
|
|||||||
// adds character to buffer
|
// adds character to buffer
|
||||||
static void appendBuffer(CLexState *state, char c)
|
static void appendBuffer(CLexState *state, char c)
|
||||||
{
|
{
|
||||||
cosmoM_growarray(state->cstate, char, state->buffer, state->bufCount, state->bufCap);
|
cosmoM_growArray(state->cstate, char, state->buffer, state->bufCount, state->bufCap);
|
||||||
|
|
||||||
state->buffer[state->bufCount++] = c;
|
state->buffer[state->bufCount++] = c;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ static char *cutBuffer(CLexState *state, int *length)
|
|||||||
resetBuffer(state);
|
resetBuffer(state);
|
||||||
|
|
||||||
// shrink the buffer to only use what we need
|
// shrink the buffer to only use what we need
|
||||||
return cosmoM_reallocate(state->cstate, buf, cap, count);
|
return cosmoM_reallocate(state->cstate, buf, cap, count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CToken makeToken(CLexState *state, CTokenType type)
|
static CToken makeToken(CLexState *state, CTokenType type)
|
||||||
|
27
src/cmem.c
27
src/cmem.c
@ -8,7 +8,7 @@
|
|||||||
#include "cvalue.h"
|
#include "cvalue.h"
|
||||||
|
|
||||||
// realloc wrapper
|
// realloc wrapper
|
||||||
void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize)
|
void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize, bool isGC)
|
||||||
{
|
{
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
oldSize = 0;
|
oldSize = 0;
|
||||||
@ -34,18 +34,20 @@ void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGC) {
|
||||||
#ifdef GC_STRESS
|
#ifdef GC_STRESS
|
||||||
if (!(cosmoM_isFrozen(state)) && newSize > oldSize) {
|
if (!(cosmoM_isFrozen(state)) && newSize > oldSize) {
|
||||||
cosmoM_collectGarbage(state);
|
cosmoM_collectGarbage(state);
|
||||||
}
|
}
|
||||||
# ifdef GC_DEBUG
|
# ifdef GC_DEBUG
|
||||||
else {
|
else {
|
||||||
printf("GC event ignored! state frozen! [%d]\n", state->freezeGC);
|
printf("GC event ignored! state frozen! [%d]\n", state->freezeGC);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
cosmoM_checkGarbage(state, 0);
|
cosmoM_checkGarbage(state, 0);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// if NULL is passed, realloc() acts like malloc()
|
// if NULL is passed, realloc() acts like malloc()
|
||||||
void *newBuf = realloc(buf, newSize);
|
void *newBuf = realloc(buf, newSize);
|
||||||
@ -206,8 +208,8 @@ static void markObject(CState *state, CObj *obj)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// we can use cosmoM_growarray because we lock the GC when we entered in cosmoM_collectGarbage
|
// we can use cosmoM_growarray because we lock the GC when we entered in cosmoM_collectGarbage
|
||||||
cosmoM_growarray(state, CObj *, state->grayStack.array, state->grayStack.count,
|
cosmoM_growArrayNonGC(state, CObj *, state->grayStack.array, state->grayStack.count,
|
||||||
state->grayStack.capacity);
|
state->grayStack.capacity);
|
||||||
|
|
||||||
state->grayStack.array[state->grayStack.count++] = obj;
|
state->grayStack.array[state->grayStack.count++] = obj;
|
||||||
}
|
}
|
||||||
@ -300,8 +302,6 @@ COSMO_API void cosmoM_collectGarbage(CState *state)
|
|||||||
printf("-- GC start\n");
|
printf("-- GC start\n");
|
||||||
size_t start = state->allocatedBytes;
|
size_t start = state->allocatedBytes;
|
||||||
#endif
|
#endif
|
||||||
cosmoM_freezeGC(state); // we don't want a recursive garbage collection event!
|
|
||||||
|
|
||||||
markRoots(state);
|
markRoots(state);
|
||||||
|
|
||||||
tableRemoveWhite(
|
tableRemoveWhite(
|
||||||
@ -312,9 +312,6 @@ COSMO_API void cosmoM_collectGarbage(CState *state)
|
|||||||
|
|
||||||
// set our next GC event
|
// set our next GC event
|
||||||
cosmoM_updateThreshhold(state);
|
cosmoM_updateThreshhold(state);
|
||||||
|
|
||||||
state->freezeGC--; // we don't want to use cosmoM_unfreezeGC because that might trigger a GC
|
|
||||||
// event (if GC_STRESS is defined)
|
|
||||||
#ifdef GC_DEBUG
|
#ifdef GC_DEBUG
|
||||||
printf("-- GC end, reclaimed %ld bytes (started at %ld, ended at %ld), next garbage collection "
|
printf("-- GC end, reclaimed %ld bytes (started at %ld, ended at %ld), next garbage collection "
|
||||||
"scheduled at %ld bytes\n",
|
"scheduled at %ld bytes\n",
|
||||||
|
33
src/cmem.h
33
src/cmem.h
@ -12,28 +12,37 @@
|
|||||||
#define ARRAY_START 8
|
#define ARRAY_START 8
|
||||||
|
|
||||||
#ifdef GC_DEBUG
|
#ifdef GC_DEBUG
|
||||||
# define cosmoM_freearray(state, type, buf, capacity) \
|
# define cosmoM_freeArray(state, type, buf, capacity) \
|
||||||
printf("freeing array %p [size %lu] at %s:%d\n", buf, sizeof(type) * capacity, __FILE__, \
|
printf("freeing array %p [size %lu] at %s:%d\n", buf, sizeof(type) * capacity, __FILE__, \
|
||||||
__LINE__); \
|
__LINE__); \
|
||||||
cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0)
|
cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0, true)
|
||||||
#else
|
#else
|
||||||
# define cosmoM_freearray(state, type, buf, capacity) \
|
# define cosmoM_freeArray(state, type, buf, capacity) \
|
||||||
cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0)
|
cosmoM_reallocate(state, buf, sizeof(type) * capacity, 0, true)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define cosmoM_growarray(state, type, buf, count, capacity) \
|
#define cosmoM_growArray(state, type, buf, count, capacity) \
|
||||||
if (count >= capacity || buf == NULL) { \
|
if (count >= capacity || buf == NULL) { \
|
||||||
int old = capacity; \
|
int old = capacity; \
|
||||||
capacity = old * GROW_FACTOR; \
|
capacity = old * GROW_FACTOR; \
|
||||||
buf = (type *)cosmoM_reallocate(state, buf, sizeof(type) * old, sizeof(type) * capacity); \
|
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); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GC_DEBUG
|
#ifdef GC_DEBUG
|
||||||
# define cosmoM_free(state, type, x) \
|
# define cosmoM_free(state, type, x) \
|
||||||
printf("freeing %p [size %lu] at %s:%d\n", x, sizeof(type), __FILE__, __LINE__); \
|
printf("freeing %p [size %lu] at %s:%d\n", x, sizeof(type), __FILE__, __LINE__); \
|
||||||
cosmoM_reallocate(state, x, sizeof(type), 0)
|
cosmoM_reallocate(state, x, sizeof(type), 0, true)
|
||||||
#else
|
#else
|
||||||
# define cosmoM_free(state, type, x) cosmoM_reallocate(state, x, sizeof(type), 0)
|
# define cosmoM_free(state, type, x) cosmoM_reallocate(state, x, sizeof(type), 0, true)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define cosmoM_isFrozen(state) (state->freezeGC > 0)
|
#define cosmoM_isFrozen(state) (state->freezeGC > 0)
|
||||||
@ -60,7 +69,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
COSMO_API void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize);
|
COSMO_API void *cosmoM_reallocate(CState *state, void *buf, size_t oldSize, size_t newSize,
|
||||||
|
bool isGC);
|
||||||
COSMO_API bool cosmoM_checkGarbage(CState *state,
|
COSMO_API bool cosmoM_checkGarbage(CState *state,
|
||||||
size_t needed); // returns true if GC event was triggered
|
size_t needed); // returns true if GC event was triggered
|
||||||
COSMO_API void cosmoM_collectGarbage(CState *state);
|
COSMO_API void cosmoM_collectGarbage(CState *state);
|
||||||
@ -76,10 +86,7 @@ COSMO_API void cosmoM_removeRoot(CState *state, CObj *oldRoot);
|
|||||||
// wrapper for cosmoM_reallocate so we can track our memory usage
|
// wrapper for cosmoM_reallocate so we can track our memory usage
|
||||||
static inline void *cosmoM_xmalloc(CState *state, size_t sz)
|
static inline void *cosmoM_xmalloc(CState *state, size_t sz)
|
||||||
{
|
{
|
||||||
return cosmoM_reallocate(state, NULL, 0, sz);
|
return cosmoM_reallocate(state, NULL, 0, sz, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define cosmoM_xmalloc(state, sz) \
|
|
||||||
// (printf("allocating new buffer at %s:%d of size %ld\n", __FILE__, __LINE__, sz), cosmoM_reallocate(state, NULL, 0, sz))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
18
src/cobj.c
18
src/cobj.c
@ -46,7 +46,7 @@ void cosmoO_free(CState *state, CObj *obj)
|
|||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case COBJ_STRING: {
|
case COBJ_STRING: {
|
||||||
CObjString *objStr = (CObjString *)obj;
|
CObjString *objStr = (CObjString *)obj;
|
||||||
cosmoM_freearray(state, char, objStr->str, objStr->length + 1);
|
cosmoM_freeArray(state, char, objStr->str, objStr->length + 1);
|
||||||
cosmoM_free(state, CObjString, objStr);
|
cosmoM_free(state, CObjString, objStr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -82,13 +82,13 @@ void cosmoO_free(CState *state, CObj *obj)
|
|||||||
}
|
}
|
||||||
case COBJ_ERROR: {
|
case COBJ_ERROR: {
|
||||||
CObjError *err = (CObjError *)obj;
|
CObjError *err = (CObjError *)obj;
|
||||||
cosmoM_freearray(state, CCallFrame, err->frames, err->frameCount);
|
cosmoM_freeArray(state, CCallFrame, err->frames, err->frameCount);
|
||||||
cosmoM_free(state, CObjError, obj);
|
cosmoM_free(state, CObjError, obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_CLOSURE: {
|
case COBJ_CLOSURE: {
|
||||||
CObjClosure *closure = (CObjClosure *)obj;
|
CObjClosure *closure = (CObjClosure *)obj;
|
||||||
cosmoM_freearray(state, CObjUpval *, closure->upvalues, closure->upvalueCount);
|
cosmoM_freeArray(state, CObjUpval *, closure->upvalues, closure->upvalueCount);
|
||||||
cosmoM_free(state, CObjClosure, closure);
|
cosmoM_free(state, CObjClosure, closure);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -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];
|
||||||
@ -306,7 +305,7 @@ CObjString *cosmoO_takeString(CState *state, char *str, size_t length)
|
|||||||
|
|
||||||
// have we already interned this string?
|
// have we already interned this string?
|
||||||
if (lookup != NULL) {
|
if (lookup != NULL) {
|
||||||
cosmoM_freearray(state, char, str,
|
cosmoM_freeArray(state, char, str,
|
||||||
length + 1); // free our passed character array, it's unneeded!
|
length + 1); // free our passed character array, it's unneeded!
|
||||||
return lookup;
|
return lookup;
|
||||||
}
|
}
|
||||||
@ -322,8 +321,7 @@ CObjString *cosmoO_allocateString(CState *state, const char *str, size_t sz, uin
|
|||||||
strObj->length = sz;
|
strObj->length = sz;
|
||||||
strObj->hash = hash;
|
strObj->hash = hash;
|
||||||
|
|
||||||
// we push & pop the string so our GC can find it (we don't use freezeGC/unfreezeGC because we
|
// push/pop to make sure GC doesn't collect it
|
||||||
// *want* a GC event to happen)
|
|
||||||
cosmoV_pushRef(state, (CObj *)strObj);
|
cosmoV_pushRef(state, (CObj *)strObj);
|
||||||
cosmoT_insert(state, &state->strings, cosmoV_newRef((CObj *)strObj));
|
cosmoT_insert(state, &state->strings, cosmoV_newRef((CObj *)strObj));
|
||||||
cosmoV_pop(state);
|
cosmoV_pop(state);
|
||||||
@ -762,6 +760,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:
|
||||||
|
12
src/cparse.c
12
src/cparse.c
@ -64,9 +64,10 @@ typedef struct
|
|||||||
CCompilerState *compiler;
|
CCompilerState *compiler;
|
||||||
CObjString *module; // name of the module
|
CObjString *module; // name of the module
|
||||||
CToken current;
|
CToken current;
|
||||||
CToken previous; // token right after the current token
|
CToken previous; // token right after the current token
|
||||||
int workingStackCount; // we push CValues of objects we need onto the stack so the garbage collector can see them.
|
int workingStackCount; // we push CValues of objects we need onto the stack so the garbage
|
||||||
// this is the count of those values so we'll know how many to pop off when we're done
|
// collector can see them. this is the count of those values so we'll
|
||||||
|
// know how many to pop off when we're done
|
||||||
} CParseState;
|
} CParseState;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -481,6 +482,7 @@ static void string(CParseState *pstate, bool canAssign, Precedence prec)
|
|||||||
{
|
{
|
||||||
CObjString *strObj =
|
CObjString *strObj =
|
||||||
cosmoO_takeString(pstate->state, pstate->previous.start, pstate->previous.length);
|
cosmoO_takeString(pstate->state, pstate->previous.start, pstate->previous.length);
|
||||||
|
keepTrackOf(pstate, cosmoV_newRef((CObj *)strObj));
|
||||||
writeConstant(pstate, cosmoV_newRef((CObj *)strObj));
|
writeConstant(pstate, cosmoV_newRef((CObj *)strObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,7 +1371,7 @@ static void endLoop(CParseState *pstate)
|
|||||||
patchJmp(pstate, pstate->compiler->loop.breaks[--pstate->compiler->loop.breakCount]);
|
patchJmp(pstate, pstate->compiler->loop.breaks[--pstate->compiler->loop.breakCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmoM_freearray(pstate->state, int, pstate->compiler->loop.breaks,
|
cosmoM_freeArray(pstate->state, int, pstate->compiler->loop.breaks,
|
||||||
pstate->compiler->loop.breakCapacity);
|
pstate->compiler->loop.breakCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1658,7 +1660,7 @@ static void breakStatement(CParseState *pstate)
|
|||||||
pstate->compiler->localCount = savedLocals;
|
pstate->compiler->localCount = savedLocals;
|
||||||
|
|
||||||
// add break to loop
|
// add break to loop
|
||||||
cosmoM_growarray(pstate->state, int, pstate->compiler->loop.breaks,
|
cosmoM_growArray(pstate->state, int, pstate->compiler->loop.breaks,
|
||||||
pstate->compiler->loop.breakCount, pstate->compiler->loop.breakCapacity);
|
pstate->compiler->loop.breakCount, pstate->compiler->loop.breakCapacity);
|
||||||
pstate->compiler->loop.breaks[pstate->compiler->loop.breakCount++] = writeJmp(pstate, OP_JMP);
|
pstate->compiler->loop.breaks[pstate->compiler->loop.breakCount++] = writeJmp(pstate, OP_JMP);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
@ -119,7 +120,7 @@ void cosmoV_freeState(CState *state)
|
|||||||
cosmoT_clearTable(state, &state->strings);
|
cosmoT_clearTable(state, &state->strings);
|
||||||
|
|
||||||
// free our gray stack & finally free the state structure
|
// free our gray stack & finally free the state structure
|
||||||
cosmoM_freearray(state, CObj *, state->grayStack.array, state->grayStack.capacity);
|
cosmoM_freeArray(state, CObj *, state->grayStack.array, state->grayStack.capacity);
|
||||||
|
|
||||||
#ifdef GC_DEBUG
|
#ifdef GC_DEBUG
|
||||||
if (state->allocatedBytes != 0) {
|
if (state->allocatedBytes != 0) {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -52,9 +54,9 @@ struct CState
|
|||||||
int frameCount;
|
int frameCount;
|
||||||
CPanic *panic;
|
CPanic *panic;
|
||||||
|
|
||||||
CObj *objects; // tracks all of our allocated objects
|
CObj *objects; // tracks all of our allocated objects
|
||||||
CObj *userRoots; // user definable roots, this holds CObjs that should be considered "roots",
|
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
|
// 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
|
ArrayCObj grayStack; // keeps track of which objects *haven't yet* been traversed in our GC, but
|
||||||
// *have been* found
|
// *have been* found
|
||||||
size_t allocatedBytes;
|
size_t allocatedBytes;
|
||||||
|
@ -61,7 +61,7 @@ void cosmoT_addTable(CState *state, CTable *from, CTable *to)
|
|||||||
|
|
||||||
void cosmoT_clearTable(CState *state, CTable *tbl)
|
void cosmoT_clearTable(CState *state, CTable *tbl)
|
||||||
{
|
{
|
||||||
cosmoM_freearray(state, CTableEntry, tbl->table, cosmoT_getCapacity(tbl));
|
cosmoM_freeArray(state, CTableEntry, tbl->table, cosmoT_getCapacity(tbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t getObjectHash(CObj *obj)
|
static uint32_t getObjectHash(CObj *obj)
|
||||||
@ -165,7 +165,7 @@ static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// free the old table
|
// free the old table
|
||||||
cosmoM_freearray(state, CTableEntry, tbl->table, oldCap);
|
cosmoM_freeArray(state, CTableEntry, tbl->table, oldCap);
|
||||||
|
|
||||||
tbl->table = entries;
|
tbl->table = entries;
|
||||||
tbl->capacityMask = newCapacity - 1;
|
tbl->capacityMask = newCapacity - 1;
|
||||||
|
@ -13,12 +13,12 @@ void initValArray(CState *state, CValueArray *val, size_t startCapacity)
|
|||||||
|
|
||||||
void cleanValArray(CState *state, CValueArray *array)
|
void cleanValArray(CState *state, CValueArray *array)
|
||||||
{
|
{
|
||||||
cosmoM_freearray(state, CValue, array->values, array->capacity);
|
cosmoM_freeArray(state, CValue, array->values, array->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendValArray(CState *state, CValueArray *array, CValue val)
|
void appendValArray(CState *state, CValueArray *array, CValue val)
|
||||||
{
|
{
|
||||||
cosmoM_growarray(state, CValue, array->values, array->count, array->capacity);
|
cosmoM_growArray(state, CValue, array->values, array->count, array->capacity);
|
||||||
|
|
||||||
array->values[array->count++] = val;
|
array->values[array->count++] = val;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user