sqobject.h 11 KB

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