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