Fixed table iteration bug, added vm.globals to debug lib

This commit is contained in:
CPunch 2021-01-25 16:14:51 -06:00
parent cd6744ab65
commit cff26574bb
7 changed files with 73 additions and 17 deletions

View File

@ -338,14 +338,41 @@ int cosmoB_dgetProto(CState *state, int nargs, CValue *args) {
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) {
if (nargs != 2) {
cosmoV_error(state, "Expected 2 argument, got %d!", nargs);
cosmoV_error(state, "Expected 2 arguments, got %d!", nargs);
return 0;
}
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;
}
@ -410,6 +437,7 @@ void cosmoB_loadDebug(CState *state) {
// set debug protos to the debug object
cosmoV_registerProtoObject(state, COBJ_OBJECT, obj);
cosmoV_pop(state); // pops the debug object
// make vm.* object
cosmoV_pushString(state, "vm");
@ -424,10 +452,27 @@ void cosmoB_loadDebug(CState *state) {
cosmoV_pushCFunction(state, cosmoB_vnewindexBProto);
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
cosmoV_register(state, 1);
printf("[WARNING] the debug library has been loaded!");
printf("[WARNING] the debug library has been loaded!\n");
}

View File

@ -235,7 +235,7 @@ void markRoots(CState *state) {
markObject(state, (CObj*)upvalue);
}
markTable(state, &state->globals);
markObject(state, (CObj*)state->globals);
// mark all internal strings
for (int i = 0; i < ISTRING_MAX; i++)

View File

@ -442,6 +442,12 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) {
CObjFunction *func = (CObjFunction*)obj;
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: {
char buf[64];
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
return cosmoO_copyString(state, buf, sz);
}
default:
return cosmoO_copyString(state, "<unkn obj>", 10);
default: {
char buf[64];
int sz = sprintf(buf, "<unkn obj> %p", (void*)obj) + 1; // +1 for the null character
return cosmoO_copyString(state, buf, sz);
}
}
}

View File

@ -38,6 +38,7 @@ typedef struct CObjCFunction CObjCFunction;
typedef struct CObjMethod CObjMethod;
typedef struct CObjError CObjError;
typedef struct CObjObject CObjObject;
typedef struct CObjTable CObjTable;
typedef struct CObjClosure CObjClosure;
typedef uint8_t INSTRUCTION;

View File

@ -42,7 +42,8 @@ CState *cosmoV_newState() {
state->iStrings[i] = NULL;
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
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++)
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->globals);
// free our gray stack & finally free the state structure
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 val = cosmoV_getTop(state, 0);
CValue *oldVal = cosmoT_insert(state, &state->globals, *key);
CValue *oldVal = cosmoT_insert(state, &state->globals->tbl, *key);
*oldVal = *val;
cosmoV_setTop(state, 2); // pops the 2 values off the stack

View File

@ -47,7 +47,7 @@ typedef struct CState {
CObjUpval *openUpvalues; // tracks all of our still open (meaning still on the stack) upvalues
CTable strings;
CTable globals;
CObjTable *globals;
CValue *top; // top of the stack
CObjObject *protoObjects[COBJ_MAX]; // proto object for each COBJ type [NULL = no default proto]

View File

@ -303,7 +303,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
printf("\n");
printIndent(state->frameCount - 1);
printValue(func);
printf("()\n");
printf("(%d args)\n", args);
#endif
if (!IS_OBJ(func)) {
@ -533,7 +533,7 @@ int _tbl__next(CState *state, int nargs, CValue *args) {
} while (IS_NIL(entry->key) && index < cap);
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->val);
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) {
#ifdef VM_DEBUG
cosmoV_printStack(state);
disasmInstr(&frame->closure->function->chunk, frame->pc - frame->closure->function->chunk.buf, state->frameCount - 1);
printf("\n");
#endif
@ -575,7 +576,7 @@ int cosmoV_execute(CState *state) {
case OP_SETGLOBAL: {
uint16_t indx = READUINT();
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
continue;
}
@ -583,7 +584,7 @@ int cosmoV_execute(CState *state) {
uint16_t indx = READUINT();
CValue ident = constants[indx]; // grabs identifier
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
continue;
}
@ -1003,7 +1004,7 @@ int cosmoV_execute(CState *state) {
int8_t inc = READBYTE() - 128; // amount we're incrementing by
uint16_t indx = READUINT();
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
if (IS_NUMBER(*val)) {