Compare commits

..

No commits in common. "dcf6a09dae1d0ebddbfdf6fe93707aeb5d1c9809" and "861607d6a8815a68bed1b476022fab42a8f50dec" have entirely different histories.

10 changed files with 637 additions and 697 deletions

View File

@ -9,53 +9,53 @@ void printIndent(int indent)
printf("\t");
}
static int simpleInstruction(const char *name, int offset)
int simpleInstruction(const char *name, int offset)
{
printf("%s", name);
return offset + 1; // consume opcode
}
static int u8OperandInstruction(const char *name, CChunk *chunk, int offset)
int u8OperandInstruction(const char *name, CChunk *chunk, int offset)
{
printf("%-16s [%03d]", name, readu8Chunk(chunk, offset + 1));
return offset + 2;
}
static int u16OperandInstruction(const char *name, CChunk *chunk, int offset)
int u16OperandInstruction(const char *name, CChunk *chunk, int offset)
{
printf("%-16s [%05d]", name, readu16Chunk(chunk, offset + 1));
return offset + 1 + (sizeof(uint16_t) / sizeof(INSTRUCTION));
}
static int JumpInstruction(const char *name, CChunk *chunk, int offset, int dir)
int JumpInstruction(const char *name, CChunk *chunk, int offset, int dir)
{
int jmp = ((int)readu16Chunk(chunk, offset + 1)) * dir;
printf("%-16s [%05d] - jumps to %04d", name, jmp, offset + 3 + jmp);
return offset + 1 + (sizeof(uint16_t) / sizeof(INSTRUCTION));
}
static int u8u8OperandInstruction(const char *name, CChunk *chunk, int offset)
int u8u8OperandInstruction(const char *name, CChunk *chunk, int offset)
{
printf("%-16s [%03d] [%03d]", name, readu8Chunk(chunk, offset + 1),
readu8Chunk(chunk, offset + 2));
return offset + 3; // op + u8 + u8
}
static int u8u16OperandInstruction(const char *name, CChunk *chunk, int offset)
int u8u16OperandInstruction(const char *name, CChunk *chunk, int offset)
{
printf("%-16s [%03d] [%05d]", name, readu8Chunk(chunk, offset + 1),
readu16Chunk(chunk, offset + 2));
return offset + 4; // op + u8 + u16
}
static int u8u8u16OperandInstruction(const char *name, CChunk *chunk, int offset)
int u8u8u16OperandInstruction(const char *name, CChunk *chunk, int offset)
{
printf("%-16s [%03d] [%03d] [%05d]", name, readu8Chunk(chunk, offset + 1),
readu8Chunk(chunk, offset + 2), readu16Chunk(chunk, offset + 3));
return offset + 5; // op + u8 + u8 + u16
}
static int constInstruction(const char *name, CChunk *chunk, int offset)
int constInstruction(const char *name, CChunk *chunk, int offset)
{
int index = readu16Chunk(chunk, offset + 1);
printf("%-16s [%05d] - ", name, index);

View File

@ -150,7 +150,7 @@ static bool match(CLexState *state, char expected)
return true;
}
static char peek(CLexState *state)
char peek(CLexState *state)
{
return *state->currentChar;
}
@ -163,7 +163,7 @@ static char peekNext(CLexState *state)
return state->currentChar[1];
}
static char next(CLexState *state)
char next(CLexState *state)
{
if (isEnd(state))
return '\0'; // return a null terminator
@ -171,12 +171,12 @@ static char next(CLexState *state)
return state->currentChar[-1];
}
static bool isHex(char c)
bool isHex(char c)
{
return isNumerical(c) || ('A' <= c && 'F' >= c) || ('a' <= c && 'f' >= c);
}
static CTokenType identifierType(CLexState *state)
CTokenType identifierType(CLexState *state)
{
int length = state->currentChar - state->startChar;
@ -192,7 +192,7 @@ static CTokenType identifierType(CLexState *state)
return TOKEN_IDENTIFIER;
}
static void skipWhitespace(CLexState *state)
void skipWhitespace(CLexState *state)
{
while (true) {
char c = peek(state);
@ -235,7 +235,7 @@ static void skipWhitespace(CLexState *state)
}
}
static CToken parseString(CLexState *state)
CToken parseString(CLexState *state)
{
makeBuffer(state); // buffer mode
while (peek(state) != '"' && !isEnd(state)) {
@ -341,7 +341,7 @@ static CToken parseString(CLexState *state)
return makeToken(state, TOKEN_STRING);
}
static CToken parseNumber(CLexState *state)
CToken parseNumber(CLexState *state)
{
switch (peek(state)) {
case 'x': // hexadecimal number
@ -380,7 +380,7 @@ static CToken parseNumber(CLexState *state)
return makeToken(state, TOKEN_NUMBER);
}
static CToken parseIdentifier(CLexState *state)
CToken parseIdentifier(CLexState *state)
{
// read literal
while ((isAlpha(peek(state)) || isNumerical(peek(state))) && !isEnd(state))

View File

@ -93,7 +93,7 @@ typedef struct
char *currentChar;
char *startChar;
char *buffer; // if non-NULL & bufCount > 0, token->start & token->length will be set to buffer
// & bufCount respectively. used exclusively for string literals
// & bufCount respectively
size_t bufCount;
size_t bufCap;
int line; // current line

View File

@ -51,10 +51,10 @@ COSMO_API bool cosmoM_checkGarbage(CState *state, size_t needed)
return false;
}
static void markObject(CState *state, CObj *obj);
static void markValue(CState *state, CValue val);
void markObject(CState *state, CObj *obj);
void markValue(CState *state, CValue val);
static void markTable(CState *state, CTable *tbl)
void markTable(CState *state, CTable *tbl)
{
if (tbl->table == NULL) // table is still being initialized
return;
@ -68,7 +68,7 @@ static void markTable(CState *state, CTable *tbl)
}
// frees white members from the table
static void tableRemoveWhite(CState *state, CTable *tbl)
void tableRemoveWhite(CState *state, CTable *tbl)
{
if (tbl->table == NULL) // table is still being initialized
return;
@ -86,7 +86,7 @@ static void tableRemoveWhite(CState *state, CTable *tbl)
cosmoT_checkShrink(state, tbl); // recovers the memory we're no longer using
}
static void markArray(CState *state, CValueArray *array)
void markArray(CState *state, CValueArray *array)
{
for (size_t i = 0; i < array->count; i++) {
markValue(state, array->values[i]);
@ -95,7 +95,7 @@ static void markArray(CState *state, CValueArray *array)
// mark all references associated with the object
// black = keep, white = discard
static void blackenObject(CState *state, CObj *obj)
void blackenObject(CState *state, CObj *obj)
{
markObject(state, (CObj *)obj->proto);
switch (obj->type) {
@ -161,7 +161,7 @@ static void blackenObject(CState *state, CObj *obj)
}
}
static void markObject(CState *state, CObj *obj)
void markObject(CState *state, CObj *obj)
{
if (obj == NULL || obj->isMarked) // skip if NULL or already marked
return;
@ -185,14 +185,14 @@ static void markObject(CState *state, CObj *obj)
state->grayStack.array[state->grayStack.count++] = obj;
}
static void markValue(CState *state, CValue val)
void markValue(CState *state, CValue val)
{
if (IS_REF(val))
markObject(state, cosmoV_readRef(val));
}
// trace our gray references
static void traceGrays(CState *state)
void traceGrays(CState *state)
{
while (state->grayStack.count > 0) {
CObj *obj = state->grayStack.array[--state->grayStack.count];
@ -200,7 +200,7 @@ static void traceGrays(CState *state)
}
}
static void sweep(CState *state)
void sweep(CState *state)
{
CObj *prev = NULL;
CObj *object = state->objects;
@ -224,7 +224,7 @@ static void sweep(CState *state)
}
}
static void markUserRoots(CState *state)
void markUserRoots(CState *state)
{
CObj *root = state->userRoots;
@ -235,7 +235,7 @@ static void markUserRoots(CState *state)
}
}
static void markRoots(CState *state)
void markRoots(CState *state)
{
// mark all values on the stack
for (StkPtr value = state->stack; value < state->top; value++) {

View File

@ -67,7 +67,6 @@ COSMO_API void cosmoM_collectGarbage(CState *state);
COSMO_API void cosmoM_updateThreshhold(CState *state);
// lets the VM know you are holding a reference to a CObj and to not free it
// NOTE: prefer to use the stack when possible
COSMO_API void cosmoM_addRoot(CState *state, CObj *newRoot);
// lets the VM know this root is no longer held in a reference and is able to be freed

View File

@ -64,7 +64,7 @@ typedef enum
OP_FALSE,
OP_NIL,
OP_RETURN,
OP_RETURN
} COPCODE; // there can be a max of 256 instructions
#endif

View File

@ -14,15 +14,7 @@
performance, however this will produce undefined behavior as you reach the stack limit (and may
cause a seg fault!). It is recommended to keep this enabled.
*/
// #define SAFE_STACK
/*
NAN_BOXXED:
if undefined, the interpreter will use a tagged union to store values. This is the default.
Note that even though the sizeof(CValue) is 8 bytes for NAN_BOXXED (as opposed to 16 bytes for
the tagged union) no performance benefits were measured. I recommend keeping this undefined for
now.
*/
#define SAFE_STACK
// #define NAN_BOXXED
// forward declare *most* stuff so our headers are cleaner

View File

@ -11,7 +11,7 @@
#define MIN_TABLE_CAPACITY ARRAY_START
// bit-twiddling hacks, gets the next power of 2
static unsigned int nextPow2(unsigned int x)
unsigned int nextPow2(unsigned int x)
{
if (x <= ARRAY_START - 1)
return ARRAY_START; // sanity check
@ -46,14 +46,13 @@ void cosmoT_initTable(CState *state, CTable *tbl, int startCap)
void cosmoT_addTable(CState *state, CTable *from, CTable *to)
{
CTableEntry *entry;
int cap = from->capacityMask + 1;
for (int i = 0; i < cap; i++) {
entry = &from->table[i];
CTableEntry *entry = &from->table[i];
if (!(IS_NIL(entry->key))) {
*cosmoT_insert(state, to, entry->key) = entry->val;
CValue *newVal = cosmoT_insert(state, to, entry->key);
*newVal = entry->val;
}
}
}
@ -63,7 +62,7 @@ void cosmoT_clearTable(CState *state, CTable *tbl)
cosmoM_freearray(state, CTableEntry, tbl->table, (tbl->capacityMask + 1));
}
static uint32_t getObjectHash(CObj *obj)
uint32_t getObjectHash(CObj *obj)
{
switch (obj->type) {
case COBJ_STRING:
@ -73,7 +72,7 @@ static uint32_t getObjectHash(CObj *obj)
}
}
static uint32_t getValueHash(CValue *val)
uint32_t getValueHash(CValue *val)
{
switch (GET_TYPE(*val)) {
case COSMO_TREF:

1237
src/cvm.c

File diff suppressed because it is too large Load Diff

View File

@ -8,19 +8,6 @@
// #define VM_DEBUG
/*
if we're using GNUC or clang, we can use computed gotos which speeds up
cosmoV_execute by about 20% from benchmarking. of course, if you know
your compiler supports computed gotos, you can define VM_JUMPTABLE
BTW: be weary of maliciously crafted cosmo dumps!! it's very easy to crash
cosmo with this enabled and reading invalid opcodes due to us just using the
opcode as an index into the jump table
*/
#if defined(__GNUC__) || defined(__clang__)
# define VM_JUMPTABLE
#endif
typedef enum
{
COSMOVM_OK,