mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-24 16:11:04 +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
|
// 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
|
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);
|
cosmoV_registerProtoObject(state, COBJ_OBJECT, obj);
|
||||||
|
|
||||||
// register "object" to the global table
|
// 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
|
// make the object and set the protoobject for all strings
|
||||||
CObjObject *obj = cosmoV_makeObject(state, i);
|
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);
|
cosmoV_registerProtoObject(state, COBJ_STRING, obj);
|
||||||
|
|
||||||
// register "string" to the global table
|
// 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);
|
CObjObject *obj = (CObjObject*)cosmoO_allocateBase(state, sizeof(CObjObject), COBJ_OBJECT);
|
||||||
obj->istringFlags = 0;
|
obj->istringFlags = 0;
|
||||||
obj->userP = NULL; // reserved for C API
|
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
|
cosmoV_pushObj(state, (CObj*)obj); // so our GC can keep track of it
|
||||||
cosmoT_initTable(state, &obj->tbl, ARRAY_START);
|
cosmoT_initTable(state, &obj->tbl, ARRAY_START);
|
||||||
cosmoV_pop(state);
|
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) {
|
void cosmoO_setRawObject(CState *state, CObjObject *proto, CValue key, CValue val, CObj *obj) {
|
||||||
CValue ret;
|
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)) {
|
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_pushValue(state, ret); // push function
|
||||||
cosmoV_pushObj(state, (CObj*)obj); // push object
|
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;
|
object->userP = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *cosmoO_getUserP(CState *state, CObjObject *object) {
|
void *cosmoO_getUserP(CObjObject *object) {
|
||||||
return object->userP;
|
return object->userP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cosmoO_setUserI(CState *state, CObjObject *object, int i) {
|
void cosmoO_setUserI(CObjObject *object, int i) {
|
||||||
object->userI = i;
|
object->userI = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cosmoO_getUserI(CState *state, CObjObject *object) {
|
int cosmoO_getUserI(CObjObject *object) {
|
||||||
return object->userI;
|
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) {
|
bool rawgetIString(CState *state, CObjObject *object, int flag, CValue *val) {
|
||||||
if (readFlag(object->istringFlags, flag))
|
if (readFlag(object->istringFlags, flag))
|
||||||
return false; // it's been cached as bad
|
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 int (*CosmoCFunction)(CState *state, int argCount, CValue *args);
|
||||||
|
|
||||||
typedef struct CObj {
|
typedef struct CObj {
|
||||||
CObjType type;
|
|
||||||
bool isMarked; // for the GC
|
|
||||||
struct CObj *next;
|
struct CObj *next;
|
||||||
struct CObj *nextRoot; // for the root linked list
|
struct CObj *nextRoot; // for the root linked list
|
||||||
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
struct CObjObject *proto; // protoobject, describes the behavior of the object
|
||||||
|
CObjType type;
|
||||||
|
bool isMarked; // for the GC
|
||||||
} CObj;
|
} CObj;
|
||||||
|
|
||||||
typedef struct CObjString {
|
typedef struct CObjString {
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
bool isIString;
|
|
||||||
int length;
|
|
||||||
char *str; // NULL termincated string
|
char *str; // NULL termincated string
|
||||||
uint32_t hash; // for hashtable lookup
|
uint32_t hash; // for hashtable lookup
|
||||||
|
int length;
|
||||||
|
bool isIString;
|
||||||
} CObjString;
|
} CObjString;
|
||||||
|
|
||||||
typedef struct CObjError {
|
typedef struct CObjError {
|
||||||
CommonHeader; // "is a" CObj
|
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
|
CValue err; // error string
|
||||||
CCallFrame *frames;
|
CCallFrame *frames;
|
||||||
|
int frameCount;
|
||||||
|
int line; // reserved for parser errors
|
||||||
|
bool parserError; // if true, cosmoV_printError will format the error to the lexer
|
||||||
} CObjError;
|
} CObjError;
|
||||||
|
|
||||||
typedef struct CObjObject {
|
typedef struct CObjObject {
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
cosmo_Flag istringFlags; // enables us to have a much faster lookup for reserved IStrings (like __init, __index, etc.)
|
|
||||||
CTable tbl;
|
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)
|
union { // userdata (NULL by default)
|
||||||
void *userP;
|
void *userP;
|
||||||
int userI;
|
int userI;
|
||||||
};
|
};
|
||||||
|
int userT; // user-defined type (for describing the userdata pointer/integer)
|
||||||
|
bool isLocked;
|
||||||
} CObjObject;
|
} CObjObject;
|
||||||
|
|
||||||
typedef struct CObjTable { // table, a wrapper for CTable
|
typedef struct CObjTable { // table, a wrapper for CTable
|
||||||
@ -75,11 +77,11 @@ typedef struct CObjTable { // table, a wrapper for CTable
|
|||||||
typedef struct CObjFunction {
|
typedef struct CObjFunction {
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
CChunk chunk;
|
CChunk chunk;
|
||||||
|
CObjString *name;
|
||||||
|
CObjString *module; // name of the "module"
|
||||||
int args;
|
int args;
|
||||||
int upvals;
|
int upvals;
|
||||||
bool variadic;
|
bool variadic;
|
||||||
CObjString *name;
|
|
||||||
CObjString *module; // name of the "module"
|
|
||||||
} CObjFunction;
|
} CObjFunction;
|
||||||
|
|
||||||
typedef struct CObjCFunction {
|
typedef struct CObjCFunction {
|
||||||
@ -96,14 +98,14 @@ typedef struct CObjClosure {
|
|||||||
|
|
||||||
typedef struct CObjMethod {
|
typedef struct CObjMethod {
|
||||||
CommonHeader; // "is a " CObj
|
CommonHeader; // "is a " CObj
|
||||||
CObj *obj; // obj this method is bound too
|
|
||||||
CValue func;
|
CValue func;
|
||||||
|
CObj *obj; // obj this method is bound too
|
||||||
} CObjMethod;
|
} CObjMethod;
|
||||||
|
|
||||||
typedef struct CObjUpval {
|
typedef struct CObjUpval {
|
||||||
CommonHeader; // "is a" CObj
|
CommonHeader; // "is a" CObj
|
||||||
CValue *val;
|
|
||||||
CValue closed;
|
CValue closed;
|
||||||
|
CValue *val;
|
||||||
struct CObjUpval *next;
|
struct CObjUpval *next;
|
||||||
} CObjUpval;
|
} 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_indexObject(CState *state, CObjObject *object, CValue key, CValue *val);
|
||||||
bool cosmoO_newIndexObject(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);
|
// sets the user-defined pointer, if a user-define integer is already defined it will be over written
|
||||||
void *cosmoO_getUserP(CState *state, CObjObject *object);
|
void cosmoO_setUserP(CObjObject *object, void *p);
|
||||||
void cosmoO_setUserI(CState *state, CObjObject *object, int i);
|
// gets the user-defined pointer
|
||||||
int cosmoO_getUserI(CState *state, CObjObject *object);
|
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
|
// internal string
|
||||||
bool cosmoO_getIString(CState *state, CObjObject *object, int flag, CValue *val);
|
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]);
|
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;
|
CValue val;
|
||||||
|
|
||||||
cosmoO_getIString(state, obj, ISTRING_RESERVED, &val);
|
cosmoO_getIString(state, obj, ISTRING_RESERVED, &val);
|
||||||
@ -531,7 +531,7 @@ int _tbl__next(CState *state, int nargs, CValue *args) {
|
|||||||
do {
|
do {
|
||||||
entry = &table->tbl.table[index++];
|
entry = &table->tbl.table[index++];
|
||||||
} while (IS_NIL(entry->key) && index < cap);
|
} 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
|
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->key);
|
||||||
@ -887,7 +887,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoV_pushObj(state, (CObj*)tbl_next); // value
|
cosmoV_pushObj(state, (CObj*)tbl_next); // value
|
||||||
|
|
||||||
CObjObject *obj = cosmoV_makeObject(state, 2); // pushes the new object to the stack
|
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
|
// make our CObjMethod for OP_NEXT to call
|
||||||
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(tbl_next), (CObj*)obj);
|
CObjMethod *method = cosmoO_newMethod(state, cosmoV_newObj(tbl_next), (CObj*)obj);
|
||||||
|
Loading…
Reference in New Issue
Block a user