sqobject.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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.p##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.p##sym = x; \
  158. _unVal.pRefCounted->_uiRef++; \
  159. if(isRefCounted) __ReleaseRefCounted(old_unVal); \
  160. return *this; \
  161. } \
  162. inline _class *to##sym()\
  163. { \
  164. assert(_type == type); \
  165. return _unVal.p##sym;\
  166. }
  167. #define _SCALAR_TYPE_DECL(type,_class,prefix,sym) \
  168. SQObjectPtr(_class x) \
  169. { \
  170. SQ_OBJECT_RAWINIT() \
  171. _type=type; \
  172. _unVal.prefix##sym = x; \
  173. } \
  174. inline SQObjectPtr& operator=(_class x) \
  175. { \
  176. if(_type != type){\
  177. __Release(_type,_unVal); \
  178. _type = type; \
  179. SQ_OBJECT_RAWINIT() \
  180. }\
  181. _unVal.prefix##sym = x; \
  182. return *this; \
  183. } \
  184. inline _class to##sym()\
  185. { \
  186. assert(_type == type); \
  187. return _unVal.prefix##sym;\
  188. }
  189. struct SQObjectPtr : public SQObject
  190. {
  191. SQObjectPtr()
  192. {
  193. SQ_OBJECT_RAWINIT()
  194. _type=OT_NULL;
  195. _unVal.pUserPointer=NULL;
  196. }
  197. SQObjectPtr(const SQObjectPtr &o)
  198. {
  199. _type = o._type;
  200. _unVal = o._unVal;
  201. __AddRef(_type,_unVal);
  202. }
  203. SQObjectPtr(const SQObject &o)
  204. {
  205. _type = o._type;
  206. _unVal = o._unVal;
  207. __AddRef(_type,_unVal);
  208. }
  209. _REF_TYPE_DECL(OT_TABLE,SQTable,Table)
  210. _REF_TYPE_DECL(OT_CLASS,SQClass,Class)
  211. _REF_TYPE_DECL(OT_INSTANCE,SQInstance,Instance)
  212. _REF_TYPE_DECL(OT_ARRAY,SQArray,Array)
  213. _REF_TYPE_DECL(OT_CLOSURE,SQClosure,Closure)
  214. _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,NativeClosure)
  215. _REF_TYPE_DECL(OT_OUTER,SQOuter,Outer)
  216. _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,Generator)
  217. _REF_TYPE_DECL(OT_STRING,SQString,String)
  218. _REF_TYPE_DECL(OT_USERDATA,SQUserData,UserData)
  219. _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,WeakRef)
  220. _REF_TYPE_DECL(OT_THREAD,SQVM,Thread)
  221. _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,FunctionProto)
  222. _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,n, Integer)
  223. _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,f, Float)
  224. _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,p, UserPointer)
  225. SQObjectPtr(bool bBool)
  226. {
  227. SQ_OBJECT_RAWINIT()
  228. _type = OT_BOOL;
  229. _unVal.nInteger = bBool?1:0;
  230. }
  231. inline SQObjectPtr& operator=(bool b)
  232. {
  233. if(_type != OT_BOOL){
  234. __Release(_type,_unVal);
  235. SQ_OBJECT_RAWINIT()
  236. _type = OT_BOOL;
  237. }
  238. _unVal.nInteger = b?1:0;
  239. return *this;
  240. }
  241. ~SQObjectPtr()
  242. {
  243. __Release(_type,_unVal);
  244. }
  245. inline SQObjectPtr& operator=(const SQObjectPtr& obj)
  246. {
  247. //saving temporarily the old value for cases
  248. //where we are assigning a inner value to the old value
  249. //local tbl = {a=2, b=4}; tbl = tbl.a;
  250. SQObjectValue old_unVal;
  251. bool isRefCounted = ISREFCOUNTED(_type);
  252. if(isRefCounted) old_unVal = _unVal;
  253. _unVal = obj._unVal;
  254. _type = obj._type;
  255. __AddRef(_type,_unVal);
  256. if(isRefCounted) __ReleaseRefCounted(old_unVal);
  257. return *this;
  258. }
  259. inline SQObjectPtr& operator=(const SQObject& obj)
  260. {
  261. SQObjectValue old_unVal;
  262. bool isRefCounted = ISREFCOUNTED(_type);
  263. if(isRefCounted) old_unVal = _unVal;
  264. _unVal = obj._unVal;
  265. _type = obj._type;
  266. __AddRef(_type,_unVal);
  267. if(isRefCounted) __ReleaseRefCounted(old_unVal);
  268. return *this;
  269. }
  270. inline void Null()
  271. {
  272. if(_type != OT_NULL){
  273. __Release(_type,_unVal);
  274. _type = OT_NULL;
  275. _unVal.raw = (SQRawObjectVal)NULL;
  276. }
  277. }
  278. inline bool isNull()
  279. {
  280. return _type == OT_NULL;
  281. }
  282. SQObjectPtr operator[](SQInteger nidx);
  283. SQObjectPtr operator[](const SQChar *key);
  284. private:
  285. SQObjectPtr(const SQChar *){} //safety
  286. };
  287. inline void _Swap(SQObject &a,SQObject &b)
  288. {
  289. SQObjectType tOldType = a._type;
  290. SQObjectValue unOldVal = a._unVal;
  291. a._type = b._type;
  292. a._unVal = b._unVal;
  293. b._type = tOldType;
  294. b._unVal = unOldVal;
  295. }
  296. /////////////////////////////////////////////////////////////////////////////////////
  297. #ifndef NO_GARBAGE_COLLECTOR
  298. #define MARK_FLAG 0x80000000
  299. struct SQCollectable : public SQRefCounted {
  300. SQCollectable *_next;
  301. SQCollectable *_prev;
  302. SQSharedState *_sharedstate;
  303. virtual SQObjectType GetType()=0;
  304. virtual void Release()=0;
  305. virtual void Mark(SQCollectable **chain)=0;
  306. void UnMark();
  307. virtual void Finalize()=0;
  308. static void AddToChain(SQCollectable **chain,SQCollectable *c);
  309. static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
  310. };
  311. #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
  312. #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
  313. #define CHAINABLE_OBJ SQCollectable
  314. #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
  315. #else
  316. #define ADD_TO_CHAIN(chain,obj) ((void)0)
  317. #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
  318. #define CHAINABLE_OBJ SQRefCounted
  319. #define INIT_CHAIN() ((void)0)
  320. #endif
  321. struct SQDelegable : public CHAINABLE_OBJ {
  322. bool SetDelegate(SQTable *m);
  323. virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
  324. SQTable *_delegate;
  325. };
  326. SQUnsignedInteger SQTranslateIndex(const SQObjectPtr &idx);
  327. typedef sqvector<SQObjectPtr> SQObjectPtrVec;
  328. typedef sqvector<SQInteger> SQIntVec;
  329. const SQChar *GetTypeName(const SQObjectPtr &obj1);
  330. const SQChar *IdType2Name(SQObjectType type);
  331. const SQChar *SQGetOpName(int op_code);
  332. const SQChar *SQGetArithOpName(int it);
  333. const SQChar *SQGetNewObjTypeName(int it);
  334. const SQChar *SQGetArrayAppendTypeName(int it);
  335. const SQChar *SQGetCmpOpName(int it);
  336. const SQChar *SQGetBitwiseOpName(int it);
  337. #endif //_SQOBJECT_H_