Back to home page

Enduro/X

 
 

    


0001 /*  see copyright notice in pscript.h */
0002 #ifndef _PSOBJECT_H_
0003 #define _PSOBJECT_H_
0004 
0005 #include "psutils.h"
0006 
0007 #ifdef _PS64
0008 #define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
0009 #else
0010 #define UINT_MINUS_ONE (0xFFFFFFFF)
0011 #endif
0012 
0013 #define PS_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
0014 #define PS_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
0015 #define PS_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
0016 
0017 struct PSSharedState;
0018 
0019 enum PSMetaMethod{
0020     MT_ADD=0,
0021     MT_SUB=1,
0022     MT_MUL=2,
0023     MT_DIV=3,
0024     MT_UNM=4,
0025     MT_MODULO=5,
0026     MT_SET=6,
0027     MT_GET=7,
0028     MT_TYPEOF=8,
0029     MT_NEXTI=9,
0030     MT_CMP=10,
0031     MT_CALL=11,
0032     MT_CLONED=12,
0033     MT_NEWSLOT=13,
0034     MT_DELSLOT=14,
0035     MT_TOSTRING=15,
0036     MT_NEWMEMBER=16,
0037     MT_INHERITED=17,
0038     MT_LAST = 18
0039 };
0040 
0041 #define MM_ADD      _SC("_add")
0042 #define MM_SUB      _SC("_sub")
0043 #define MM_MUL      _SC("_mul")
0044 #define MM_DIV      _SC("_div")
0045 #define MM_UNM      _SC("_unm")
0046 #define MM_MODULO   _SC("_modulo")
0047 #define MM_SET      _SC("_set")
0048 #define MM_GET      _SC("_get")
0049 #define MM_TYPEOF   _SC("_typeof")
0050 #define MM_NEXTI    _SC("_nexti")
0051 #define MM_CMP      _SC("_cmp")
0052 #define MM_CALL     _SC("_call")
0053 #define MM_CLONED   _SC("_cloned")
0054 #define MM_NEWSLOT  _SC("_newslot")
0055 #define MM_DELSLOT  _SC("_delslot")
0056 #define MM_TOSTRING _SC("_tostring")
0057 #define MM_NEWMEMBER _SC("_newmember")
0058 #define MM_INHERITED _SC("_inherited")
0059 
0060 
0061 #define _CONSTRUCT_VECTOR(type,size,ptr) { \
0062     for(PSInteger n = 0; n < ((PSInteger)size); n++) { \
0063             new (&ptr[n]) type(); \
0064         } \
0065 }
0066 
0067 #define _DESTRUCT_VECTOR(type,size,ptr) { \
0068     for(PSInteger nl = 0; nl < ((PSInteger)size); nl++) { \
0069             ptr[nl].~type(); \
0070     } \
0071 }
0072 
0073 #define _COPY_VECTOR(dest,src,size) { \
0074     for(PSInteger _n_ = 0; _n_ < ((PSInteger)size); _n_++) { \
0075         dest[_n_] = src[_n_]; \
0076     } \
0077 }
0078 
0079 #define _NULL_PSOBJECT_VECTOR(vec,size) { \
0080     for(PSInteger _n_ = 0; _n_ < ((PSInteger)size); _n_++) { \
0081         vec[_n_].Null(); \
0082     } \
0083 }
0084 
0085 #define MINPOWER2 4
0086 
0087 struct PSRefCounted
0088 {
0089     PSUnsignedInteger _uiRef;
0090     struct PSWeakRef *_weakref;
0091     PSRefCounted() { _uiRef = 0; _weakref = NULL; }
0092     virtual ~PSRefCounted();
0093     PSWeakRef *GetWeakRef(PSObjectType type);
0094     virtual void Release()=0;
0095 
0096 };
0097 
0098 struct PSWeakRef : PSRefCounted
0099 {
0100     void Release();
0101     PSObject _obj;
0102 };
0103 
0104 #define _realval(o) (type((o)) != OT_WEAKREF?(PSObject)o:_weakref(o)->_obj)
0105 
0106 struct PSObjectPtr;
0107 
0108 #define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
0109         { \
0110             unval.pRefCounted->_uiRef++; \
0111         }
0112 
0113 #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0))  \
0114         {   \
0115             unval.pRefCounted->Release();   \
0116         }
0117 
0118 #define __ObjRelease(obj) { \
0119     if((obj)) { \
0120         (obj)->_uiRef--; \
0121         if((obj)->_uiRef == 0) \
0122             (obj)->Release(); \
0123         (obj) = NULL;   \
0124     } \
0125 }
0126 
0127 #define __ObjAddRef(obj) { \
0128     (obj)->_uiRef++; \
0129 }
0130 
0131 #define type(obj) ((obj)._type)
0132 #define is_delegable(t) (type(t)&PSOBJECT_DELEGABLE)
0133 #define raw_type(obj) _RAW_TYPE((obj)._type)
0134 
0135 #define _integer(obj) ((obj)._unVal.nInteger)
0136 #define _float(obj) ((obj)._unVal.fFloat)
0137 #define _string(obj) ((obj)._unVal.pString)
0138 #define _table(obj) ((obj)._unVal.pTable)
0139 #define _array(obj) ((obj)._unVal.pArray)
0140 #define _closure(obj) ((obj)._unVal.pClosure)
0141 #define _generator(obj) ((obj)._unVal.pGenerator)
0142 #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
0143 #define _userdata(obj) ((obj)._unVal.pUserData)
0144 #define _userpointer(obj) ((obj)._unVal.pUserPointer)
0145 #define _thread(obj) ((obj)._unVal.pThread)
0146 #define _funcproto(obj) ((obj)._unVal.pFunctionProto)
0147 #define _class(obj) ((obj)._unVal.pClass)
0148 #define _instance(obj) ((obj)._unVal.pInstance)
0149 #define _delegable(obj) ((PSDelegable *)(obj)._unVal.pDelegable)
0150 #define _weakref(obj) ((obj)._unVal.pWeakRef)
0151 #define _outer(obj) ((obj)._unVal.pOuter)
0152 #define _refcounted(obj) ((obj)._unVal.pRefCounted)
0153 #define _rawval(obj) ((obj)._unVal.raw)
0154 
0155 #define _stringval(obj) (obj)._unVal.pString->_val
0156 #define _userdataval(obj) ((PSUserPointer)ps_aligning((obj)._unVal.pUserData + 1))
0157 
0158 #define tofloat(num) ((type(num)==OT_INTEGER)?(PSFloat)_integer(num):_float(num))
0159 #define tointeger(num) ((type(num)==OT_FLOAT)?(PSInteger)_float(num):_integer(num))
0160 /////////////////////////////////////////////////////////////////////////////////////

