mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 00:00:10 +00:00
Fixed table iteration bug, added vm.globals to debug lib
This commit is contained in:
parent
cd6744ab65
commit
cff26574bb
@ -338,14 +338,41 @@ int cosmoB_dgetProto(CState *state, int nargs, CValue *args) {
|
|||||||
return 1; // 1 result
|
return 1; // 1 result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================================ [VM.*] ================================================================
|
||||||
|
|
||||||
|
int cosmoB_vgetGlobal(CState *state, int nargs, CValue *args) {
|
||||||
|
// this function doesn't need to check anything, just return the global table
|
||||||
|
cosmoV_pushObj(state, (CObj*)state->globals);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hmmm i guess i could allow this?? no idea how the VM will react to the global table being suddenly being yoinked
|
||||||
|
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.__getter.globals", "<object>, <table>", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this makes me very nervous ngl
|
||||||
|
CObjTable *tbl = (CObjTable*)cosmoV_readObj(args[1]);
|
||||||
|
state->globals = tbl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cosmoB_vindexBProto(CState *state, int nargs, CValue *args) {
|
int cosmoB_vindexBProto(CState *state, int nargs, CValue *args) {
|
||||||
if (nargs != 2) {
|
if (nargs != 2) {
|
||||||
cosmoV_error(state, "Expected 2 argument, got %d!", nargs);
|
cosmoV_error(state, "Expected 2 arguments, got %d!", nargs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_NUMBER(args[1])) {
|
if (!IS_NUMBER(args[1])) {
|
||||||
cosmoV_typeError(state, "baseProtos.__index", "<number>", "%s", cosmoV_typeStr(args[0]));
|
cosmoV_typeError(state, "baseProtos.__index", "<object>, <number>", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,6 +437,7 @@ void cosmoB_loadDebug(CState *state) {
|
|||||||
|
|
||||||
// set debug protos to the debug object
|
// set debug protos to the debug object
|
||||||
cosmoV_registerProtoObject(state, COBJ_OBJECT, obj);
|
cosmoV_registerProtoObject(state, COBJ_OBJECT, obj);
|
||||||
|
cosmoV_pop(state); // pops the debug object
|
||||||
|
|
||||||
// make vm.* object
|
// make vm.* object
|
||||||
cosmoV_pushString(state, "vm");
|
cosmoV_pushString(state, "vm");
|
||||||
@ -424,10 +452,27 @@ void cosmoB_loadDebug(CState *state) {
|
|||||||
cosmoV_pushCFunction(state, cosmoB_vnewindexBProto);
|
cosmoV_pushCFunction(state, cosmoB_vnewindexBProto);
|
||||||
|
|
||||||
cosmoV_makeObject(state, 2); // makes the baseProtos object
|
cosmoV_makeObject(state, 2); // makes the baseProtos object
|
||||||
cosmoV_makeObject(state, 1); // makes the vm object
|
|
||||||
|
// make __getter table for vm object
|
||||||
|
cosmoV_pushString(state, "__getter");
|
||||||
|
|
||||||
|
cosmoV_pushString(state, "globals");
|
||||||
|
cosmoV_pushCFunction(state, cosmoB_vgetGlobal);
|
||||||
|
|
||||||
|
cosmoV_makeTable(state, 1);
|
||||||
|
|
||||||
|
// make __setter table for vm object
|
||||||
|
cosmoV_pushString(state, "__setter");
|
||||||
|
|
||||||
|
cosmoV_pushString(state, "globals");
|
||||||
|
cosmoV_pushCFunction(state, cosmoB_vsetGlobal);
|
||||||
|
|
||||||
|
cosmoV_makeTable(state, 1);
|
||||||
|
|
||||||
|
cosmoV_makeObject(state, 3); // makes the vm object
|
||||||
|
|
||||||
// register "vm" to the global table
|
// register "vm" to the global table
|
||||||
cosmoV_register(state, 1);
|
cosmoV_register(state, 1);
|
||||||
|
|
||||||
printf("[WARNING] the debug library has been loaded!");
|
printf("[WARNING] the debug library has been loaded!\n");
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ void markRoots(CState *state) {
|
|||||||
markObject(state, (CObj*)upvalue);
|
markObject(state, (CObj*)upvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
markTable(state, &state->globals);
|
markObject(state, (CObj*)state->globals);
|
||||||
|
|
||||||
// mark all internal strings
|
// mark all internal strings
|
||||||
for (int i = 0; i < ISTRING_MAX; i++)
|
for (int i = 0; i < ISTRING_MAX; i++)
|
||||||
|
13
src/cobj.c
13
src/cobj.c
@ -442,6 +442,12 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
|||||||
CObjFunction *func = (CObjFunction*)obj;
|
CObjFunction *func = (CObjFunction*)obj;
|
||||||
return func->name != NULL ? func->name : cosmoO_copyString(state, UNNAMEDCHUNK, strlen(UNNAMEDCHUNK));
|
return func->name != NULL ? func->name : cosmoO_copyString(state, UNNAMEDCHUNK, strlen(UNNAMEDCHUNK));
|
||||||
}
|
}
|
||||||
|
case COBJ_CFUNCTION: {
|
||||||
|
CObjCFunction *cfunc = (CObjCFunction*)obj;
|
||||||
|
char buf[64];
|
||||||
|
int sz = sprintf(buf, "<c function> %p", (void*)cfunc->cfunc) + 1; // +1 for the null character
|
||||||
|
return cosmoO_copyString(state, buf, sz);
|
||||||
|
}
|
||||||
case COBJ_OBJECT: {
|
case COBJ_OBJECT: {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int sz = sprintf(buf, "<obj> %p", (void*)obj) + 1; // +1 for the null character
|
int sz = sprintf(buf, "<obj> %p", (void*)obj) + 1; // +1 for the null character
|
||||||
@ -456,8 +462,11 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) {
|
|||||||
int sz = sprintf(buf, "<tbl> %p", (void*)obj) + 1; // +1 for the null character
|
int sz = sprintf(buf, "<tbl> %p", (void*)obj) + 1; // +1 for the null character
|
||||||
return cosmoO_copyString(state, buf, sz);
|
return cosmoO_copyString(state, buf, sz);
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
return cosmoO_copyString(state, "<unkn obj>", 10);
|
char buf[64];
|
||||||
|
int sz = sprintf(buf, "<unkn obj> %p", (void*)obj) + 1; // +1 for the null character
|
||||||
|
return cosmoO_copyString(state, buf, sz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ typedef struct CObjCFunction CObjCFunction;
|
|||||||
typedef struct CObjMethod CObjMethod;
|
typedef struct CObjMethod CObjMethod;
|
||||||
typedef struct CObjError CObjError;
|
typedef struct CObjError CObjError;
|
||||||
typedef struct CObjObject CObjObject;
|
typedef struct CObjObject CObjObject;
|
||||||
|
typedef struct CObjTable CObjTable;
|
||||||
typedef struct CObjClosure CObjClosure;
|
typedef struct CObjClosure CObjClosure;
|
||||||
|
|
||||||
typedef uint8_t INSTRUCTION;
|
typedef uint8_t INSTRUCTION;
|
||||||
|
@ -42,7 +42,8 @@ CState *cosmoV_newState() {
|
|||||||
state->iStrings[i] = NULL;
|
state->iStrings[i] = NULL;
|
||||||
|
|
||||||
cosmoT_initTable(state, &state->strings, 16); // init string table
|
cosmoT_initTable(state, &state->strings, 16); // init string table
|
||||||
cosmoT_initTable(state, &state->globals, 8); // init global table
|
|
||||||
|
state->globals = cosmoO_newTable(state); // init global table
|
||||||
|
|
||||||
// setup all strings used by the VM
|
// setup all strings used by the VM
|
||||||
state->iStrings[ISTRING_INIT] = cosmoO_copyString(state, "__init", 6);
|
state->iStrings[ISTRING_INIT] = cosmoO_copyString(state, "__init", 6);
|
||||||
@ -89,9 +90,8 @@ void cosmoV_freeState(CState *state) {
|
|||||||
for (int i = 0; i < ISTRING_MAX; i++)
|
for (int i = 0; i < ISTRING_MAX; i++)
|
||||||
state->iStrings[i] = NULL;
|
state->iStrings[i] = NULL;
|
||||||
|
|
||||||
// free our string & global table (the string table includes the internal VM strings)
|
// free our string table (the string table includes the internal VM strings)
|
||||||
cosmoT_clearTable(state, &state->strings);
|
cosmoT_clearTable(state, &state->strings);
|
||||||
cosmoT_clearTable(state, &state->globals);
|
|
||||||
|
|
||||||
// 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);
|
||||||
@ -112,7 +112,7 @@ void cosmoV_register(CState *state, int pairs) {
|
|||||||
StkPtr key = cosmoV_getTop(state, 1);
|
StkPtr key = cosmoV_getTop(state, 1);
|
||||||
StkPtr val = cosmoV_getTop(state, 0);
|
StkPtr val = cosmoV_getTop(state, 0);
|
||||||
|
|
||||||
CValue *oldVal = cosmoT_insert(state, &state->globals, *key);
|
CValue *oldVal = cosmoT_insert(state, &state->globals->tbl, *key);
|
||||||
*oldVal = *val;
|
*oldVal = *val;
|
||||||
|
|
||||||
cosmoV_setTop(state, 2); // pops the 2 values off the stack
|
cosmoV_setTop(state, 2); // pops the 2 values off the stack
|
||||||
|
@ -47,7 +47,7 @@ typedef struct CState {
|
|||||||
|
|
||||||
CObjUpval *openUpvalues; // tracks all of our still open (meaning still on the stack) upvalues
|
CObjUpval *openUpvalues; // tracks all of our still open (meaning still on the stack) upvalues
|
||||||
CTable strings;
|
CTable strings;
|
||||||
CTable globals;
|
CObjTable *globals;
|
||||||
|
|
||||||
CValue *top; // top of the stack
|
CValue *top; // top of the stack
|
||||||
CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto]
|
CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto]
|
||||||
|
11
src/cvm.c
11
src/cvm.c
@ -303,7 +303,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
printIndent(state->frameCount - 1);
|
printIndent(state->frameCount - 1);
|
||||||
printValue(func);
|
printValue(func);
|
||||||
printf("()\n");
|
printf("(%d args)\n", args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!IS_OBJ(func)) {
|
if (!IS_OBJ(func)) {
|
||||||
@ -533,7 +533,7 @@ int _tbl__next(CState *state, int nargs, CValue *args) {
|
|||||||
} while (IS_NIL(entry->key) && index < cap);
|
} while (IS_NIL(entry->key) && index < cap);
|
||||||
cosmoO_setUserI(state, obj, index); // update the userdata
|
cosmoO_setUserI(state, obj, index); // update the userdata
|
||||||
|
|
||||||
if (!IS_NIL(entry->key)) { // if the entry is valid, return it's key and value pair
|
if (index < cap && !IS_NIL(entry->key)) { // if the entry is valid, return it's key and value pair
|
||||||
cosmoV_pushValue(state, entry->key);
|
cosmoV_pushValue(state, entry->key);
|
||||||
cosmoV_pushValue(state, entry->val);
|
cosmoV_pushValue(state, entry->val);
|
||||||
return 2; // we pushed 2 values onto the stack for the return values
|
return 2; // we pushed 2 values onto the stack for the return values
|
||||||
@ -563,6 +563,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
|
|
||||||
while (!state->panic) {
|
while (!state->panic) {
|
||||||
#ifdef VM_DEBUG
|
#ifdef VM_DEBUG
|
||||||
|
cosmoV_printStack(state);
|
||||||
disasmInstr(&frame->closure->function->chunk, frame->pc - frame->closure->function->chunk.buf, state->frameCount - 1);
|
disasmInstr(&frame->closure->function->chunk, frame->pc - frame->closure->function->chunk.buf, state->frameCount - 1);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
@ -575,7 +576,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
case OP_SETGLOBAL: {
|
case OP_SETGLOBAL: {
|
||||||
uint16_t indx = READUINT();
|
uint16_t indx = READUINT();
|
||||||
CValue ident = constants[indx]; // grabs identifier
|
CValue ident = constants[indx]; // grabs identifier
|
||||||
CValue *val = cosmoT_insert(state, &state->globals, ident);
|
CValue *val = cosmoT_insert(state, &state->globals->tbl, ident);
|
||||||
*val = *cosmoV_pop(state); // sets the value in the hash table
|
*val = *cosmoV_pop(state); // sets the value in the hash table
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -583,7 +584,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
uint16_t indx = READUINT();
|
uint16_t indx = READUINT();
|
||||||
CValue ident = constants[indx]; // grabs identifier
|
CValue ident = constants[indx]; // grabs identifier
|
||||||
CValue val; // to hold our value
|
CValue val; // to hold our value
|
||||||
cosmoT_get(&state->globals, ident, &val);
|
cosmoT_get(&state->globals->tbl, ident, &val);
|
||||||
cosmoV_pushValue(state, val); // pushes the value to the stack
|
cosmoV_pushValue(state, val); // pushes the value to the stack
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1003,7 +1004,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
int8_t inc = READBYTE() - 128; // amount we're incrementing by
|
int8_t inc = READBYTE() - 128; // amount we're incrementing by
|
||||||
uint16_t indx = READUINT();
|
uint16_t indx = READUINT();
|
||||||
CValue ident = constants[indx]; // grabs identifier
|
CValue ident = constants[indx]; // grabs identifier
|
||||||
CValue *val = cosmoT_insert(state, &state->globals, ident);
|
CValue *val = cosmoT_insert(state, &state->globals->tbl, ident);
|
||||||
|
|
||||||
// check that it's a number value
|
// check that it's a number value
|
||||||
if (IS_NUMBER(*val)) {
|
if (IS_NUMBER(*val)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user