Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sqobject.cpp
00001 /* 00002 see copyright notice in squirrel.h 00003 */ 00004 #include "sqpcheader.h" 00005 #include "sqvm.h" 00006 #include "sqstring.h" 00007 #include "sqarray.h" 00008 #include "sqtable.h" 00009 #include "squserdata.h" 00010 #include "sqfuncproto.h" 00011 #include "sqclass.h" 00012 #include "sqclosure.h" 00013 00014 00015 const SQChar *IdType2Name(SQObjectType type) 00016 { 00017 switch(_RAW_TYPE(type)) 00018 { 00019 case _RT_NULL:return _SC("null"); 00020 case _RT_INTEGER:return _SC("integer"); 00021 case _RT_FLOAT:return _SC("float"); 00022 case _RT_BOOL:return _SC("bool"); 00023 case _RT_STRING:return _SC("string"); 00024 case _RT_TABLE:return _SC("table"); 00025 case _RT_ARRAY:return _SC("array"); 00026 case _RT_GENERATOR:return _SC("generator"); 00027 case _RT_CLOSURE: 00028 case _RT_NATIVECLOSURE: 00029 return _SC("function"); 00030 case _RT_USERDATA: 00031 case _RT_USERPOINTER: 00032 return _SC("userdata"); 00033 case _RT_THREAD: return _SC("thread"); 00034 case _RT_FUNCPROTO: return _SC("function"); 00035 case _RT_CLASS: return _SC("class"); 00036 case _RT_INSTANCE: return _SC("instance"); 00037 case _RT_WEAKREF: return _SC("weakref"); 00038 case _RT_OUTER: return _SC("outer"); 00039 default: 00040 return NULL; 00041 } 00042 } 00043 00044 const SQChar *GetTypeName(const SQObjectPtr &obj1) 00045 { 00046 return IdType2Name(type(obj1)); 00047 } 00048 00049 SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) 00050 { 00051 SQString *str=ADD_STRING(ss,s,len); 00052 return str; 00053 } 00054 00055 void SQString::Release() 00056 { 00057 REMOVE_STRING(_sharedstate,this); 00058 } 00059 00060 SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) 00061 { 00062 SQInteger idx = (SQInteger)TranslateIndex(refpos); 00063 while(idx < _len){ 00064 outkey = (SQInteger)idx; 00065 outval = (SQInteger)((SQUnsignedInteger)_val[idx]); 00066 //return idx for the next iteration 00067 return ++idx; 00068 } 00069 //nothing to iterate anymore 00070 return -1; 00071 } 00072 00073 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) 00074 { 00075 switch(type(idx)){ 00076 case OT_NULL: 00077 return 0; 00078 case OT_INTEGER: 00079 return (SQUnsignedInteger)_integer(idx); 00080 default: assert(0); break; 00081 } 00082 return 0; 00083 } 00084 00085 SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) 00086 { 00087 if(!_weakref) { 00088 sq_new(_weakref,SQWeakRef); 00089 _weakref->_obj._type = type; 00090 _weakref->_obj._unVal.pRefCounted = this; 00091 } 00092 return _weakref; 00093 } 00094 00095 SQRefCounted::~SQRefCounted() 00096 { 00097 if(_weakref) { 00098 _weakref->_obj._type = OT_NULL; 00099 _weakref->_obj._unVal.pRefCounted = NULL; 00100 } 00101 } 00102 00103 void SQWeakRef::Release() { 00104 if(ISREFCOUNTED(_obj._type)) { 00105 _obj._unVal.pRefCounted->_weakref = NULL; 00106 } 00107 sq_delete(this,SQWeakRef); 00108 } 00109 00110 bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { 00111 if(_delegate) { 00112 return _delegate->Get((*_ss(v)->_metamethods)[mm],res); 00113 } 00114 return false; 00115 } 00116 00117 bool SQDelegable::SetDelegate(SQTable *mt) 00118 { 00119 SQTable *temp = mt; 00120 if(temp == this) return false; 00121 while (temp) { 00122 if (temp->_delegate == this) return false; //cycle detected 00123 temp = temp->_delegate; 00124 } 00125 if (mt) __ObjAddRef(mt); 00126 __ObjRelease(_delegate); 00127 _delegate = mt; 00128 return true; 00129 } 00130 00131 bool SQGenerator::Yield(SQVM *v,SQInteger target) 00132 { 00133 if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} 00134 if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } 00135 SQInteger size = v->_top-v->_stackbase; 00136 00137 _stack.resize(size); 00138 SQObject _this = v->_stack[v->_stackbase]; 00139 _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; 00140 for(SQInteger n =1; n<target; n++) { 00141 _stack._vals[n] = v->_stack[v->_stackbase+n]; 00142 } 00143 for(SQInteger j =0; j < size; j++) 00144 { 00145 v->_stack[v->_stackbase+j].Null(); 00146 } 00147 00148 _ci = *v->ci; 00149 _ci._generator=NULL; 00150 for(SQInteger i=0;i<_ci._etraps;i++) { 00151 _etraps.push_back(v->_etraps.top()); 00152 v->_etraps.pop_back(); 00153 } 00154 _state=eSuspended; 00155 return true; 00156 } 00157 00158 bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) 00159 { 00160 if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } 00161 if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } 00162 SQInteger size = _stack.size(); 00163 SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); 00164 assert(target>=0 && target<=255); 00165 if(!v->EnterFrame(v->_top, v->_top + size, false)) 00166 return false; 00167 v->ci->_generator = this; 00168 v->ci->_target = (SQInt32)target; 00169 v->ci->_closure = _ci._closure; 00170 v->ci->_ip = _ci._ip; 00171 v->ci->_literals = _ci._literals; 00172 v->ci->_ncalls = _ci._ncalls; 00173 v->ci->_etraps = _ci._etraps; 00174 v->ci->_root = _ci._root; 00175 00176 00177 for(SQInteger i=0;i<_ci._etraps;i++) { 00178 v->_etraps.push_back(_etraps.top()); 00179 _etraps.pop_back(); 00180 } 00181 SQObject _this = _stack._vals[0]; 00182 v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; 00183 00184 for(SQInteger n = 1; n<size; n++) { 00185 v->_stack[v->_stackbase+n] = _stack._vals[n]; 00186 _stack._vals[n].Null(); 00187 } 00188 00189 _state=eRunning; 00190 if (v->_debughook) 00191 v->CallDebugHook(_SC('c')); 00192 00193 return true; 00194 } 00195 00196 void SQArray::Extend(const SQArray *a){ 00197 SQInteger xlen; 00198 if((xlen=a->Size())) 00199 for(SQInteger i=0;i<xlen;i++) 00200 Append(a->_values[i]); 00201 } 00202 00203 const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) 00204 { 00205 SQUnsignedInteger nvars=_nlocalvarinfos; 00206 const SQChar *res=NULL; 00207 if(nvars>=nseq){ 00208 for(SQUnsignedInteger i=0;i<nvars;i++){ 00209 if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop) 00210 { 00211 if(nseq==0){ 00212 vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); 00213 res=_stringval(_localvarinfos[i]._name); 00214 break; 00215 } 00216 nseq--; 00217 } 00218 } 00219 } 00220 return res; 00221 } 00222 00223 00224 SQInteger SQFunctionProto::GetLine(SQInstruction *curr) 00225 { 00226 SQInteger op = (SQInteger)(curr-_instructions); 00227 SQInteger line=_lineinfos[0]._line; 00228 SQInteger low = 0; 00229 SQInteger high = _nlineinfos - 1; 00230 SQInteger mid = 0; 00231 while(low <= high) 00232 { 00233 mid = low + ((high - low) >> 1); 00234 SQInteger curop = _lineinfos[mid]._op; 00235 if(curop > op) 00236 { 00237 high = mid - 1; 00238 } 00239 else if(curop < op) { 00240 if(mid < (_nlineinfos - 1) 00241 && _lineinfos[mid + 1]._op >= op) { 00242 break; 00243 } 00244 low = mid + 1; 00245 } 00246 else { //equal 00247 break; 00248 } 00249 } 00250 00251 line = _lineinfos[mid]._line; 00252 return line; 00253 } 00254 00255 SQClosure::~SQClosure() 00256 { 00257 __ObjRelease(_env); 00258 __ObjRelease(_base); 00259 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); 00260 } 00261 00262 #define _CHECK_IO(exp) { if(!exp)return false; } 00263 bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) 00264 { 00265 if(write(up,dest,size) != size) { 00266 v->Raise_Error(_SC("io error (write function failure)")); 00267 return false; 00268 } 00269 return true; 00270 } 00271 00272 bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) 00273 { 00274 if(size && read(up,dest,size) != size) { 00275 v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); 00276 return false; 00277 } 00278 return true; 00279 } 00280 00281 bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) 00282 { 00283 return SafeWrite(v,write,up,&tag,sizeof(tag)); 00284 } 00285 00286 bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) 00287 { 00288 SQUnsignedInteger32 t; 00289 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); 00290 if(t != tag){ 00291 v->Raise_Error(_SC("invalid or corrupted closure stream")); 00292 return false; 00293 } 00294 return true; 00295 } 00296 00297 bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) 00298 { 00299 SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); 00300 _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); 00301 switch(type(o)){ 00302 case OT_STRING: 00303 _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); 00304 _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); 00305 break; 00306 case OT_BOOL: 00307 case OT_INTEGER: 00308 _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; 00309 case OT_FLOAT: 00310 _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; 00311 case OT_NULL: 00312 break; 00313 default: 00314 v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); 00315 return false; 00316 } 00317 return true; 00318 } 00319 00320 bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) 00321 { 00322 SQUnsignedInteger32 _type; 00323 _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); 00324 SQObjectType t = (SQObjectType)_type; 00325 switch(t){ 00326 case OT_STRING:{ 00327 SQInteger len; 00328 _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); 00329 _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); 00330 o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); 00331 } 00332 break; 00333 case OT_INTEGER:{ 00334 SQInteger i; 00335 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; 00336 } 00337 case OT_BOOL:{ 00338 SQInteger i; 00339 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break; 00340 } 00341 case OT_FLOAT:{ 00342 SQFloat f; 00343 _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; 00344 } 00345 case OT_NULL: 00346 o.Null(); 00347 break; 00348 default: 00349 v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); 00350 return false; 00351 } 00352 return true; 00353 } 00354 00355 bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) 00356 { 00357 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); 00358 _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); 00359 _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); 00360 _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); 00361 _CHECK_IO(_function->Save(v,up,write)); 00362 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); 00363 return true; 00364 } 00365 00366 bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) 00367 { 00368 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); 00369 _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); 00370 _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); 00371 _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); 00372 SQObjectPtr func; 00373 _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); 00374 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); 00375 ret = SQClosure::Create(_ss(v),_funcproto(func)); 00376 return true; 00377 } 00378 00379 SQFunctionProto::SQFunctionProto(SQSharedState *ss) 00380 { 00381 _stacksize=0; 00382 _bgenerator=false; 00383 INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); 00384 } 00385 00386 SQFunctionProto::~SQFunctionProto() 00387 { 00388 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); 00389 } 00390 00391 bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) 00392 { 00393 SQInteger i,nliterals = _nliterals,nparameters = _nparameters; 00394 SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; 00395 SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; 00396 SQInteger ndefaultparams = _ndefaultparams; 00397 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00398 _CHECK_IO(WriteObject(v,up,write,_sourcename)); 00399 _CHECK_IO(WriteObject(v,up,write,_name)); 00400 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00401 _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); 00402 _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); 00403 _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); 00404 _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); 00405 _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); 00406 _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); 00407 _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); 00408 _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); 00409 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00410 for(i=0;i<nliterals;i++){ 00411 _CHECK_IO(WriteObject(v,up,write,_literals[i])); 00412 } 00413 00414 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00415 for(i=0;i<nparameters;i++){ 00416 _CHECK_IO(WriteObject(v,up,write,_parameters[i])); 00417 } 00418 00419 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00420 for(i=0;i<noutervalues;i++){ 00421 _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger))); 00422 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src)); 00423 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name)); 00424 } 00425 00426 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00427 for(i=0;i<nlocalvarinfos;i++){ 00428 SQLocalVarInfo &lvi=_localvarinfos[i]; 00429 _CHECK_IO(WriteObject(v,up,write,lvi._name)); 00430 _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger))); 00431 _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger))); 00432 _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger))); 00433 } 00434 00435 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00436 _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos)); 00437 00438 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00439 _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams)); 00440 00441 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00442 _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions)); 00443 00444 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); 00445 for(i=0;i<nfunctions;i++){ 00446 _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write)); 00447 } 00448 _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); 00449 _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); 00450 _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); 00451 return true; 00452 } 00453 00454 bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) 00455 { 00456 SQInteger i, nliterals,nparameters; 00457 SQInteger noutervalues ,nlocalvarinfos ; 00458 SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; 00459 SQObjectPtr sourcename, name; 00460 SQObjectPtr o; 00461 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00462 _CHECK_IO(ReadObject(v, up, read, sourcename)); 00463 _CHECK_IO(ReadObject(v, up, read, name)); 00464 00465 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00466 _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); 00467 _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); 00468 _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); 00469 _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); 00470 _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); 00471 _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); 00472 _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); 00473 _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); 00474 00475 00476 SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, 00477 nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); 00478 SQObjectPtr proto = f; //gets a ref in case of failure 00479 f->_sourcename = sourcename; 00480 f->_name = name; 00481 00482 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00483 00484 for(i = 0;i < nliterals; i++){ 00485 _CHECK_IO(ReadObject(v, up, read, o)); 00486 f->_literals[i] = o; 00487 } 00488 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00489 00490 for(i = 0; i < nparameters; i++){ 00491 _CHECK_IO(ReadObject(v, up, read, o)); 00492 f->_parameters[i] = o; 00493 } 00494 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00495 00496 for(i = 0; i < noutervalues; i++){ 00497 SQUnsignedInteger type; 00498 SQObjectPtr name; 00499 _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); 00500 _CHECK_IO(ReadObject(v, up, read, o)); 00501 _CHECK_IO(ReadObject(v, up, read, name)); 00502 f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); 00503 } 00504 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00505 00506 for(i = 0; i < nlocalvarinfos; i++){ 00507 SQLocalVarInfo lvi; 00508 _CHECK_IO(ReadObject(v, up, read, lvi._name)); 00509 _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); 00510 _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); 00511 _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); 00512 f->_localvarinfos[i] = lvi; 00513 } 00514 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00515 _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); 00516 00517 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00518 _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); 00519 00520 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00521 _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); 00522 00523 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); 00524 for(i = 0; i < nfunctions; i++){ 00525 _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); 00526 f->_functions[i] = o; 00527 } 00528 _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); 00529 _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); 00530 _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); 00531 00532 ret = f; 00533 return true; 00534 } 00535 00536 #ifndef NO_GARBAGE_COLLECTOR 00537 00538 #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ 00539 _uiRef|=MARK_FLAG; 00540 00541 #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ 00542 AddToChain(chain, this); } 00543 00544 void SQVM::Mark(SQCollectable **chain) 00545 { 00546 START_MARK() 00547 SQSharedState::MarkObject(_lasterror,chain); 00548 SQSharedState::MarkObject(_errorhandler,chain); 00549 SQSharedState::MarkObject(_debughook_closure,chain); 00550 SQSharedState::MarkObject(_roottable, chain); 00551 SQSharedState::MarkObject(temp_reg, chain); 00552 for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); 00553 for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); 00554 END_MARK() 00555 } 00556 00557 void SQArray::Mark(SQCollectable **chain) 00558 { 00559 START_MARK() 00560 SQInteger len = _values.size(); 00561 for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); 00562 END_MARK() 00563 } 00564 void SQTable::Mark(SQCollectable **chain) 00565 { 00566 START_MARK() 00567 if(_delegate) _delegate->Mark(chain); 00568 SQInteger len = _numofnodes; 00569 for(SQInteger i = 0; i < len; i++){ 00570 SQSharedState::MarkObject(_nodes[i].key, chain); 00571 SQSharedState::MarkObject(_nodes[i].val, chain); 00572 } 00573 END_MARK() 00574 } 00575 00576 void SQClass::Mark(SQCollectable **chain) 00577 { 00578 START_MARK() 00579 _members->Mark(chain); 00580 if(_base) _base->Mark(chain); 00581 SQSharedState::MarkObject(_attributes, chain); 00582 for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { 00583 SQSharedState::MarkObject(_defaultvalues[i].val, chain); 00584 SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); 00585 } 00586 for(SQUnsignedInteger j =0; j< _methods.size(); j++) { 00587 SQSharedState::MarkObject(_methods[j].val, chain); 00588 SQSharedState::MarkObject(_methods[j].attrs, chain); 00589 } 00590 for(SQUnsignedInteger k =0; k< MT_LAST; k++) { 00591 SQSharedState::MarkObject(_metamethods[k], chain); 00592 } 00593 END_MARK() 00594 } 00595 00596 void SQInstance::Mark(SQCollectable **chain) 00597 { 00598 START_MARK() 00599 _class->Mark(chain); 00600 SQUnsignedInteger nvalues = _class->_defaultvalues.size(); 00601 for(SQUnsignedInteger i =0; i< nvalues; i++) { 00602 SQSharedState::MarkObject(_values[i], chain); 00603 } 00604 END_MARK() 00605 } 00606 00607 void SQGenerator::Mark(SQCollectable **chain) 00608 { 00609 START_MARK() 00610 for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); 00611 SQSharedState::MarkObject(_closure, chain); 00612 END_MARK() 00613 } 00614 00615 void SQFunctionProto::Mark(SQCollectable **chain) 00616 { 00617 START_MARK() 00618 for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); 00619 for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); 00620 END_MARK() 00621 } 00622 00623 void SQClosure::Mark(SQCollectable **chain) 00624 { 00625 START_MARK() 00626 if(_base) _base->Mark(chain); 00627 SQFunctionProto *fp = _function; 00628 fp->Mark(chain); 00629 for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); 00630 for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); 00631 END_MARK() 00632 } 00633 00634 void SQNativeClosure::Mark(SQCollectable **chain) 00635 { 00636 START_MARK() 00637 for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); 00638 END_MARK() 00639 } 00640 00641 void SQOuter::Mark(SQCollectable **chain) 00642 { 00643 START_MARK() 00644 /* If the valptr points to a closed value, that value is alive */ 00645 if(_valptr == &_value) { 00646 SQSharedState::MarkObject(_value, chain); 00647 } 00648 END_MARK() 00649 } 00650 00651 void SQUserData::Mark(SQCollectable **chain){ 00652 START_MARK() 00653 if(_delegate) _delegate->Mark(chain); 00654 END_MARK() 00655 } 00656 00657 void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } 00658 00659 #endif 00660
Generated on Tue Jul 12 2022 21:35:49 by
