Cosmo/src/cvm.h

143 lines
4.7 KiB
C
Raw Normal View History

2020-10-28 05:16:30 +00:00
#ifndef COSMOVM_H
#define COSMOVM_H
2020-11-12 23:17:41 +00:00
#include <string.h>
2020-10-28 05:16:30 +00:00
#include "cosmo.h"
#include "cstate.h"
//#define VM_DEBUG
2020-10-28 05:16:30 +00:00
typedef enum {
COSMOVM_OK,
COSMOVM_RUNTIME_ERR,
COSMOVM_BUILDTIME_ERR
} COSMOVMRESULT;
// args = # of pass parameters, nresults = # of expected results
COSMO_API COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults);
COSMO_API COSMOVMRESULT cosmoV_pcall(CState *state, int args, int nresults);
// pushes new object onto the stack & returns a pointer to the new object
COSMO_API CObjObject* cosmoV_makeObject(CState *state, int pairs);
COSMO_API void cosmoV_makeTable(CState *state, int pairs);
COSMO_API void cosmoV_concat(CState *state, int vals);
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...);
COSMO_API void cosmoV_printError(CState *state, CObjError *err);
COSMO_API CObjError* cosmoV_throw(CState *state);
2020-11-13 18:54:06 +00:00
COSMO_API void cosmoV_error(CState *state, const char *format, ...);
COSMO_API void cosmo_insert(CState *state, int indx, CValue val);
2020-11-12 23:17:41 +00:00
/*
Sets the default proto objects for the passed objType. Also walks through the object heap and updates protos
for the passed objType if that CObj* has no proto.
returns true if replacing a previously registered proto object for this type
*/
COSMO_API bool cosmoV_registerProtoObject(CState *state, CObjType objType, CObjObject *obj);
/*
compiles string into a <closure>, if successful, <closure> will be pushed onto the stack otherwise the <error> will be pushed.
returns:
false : <error> is at the top of the stack
true : <closure> is at the top of the stack
*/
COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *name);
/*
expects object to be pushed, then the key.
returns false if an error was thrown, returns true if the value was pushed onto the stack and the object and key were popped
*/
COSMO_API bool cosmoV_get(CState *state);
/*
expects object to be pushed, then the key, and finally the new value.
returns false if an error was thrown, returns true if the value was set and the object key, and value were popped
*/
COSMO_API bool cosmoV_set(CState *state);
// wraps the closure into a CObjMethod, so the function is called as an invoked method
COSMO_API bool cosmoV_getMethod(CState *state, CObj *obj, CValue key, CValue *val);
// clears the stack, callstack and restores the state into a usable state after a calloverflow or another hard to recover error
// (keeps the global table intact)
COSMO_API bool cosmoV_restore(CState *state);
2020-11-12 23:17:41 +00:00
// nice to have wrappers
// pushes a raw CValue to the stack, might throw an error if the stack is overflowed (with the SAFE_STACK macro on)
2021-01-02 01:20:24 +00:00
static inline void cosmoV_pushValue(CState *state, CValue val) {
2021-01-02 02:02:36 +00:00
#ifdef SAFE_STACK
2021-01-02 01:20:24 +00:00
ptrdiff_t stackSize = state->top - state->stack;
// we reserve 8 slots for the error string and whatever c api we might be in
if (stackSize >= STACK_MAX - 8) {
if (state->panic) { // we're in a panic state, let the 8 reserved slots be filled
if (stackSize < STACK_MAX)
*(state->top++) = val;
return;
}
cosmoV_error(state, "Stack overflow!");
return;
}
2021-01-02 02:02:36 +00:00
#endif
2021-01-02 01:20:24 +00:00
*(state->top++) = val;
}
// sets stack->top to stack->top - indx
static inline StkPtr cosmoV_setTop(CState *state, int indx) {
state->top -= indx;
return state->top;
}
// returns stack->top - indx - 1
static inline StkPtr cosmoV_getTop(CState *state, int indx) {
return &state->top[-(indx + 1)];
}
// pops 1 value off the stack, returns the popped value
2021-01-02 01:20:24 +00:00
static inline StkPtr cosmoV_pop(CState *state) {
return cosmoV_setTop(state, 1);
}
2020-11-12 23:17:41 +00:00
// 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));
}
static inline void cosmoV_pushRef(CState *state, CObj *obj) {
cosmoV_pushValue(state, cosmoV_newRef(obj));
}
2020-11-12 23:17:41 +00:00
// pushes a C Function to the stack
static inline void cosmoV_pushCFunction(CState *state, CosmoCFunction func) {
cosmoV_pushRef(state, (CObj*)cosmoO_newCFunction(state, func));
2020-11-12 23:17:41 +00:00
}
// len is the length of the string without the NULL terminator
2020-11-12 23:17:41 +00:00
static inline void cosmoV_pushLString(CState *state, const char *str, size_t len) {
cosmoV_pushRef(state, (CObj*)cosmoO_copyString(state, str, len));
2020-11-12 23:17:41 +00:00
}
// 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));
}
2020-10-28 05:16:30 +00:00
static inline void cosmoV_pushNil(CState *state) {
cosmoV_pushValue(state, cosmoV_newNil());
}
2021-01-02 05:06:24 +00:00
#endif