sqobject.h 9.5 KB

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