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