diff --git a/src/cbaselib.c b/src/cbaselib.c index b3d1cf4..a4247e5 100644 --- a/src/cbaselib.c +++ b/src/cbaselib.c @@ -1,4 +1,5 @@ #include "cbaselib.h" +#include "cvm.h" #include "cvalue.h" #include "cobj.h" #include "cmem.h" diff --git a/src/cvm.c b/src/cvm.c index b3c694f..fe934ad 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -243,6 +243,25 @@ static inline bool isFalsey(StkPtr val) { return val->type == COSMO_TNIL || (val->type == COSMO_TBOOLEAN && !val->val.b); } +COSMO_API void cosmoV_pushObject(CState *state, int pairs) { + StkPtr key, val; + CObjObject *newObj = cosmoO_newObject(state); // start the table with enough space to hopefully prevent reallocation since that's costly + cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new object + + for (int i = 0; i < pairs; i++) { + val = cosmoV_getTop(state, (i*2) + 1); + key = cosmoV_getTop(state, (i*2) + 2); + + // set key/value pair + CValue *newVal = cosmoT_insert(state, &newObj->tbl, *key); + *newVal = *val; + } + + // once done, pop everything off the stack + push new object + cosmoV_setTop(state, (pairs * 2) + 1); + cosmoV_pushValue(state, cosmoV_newObj(newObj)); +} + #define BINARYOP(typeConst, op) \ StkPtr valA = cosmoV_getTop(state, 1); \ StkPtr valB = cosmoV_getTop(state, 0); \ @@ -367,23 +386,8 @@ bool cosmoV_execute(CState *state) { break; } case OP_NEWOBJECT: { - uint8_t entries = READBYTE(); - StkPtr key, val; - CObjObject *newObj = cosmoO_newObject(state); // start the table with enough space to hopefully prevent reallocation since that's costly - cosmoV_pushValue(state, cosmoV_newObj(newObj)); // so our GC doesn't free our new object - - for (int i = 0; i < entries; i++) { - val = cosmoV_getTop(state, (i*2) + 1); - key = cosmoV_getTop(state, (i*2) + 2); - - // set key/value pair - CValue *newVal = cosmoT_insert(state, &newObj->tbl, *key); - *newVal = *val; - } - - // once done, pop everything off the stack + push new object - cosmoV_setTop(state, (entries * 2) + 1); - cosmoV_pushValue(state, cosmoV_newObj(newObj)); + uint8_t pairs = READBYTE(); + cosmoV_pushObject(state, pairs); break; } case OP_GETOBJECT: { diff --git a/src/cvm.h b/src/cvm.h index cd47006..b56f83e 100644 --- a/src/cvm.h +++ b/src/cvm.h @@ -1,6 +1,8 @@ #ifndef COSMOVM_H #define COSMOVM_H +#include + #include "cosmo.h" #include "cstate.h" @@ -12,5 +14,32 @@ typedef enum { // args = # of pass parameters, nresults = # of expected results COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args); +COSMO_API void cosmoV_pushObject(CState *state, int pairs); + +// nice to have wrappers + +// pushes a cosmo_Number to the stack +static inline void cosmoV_pushNumber(CState *state, cosmo_Number num) { + cosmoV_pushValue(state, cosmoV_newNumber(num)); +} + +// pushes a boolean to the stack +static inline void cosmoV_pushBoolean(CState *state, bool b) { + cosmoV_pushValue(state, cosmoV_newBoolean(b)); +} + +// pushes a C Function to the stack +static inline void cosmoV_pushCFunction(CState *state, CosmoCFunction func) { + cosmoV_pushValue(state, cosmoV_newObj(cosmoO_newCFunction(state, func))); +} + +static inline void cosmoV_pushLString(CState *state, const char *str, size_t len) { + cosmoV_pushValue(state, cosmoV_newObj(cosmoO_copyString(state, str, len))); +} + +// accepts a null terminated string and copys the buffer to the VM heap +static inline void cosmoV_pushString(CState *state, const char *str) { + cosmoV_pushLString(state, str, strlen(str)); +} #endif \ No newline at end of file