00001
00002 #ifndef _SQOBJECT_H_
00003 #define _SQOBJECT_H_
00004
00005 #include "squtils.h"
00006
00007 #define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
00008 #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
00009 #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
00010
00011 struct SQSharedState;
00012
00013 enum SQMetaMethod{
00014 MT_ADD=0,
00015 MT_SUB=1,
00016 MT_MUL=2,
00017 MT_DIV=3,
00018 MT_UNM=4,
00019 MT_MODULO=5,
00020 MT_SET=6,
00021 MT_GET=7,
00022 MT_TYPEOF=8,
00023 MT_NEXTI=9,
00024 MT_CMP=10,
00025 MT_CALL=11,
00026 MT_CLONED=12,
00027 MT_NEWSLOT=13,
00028 MT_DELSLOT=14,
00029 MT_TOSTRING=15,
00030 MT_NEWMEMBER=16,
00031 MT_INHERITED=17,
00032 MT_LAST = 18
00033 };
00034
00035 #define MM_ADD _SC("_add")
00036 #define MM_SUB _SC("_sub")
00037 #define MM_MUL _SC("_mul")
00038 #define MM_DIV _SC("_div")
00039 #define MM_UNM _SC("_unm")
00040 #define MM_MODULO _SC("_modulo")
00041 #define MM_SET _SC("_set")
00042 #define MM_GET _SC("_get")
00043 #define MM_TYPEOF _SC("_typeof")
00044 #define MM_NEXTI _SC("_nexti")
00045 #define MM_CMP _SC("_cmp")
00046 #define MM_CALL _SC("_call")
00047 #define MM_CLONED _SC("_cloned")
00048 #define MM_NEWSLOT _SC("_newslot")
00049 #define MM_DELSLOT _SC("_delslot")
00050 #define MM_TOSTRING _SC("_tostring")
00051 #define MM_NEWMEMBER _SC("_newmember")
00052 #define MM_INHERITED _SC("_inherited")
00053
00054 #define MINPOWER2 4
00055
00056 struct SQRefCounted
00057 {
00058 SQRefCounted() { _uiRef = 0; _weakref = NULL; }
00059 virtual ~SQRefCounted();
00060 SQWeakRef *GetWeakRef(SQObjectType type);
00061 SQUnsignedInteger _uiRef;
00062 struct SQWeakRef *_weakref;
00063 virtual void Release()=0;
00064 };
00065
00066 struct SQWeakRef : SQRefCounted
00067 {
00068 void Release();
00069 SQObject _obj;
00070 };
00071
00072 #define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
00073
00074 struct SQObjectPtr;
00075
00076 #define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
00077 { \
00078 unval.pRefCounted->_uiRef++; \
00079 }
00080
00081 #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \
00082 { \
00083 unval.pRefCounted->Release(); \
00084 }
00085
00086 #define __ObjRelease(obj) { \
00087 if((obj)) { \
00088 (obj)->_uiRef--; \
00089 if((obj)->_uiRef == 0) \
00090 (obj)->Release(); \
00091 (obj) = NULL; \
00092 } \
00093 }
00094
00095 #define __ObjAddRef(obj) { \
00096 (obj)->_uiRef++; \
00097 }
00098
00099 #define type(obj) ((obj)._type)
00100 #define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
00101 #define raw_type(obj) _RAW_TYPE((obj)._type)
00102
00103 #define _integer(obj) ((obj)._unVal.nInteger)
00104 #define _float(obj) ((obj)._unVal.fFloat)
00105 #define _string(obj) ((obj)._unVal.pString)
00106 #define _table(obj) ((obj)._unVal.pTable)
00107 #define _array(obj) ((obj)._unVal.pArray)
00108 #define _closure(obj) ((obj)._unVal.pClosure)
00109 #define _generator(obj) ((obj)._unVal.pGenerator)
00110 #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
00111 #define _userdata(obj) ((obj)._unVal.pUserData)
00112 #define _userpointer(obj) ((obj)._unVal.pUserPointer)
00113 #define _thread(obj) ((obj)._unVal.pThread)
00114 #define _funcproto(obj) ((obj)._unVal.pFunctionProto)
00115 #define _class(obj) ((obj)._unVal.pClass)
00116 #define _instance(obj) ((obj)._unVal.pInstance)
00117 #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
00118 #define _weakref(obj) ((obj)._unVal.pWeakRef)
00119 #define _refcounted(obj) ((obj)._unVal.pRefCounted)
00120 #define _rawval(obj) ((obj)._unVal.pRefCounted)
00121
00122 #define _stringval(obj) (obj)._unVal.pString->_val
00123 #define _userdataval(obj) (obj)._unVal.pUserData->_val
00124
00125 #define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
00126 #define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
00129 struct SQObjectPtr : public SQObject
00130 {
00131 SQObjectPtr()
00132 {
00133 _type=OT_NULL;
00134 _unVal.pUserPointer=NULL;
00135 }
00136 SQObjectPtr(const SQObjectPtr &o)
00137 {
00138 _type=o._type;
00139 _unVal=o._unVal;
00140 __AddRef(_type,_unVal);
00141 }
00142 SQObjectPtr(const SQObject &o)
00143 {
00144 _type=o._type;
00145 _unVal=o._unVal;
00146 __AddRef(_type,_unVal);
00147 }
00148 SQObjectPtr(SQTable *pTable)
00149 {
00150 _type=OT_TABLE;
00151 _unVal.pTable=pTable;
00152 assert(_unVal.pTable);
00153 __AddRef(_type,_unVal);
00154 }
00155 SQObjectPtr(SQClass *pClass)
00156 {
00157 _type=OT_CLASS;
00158 _unVal.pClass=pClass;
00159 assert(_unVal.pClass);
00160 __AddRef(_type,_unVal);
00161 }
00162 SQObjectPtr(SQInstance *pInstance)
00163 {
00164 _type=OT_INSTANCE;
00165 _unVal.pInstance=pInstance;
00166 assert(_unVal.pInstance);
00167 __AddRef(_type,_unVal);
00168 }
00169 SQObjectPtr(SQArray *pArray)
00170 {
00171 _type=OT_ARRAY;
00172 _unVal.pArray=pArray;
00173 assert(_unVal.pArray);
00174 __AddRef(_type,_unVal);
00175 }
00176 SQObjectPtr(SQClosure *pClosure)
00177 {
00178 _type=OT_CLOSURE;
00179 _unVal.pClosure=pClosure;
00180 assert(_unVal.pClosure);
00181 __AddRef(_type,_unVal);
00182 }
00183 SQObjectPtr(SQGenerator *pGenerator)
00184 {
00185 _type=OT_GENERATOR;
00186 _unVal.pGenerator=pGenerator;
00187 assert(_unVal.pGenerator);
00188 __AddRef(_type,_unVal);
00189 }
00190 SQObjectPtr(SQNativeClosure *pNativeClosure)
00191 {
00192 _type=OT_NATIVECLOSURE;
00193 _unVal.pNativeClosure=pNativeClosure;
00194 assert(_unVal.pNativeClosure);
00195 __AddRef(_type,_unVal);
00196 }
00197 SQObjectPtr(SQString *pString)
00198 {
00199 _type=OT_STRING;
00200 _unVal.pString=pString;
00201 assert(_unVal.pString);
00202 __AddRef(_type,_unVal);
00203 }
00204 SQObjectPtr(SQUserData *pUserData)
00205 {
00206 _type=OT_USERDATA;
00207 _unVal.pUserData=pUserData;
00208 assert(_unVal.pUserData);
00209 __AddRef(_type,_unVal);
00210 }
00211 SQObjectPtr(SQVM *pThread)
00212 {
00213 _type=OT_THREAD;
00214 _unVal.pThread=pThread;
00215 assert(_unVal.pThread);
00216 __AddRef(_type,_unVal);
00217 }
00218 SQObjectPtr(SQWeakRef *pWeakRef)
00219 {
00220 _type=OT_WEAKREF;
00221 _unVal.pWeakRef=pWeakRef;
00222 assert(_unVal.pWeakRef);
00223 __AddRef(_type,_unVal);
00224 }
00225 SQObjectPtr(SQFunctionProto *pFunctionProto)
00226 {
00227 _type=OT_FUNCPROTO;
00228 _unVal.pFunctionProto=pFunctionProto;
00229 assert(_unVal.pFunctionProto);
00230 __AddRef(_type,_unVal);
00231 }
00232 SQObjectPtr(SQInteger nInteger)
00233 {
00234 _unVal.pUserPointer=NULL;
00235 _type=OT_INTEGER;
00236 _unVal.nInteger=nInteger;
00237 }
00238 SQObjectPtr(SQFloat fFloat)
00239 {
00240 _unVal.pUserPointer=NULL;
00241 _type=OT_FLOAT;
00242 _unVal.fFloat=fFloat;
00243 }
00244 SQObjectPtr(bool bBool)
00245 {
00246 _unVal.pUserPointer=NULL;
00247 _type = OT_BOOL;
00248 _unVal.nInteger = bBool?1:0;
00249 }
00250 SQObjectPtr(SQUserPointer pUserPointer)
00251 {
00252 _type=OT_USERPOINTER;
00253 _unVal.pUserPointer=pUserPointer;
00254 }
00255 ~SQObjectPtr()
00256 {
00257 __Release(_type,_unVal);
00258 }
00259 inline void Null()
00260 {
00261 SQObjectType tOldType;
00262 SQObjectValue unOldVal;
00263 tOldType = _type;
00264 unOldVal = _unVal;
00265 _type = OT_NULL;
00266 _unVal.pUserPointer = NULL;
00267 __Release(tOldType,unOldVal);
00268 }
00269 inline SQObjectPtr& operator=(SQInteger i)
00270 {
00271 __Release(_type,_unVal);
00272 _unVal.nInteger = i;
00273 _type = OT_INTEGER;
00274 return *this;
00275 }
00276 inline SQObjectPtr& operator=(SQFloat f)
00277 {
00278 __Release(_type,_unVal);
00279 _unVal.fFloat = f;
00280 _type = OT_FLOAT;
00281 return *this;
00282 }
00283 inline SQObjectPtr& operator=(const SQObjectPtr& obj)
00284 {
00285 SQObjectType tOldType;
00286 SQObjectValue unOldVal;
00287 tOldType=_type;
00288 unOldVal=_unVal;
00289 _unVal = obj._unVal;
00290 _type = obj._type;
00291 __AddRef(_type,_unVal);
00292 __Release(tOldType,unOldVal);
00293 return *this;
00294 }
00295 inline SQObjectPtr& operator=(const SQObject& obj)
00296 {
00297 SQObjectType tOldType;
00298 SQObjectValue unOldVal;
00299 tOldType=_type;
00300 unOldVal=_unVal;
00301 _unVal = obj._unVal;
00302 _type = obj._type;
00303 __AddRef(_type,_unVal);
00304 __Release(tOldType,unOldVal);
00305 return *this;
00306 }
00307 private:
00308 SQObjectPtr(const SQChar *){}
00309 };
00311 #ifndef NO_GARBAGE_COLLECTOR
00312 #define MARK_FLAG 0x80000000
00313 struct SQCollectable : public SQRefCounted {
00314 SQCollectable *_next;
00315 SQCollectable *_prev;
00316 SQSharedState *_sharedstate;
00317 virtual void Release()=0;
00318 virtual void Mark(SQCollectable **chain)=0;
00319 void UnMark();
00320 virtual void Finalize()=0;
00321 static void AddToChain(SQCollectable **chain,SQCollectable *c);
00322 static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
00323 };
00324
00325
00326 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
00327 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
00328 #define CHAINABLE_OBJ SQCollectable
00329 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
00330 #else
00331
00332 #define ADD_TO_CHAIN(chain,obj) ((void)0)
00333 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
00334 #define CHAINABLE_OBJ SQRefCounted
00335 #define INIT_CHAIN() ((void)0)
00336 #endif
00337
00338 struct SQDelegable : public CHAINABLE_OBJ {
00339 bool SetDelegate(SQTable *m);
00340 virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
00341 SQTable *_delegate;
00342 };
00343
00344 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
00345 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
00346 typedef sqvector<SQInteger> SQIntVec;
00347 const SQChar *GetTypeName(const SQObjectPtr &obj1);
00348 const SQChar *IdType2Name(SQObjectType type);
00349
00350
00351
00352 #endif //_SQOBJECT_H_