mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 00:00:10 +00:00
Minor CObj* refactor, added cosmoO_lock and cosmoO_unlock
- cosmoO_getUser* and cosmoO_setUser* no longer take the `CState*` argument - if a set is performed on a locked object an error is thrown
This commit is contained in:
parent
8151cde6f3
commit
5faa40bdef
@ -223,6 +223,7 @@ COSMO_API void cosmoB_loadObjLib(CState *state) {
|
||||
|
||||
// make the object and set the protoobject for all runtime-allocated objects
|
||||
CObjObject *obj = cosmoV_makeObject(state, i + 2); // + 2 for the getter/setter tables
|
||||
cosmoO_lock(obj); // lock so pesky people don't mess with it (feel free to remove if debugging)
|
||||
cosmoV_registerProtoObject(state, COBJ_OBJECT, obj);
|
||||
|
||||
// register "object" to the global table
|
||||
@ -431,6 +432,7 @@ void cosmoB_loadStrLib(CState *state) {
|
||||
|
||||
// make the object and set the protoobject for all strings
|
||||
CObjObject *obj = cosmoV_makeObject(state, i);
|
||||
cosmoO_lock(obj); // lock so pesky people don't mess with it (feel free to remove if debugging)
|
||||
cosmoV_registerProtoObject(state, COBJ_STRING, obj);
|
||||
|
||||
// register "string" to the global table
|
||||
|
34
src/cobj.c
34
src/cobj.c
@ -114,6 +114,8 @@ CObjObject *cosmoO_newObject(CState *state) {
|
||||
CObjObject *obj = (CObjObject*)cosmoO_allocateBase(state, sizeof(CObjObject), COBJ_OBJECT);
|
||||
obj->istringFlags = 0;
|
||||
obj->userP = NULL; // reserved for C API
|
||||
obj->userT = 0;
|
||||
obj->isLocked = false;
|
||||
cosmoV_pushObj(state, (CObj*)obj); // so our GC can keep track of it
|
||||
cosmoT_initTable(state, &obj->tbl, ARRAY_START);
|
||||
cosmoV_pop(state);
|
||||
@ -332,7 +334,13 @@ bool cosmoO_getRawObject(CState *state, CObjObject *proto, CValue key, CValue *v
|
||||
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj) {
|
||||
CValue ret;
|
||||
|
||||
// first check for __setters
|
||||
// if the object is locked, throw an error
|
||||
if (proto->isLocked) {
|
||||
cosmoV_error(state, "Couldn't set on a locked object!");
|
||||
return;
|
||||
}
|
||||
|
||||
// check for __setters
|
||||
if (cosmoO_getIString(state, proto, ISTRING_SETTER, &ret) && IS_TABLE(ret) && cosmoT_get(&cosmoV_readTable(ret)->tbl, key, &ret)) {
|
||||
cosmoV_pushValue(state, ret); // push function
|
||||
cosmoV_pushObj(state, (CObj*)obj); // push object
|
||||
@ -353,22 +361,38 @@ void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue va
|
||||
}
|
||||
}
|
||||
|
||||
void cosmoO_setUserP(CState *state, CObjObject *object, void *p) {
|
||||
void cosmoO_setUserP(CObjObject *object, void *p) {
|
||||
object->userP = p;
|
||||
}
|
||||
|
||||
void *cosmoO_getUserP(CState *state, CObjObject *object) {
|
||||
void *cosmoO_getUserP(CObjObject *object) {
|
||||
return object->userP;
|
||||
}
|
||||
|
||||
void cosmoO_setUserI(CState *state, CObjObject *object, int i) {
|
||||
void cosmoO_setUserI(CObjObject *object, int i) {
|
||||
object->userI = i;
|
||||
}
|
||||
|
||||
int cosmoO_getUserI(CState *state, CObjObject *object) {
|
||||
int cosmoO_getUserI(CObjObject *object) {
|
||||
return object->userI;
|
||||
}
|
||||
|
||||
void cosmoO_setUserT(CObjObject *object, int t) {
|
||||
object->userT = t;
|
||||
}
|
||||
|
||||
int cosmoO_getUserT(CObjObject *object) {
|
||||
return object->userT;
|
||||
}
|
||||
|
||||
void cosmoO_lock(CObjObject *object) {
|
||||
object->isLocked = true;
|
||||
}
|
||||
|
||||
void cosmoO_unlock(CObjObject *object) {
|
||||
object->isLocked = false;
|
||||
}
|
||||
|
||||
bool rawgetIString(CState *state, CObjObject *object, int flag, CValue *val) {
|
||||
if (readFlag(object->istringFlags, flag))
|
||||
return false; // it's been cached as bad
|
||||
|
46
src/cobj.h
46
src/cobj.h
@ -33,38 +33,40 @@ typedef uint32_t cosmo_Flag;
|
||||
typedef int (*CosmoCFunction)(CState *state, int argCount, CValue *args);
|
||||
|
||||
typedef struct CObj {
|
||||
CObjType type;
|
||||
bool isMarked; // for the GC
|
||||
struct CObj *next;
|
||||
struct CObj *nextRoot; // for the root linked list
|
||||
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
||||
CObjType type;
|
||||
bool isMarked; // for the GC
|
||||
} CObj;
|
||||
|
||||
typedef struct CObjString {
|
||||
CommonHeader; // "is a" CObj
|
||||
bool isIString;
|
||||
int length;
|
||||
char *str; // NULL termincated string
|
||||
uint32_t hash; // for hashtable lookup
|
||||
int length;
|
||||
bool isIString;
|
||||
} CObjString;
|
||||
|
||||
typedef struct CObjError {
|
||||
CommonHeader; // "is a" CObj
|
||||
bool parserError; // if true, cosmoV_printError will format the error to the lexer
|
||||
int frameCount;
|
||||
int line; // reserved for parser errors
|
||||
CValue err; // error string
|
||||
CCallFrame *frames;
|
||||
int frameCount;
|
||||
int line; // reserved for parser errors
|
||||
bool parserError; // if true, cosmoV_printError will format the error to the lexer
|
||||
} CObjError;
|
||||
|
||||
typedef struct CObjObject {
|
||||
CommonHeader; // "is a" CObj
|
||||
cosmo_Flag istringFlags; // enables us to have a much faster lookup for reserved IStrings (like __init, __index, etc.)
|
||||
CTable tbl;
|
||||
cosmo_Flag istringFlags; // enables us to have a much faster lookup for reserved IStrings (like __init, __index, etc.)
|
||||
union { // userdata (NULL by default)
|
||||
void *userP;
|
||||
int userI;
|
||||
};
|
||||
int userT; // user-defined type (for describing the userdata pointer/integer)
|
||||
bool isLocked;
|
||||
} CObjObject;
|
||||
|
||||
typedef struct CObjTable { // table, a wrapper for CTable
|
||||
@ -75,11 +77,11 @@ typedef struct CObjTable { // table, a wrapper for CTable
|
||||
typedef struct CObjFunction {
|
||||
CommonHeader; // "is a" CObj
|
||||
CChunk chunk;
|
||||
CObjString *name;
|
||||
CObjString *module; // name of the "module"
|
||||
int args;
|
||||
int upvals;
|
||||
bool variadic;
|
||||
CObjString *name;
|
||||
CObjString *module; // name of the "module"
|
||||
} CObjFunction;
|
||||
|
||||
typedef struct CObjCFunction {
|
||||
@ -96,14 +98,14 @@ typedef struct CObjClosure {
|
||||
|
||||
typedef struct CObjMethod {
|
||||
CommonHeader; // "is a " CObj
|
||||
CObj *obj; // obj this method is bound too
|
||||
CValue func;
|
||||
CObj *obj; // obj this method is bound too
|
||||
} CObjMethod;
|
||||
|
||||
typedef struct CObjUpval {
|
||||
CommonHeader; // "is a" CObj
|
||||
CValue *val;
|
||||
CValue closed;
|
||||
CValue *val;
|
||||
struct CObjUpval *next;
|
||||
} CObjUpval;
|
||||
|
||||
@ -161,10 +163,22 @@ void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue va
|
||||
bool cosmoO_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||
bool cosmoO_newIndexObject(CState *state, CObjObject *object, CValue key, CValue val);
|
||||
|
||||
void cosmoO_setUserP(CState *state, CObjObject *object, void *p);
|
||||
void *cosmoO_getUserP(CState *state, CObjObject *object);
|
||||
void cosmoO_setUserI(CState *state, CObjObject *object, int i);
|
||||
int cosmoO_getUserI(CState *state, CObjObject *object);
|
||||
// sets the user-defined pointer, if a user-define integer is already defined it will be over written
|
||||
void cosmoO_setUserP(CObjObject *object, void *p);
|
||||
// gets the user-defined pointer
|
||||
void *cosmoO_getUserP(CObjObject *object);
|
||||
// sets the user-defined integer, if a user-define pointer is already defined it will be over written
|
||||
void cosmoO_setUserI(CObjObject *object, int i);
|
||||
// gets the user-defined integer
|
||||
int cosmoO_getUserI(CObjObject *object);
|
||||
// sets the user-defined type
|
||||
void cosmoO_setUserT(CObjObject *object, int t);
|
||||
// gets the user type
|
||||
int cosmoO_getUserT(CObjObject *object);
|
||||
// locks the object
|
||||
void cosmoO_lock(CObjObject *object);
|
||||
// unlocks the object
|
||||
void cosmoO_unlock(CObjObject *object);
|
||||
|
||||
// internal string
|
||||
bool cosmoO_getIString(CState *state, CObjObject *object, int flag, CValue *val);
|
||||
|
@ -514,7 +514,7 @@ int _tbl__next(CState *state, int nargs, CValue *args) {
|
||||
}
|
||||
|
||||
CObjObject *obj = cosmoV_readObject(args[0]);
|
||||
int index = cosmoO_getUserI(state, obj); // we store the index in the userdata
|
||||
int index = cosmoO_getUserI(obj); // we store the index in the userdata
|
||||
CValue val;
|
||||
|
||||
cosmoO_getIString(state, obj, ISTRING_RESERVED, &val);
|
||||
@ -531,7 +531,7 @@ int _tbl__next(CState *state, int nargs, CValue *args) {
|
||||
do {
|
||||
entry = &table->tbl.table[index++];
|
||||
} while (IS_NIL(entry->key) && index < cap);
|
||||
cosmoO_setUserI(state, obj, index); // update the userdata
|
||||
cosmoO_setUserI(obj, index); // update the userdata
|
||||
|
||||
if (index < cap && !IS_NIL(entry->key)) { // if the entry is valid, return it's key and value pair
|
||||
cosmoV_pushValue(state, entry->key);
|
||||
@ -887,7 +887,7 @@ int cosmoV_execute(CState *state) {
|
||||
cosmoV_pushObj(state, (CObj*)tbl_next); // value
|
||||
|
||||
CObjObject *obj = cosmoV_makeObject(state, 2); // pushes the new object to the stack
|
||||
cosmoO_setUserI(state, obj, 0); // increment for iterator
|
||||
cosmoO_setUserI(obj, 0); // increment for iterator
|
||||
|
||||
// make our CObjMethod for OP_NEXT to call
|
||||
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(tbl_next), (CObj*)obj);
|
||||
|
Loading…
Reference in New Issue
Block a user