1 /* see copyright notice in squirrel.h */ 2 #ifndef _SQOBJECT_H_ 3 #define _SQOBJECT_H_ 4 5 #include "squtils.h" 6 7 #define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R')) 8 #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T')) 9 #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L')) 10 11 struct SQSharedState; 12 13 enum SQMetaMethod{ 14 MT_ADD=0, 15 MT_SUB=1, 16 MT_MUL=2, 17 MT_DIV=3, 18 MT_UNM=4, 19 MT_MODULO=5, 20 MT_SET=6, 21 MT_GET=7, 22 MT_TYPEOF=8, 23 MT_NEXTI=9, 24 MT_CMP=10, 25 MT_CALL=11, 26 MT_CLONED=12, 27 MT_NEWSLOT=13, 28 MT_DELSLOT=14, 29 MT_TOSTRING=15, 30 MT_LAST = 16, 31 }; 32 33 #define MM_ADD _SC("_add") 34 #define MM_SUB _SC("_sub") 35 #define MM_MUL _SC("_mul") 36 #define MM_DIV _SC("_div") 37 #define MM_UNM _SC("_unm") 38 #define MM_MODULO _SC("_modulo") 39 #define MM_SET _SC("_set") 40 #define MM_GET _SC("_get") 41 #define MM_TYPEOF _SC("_typeof") 42 #define MM_NEXTI _SC("_nexti") 43 #define MM_CMP _SC("_cmp") 44 #define MM_CALL _SC("_call") 45 #define MM_CLONED _SC("_cloned") 46 #define MM_NEWSLOT _SC("_newslot") 47 #define MM_DELSLOT _SC("_delslot") 48 #define MM_TOSTRING _SC("_tostring") 49 50 #define MINPOWER2 4 51 52 struct SQRefCounted 53 { SQRefCountedSQRefCounted54 SQRefCounted() { _uiRef = 0; _weakref = NULL; } 55 virtual ~SQRefCounted(); 56 SQWeakRef *GetWeakRef(SQObjectType type); 57 SQUnsignedInteger _uiRef; 58 struct SQWeakRef *_weakref; 59 virtual void Release()=0; 60 }; 61 62 struct SQWeakRef : SQRefCounted 63 { ~SQWeakRefSQWeakRef64 virtual ~SQWeakRef() {} 65 void Release(); 66 SQObject _obj; 67 }; 68 69 #define _realval(o) (squirrel_type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj) 70 71 struct SQObjectPtr; 72 73 #define __AddRef(type,unval) if(ISREFCOUNTED(type)) \ 74 { \ 75 unval.pRefCounted->_uiRef++; \ 76 } 77 78 #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \ 79 { \ 80 unval.pRefCounted->Release(); \ 81 } 82 83 #define __ObjRelease(obj) { \ 84 if((obj)) { \ 85 (obj)->_uiRef--; \ 86 if((obj)->_uiRef == 0) \ 87 (obj)->Release(); \ 88 (obj) = NULL; \ 89 } \ 90 } 91 92 #define __ObjAddRef(obj) { \ 93 (obj)->_uiRef++; \ 94 } 95 96 #define squirrel_type(obj) ((obj)._type) 97 #define is_delegable(t) (squirrel_type(t)&SQOBJECT_DELEGABLE) 98 #define raw_type(obj) _RAW_TYPE((obj)._type) 99 100 #define _integer(obj) ((obj)._unVal.nInteger) 101 #define _float(obj) ((obj)._unVal.fFloat) 102 #define _string(obj) ((obj)._unVal.pString) 103 #define _table(obj) ((obj)._unVal.pTable) 104 #define _array(obj) ((obj)._unVal.pArray) 105 #define _closure(obj) ((obj)._unVal.pClosure) 106 #define _generator(obj) ((obj)._unVal.pGenerator) 107 #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) 108 #define _userdata(obj) ((obj)._unVal.pUserData) 109 #define _userpointer(obj) ((obj)._unVal.pUserPointer) 110 #define _thread(obj) ((obj)._unVal.pThread) 111 #define _funcproto(obj) ((obj)._unVal.pFunctionProto) 112 #define _class(obj) ((obj)._unVal.pClass) 113 #define _instance(obj) ((obj)._unVal.pInstance) 114 #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) 115 #define _weakref(obj) ((obj)._unVal.pWeakRef) 116 #define _refcounted(obj) ((obj)._unVal.pRefCounted) 117 #define _rawval(obj) ((obj)._unVal.pRefCounted) 118 119 #define _stringval(obj) (obj)._unVal.pString->_val 120 #define _userdataval(obj) (obj)._unVal.pUserData->_val 121 122 #define tofloat(num) ((squirrel_type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num)) 123 #define tointeger(num) ((squirrel_type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num)) 124 ///////////////////////////////////////////////////////////////////////////////////// 125 ///////////////////////////////////////////////////////////////////////////////////// 126 struct SQObjectPtr : public SQObject 127 { SQObjectPtrSQObjectPtr128 SQObjectPtr() 129 { 130 _type=OT_NULL; 131 _unVal.pUserPointer=NULL; 132 } SQObjectPtrSQObjectPtr133 SQObjectPtr(const SQObjectPtr &o) 134 { 135 _type=o._type; 136 _unVal=o._unVal; 137 __AddRef(_type,_unVal); 138 } SQObjectPtrSQObjectPtr139 SQObjectPtr(const SQObject &o) 140 { 141 _type=o._type; 142 _unVal=o._unVal; 143 __AddRef(_type,_unVal); 144 } SQObjectPtrSQObjectPtr145 SQObjectPtr(SQTable *pTable) 146 { 147 _type=OT_TABLE; 148 _unVal.pTable=pTable; 149 assert(_unVal.pTable); 150 __AddRef(_type,_unVal); 151 } SQObjectPtrSQObjectPtr152 SQObjectPtr(SQClass *pClass) 153 { 154 _type=OT_CLASS; 155 _unVal.pClass=pClass; 156 assert(_unVal.pClass); 157 __AddRef(_type,_unVal); 158 } SQObjectPtrSQObjectPtr159 SQObjectPtr(SQInstance *pInstance) 160 { 161 _type=OT_INSTANCE; 162 _unVal.pInstance=pInstance; 163 assert(_unVal.pInstance); 164 __AddRef(_type,_unVal); 165 } SQObjectPtrSQObjectPtr166 SQObjectPtr(SQArray *pArray) 167 { 168 _type=OT_ARRAY; 169 _unVal.pArray=pArray; 170 assert(_unVal.pArray); 171 __AddRef(_type,_unVal); 172 } SQObjectPtrSQObjectPtr173 SQObjectPtr(SQClosure *pClosure) 174 { 175 _type=OT_CLOSURE; 176 _unVal.pClosure=pClosure; 177 assert(_unVal.pClosure); 178 __AddRef(_type,_unVal); 179 } SQObjectPtrSQObjectPtr180 SQObjectPtr(SQGenerator *pGenerator) 181 { 182 _type=OT_GENERATOR; 183 _unVal.pGenerator=pGenerator; 184 assert(_unVal.pGenerator); 185 __AddRef(_type,_unVal); 186 } SQObjectPtrSQObjectPtr187 SQObjectPtr(SQNativeClosure *pNativeClosure) 188 { 189 _type=OT_NATIVECLOSURE; 190 _unVal.pNativeClosure=pNativeClosure; 191 assert(_unVal.pNativeClosure); 192 __AddRef(_type,_unVal); 193 } SQObjectPtrSQObjectPtr194 SQObjectPtr(SQString *pString) 195 { 196 _type=OT_STRING; 197 _unVal.pString=pString; 198 assert(_unVal.pString); 199 __AddRef(_type,_unVal); 200 } SQObjectPtrSQObjectPtr201 SQObjectPtr(SQUserData *pUserData) 202 { 203 _type=OT_USERDATA; 204 _unVal.pUserData=pUserData; 205 assert(_unVal.pUserData); 206 __AddRef(_type,_unVal); 207 } SQObjectPtrSQObjectPtr208 SQObjectPtr(SQVM *pThread) 209 { 210 _type=OT_THREAD; 211 _unVal.pThread=pThread; 212 assert(_unVal.pThread); 213 __AddRef(_type,_unVal); 214 } SQObjectPtrSQObjectPtr215 SQObjectPtr(SQWeakRef *pWeakRef) 216 { 217 _type=OT_WEAKREF; 218 _unVal.pWeakRef=pWeakRef; 219 assert(_unVal.pWeakRef); 220 __AddRef(_type,_unVal); 221 } SQObjectPtrSQObjectPtr222 SQObjectPtr(SQFunctionProto *pFunctionProto) 223 { 224 _type=OT_FUNCPROTO; 225 _unVal.pFunctionProto=pFunctionProto; 226 assert(_unVal.pFunctionProto); 227 __AddRef(_type,_unVal); 228 } SQObjectPtrSQObjectPtr229 SQObjectPtr(SQInteger nInteger) 230 { 231 _unVal.pUserPointer=NULL; 232 _type=OT_INTEGER; 233 _unVal.nInteger=nInteger; 234 } SQObjectPtrSQObjectPtr235 SQObjectPtr(SQFloat fFloat) 236 { 237 _unVal.pUserPointer=NULL; 238 _type=OT_FLOAT; 239 _unVal.fFloat=fFloat; 240 } SQObjectPtrSQObjectPtr241 SQObjectPtr(bool bBool) 242 { 243 _unVal.pUserPointer=NULL; 244 _type = OT_BOOL; 245 _unVal.nInteger = bBool?1:0; 246 } SQObjectPtrSQObjectPtr247 SQObjectPtr(SQUserPointer pUserPointer) 248 { 249 _type=OT_USERPOINTER; 250 _unVal.pUserPointer=pUserPointer; 251 } ~SQObjectPtrSQObjectPtr252 ~SQObjectPtr() 253 { 254 __Release(_type,_unVal); 255 } NullSQObjectPtr256 inline void Null() 257 { 258 __Release(_type,_unVal); 259 _type=OT_NULL; 260 _unVal.pUserPointer=NULL; 261 } 262 inline SQObjectPtr& operator=(const SQObjectPtr& obj) 263 { 264 SQObjectType tOldType; 265 SQObjectValue unOldVal; 266 tOldType=_type; 267 unOldVal=_unVal; 268 _unVal = obj._unVal; 269 _type = obj._type; 270 __AddRef(_type,_unVal); 271 __Release(tOldType,unOldVal); 272 return *this; 273 } 274 inline SQObjectPtr& operator=(const SQObject& obj) 275 { 276 SQObjectType tOldType; 277 SQObjectValue unOldVal; 278 tOldType=_type; 279 unOldVal=_unVal; 280 _unVal = obj._unVal; 281 _type = obj._type; 282 __AddRef(_type,_unVal); 283 __Release(tOldType,unOldVal); 284 return *this; 285 } 286 private: SQObjectPtrSQObjectPtr287 SQObjectPtr(const SQChar *){} //safety 288 }; 289 ///////////////////////////////////////////////////////////////////////////////////// 290 #ifndef NO_GARBAGE_COLLECTOR 291 #define MARK_FLAG 0x80000000 292 struct SQCollectable : public SQRefCounted { 293 SQCollectable *_next; 294 SQCollectable *_prev; 295 SQSharedState *_sharedstate; ~SQCollectableSQCollectable296 virtual ~SQCollectable() {} 297 virtual void Release()=0; 298 virtual void Mark(SQCollectable **chain)=0; 299 void UnMark(); 300 virtual void Finalize()=0; 301 static void AddToChain(SQCollectable **chain,SQCollectable *c); 302 static void RemoveFromChain(SQCollectable **chain,SQCollectable *c); 303 }; 304 305 306 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj) 307 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);} 308 #define CHAINABLE_OBJ SQCollectable 309 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;} 310 #else 311 312 #define ADD_TO_CHAIN(chain,obj) ((void)0) 313 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0) 314 #define CHAINABLE_OBJ SQRefCounted 315 #define INIT_CHAIN() ((void)0) 316 #endif 317 318 struct SQDelegable : public CHAINABLE_OBJ { ~SQDelegableSQDelegable319 virtual ~SQDelegable() {} 320 bool SetDelegate(SQTable *m); 321 virtual bool GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res); 322 SQTable *_delegate; 323 }; 324 325 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); 326 typedef sqvector<SQObjectPtr> SQObjectPtrVec; 327 typedef sqvector<SQInteger> SQIntVec; 328 329 #endif //_SQOBJECT_H_ 330