# sqobject.h

    00001 /*  see copyright notice in squirrel.h */
    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 *){} //safety
    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_