0161 /////////////////////////////////////////////////////////////////////////////////////

0162 #if defined(PSUSEDOUBLE) && !defined(_PS64) || !defined(PSUSEDOUBLE) && defined(_PS64)
0163 #define PS_REFOBJECT_INIT() PS_OBJECT_RAWINIT()
0164 #else
0165 #define PS_REFOBJECT_INIT()
0166 #endif
0167 
0168 #define _REF_TYPE_DECL(type,_class,sym) \
0169     PSObjectPtr(_class * x) \
0170     { \
0171         PS_OBJECT_RAWINIT() \
0172         _type=type; \
0173         _unVal.sym = x; \
0174         assert(_unVal.pTable); \
0175         _unVal.pRefCounted->_uiRef++; \
0176     } \
0177     inline PSObjectPtr& operator=(_class *x) \
0178     {  \
0179         PSObjectType tOldType; \
0180         PSObjectValue unOldVal; \
0181         tOldType=_type; \
0182         unOldVal=_unVal; \
0183         _type = type; \
0184         PS_REFOBJECT_INIT() \
0185         _unVal.sym = x; \
0186         _unVal.pRefCounted->_uiRef++; \
0187         __Release(tOldType,unOldVal); \
0188         return *this; \
0189     }
0190 
0191 #define _SCALAR_TYPE_DECL(type,_class,sym) \
0192     PSObjectPtr(_class x) \
0193     { \
0194         PS_OBJECT_RAWINIT() \
0195         _type=type; \
0196         _unVal.sym = x; \
0197     } \
0198     inline PSObjectPtr& operator=(_class x) \
0199     {  \
0200         __Release(_type,_unVal); \
0201         _type = type; \
0202         PS_OBJECT_RAWINIT() \
0203         _unVal.sym = x; \
0204         return *this; \
0205     }
0206 struct PSObjectPtr : public PSObject
0207 {
0208     PSObjectPtr()
0209     {
0210         PS_OBJECT_RAWINIT()
0211         _type=OT_NULL;
0212         _unVal.pUserPointer=NULL;
0213     }
0214     PSObjectPtr(const PSObjectPtr &o)
0215     {
0216         _type = o._type;
0217         _unVal = o._unVal;
0218         __AddRef(_type,_unVal);
0219     }
0220     PSObjectPtr(const PSObject &o)
0221     {
0222         _type = o._type;
0223         _unVal = o._unVal;
0224         __AddRef(_type,_unVal);
0225     }
0226     _REF_TYPE_DECL(OT_TABLE,PSTable,pTable)
0227     _REF_TYPE_DECL(OT_CLASS,PSClass,pClass)
0228     _REF_TYPE_DECL(OT_INSTANCE,PSInstance,pInstance)
0229     _REF_TYPE_DECL(OT_ARRAY,PSArray,pArray)
0230     _REF_TYPE_DECL(OT_CLOSURE,PSClosure,pClosure)
0231     _REF_TYPE_DECL(OT_NATIVECLOSURE,PSNativeClosure,pNativeClosure)
0232     _REF_TYPE_DECL(OT_OUTER,PSOuter,pOuter)
0233     _REF_TYPE_DECL(OT_GENERATOR,PSGenerator,pGenerator)
0234     _REF_TYPE_DECL(OT_STRING,PSString,pString)
0235     _REF_TYPE_DECL(OT_USERDATA,PSUserData,pUserData)
0236     _REF_TYPE_DECL(OT_WEAKREF,PSWeakRef,pWeakRef)
0237     _REF_TYPE_DECL(OT_THREAD,PSVM,pThread)
0238     _REF_TYPE_DECL(OT_FUNCPROTO,PSFunctionProto,pFunctionProto)
0239 
0240     _SCALAR_TYPE_DECL(OT_INTEGER,PSInteger,nInteger)
0241     _SCALAR_TYPE_DECL(OT_FLOAT,PSFloat,fFloat)
0242     _SCALAR_TYPE_DECL(OT_USERPOINTER,PSUserPointer,pUserPointer)
0243 
0244     PSObjectPtr(bool bBool)
0245     {
0246         PS_OBJECT_RAWINIT()
0247         _type = OT_BOOL;
0248         _unVal.nInteger = bBool?1:0;
0249     }
0250     inline PSObjectPtr& operator=(bool b)
0251     {
0252         __Release(_type,_unVal);
0253         PS_OBJECT_RAWINIT()
0254         _type = OT_BOOL;
0255         _unVal.nInteger = b?1:0;
0256         return *this;
0257     }
0258 
0259     ~PSObjectPtr()
0260     {
0261         __Release(_type,_unVal);
0262     }
0263 
0264     inline PSObjectPtr& operator=(const PSObjectPtr& obj)
0265     {
0266         PSObjectType tOldType;
0267         PSObjectValue unOldVal;
0268         tOldType=_type;
0269         unOldVal=_unVal;
0270         _unVal = obj._unVal;
0271         _type = obj._type;
0272         __AddRef(_type,_unVal);
0273         __Release(tOldType,unOldVal);
0274         return *this;
0275     }
0276     inline PSObjectPtr& operator=(const PSObject& obj)
0277     {
0278         PSObjectType tOldType;
0279         PSObjectValue unOldVal;
0280         tOldType=_type;
0281         unOldVal=_unVal;
0282         _unVal = obj._unVal;
0283         _type = obj._type;
0284         __AddRef(_type,_unVal);
0285         __Release(tOldType,unOldVal);
0286         return *this;
0287     }
0288     inline void Null()
0289     {
0290         PSObjectType tOldType = _type;
0291         PSObjectValue unOldVal = _unVal;
0292         _type = OT_NULL;
0293         _unVal.raw = (PSRawObjectVal)NULL;
0294         __Release(tOldType ,unOldVal);
0295     }
0296     private:
0297         PSObjectPtr(const PSChar *){} //safety

0298 };
0299 
0300 
0301 inline void _Swap(PSObject &a,PSObject &b)
0302 {
0303     PSObjectType tOldType = a._type;
0304     PSObjectValue unOldVal = a._unVal;
0305     a._type = b._type;
0306     a._unVal = b._unVal;
0307     b._type = tOldType;
0308     b._unVal = unOldVal;
0309 }
0310 
0311 /////////////////////////////////////////////////////////////////////////////////////

