1 /*
2 see copyright notice in squirrel.h
3 */
4 #include "sqpcheader.h"
5 #include "sqvm.h"
6 #include "sqstring.h"
7 #include "sqarray.h"
8 #include "sqtable.h"
9 #include "squserdata.h"
10 #include "sqfuncproto.h"
11 #include "sqclass.h"
12 #include "sqclosure.h"
13
Create(SQSharedState * ss,const SQChar * s,SQInteger len)14 SQString *SQString::Create( SQSharedState *ss, const SQChar *s, SQInteger len ) {
15 SQString *str = ADD_STRING( ss, s, len );
16 str->_sharedstate = ss;
17 return str;
18 }
19
Release()20 void SQString::Release() {
21 REMOVE_STRING( _sharedstate, this );
22 }
23
TranslateIndex(const SQObjectPtr & idx)24 SQUnsignedInteger TranslateIndex( const SQObjectPtr &idx ) {
25 switch ( squirrel_type( idx ) ) {
26 case OT_NULL:
27 return 0;
28 case OT_INTEGER:
29 return ( SQUnsignedInteger )_integer( idx );
30 }
31 assert( 0 );
32 return 0;
33 }
34
GetWeakRef(SQObjectType type)35 SQWeakRef *SQRefCounted::GetWeakRef( SQObjectType type ) {
36 if ( !_weakref ) {
37 sq_new( _weakref, SQWeakRef );
38 _weakref->_obj._type = type;
39 _weakref->_obj._unVal.pRefCounted = this;
40 }
41 return _weakref;
42 }
43
~SQRefCounted()44 SQRefCounted::~SQRefCounted() {
45 if ( _weakref ) {
46 _weakref->_obj._type = OT_NULL;
47 _weakref->_obj._unVal.pRefCounted = NULL;
48 }
49 }
50
Release()51 void SQWeakRef::Release() {
52 if ( ISREFCOUNTED( _obj._type ) ) {
53 _obj._unVal.pRefCounted->_weakref = NULL;
54 }
55 sq_delete( this, SQWeakRef );
56 }
57
GetMetaMethod(SQMetaMethod mm,SQObjectPtr & res)58 bool SQDelegable::GetMetaMethod( SQMetaMethod mm, SQObjectPtr &res ) {
59 if ( _delegate ) {
60 return _delegate->Get( ( *_ss( this )->_metamethods )[mm], res );
61 }
62 return false;
63 }
64
SetDelegate(SQTable * mt)65 bool SQDelegable::SetDelegate( SQTable *mt ) {
66 SQTable *temp = mt;
67 while ( temp ) {
68 if ( temp->_delegate == this ) return false; //cycle detected
69 temp = temp->_delegate;
70 }
71 if ( mt ) __ObjAddRef( mt );
72 __ObjRelease( _delegate );
73 _delegate = mt;
74 return true;
75 }
76
Yield(SQVM * v)77 bool SQGenerator::Yield( SQVM *v ) {
78 if ( _state == eSuspended ) {
79 v->Raise_Error( _SC( "internal vm error, yielding dead generator" ) ); return false;
80 }
81 if ( _state == eDead ) {
82 v->Raise_Error( _SC( "internal vm error, yielding a dead generator" ) ); return false;
83 }
84 SQInteger size = v->_top - v->_stackbase;
85 _ci = *v->ci;
86 _stack.resize( size );
87 for ( SQInteger n = 0; n < size; n++ ) {
88 _stack._vals[n] = v->_stack[v->_stackbase+n];
89 v->_stack[v->_stackbase+n] = _null_;
90 }
91 SQInteger nvargs = v->ci->_vargs.size;
92 SQInteger vargsbase = v->ci->_vargs.base;
93 for ( SQInteger j = nvargs - 1; j >= 0; j-- ) {
94 _vargsstack.push_back( v->_vargsstack[vargsbase+j] );
95 }
96 _ci._generator = _null_;
97 for ( SQInteger i = 0;i < _ci._etraps;i++ ) {
98 _etraps.push_back( v->_etraps.top() );
99 v->_etraps.pop_back();
100 }
101 _state = eSuspended;
102 return true;
103 }
104
Resume(SQVM * v,SQInteger target)105 bool SQGenerator::Resume( SQVM *v, SQInteger target ) {
106 SQInteger size = _stack.size();
107 if ( _state == eDead ) {
108 v->Raise_Error( _SC( "resuming dead generator" ) ); return false;
109 }
110 if ( _state == eRunning ) {
111 v->Raise_Error( _SC( "resuming active generator" ) ); return false;
112 }
113 SQInteger prevtop = v->_top - v->_stackbase;
114 PUSH_CALLINFO( v, _ci );
115 SQInteger oldstackbase = v->_stackbase;
116 v->_stackbase = v->_top;
117 v->ci->_target = target;
118 v->ci->_generator = SQObjectPtr( this );
119 v->ci->_vargs.size = _vargsstack.size();
120
121 for ( SQInteger i = 0;i < _ci._etraps;i++ ) {
122 v->_etraps.push_back( _etraps.top() );
123 _etraps.pop_back();
124 }
125 for ( SQInteger n = 0; n < size; n++ ) {
126 v->_stack[v->_stackbase+n] = _stack._vals[n];
127 _stack._vals[0] = _null_;
128 }
129 while ( !_vargsstack.empty() ) {
130 v->_vargsstack.push_back( _vargsstack.back() );
131 _vargsstack.pop_back();
132 }
133 v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;
134 v->_top = v->_stackbase + size;
135 v->ci->_prevtop = prevtop;
136 v->ci->_prevstkbase = v->_stackbase - oldstackbase;
137 _state = eRunning;
138 return true;
139 }
140
Extend(const SQArray * a)141 void SQArray::Extend( const SQArray *a ) {
142 SQInteger xlen;
143 if ( ( xlen = a->Size() ) )
144 for ( SQInteger i = 0;i < xlen;i++ )
145 Append( a->_values[i] );
146 }
147
GetLocal(SQVM * vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)148 const SQChar* SQFunctionProto::GetLocal( SQVM *vm, SQUnsignedInteger stackbase, SQUnsignedInteger nseq, SQUnsignedInteger nop ) {
149 SQUnsignedInteger nvars = _localvarinfos.size();
150 const SQChar *res = NULL;
151 if ( nvars >= nseq ) {
152 for ( SQUnsignedInteger i = 0;i < nvars;i++ ) {
153 if ( _localvarinfos[i]._start_op <= nop && _localvarinfos[i]._end_op >= nop ) {
154 if ( nseq == 0 ) {
155 vm->Push( vm->_stack[stackbase+_localvarinfos[i]._pos] );
156 res = _stringval( _localvarinfos[i]._name );
157 break;
158 }
159 nseq--;
160 }
161 }
162 }
163 return res;
164 }
165
GetLine(SQInstruction * curr)166 SQInteger SQFunctionProto::GetLine( SQInstruction *curr ) {
167 SQInteger op = ( curr - _instructions._vals );
168 SQInteger line = _lineinfos[0]._line;
169 for ( SQUnsignedInteger i = 1;i < _lineinfos.size();i++ ) {
170 if ( _lineinfos[i]._op >= op )
171 return line;
172 line = _lineinfos[i]._line;
173 }
174 return line;
175 }
176
177 //#define _ERROR_TRAP() error_trap:
178 #define _CHECK_IO(exp) { if(!exp)return false; }
SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)179 bool SafeWrite( HSQUIRRELVM v, SQWRITEFUNC write, SQUserPointer up, SQUserPointer dest, SQInteger size ) {
180 if ( write( up, dest, size ) != size ) {
181 v->Raise_Error( _SC( "io error (write function failure)" ) );
182 return false;
183 }
184 return true;
185 }
186
SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)187 bool SafeRead( HSQUIRRELVM v, SQWRITEFUNC read, SQUserPointer up, SQUserPointer dest, SQInteger size ) {
188 if ( size && read( up, dest, size ) != size ) {
189 v->Raise_Error( _SC( "io error, read function failure, the origin stream could be corrupted/trucated" ) );
190 return false;
191 }
192 return true;
193 }
194
WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)195 bool WriteTag( HSQUIRRELVM v, SQWRITEFUNC write, SQUserPointer up, SQInteger tag ) {
196 return SafeWrite( v, write, up, &tag, sizeof( tag ) );
197 }
198
CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)199 bool CheckTag( HSQUIRRELVM v, SQWRITEFUNC read, SQUserPointer up, SQInteger tag ) {
200 SQInteger t;
201 _CHECK_IO( SafeRead( v, read, up, &t, sizeof( t ) ) );
202 if ( t != tag ) {
203 v->Raise_Error( _SC( "invalid or corrupted closure stream" ) );
204 return false;
205 }
206 return true;
207 }
208
WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr & o)209 bool WriteObject( HSQUIRRELVM v, SQUserPointer up, SQWRITEFUNC write, SQObjectPtr &o ) {
210 _CHECK_IO( SafeWrite( v, write, up, &squirrel_type( o ), sizeof( SQObjectType ) ) );
211 switch ( squirrel_type( o ) ) {
212 case OT_STRING:
213 _CHECK_IO( SafeWrite( v, write, up, &_string( o )->_len, sizeof( SQInteger ) ) );
214 _CHECK_IO( SafeWrite( v, write, up, _stringval( o ), rsl( _string( o )->_len ) ) );
215 break;
216 case OT_INTEGER:
217 _CHECK_IO( SafeWrite( v, write, up, &_integer( o ), sizeof( SQInteger ) ) );break;
218 case OT_FLOAT:
219 _CHECK_IO( SafeWrite( v, write, up, &_float( o ), sizeof( SQFloat ) ) );break;
220 case OT_NULL:
221 break;
222 default:
223 v->Raise_Error( _SC( "cannot serialize a %s" ), GetTypeName( o ) );
224 return false;
225 }
226 return true;
227 }
228
ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr & o)229 bool ReadObject( HSQUIRRELVM v, SQUserPointer up, SQREADFUNC read, SQObjectPtr &o ) {
230 SQObjectType t;
231 _CHECK_IO( SafeRead( v, read, up, &t, sizeof( SQObjectType ) ) );
232 switch ( t ) {
233 case OT_STRING: {
234 SQInteger len;
235 _CHECK_IO( SafeRead( v, read, up, &len, sizeof( SQInteger ) ) );
236 _CHECK_IO( SafeRead( v, read, up, _ss( v )->GetScratchPad( rsl( len ) ), rsl( len ) ) );
237 o = SQString::Create( _ss( v ), _ss( v )->GetScratchPad( -1 ), len );
238 }
239 break;
240 case OT_INTEGER: {
241 SQInteger i;
242 _CHECK_IO( SafeRead( v, read, up, &i, sizeof( SQInteger ) ) ); o = i; break;
243 }
244 case OT_FLOAT: {
245 SQFloat f;
246 _CHECK_IO( SafeRead( v, read, up, &f, sizeof( SQFloat ) ) ); o = f; break;
247 }
248 case OT_NULL:
249 o = _null_;
250 break;
251 default:
252 v->Raise_Error( _SC( "cannot serialize a %s" ), IdType2Name( t ) );
253 return false;
254 }
255 return true;
256 }
257
Save(SQVM * v,SQUserPointer up,SQWRITEFUNC write)258 bool SQClosure::Save( SQVM *v, SQUserPointer up, SQWRITEFUNC write ) {
259 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_HEAD ) );
260 _CHECK_IO( WriteTag( v, write, up, sizeof( SQChar ) ) );
261 _CHECK_IO( _funcproto( _function )->Save( v, up, write ) );
262 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_TAIL ) );
263 return true;
264 }
265
Load(SQVM * v,SQUserPointer up,SQREADFUNC read)266 bool SQClosure::Load( SQVM *v, SQUserPointer up, SQREADFUNC read ) {
267 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_HEAD ) );
268 _CHECK_IO( CheckTag( v, read, up, sizeof( SQChar ) ) );
269 _CHECK_IO( _funcproto( _function )->Load( v, up, read ) );
270 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_TAIL ) );
271 return true;
272 }
273
Save(SQVM * v,SQUserPointer up,SQWRITEFUNC write)274 bool SQFunctionProto::Save( SQVM *v, SQUserPointer up, SQWRITEFUNC write ) {
275 SQInteger i, nsize = _literals.size();
276 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
277 _CHECK_IO( WriteObject( v, up, write, _sourcename ) );
278 _CHECK_IO( WriteObject( v, up, write, _name ) );
279 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
280 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
281 for ( i = 0;i < nsize;i++ ) {
282 _CHECK_IO( WriteObject( v, up, write, _literals[i] ) );
283 }
284 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
285 nsize = _parameters.size();
286 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
287 for ( i = 0;i < nsize;i++ ) {
288 _CHECK_IO( WriteObject( v, up, write, _parameters[i] ) );
289 }
290 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
291 nsize = _outervalues.size();
292 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
293 for ( i = 0;i < nsize;i++ ) {
294 _CHECK_IO( SafeWrite( v, write, up, &_outervalues[i]._type, sizeof( SQUnsignedInteger ) ) );
295 _CHECK_IO( WriteObject( v, up, write, _outervalues[i]._src ) );
296 _CHECK_IO( WriteObject( v, up, write, _outervalues[i]._name ) );
297 }
298 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
299 nsize = _localvarinfos.size();
300 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
301 for ( i = 0;i < nsize;i++ ) {
302 SQLocalVarInfo &lvi = _localvarinfos[i];
303 _CHECK_IO( WriteObject( v, up, write, lvi._name ) );
304 _CHECK_IO( SafeWrite( v, write, up, &lvi._pos, sizeof( SQUnsignedInteger ) ) );
305 _CHECK_IO( SafeWrite( v, write, up, &lvi._start_op, sizeof( SQUnsignedInteger ) ) );
306 _CHECK_IO( SafeWrite( v, write, up, &lvi._end_op, sizeof( SQUnsignedInteger ) ) );
307 }
308 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
309 nsize = _lineinfos.size();
310 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
311 _CHECK_IO( SafeWrite( v, write, up, &_lineinfos[0], sizeof( SQLineInfo )*nsize ) );
312 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
313 nsize = _instructions.size();
314 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
315 _CHECK_IO( SafeWrite( v, write, up, &_instructions[0], sizeof( SQInstruction )*nsize ) );
316 _CHECK_IO( WriteTag( v, write, up, SQ_CLOSURESTREAM_PART ) );
317 nsize = _functions.size();
318 _CHECK_IO( SafeWrite( v, write, up, &nsize, sizeof( nsize ) ) );
319 for ( i = 0;i < nsize;i++ ) {
320 _CHECK_IO( _funcproto( _functions[i] )->Save( v, up, write ) );
321 }
322 _CHECK_IO( SafeWrite( v, write, up, &_stacksize, sizeof( _stacksize ) ) );
323 _CHECK_IO( SafeWrite( v, write, up, &_bgenerator, sizeof( _bgenerator ) ) );
324 _CHECK_IO( SafeWrite( v, write, up, &_varparams, sizeof( _varparams ) ) );
325 return true;
326 }
327
Load(SQVM * v,SQUserPointer up,SQREADFUNC read)328 bool SQFunctionProto::Load( SQVM *v, SQUserPointer up, SQREADFUNC read ) {
329 SQInteger i, nsize = _literals.size();
330 SQObjectPtr o;
331 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
332 _CHECK_IO( ReadObject( v, up, read, _sourcename ) );
333 _CHECK_IO( ReadObject( v, up, read, _name ) );
334 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
335 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
336 for ( i = 0;i < nsize; i++ ) {
337 _CHECK_IO( ReadObject( v, up, read, o ) );
338 _literals.push_back( o );
339 }
340 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
341 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
342 for ( i = 0; i < nsize; i++ ) {
343 _CHECK_IO( ReadObject( v, up, read, o ) );
344 _parameters.push_back( o );
345 }
346 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
347 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
348 for ( i = 0; i < nsize; i++ ) {
349 SQUnsignedInteger type;
350 SQObjectPtr name;
351 _CHECK_IO( SafeRead( v, read, up, &type, sizeof( SQUnsignedInteger ) ) );
352 _CHECK_IO( ReadObject( v, up, read, o ) );
353 _CHECK_IO( ReadObject( v, up, read, name ) );
354 _outervalues.push_back( SQOuterVar( name, o, ( SQOuterType )type ) );
355 }
356 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
357 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
358 for ( i = 0; i < nsize; i++ ) {
359 SQLocalVarInfo lvi;
360 _CHECK_IO( ReadObject( v, up, read, lvi._name ) );
361 _CHECK_IO( SafeRead( v, read, up, &lvi._pos, sizeof( SQUnsignedInteger ) ) );
362 _CHECK_IO( SafeRead( v, read, up, &lvi._start_op, sizeof( SQUnsignedInteger ) ) );
363 _CHECK_IO( SafeRead( v, read, up, &lvi._end_op, sizeof( SQUnsignedInteger ) ) );
364 _localvarinfos.push_back( lvi );
365 }
366 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
367 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
368 _lineinfos.resize( nsize );
369 _CHECK_IO( SafeRead( v, read, up, &_lineinfos[0], sizeof( SQLineInfo )*nsize ) );
370 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
371 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
372 _instructions.resize( nsize );
373 _CHECK_IO( SafeRead( v, read, up, &_instructions[0], sizeof( SQInstruction )*nsize ) );
374 _CHECK_IO( CheckTag( v, read, up, SQ_CLOSURESTREAM_PART ) );
375 _CHECK_IO( SafeRead( v, read, up, &nsize, sizeof( nsize ) ) );
376 for ( i = 0; i < nsize; i++ ) {
377 o = SQFunctionProto::Create();
378 _CHECK_IO( _funcproto( o )->Load( v, up, read ) );
379 _functions.push_back( o );
380 }
381 _CHECK_IO( SafeRead( v, read, up, &_stacksize, sizeof( _stacksize ) ) );
382 _CHECK_IO( SafeRead( v, read, up, &_bgenerator, sizeof( _bgenerator ) ) );
383 _CHECK_IO( SafeRead( v, read, up, &_varparams, sizeof( _varparams ) ) );
384 return true;
385 }
386
387 #ifndef NO_GARBAGE_COLLECTOR
388
389 #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
390 _uiRef|=MARK_FLAG;
391
392 #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
393 AddToChain(chain, this); }
394
Mark(SQCollectable ** chain)395 void SQVM::Mark( SQCollectable **chain ) {
396 START_MARK()
397 SQSharedState::MarkObject( _lasterror, chain );
398 SQSharedState::MarkObject( _errorhandler, chain );
399 SQSharedState::MarkObject( _debughook, chain );
400 SQSharedState::MarkObject( _roottable, chain );
401 SQSharedState::MarkObject( temp_reg, chain );
402 for ( SQUnsignedInteger i = 0; i < _stack.size(); i++ ) SQSharedState::MarkObject( _stack[i], chain );
403 for ( SQUnsignedInteger j = 0; j < _vargsstack.size(); j++ ) SQSharedState::MarkObject( _vargsstack[j], chain );
404 END_MARK()
405 }
406
Mark(SQCollectable ** chain)407 void SQArray::Mark( SQCollectable **chain ) {
408 START_MARK()
409 SQInteger len = _values.size();
410 for ( SQInteger i = 0;i < len; i++ ) SQSharedState::MarkObject( _values[i], chain );
411 END_MARK()
412 }
Mark(SQCollectable ** chain)413 void SQTable::Mark( SQCollectable **chain ) {
414 START_MARK()
415 if ( _delegate ) _delegate->Mark( chain );
416 SQInteger len = _numofnodes;
417 for ( SQInteger i = 0; i < len; i++ ) {
418 SQSharedState::MarkObject( _nodes[i].key, chain );
419 SQSharedState::MarkObject( _nodes[i].val, chain );
420 }
421 END_MARK()
422 }
423
Mark(SQCollectable ** chain)424 void SQClass::Mark( SQCollectable **chain ) {
425 START_MARK()
426 _members->Mark( chain );
427 if ( _base ) _base->Mark( chain );
428 SQSharedState::MarkObject( _attributes, chain );
429 for ( SQUnsignedInteger i = 0; i < _defaultvalues.size(); i++ ) {
430 SQSharedState::MarkObject( _defaultvalues[i].val, chain );
431 SQSharedState::MarkObject( _defaultvalues[i].attrs, chain );
432 }
433 for ( SQUnsignedInteger j = 0; j < _methods.size(); j++ ) {
434 SQSharedState::MarkObject( _methods[j].val, chain );
435 SQSharedState::MarkObject( _methods[j].attrs, chain );
436 }
437 for ( SQUnsignedInteger k = 0; k < _metamethods.size(); k++ ) {
438 SQSharedState::MarkObject( _metamethods[k], chain );
439 }
440 END_MARK()
441 }
442
Mark(SQCollectable ** chain)443 void SQInstance::Mark( SQCollectable **chain ) {
444 START_MARK()
445 _class->Mark( chain );
446 for ( SQUnsignedInteger i = 0; i < _nvalues; i++ ) {
447 SQSharedState::MarkObject( _values[i], chain );
448 }
449 END_MARK()
450 }
451
Mark(SQCollectable ** chain)452 void SQGenerator::Mark( SQCollectable **chain ) {
453 START_MARK()
454 for ( SQUnsignedInteger i = 0; i < _stack.size(); i++ ) SQSharedState::MarkObject( _stack[i], chain );
455 for ( SQUnsignedInteger j = 0; j < _vargsstack.size(); j++ ) SQSharedState::MarkObject( _vargsstack[j], chain );
456 SQSharedState::MarkObject( _closure, chain );
457 END_MARK()
458 }
459
Mark(SQCollectable ** chain)460 void SQClosure::Mark( SQCollectable **chain ) {
461 START_MARK()
462 for ( SQUnsignedInteger i = 0; i < _outervalues.size(); i++ ) SQSharedState::MarkObject( _outervalues[i], chain );
463 END_MARK()
464 }
465
Mark(SQCollectable ** chain)466 void SQNativeClosure::Mark( SQCollectable **chain ) {
467 START_MARK()
468 for ( SQUnsignedInteger i = 0; i < _outervalues.size(); i++ ) SQSharedState::MarkObject( _outervalues[i], chain );
469 END_MARK()
470 }
471
Mark(SQCollectable ** chain)472 void SQUserData::Mark( SQCollectable **chain ) {
473 START_MARK()
474 if ( _delegate ) _delegate->Mark( chain );
475 END_MARK()
476 }
477
UnMark()478 void SQCollectable::UnMark() {
479 _uiRef &= ~MARK_FLAG;
480 }
481
482 #endif
483
484