sqobject.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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 __AddRef(type,unval) if(ISREFCOUNTED(type)) \
  91. { \
  92. unval.pRefCounted->_uiRef++; \
  93. }
  94. #define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
  95. { \
  96. unval.pRefCounted->Release(); \
  97. }
  98. #define __ObjRelease(obj) { \
  99. if((obj)) { \
  100. (obj)->_uiRef--; \
  101. if((obj)->_uiRef == 0) \
  102. (obj)->Release(); \
  103. (obj) = NULL; \
  104. } \
  105. }
  106. #define __ObjAddRef(obj) { \
  107. (obj)->_uiRef++; \
  108. }
  109. #define type(obj) ((obj)._type)
  110. #define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
  111. #define raw_type(obj) _RAW_TYPE((obj)._type)
  112. #define _integer(obj) ((obj)._unVal.nInteger)
  113. #define _float(obj) ((obj)._unVal.fFloat)
  114. #define _string(obj) ((obj)._unVal.pString)
  115. #define _table(obj) ((obj)._unVal.pTable)
  116. #define _array(obj) ((obj)._unVal.pArray)
  117. #define _closure(obj) ((obj)._unVal.pClosure)
  118. #define _generator(obj) ((obj)._unVal.pGenerator)
  119. #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
  120. #define _userdata(obj) ((obj)._unVal.pUserData)
  121. #define _userpointer(obj) ((obj)._unVal.pUserPointer)
  122. #define _thread(obj) ((obj)._unVal.pThread)
  123. #define _funcproto(obj) ((obj)._unVal.pFunctionProto)
  124. #define _class(obj) ((obj)._unVal.pClass)
  125. #define _instance(obj) ((obj)._unVal.pInstance)
  126. #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
  127. #define _weakref(obj) ((obj)._unVal.pWeakRef)
  128. #define _outer(obj) ((obj)._unVal.pOuter)
  129. #define _refcounted(obj) ((obj)._unVal.pRefCounted)
  130. #define _rawval(obj) ((obj)._unVal.raw)
  131. #define _stringval(obj) (obj)._unVal.pString->_val
  132. #define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
  133. #define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
  134. #define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
  135. /////////////////////////////////////////////////////////////////////////////////////
  136. /////////////////////////////////////////////////////////////////////////////////////
  137. #if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
  138. #define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
  139. #else
  140. #define SQ_REFOBJECT_INIT()
  141. #endif
  142. #define _REF_TYPE_DECL(type,_class,sym) \
  143. SQObjectPtr(_class * x) \
  144. { \
  145. SQ_OBJECT_RAWINIT() \
  146. _type=type; \
  147. _unVal.sym = x; \
  148. assert(_unVal.pTable); \
  149. _unVal.pRefCounted->_uiRef++; \
  150. } \
  151. inline SQObjectPtr& operator=(_class *x) \
  152. { \
  153. SQObjectType tOldType; \
  154. SQObjectValue unOldVal; \
  155. tOldType=_type; \
  156. unOldVal=_unVal; \
  157. _type = type; \
  158. SQ_REFOBJECT_INIT() \
  159. _unVal.sym = x; \
  160. _unVal.pRefCounted->_uiRef++; \
  161. __Release(tOldType,unOldVal); \
  162. return *this; \
  163. }
  164. #define _SCALAR_TYPE_DECL(type,_class,sym) \
  165. SQObjectPtr(_class x) \
  166. { \
  167. SQ_OBJECT_RAWINIT() \
  168. _type=type; \
  169. _unVal.sym = x; \
  170. } \
  171. inline SQObjectPtr& operator=(_class x) \
  172. { \
  173. __Release(_type,_unVal); \
  174. _type = type; \
  175. SQ_OBJECT_RAWINIT() \
  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. __Release(_type,_unVal);
  224. SQ_OBJECT_RAWINIT()
  225. _type = OT_BOOL;
  226. _unVal.nInteger = b?1:0;
  227. return *this;
  228. }
  229. ~SQObjectPtr()
  230. {
  231. __Release(_type,_unVal);
  232. }
  233. inline SQObjectPtr& operator=(const SQObjectPtr& obj)
  234. {
  235. SQObjectType tOldType;
  236. SQObjectValue unOldVal;
  237. tOldType=_type;
  238. unOldVal=_unVal;
  239. _unVal = obj._unVal;
  240. _type = obj._type;
  241. __AddRef(_type,_unVal);
  242. __Release(tOldType,unOldVal);
  243. return *this;
  244. }
  245. inline SQObjectPtr& operator=(const SQObject& obj)
  246. {
  247. SQObjectType tOldType;
  248. SQObjectValue unOldVal;
  249. tOldType=_type;
  250. unOldVal=_unVal;
  251. _unVal = obj._unVal;
  252. _type = obj._type;
  253. __AddRef(_type,_unVal);
  254. __Release(tOldType,unOldVal);
  255. return *this;
  256. }
  257. inline void Null()
  258. {
  259. SQObjectType tOldType = _type;
  260. SQObjectValue unOldVal = _unVal;
  261. _type = OT_NULL;
  262. _unVal.raw = (SQRawObjectVal)NULL;
  263. __Release(tOldType ,unOldVal);
  264. }
  265. private:
  266. SQObjectPtr(const SQChar *){} //safety
  267. };
  268. inline void _Swap(SQObject &a,SQObject &b)
  269. {
  270. SQObjectType tOldType = a._type;
  271. SQObjectValue unOldVal = a._unVal;
  272. a._type = b._type;
  273. a._unVal = b._unVal;
  274. b._type = tOldType;
  275. b._unVal = unOldVal;
  276. }
  277. /////////////////////////////////////////////////////////////////////////////////////
  278. #ifndef NO_GARBAGE_COLLECTOR
  279. #define MARK_FLAG 0x80000000
  280. struct SQCollectable : public SQRefCounted {
  281. SQCollectable *_next;
  282. SQCollectable *_prev;
  283. SQSharedState *_sharedstate;
  284. virtual SQObjectType GetType()=0;
  285. virtual void Release()=0;
  286. virtual void Mark(SQCollectable **chain)=0;
  287. void UnMark();
  288. virtual void Finalize()=0;
  289. static void AddToChain(SQCollectable **chain,SQCollectable *c);
  290. static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
  291. };
  292. #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
  293. #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
  294. #define CHAINABLE_OBJ SQCollectable
  295. #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
  296. #else
  297. #define ADD_TO_CHAIN(chain,obj) ((void)0)
  298. #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
  299. #define CHAINABLE_OBJ SQRefCounted
  300. #define INIT_CHAIN() ((void)0)
  301. #endif
  302. struct SQDelegable : public CHAINABLE_OBJ {
  303. bool SetDelegate(SQTable *m);
  304. virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
  305. SQTable *_delegate;
  306. };
  307. SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
  308. typedef sqvector<SQObjectPtr> SQObjectPtrVec;
  309. typedef sqvector<SQInteger> SQIntVec;
  310. const SQChar *GetTypeName(const SQObjectPtr &obj1);
  311. const SQChar *IdType2Name(SQObjectType type);
  312. #endif //_SQOBJECT_H_