sqobject.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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) (sq_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 is_delegable(t) (sq_type(t)&SQOBJECT_DELEGABLE)
  109. #define raw_type(obj) _RAW_TYPE((obj)._type)
  110. #define _integer(obj) ((obj)._unVal.nInteger)
  111. #define _float(obj) ((obj)._unVal.fFloat)
  112. #define _string(obj) ((obj)._unVal.pString)
  113. #define _table(obj) ((obj)._unVal.pTable)
  114. #define _array(obj) ((obj)._unVal.pArray)
  115. #define _closure(obj) ((obj)._unVal.pClosure)
  116. #define _generator(obj) ((obj)._unVal.pGenerator)
  117. #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
  118. #define _userdata(obj) ((obj)._unVal.pUserData)
  119. #define _userpointer(obj) ((obj)._unVal.pUserPointer)
  120. #define _thread(obj) ((obj)._unVal.pThread)
  121. #define _funcproto(obj) ((obj)._unVal.pFunctionProto)
  122. #define _class(obj) ((obj)._unVal.pClass)
  123. #define _instance(obj) ((obj)._unVal.pInstance)
  124. #define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
  125. #define _weakref(obj) ((obj)._unVal.pWeakRef)
  126. #define _outer(obj) ((obj)._unVal.pOuter)
  127. #define _refcounted(obj) ((obj)._unVal.pRefCounted)
  128. #define _rawval(obj) ((obj)._unVal.raw)
  129. #define _stringval(obj) (obj)._unVal.pString->_val
  130. #define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
  131. #define tofloat(num) ((sq_type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
  132. #define tointeger(num) ((sq_type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
  133. /////////////////////////////////////////////////////////////////////////////////////
  134. /////////////////////////////////////////////////////////////////////////////////////
  135. #if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
  136. #define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
  137. #else
  138. #define SQ_REFOBJECT_INIT()
  139. #endif
  140. #define _REF_TYPE_DECL(type,_class,sym) \
  141. SQObjectPtr(_class * x) \
  142. { \
  143. SQ_OBJECT_RAWINIT() \
  144. _type=type; \
  145. _unVal.p##sym = x; \
  146. assert(_unVal.pTable); \
  147. _unVal.pRefCounted->_uiRef++; \
  148. } \
  149. inline SQObjectPtr& operator=(_class *x) \
  150. { \
  151. SQObjectValue old_unVal; \
  152. bool isRefCounted = ISREFCOUNTED(_type);\
  153. if(isRefCounted) old_unVal = _unVal;\
  154. _type = type; \
  155. SQ_REFOBJECT_INIT() \
  156. _unVal.p##sym = x; \
  157. _unVal.pRefCounted->_uiRef++; \
  158. if(isRefCounted) __ReleaseRefCounted(old_unVal); \
  159. return *this; \
  160. } \
  161. inline _class *to##sym()\
  162. { \
  163. assert(_type == type); \
  164. return _unVal.p##sym;\
  165. }
  166. #define _SCALAR_TYPE_DECL(type,_class,prefix,sym) \
  167. SQObjectPtr(_class x) \
  168. { \
  169. SQ_OBJECT_RAWINIT() \
  170. _type=type; \
  171. _unVal.prefix##sym = x; \
  172. } \
  173. inline SQObjectPtr& operator=(_class x) \
  174. { \
  175. if(_type != type){\
  176. __Release(_type,_unVal); \
  177. _type = type; \
  178. SQ_OBJECT_RAWINIT() \
  179. }\
  180. _unVal.prefix##sym = x; \
  181. return *this; \
  182. } \
  183. inline _class to##sym()\
  184. { \
  185. assert(_type == type); \
  186. return _unVal.prefix##sym;\
  187. }
  188. struct SQObjectPtr : public SQObject
  189. {
  190. SQObjectPtr()
  191. {
  192. SQ_OBJECT_RAWINIT()
  193. _type=OT_NULL;
  194. _unVal.pUserPointer=NULL;
  195. }
  196. #define _constructWith(o){_type = o._type; _unVal = o._unVal; __AddRef(_type,_unVal);}
  197. SQObjectPtr(const SQObjectPtr &o)
  198. {
  199. _constructWith(o);
  200. }
  201. SQObjectPtr(const SQObject &o)
  202. {
  203. _constructWith(o);
  204. }
  205. #undef _constructWith
  206. _REF_TYPE_DECL(OT_TABLE,SQTable,Table)
  207. _REF_TYPE_DECL(OT_CLASS,SQClass,Class)
  208. _REF_TYPE_DECL(OT_INSTANCE,SQInstance,Instance)
  209. _REF_TYPE_DECL(OT_ARRAY,SQArray,Array)
  210. _REF_TYPE_DECL(OT_CLOSURE,SQClosure,Closure)
  211. _REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,NativeClosure)
  212. _REF_TYPE_DECL(OT_OUTER,SQOuter,Outer)
  213. _REF_TYPE_DECL(OT_GENERATOR,SQGenerator,Generator)
  214. _REF_TYPE_DECL(OT_STRING,SQString,String)
  215. _REF_TYPE_DECL(OT_USERDATA,SQUserData,UserData)
  216. _REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,WeakRef)
  217. _REF_TYPE_DECL(OT_THREAD,SQVM,Thread)
  218. _REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,FunctionProto)
  219. _SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,n, Integer)
  220. _SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,f, Float)
  221. _SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,p, UserPointer)
  222. SQObjectPtr(bool bBool)
  223. {
  224. SQ_OBJECT_RAWINIT()
  225. _type = OT_BOOL;
  226. _unVal.nInteger = bBool?1:0;
  227. }
  228. inline SQObjectPtr& operator=(bool b)
  229. {
  230. if(_type != OT_BOOL){
  231. __Release(_type,_unVal);
  232. SQ_OBJECT_RAWINIT()
  233. _type = OT_BOOL;
  234. }
  235. _unVal.nInteger = b?1:0;
  236. return *this;
  237. }
  238. ~SQObjectPtr()
  239. {
  240. __Release(_type,_unVal);
  241. }
  242. inline SQObjectPtr& _assignThis(const SQObject& obj)
  243. {
  244. //saving temporarily the old value for cases
  245. //where we are assigning a inner value to the old value
  246. //local tbl = {a=2, b=4}; tbl = tbl.a;
  247. SQObjectValue old_unVal;
  248. bool isRefCounted = ISREFCOUNTED(_type);
  249. if(isRefCounted) old_unVal = _unVal;
  250. _unVal = obj._unVal;
  251. _type = obj._type;
  252. __AddRef(_type,_unVal);
  253. if(isRefCounted) __ReleaseRefCounted(old_unVal);
  254. return *this;
  255. }
  256. inline SQObjectPtr& operator=(const SQObjectPtr& obj)
  257. {
  258. return _assignThis(obj);
  259. }
  260. inline SQObjectPtr& operator=(const SQObject& obj)
  261. {
  262. return _assignThis(obj);
  263. }
  264. inline bool isNull()
  265. {
  266. return _type == OT_NULL;
  267. }
  268. inline void Null()
  269. {
  270. if(!isNull()){
  271. __Release(_type,_unVal);
  272. _type = OT_NULL;
  273. _unVal.raw = (SQRawObjectVal)NULL;
  274. }
  275. }
  276. SQObjectPtr operator[](SQInteger nidx);
  277. SQObjectPtr operator[](const SQChar *key);
  278. private:
  279. SQObjectPtr(const SQChar *){} //safety
  280. };
  281. inline void _Swap(SQObject &a,SQObject &b)
  282. {
  283. SQObjectType tOldType = a._type;
  284. SQObjectValue unOldVal = a._unVal;
  285. a._type = b._type;
  286. a._unVal = b._unVal;
  287. b._type = tOldType;
  288. b._unVal = unOldVal;
  289. }
  290. /////////////////////////////////////////////////////////////////////////////////////
  291. #ifndef NO_GARBAGE_COLLECTOR
  292. #define MARK_FLAG 0x80000000
  293. struct SQCollectable : public SQRefCounted {
  294. SQCollectable *_next;
  295. SQCollectable *_prev;
  296. SQSharedState *_sharedstate;
  297. virtual SQObjectType GetType()=0;
  298. virtual void Release()=0;
  299. virtual void Mark(SQCollectable **chain)=0;
  300. void UnMark();
  301. virtual void Finalize()=0;
  302. static void AddToChain(SQCollectable **chain,SQCollectable *c);
  303. static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
  304. };
  305. #define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
  306. #define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
  307. #define CHAINABLE_OBJ SQCollectable
  308. #define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
  309. #else
  310. #define ADD_TO_CHAIN(chain,obj) ((void)0)
  311. #define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
  312. #define CHAINABLE_OBJ SQRefCounted
  313. #define INIT_CHAIN() ((void)0)
  314. #endif
  315. struct SQDelegable : public CHAINABLE_OBJ {
  316. bool SetDelegate(SQTable *m);
  317. virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
  318. SQTable *_delegate;
  319. };
  320. SQUnsignedInteger SQTranslateIndex(const SQObjectPtr &idx);
  321. typedef sqvector<SQObjectPtr> SQObjectPtrVec;
  322. typedef sqvector<SQInteger> SQIntVec;
  323. const SQChar *GetTypeName(const SQObjectPtr &obj1);
  324. const SQChar *IdType2Name(SQObjectType type);
  325. const SQChar *SQGetOpName(int op_code);
  326. const SQChar *SQGetArithOpName(int it);
  327. const SQChar *SQGetNewObjTypeName(int it);
  328. const SQChar *SQGetArrayAppendTypeName(int it);
  329. const SQChar *SQGetCmpOpName(int it);
  330. const SQChar *SQGetBitwiseOpName(int it);
  331. const SQChar *SQGetVarTypeName(int it);
  332. #endif //_SQOBJECT_H_