0312 #ifndef NO_GARBAGE_COLLECTOR
0313 #define MARK_FLAG 0x80000000
0314 struct PSCollectable : public PSRefCounted {
0315     PSCollectable *_next;
0316     PSCollectable *_prev;
0317     PSSharedState *_sharedstate;
0318     virtual PSObjectType GetType()=0;
0319     virtual void Release()=0;
0320     virtual void Mark(PSCollectable **chain)=0;
0321     void UnMark();
0322     virtual void Finalize()=0;
0323     static void AddToChain(PSCollectable **chain,PSCollectable *c);
0324     static void RemoveFromChain(PSCollectable **chain,PSCollectable *c);
0325 };
0326 
0327 
0328 #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
0329 #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
0330 #define CHAINABLE_OBJ PSCollectable
0331 #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
0332 #else
0333 
0334 #define ADD_TO_CHAIN(chain,obj) ((void)0)
0335 #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
0336 #define CHAINABLE_OBJ PSRefCounted
0337 #define INIT_CHAIN() ((void)0)
0338 #endif
0339 
0340 struct PSDelegable : public CHAINABLE_OBJ {
0341     bool SetDelegate(PSTable *m);
0342     virtual bool GetMetaMethod(PSVM *v,PSMetaMethod mm,PSObjectPtr &res);
0343     PSTable *_delegate;
0344 };
0345 
0346 PSUnsignedInteger TranslateIndex(const PSObjectPtr &idx);
0347 typedef psvector<PSObjectPtr> PSObjectPtrVec;
0348 typedef psvector<PSInteger> PSIntVec;
0349 const PSChar *GetTypeName(const PSObjectPtr &obj1);
0350 const PSChar *IdType2Name(PSObjectType type);
0351 
0352 
0353 
0354 #endif //_PSOBJECT_H_