diff --git a/src/cbaselib.c b/src/cbaselib.c index 3a78301..8b72bdc 100644 --- a/src/cbaselib.c +++ b/src/cbaselib.c @@ -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", ", ", "%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", "", "%s", cosmoV_typeStr(args[0])); + cosmoV_typeError(state, "baseProtos.__index", ", ", "%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"); } diff --git a/src/cmem.c b/src/cmem.c index 0ed1141..4087d43 100644 --- a/src/cmem.c +++ b/src/cmem.c @@ -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++) diff --git a/src/cobj.c b/src/cobj.c index 2b13261..7430dc1 100644 --- a/src/cobj.c +++ b/src/cobj.c @@ -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, " %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, " %p", (void*)obj) + 1; // +1 for the null character @@ -456,8 +462,11 @@ CObjString *cosmoO_toString(CState *state, CObj *obj) { int sz = sprintf(buf, " %p", (void*)obj) + 1; // +1 for the null character return cosmoO_copyString(state, buf, sz); } - default: - return cosmoO_copyString(state, "", 10); + default: { + char buf[64]; + int sz = sprintf(buf, " %p", (void*)obj) + 1; // +1 for the null character + return cosmoO_copyString(state, buf, sz); + } } } diff --git a/src/cosmo.h b/src/cosmo.h index 664cc60..3385a40 100644 --- a/src/cosmo.h +++ b/src/cosmo.h @@ -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; diff --git a/src/cstate.c b/src/cstate.c index feb800d..5f60be2 100644 --- a/src/cstate.c +++ b/src/cstate.c @@ -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 diff --git a/src/cstate.h b/src/cstate.h index d3df773..ded8cae 100644 --- a/src/cstate.h +++ b/src/cstate.h @@ -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] diff --git a/src/cvm.c b/src/cvm.c index 667b746..b045f48 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -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)) {