Johan Wikman / SQUIRREL3

Dependents:   Squirrel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sqobject.h Source File

sqobject.h

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