0001
0002
0003
0004 #include "pspcheader.h"
0005 #include "psvm.h"
0006 #include "psstring.h"
0007 #include "psarray.h"
0008 #include "pstable.h"
0009 #include "psuserdata.h"
0010 #include "psfuncproto.h"
0011 #include "psclass.h"
0012 #include "psclosure.h"
0013
0014
0015 const PSChar *IdType2Name(PSObjectType type)
0016 {
0017 switch(_RAW_TYPE(type))
0018 {
0019 case _RT_NULL:return _SC("null");
0020 case _RT_INTEGER:return _SC("integer");
0021 case _RT_FLOAT:return _SC("float");
0022 case _RT_BOOL:return _SC("bool");
0023 case _RT_STRING:return _SC("string");
0024 case _RT_TABLE:return _SC("table");
0025 case _RT_ARRAY:return _SC("array");
0026 case _RT_GENERATOR:return _SC("generator");
0027 case _RT_CLOSURE:
0028 case _RT_NATIVECLOSURE:
0029 return _SC("function");
0030 case _RT_USERDATA:
0031 case _RT_USERPOINTER:
0032 return _SC("userdata");
0033 case _RT_THREAD: return _SC("thread");
0034 case _RT_FUNCPROTO: return _SC("function");
0035 case _RT_CLASS: return _SC("class");
0036 case _RT_INSTANCE: return _SC("instance");
0037 case _RT_WEAKREF: return _SC("weakref");
0038 case _RT_OUTER: return _SC("outer");
0039 default:
0040 return NULL;
0041 }
0042 }
0043
0044 const PSChar *GetTypeName(const PSObjectPtr &obj1)
0045 {
0046 return IdType2Name(type(obj1));
0047 }
0048
0049 PSString *PSString::Create(PSSharedState *ss,const PSChar *s,PSInteger len)
0050 {
0051 PSString *str=ADD_STRING(ss,s,len);
0052 return str;
0053 }
0054
0055 void PSString::Release()
0056 {
0057 REMOVE_STRING(_sharedstate,this);
0058 }
0059
0060 PSInteger PSString::Next(const PSObjectPtr &refpos, PSObjectPtr &outkey, PSObjectPtr &outval)
0061 {
0062 PSInteger idx = (PSInteger)TranslateIndex(refpos);
0063 while(idx < _len){
0064 outkey = (PSInteger)idx;
0065 outval = (PSInteger)((PSUnsignedInteger)_val[idx]);
0066
0067 return ++idx;
0068 }
0069
0070 return -1;
0071 }
0072
0073 PSUnsignedInteger TranslateIndex(const PSObjectPtr &idx)
0074 {
0075 switch(type(idx)){
0076 case OT_NULL:
0077 return 0;
0078 case OT_INTEGER:
0079 return (PSUnsignedInteger)_integer(idx);
0080 default: assert(0); break;
0081 }
0082 return 0;
0083 }
0084
0085 PSWeakRef *PSRefCounted::GetWeakRef(PSObjectType type)
0086 {
0087 if(!_weakref) {
0088 ps_new(_weakref,PSWeakRef);
0089 #if defined(PSUSEDOUBLE) && !defined(_PS64)
0090 _weakref->_obj._unVal.raw = 0;
0091 #endif
0092 _weakref->_obj._type = type;
0093 _weakref->_obj._unVal.pRefCounted = this;
0094 }
0095 return _weakref;
0096 }
0097
0098 PSRefCounted::~PSRefCounted()
0099 {
0100 if(_weakref) {
0101 _weakref->_obj._type = OT_NULL;
0102 _weakref->_obj._unVal.pRefCounted = NULL;
0103 }
0104 }
0105
0106 void PSWeakRef::Release() {
0107 if(ISREFCOUNTED(_obj._type)) {
0108 _obj._unVal.pRefCounted->_weakref = NULL;
0109 }
0110 ps_delete(this,PSWeakRef);
0111 }
0112
0113 bool PSDelegable::GetMetaMethod(PSVM *v,PSMetaMethod mm,PSObjectPtr &res) {
0114 if(_delegate) {
0115 return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
0116 }
0117 return false;
0118 }
0119
0120 bool PSDelegable::SetDelegate(PSTable *mt)
0121 {
0122 PSTable *temp = mt;
0123 if(temp == this) return false;
0124 while (temp) {
0125 if (temp->_delegate == this) return false;
0126 temp = temp->_delegate;
0127 }
0128 if (mt) __ObjAddRef(mt);
0129 __ObjRelease(_delegate);
0130 _delegate = mt;
0131 return true;
0132 }
0133
0134 bool PSGenerator::Yield(PSVM *v,PSInteger target)
0135 {
0136 if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
0137 if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
0138 PSInteger size = v->_top-v->_stackbase;
0139
0140 _stack.resize(size);
0141 PSObject _this = v->_stack[v->_stackbase];
0142 _stack._vals[0] = ISREFCOUNTED(type(_this)) ? PSObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this;
0143 for(PSInteger n =1; n<target; n++) {
0144 _stack._vals[n] = v->_stack[v->_stackbase+n];
0145 }
0146 for(PSInteger j =0; j < size; j++)
0147 {
0148 v->_stack[v->_stackbase+j].Null();
0149 }
0150
0151 _ci = *v->ci;
0152 _ci._generator=NULL;
0153 for(PSInteger i=0;i<_ci._etraps;i++) {
0154 _etraps.push_back(v->_etraps.top());
0155 v->_etraps.pop_back();
0156
0157 PSExceptionTrap &et = _etraps.back();
0158 et._stackbase -= v->_stackbase;
0159 et._stacksize -= v->_stackbase;
0160 }
0161 _state=eSuspended;
0162 return true;
0163 }
0164
0165 bool PSGenerator::Resume(PSVM *v,PSObjectPtr &dest)
0166 {
0167 if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
0168 if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
0169 PSInteger size = _stack.size();
0170 PSInteger target = &dest - &(v->_stack._vals[v->_stackbase]);
0171 assert(target>=0 && target<=255);
0172 PSInteger newbase = v->_top;
0173 if(!v->EnterFrame(v->_top, v->_top + size, false))
0174 return false;
0175 v->ci->_generator = this;
0176 v->ci->_target = (PSInt32)target;
0177 v->ci->_closure = _ci._closure;
0178 v->ci->_ip = _ci._ip;
0179 v->ci->_literals = _ci._literals;
0180 v->ci->_ncalls = _ci._ncalls;
0181 v->ci->_etraps = _ci._etraps;
0182 v->ci->_root = _ci._root;
0183
0184
0185 for(PSInteger i=0;i<_ci._etraps;i++) {
0186 v->_etraps.push_back(_etraps.top());
0187 _etraps.pop_back();
0188 PSExceptionTrap &et = v->_etraps.back();
0189
0190 et._stackbase += newbase;
0191 et._stacksize += newbase;
0192 }
0193 PSObject _this = _stack._vals[0];
0194 v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this;
0195
0196 for(PSInteger n = 1; n<size; n++) {
0197 v->_stack[v->_stackbase+n] = _stack._vals[n];
0198 _stack._vals[n].Null();
0199 }
0200
0201 _state=eRunning;
0202 if (v->_debughook)
0203 v->CallDebugHook(_SC('c'));
0204
0205 return true;
0206 }
0207
0208 void PSArray::Extend(const PSArray *a){
0209 PSInteger xlen;
0210 if((xlen=a->Size()))
0211 for(PSInteger i=0;i<xlen;i++)
0212 Append(a->_values[i]);
0213 }
0214
0215 const PSChar* PSFunctionProto::GetLocal(PSVM *vm,PSUnsignedInteger stackbase,PSUnsignedInteger nseq,PSUnsignedInteger nop)
0216 {
0217 PSUnsignedInteger nvars=_nlocalvarinfos;
0218 const PSChar *res=NULL;
0219 if(nvars>=nseq){
0220 for(PSUnsignedInteger i=0;i<nvars;i++){
0221 if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
0222 {
0223 if(nseq==0){
0224 vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
0225 res=_stringval(_localvarinfos[i]._name);
0226 break;
0227 }
0228 nseq--;
0229 }
0230 }
0231 }
0232 return res;
0233 }
0234
0235
0236 PSInteger PSFunctionProto::GetLine(PSInstruction *curr)
0237 {
0238 PSInteger op = (PSInteger)(curr-_instructions);
0239 PSInteger line=_lineinfos[0]._line;
0240 PSInteger low = 0;
0241 PSInteger high = _nlineinfos - 1;
0242 PSInteger mid = 0;
0243 while(low <= high)
0244 {
0245 mid = low + ((high - low) >> 1);
0246 PSInteger curop = _lineinfos[mid]._op;
0247 if(curop > op)
0248 {
0249 high = mid - 1;
0250 }
0251 else if(curop < op) {
0252 if(mid < (_nlineinfos - 1)
0253 && _lineinfos[mid + 1]._op >= op) {
0254 break;
0255 }
0256 low = mid + 1;
0257 }
0258 else {
0259 break;
0260 }
0261 }
0262
0263 while(mid > 0 && _lineinfos[mid]._op >= op) mid--;
0264
0265 line = _lineinfos[mid]._line;
0266
0267 return line;
0268 }
0269
0270 PSClosure::~PSClosure()
0271 {
0272 __ObjRelease(_root);
0273 __ObjRelease(_env);
0274 __ObjRelease(_base);
0275 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
0276 }
0277
0278 #define _CHECK_IO(exp) { if(!exp)return false; }
0279 bool SafeWrite(HPSCRIPTVM v,PSWRITEFUNC write,PSUserPointer up,PSUserPointer dest,PSInteger size)
0280 {
0281 if(write(up,dest,size) != size) {
0282 v->Raise_Error(_SC("io error (write function failure)"));
0283 return false;
0284 }
0285 return true;
0286 }
0287
0288 bool SafeRead(HPSCRIPTVM v,PSWRITEFUNC read,PSUserPointer up,PSUserPointer dest,PSInteger size)
0289 {
0290 if(size && read(up,dest,size) != size) {
0291 v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
0292 return false;
0293 }
0294 return true;
0295 }
0296
0297 bool WriteTag(HPSCRIPTVM v,PSWRITEFUNC write,PSUserPointer up,PSUnsignedInteger32 tag)
0298 {
0299 return SafeWrite(v,write,up,&tag,sizeof(tag));
0300 }
0301
0302 bool CheckTag(HPSCRIPTVM v,PSWRITEFUNC read,PSUserPointer up,PSUnsignedInteger32 tag)
0303 {
0304 PSUnsignedInteger32 t;
0305 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
0306 if(t != tag){
0307 v->Raise_Error(_SC("invalid or corrupted closure stream"));
0308 return false;
0309 }
0310 return true;
0311 }
0312
0313 bool WriteObject(HPSCRIPTVM v,PSUserPointer up,PSWRITEFUNC write,PSObjectPtr &o)
0314 {
0315 PSUnsignedInteger32 _type = (PSUnsignedInteger32)type(o);
0316 _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
0317 switch(type(o)){
0318 case OT_STRING:
0319 _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(PSInteger)));
0320 _CHECK_IO(SafeWrite(v,write,up,_stringval(o),ps_rsl(_string(o)->_len)));
0321 break;
0322 case OT_BOOL:
0323 case OT_INTEGER:
0324 _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(PSInteger)));break;
0325 case OT_FLOAT:
0326 _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(PSFloat)));break;
0327 case OT_NULL:
0328 break;
0329 default:
0330 v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
0331 return false;
0332 }
0333 return true;
0334 }
0335
0336 bool ReadObject(HPSCRIPTVM v,PSUserPointer up,PSREADFUNC read,PSObjectPtr &o)
0337 {
0338 PSUnsignedInteger32 _type;
0339 _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
0340 PSObjectType t = (PSObjectType)_type;
0341 switch(t){
0342 case OT_STRING:{
0343 PSInteger len;
0344 _CHECK_IO(SafeRead(v,read,up,&len,sizeof(PSInteger)));
0345 _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(ps_rsl(len)),ps_rsl(len)));
0346 o=PSString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
0347 }
0348 break;
0349 case OT_INTEGER:{
0350 PSInteger i;
0351 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(PSInteger))); o = i; break;
0352 }
0353 case OT_BOOL:{
0354 PSInteger i;
0355 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(PSInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break;
0356 }
0357 case OT_FLOAT:{
0358 PSFloat f;
0359 _CHECK_IO(SafeRead(v,read,up,&f,sizeof(PSFloat))); o = f; break;
0360 }
0361 case OT_NULL:
0362 o.Null();
0363 break;
0364 default:
0365 v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
0366 return false;
0367 }
0368 return true;
0369 }
0370
0371 bool PSClosure::Save(PSVM *v,PSUserPointer up,PSWRITEFUNC write)
0372 {
0373 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_HEAD));
0374 _CHECK_IO(WriteTag(v,write,up,sizeof(PSChar)));
0375 _CHECK_IO(WriteTag(v,write,up,sizeof(PSInteger)));
0376 _CHECK_IO(WriteTag(v,write,up,sizeof(PSFloat)));
0377 _CHECK_IO(_function->Save(v,up,write));
0378 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_TAIL));
0379 return true;
0380 }
0381
0382 bool PSClosure::Load(PSVM *v,PSUserPointer up,PSREADFUNC read,PSObjectPtr &ret)
0383 {
0384 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_HEAD));
0385 _CHECK_IO(CheckTag(v,read,up,sizeof(PSChar)));
0386 _CHECK_IO(CheckTag(v,read,up,sizeof(PSInteger)));
0387 _CHECK_IO(CheckTag(v,read,up,sizeof(PSFloat)));
0388 PSObjectPtr func;
0389 _CHECK_IO(PSFunctionProto::Load(v,up,read,func));
0390 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_TAIL));
0391 ret = PSClosure::Create(_ss(v),_funcproto(func),_table(v->_roottable)->GetWeakRef(OT_TABLE));
0392
0393 return true;
0394 }
0395
0396 PSFunctionProto::PSFunctionProto(PSSharedState *ss)
0397 {
0398 _stacksize=0;
0399 _bgenerator=false;
0400 INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
0401 }
0402
0403 PSFunctionProto::~PSFunctionProto()
0404 {
0405 REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
0406 }
0407
0408 bool PSFunctionProto::Save(PSVM *v,PSUserPointer up,PSWRITEFUNC write)
0409 {
0410 PSInteger i,nliterals = _nliterals,nparameters = _nparameters;
0411 PSInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
0412 PSInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
0413 PSInteger ndefaultparams = _ndefaultparams;
0414 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0415 _CHECK_IO(WriteObject(v,up,write,_sourcename));
0416 _CHECK_IO(WriteObject(v,up,write,_name));
0417 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0418 _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
0419 _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
0420 _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
0421 _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
0422 _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
0423 _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
0424 _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
0425 _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
0426 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0427 for(i=0;i<nliterals;i++){
0428 _CHECK_IO(WriteObject(v,up,write,_literals[i]));
0429 }
0430
0431 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0432 for(i=0;i<nparameters;i++){
0433 _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
0434 }
0435
0436 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0437 for(i=0;i<noutervalues;i++){
0438 _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(PSUnsignedInteger)));
0439 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
0440 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
0441 }
0442
0443 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0444 for(i=0;i<nlocalvarinfos;i++){
0445 PSLocalVarInfo &lvi=_localvarinfos[i];
0446 _CHECK_IO(WriteObject(v,up,write,lvi._name));
0447 _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(PSUnsignedInteger)));
0448 _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(PSUnsignedInteger)));
0449 _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(PSUnsignedInteger)));
0450 }
0451
0452 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0453 _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(PSLineInfo)*nlineinfos));
0454
0455 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0456 _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(PSInteger)*ndefaultparams));
0457
0458 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0459 _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(PSInstruction)*ninstructions));
0460
0461 _CHECK_IO(WriteTag(v,write,up,PS_CLOSURESTREAM_PART));
0462 for(i=0;i<nfunctions;i++){
0463 _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
0464 }
0465 _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
0466 _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
0467 _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
0468 return true;
0469 }
0470
0471 bool PSFunctionProto::Load(PSVM *v,PSUserPointer up,PSREADFUNC read,PSObjectPtr &ret)
0472 {
0473 PSInteger i, nliterals,nparameters;
0474 PSInteger noutervalues ,nlocalvarinfos ;
0475 PSInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
0476 PSObjectPtr sourcename, name;
0477 PSObjectPtr o;
0478 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0479 _CHECK_IO(ReadObject(v, up, read, sourcename));
0480 _CHECK_IO(ReadObject(v, up, read, name));
0481
0482 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0483 _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
0484 _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
0485 _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
0486 _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
0487 _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
0488 _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
0489 _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
0490 _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
0491
0492
0493 PSFunctionProto *f = PSFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters,
0494 nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
0495 PSObjectPtr proto = f;
0496 f->_sourcename = sourcename;
0497 f->_name = name;
0498
0499 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0500
0501 for(i = 0;i < nliterals; i++){
0502 _CHECK_IO(ReadObject(v, up, read, o));
0503 f->_literals[i] = o;
0504 }
0505 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0506
0507 for(i = 0; i < nparameters; i++){
0508 _CHECK_IO(ReadObject(v, up, read, o));
0509 f->_parameters[i] = o;
0510 }
0511 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0512
0513 for(i = 0; i < noutervalues; i++){
0514 PSUnsignedInteger type;
0515 PSObjectPtr name;
0516 _CHECK_IO(SafeRead(v,read,up, &type, sizeof(PSUnsignedInteger)));
0517 _CHECK_IO(ReadObject(v, up, read, o));
0518 _CHECK_IO(ReadObject(v, up, read, name));
0519 f->_outervalues[i] = PSOuterVar(name,o, (PSOuterType)type);
0520 }
0521 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0522
0523 for(i = 0; i < nlocalvarinfos; i++){
0524 PSLocalVarInfo lvi;
0525 _CHECK_IO(ReadObject(v, up, read, lvi._name));
0526 _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(PSUnsignedInteger)));
0527 _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(PSUnsignedInteger)));
0528 _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(PSUnsignedInteger)));
0529 f->_localvarinfos[i] = lvi;
0530 }
0531 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0532 _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(PSLineInfo)*nlineinfos));
0533
0534 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0535 _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(PSInteger)*ndefaultparams));
0536
0537 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0538 _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(PSInstruction)*ninstructions));
0539
0540 _CHECK_IO(CheckTag(v,read,up,PS_CLOSURESTREAM_PART));
0541 for(i = 0; i < nfunctions; i++){
0542 _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
0543 f->_functions[i] = o;
0544 }
0545 _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
0546 _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
0547 _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
0548
0549 ret = f;
0550 return true;
0551 }
0552
0553 #ifndef NO_GARBAGE_COLLECTOR
0554
0555 #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
0556 _uiRef|=MARK_FLAG;
0557
0558 #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
0559 AddToChain(chain, this); }
0560
0561 void PSVM::Mark(PSCollectable **chain)
0562 {
0563 START_MARK()
0564 PSSharedState::MarkObject(_lasterror,chain);
0565 PSSharedState::MarkObject(_errorhandler,chain);
0566 PSSharedState::MarkObject(_debughook_closure,chain);
0567 PSSharedState::MarkObject(_roottable, chain);
0568 PSSharedState::MarkObject(temp_reg, chain);
0569 for(PSUnsignedInteger i = 0; i < _stack.size(); i++) PSSharedState::MarkObject(_stack[i], chain);
0570 for(PSInteger k = 0; k < _callsstacksize; k++) PSSharedState::MarkObject(_callsstack[k]._closure, chain);
0571 END_MARK()
0572 }
0573
0574 void PSArray::Mark(PSCollectable **chain)
0575 {
0576 START_MARK()
0577 PSInteger len = _values.size();
0578 for(PSInteger i = 0;i < len; i++) PSSharedState::MarkObject(_values[i], chain);
0579 END_MARK()
0580 }
0581 void PSTable::Mark(PSCollectable **chain)
0582 {
0583 START_MARK()
0584 if(_delegate) _delegate->Mark(chain);
0585 PSInteger len = _numofnodes;
0586 for(PSInteger i = 0; i < len; i++){
0587 PSSharedState::MarkObject(_nodes[i].key, chain);
0588 PSSharedState::MarkObject(_nodes[i].val, chain);
0589 }
0590 END_MARK()
0591 }
0592
0593 void PSClass::Mark(PSCollectable **chain)
0594 {
0595 START_MARK()
0596 _members->Mark(chain);
0597 if(_base) _base->Mark(chain);
0598 PSSharedState::MarkObject(_attributes, chain);
0599 for(PSUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
0600 PSSharedState::MarkObject(_defaultvalues[i].val, chain);
0601 PSSharedState::MarkObject(_defaultvalues[i].attrs, chain);
0602 }
0603 for(PSUnsignedInteger j =0; j< _methods.size(); j++) {
0604 PSSharedState::MarkObject(_methods[j].val, chain);
0605 PSSharedState::MarkObject(_methods[j].attrs, chain);
0606 }
0607 for(PSUnsignedInteger k =0; k< MT_LAST; k++) {
0608 PSSharedState::MarkObject(_metamethods[k], chain);
0609 }
0610 END_MARK()
0611 }
0612
0613 void PSInstance::Mark(PSCollectable **chain)
0614 {
0615 START_MARK()
0616 _class->Mark(chain);
0617 PSUnsignedInteger nvalues = _class->_defaultvalues.size();
0618 for(PSUnsignedInteger i =0; i< nvalues; i++) {
0619 PSSharedState::MarkObject(_values[i], chain);
0620 }
0621 END_MARK()
0622 }
0623
0624 void PSGenerator::Mark(PSCollectable **chain)
0625 {
0626 START_MARK()
0627 for(PSUnsignedInteger i = 0; i < _stack.size(); i++) PSSharedState::MarkObject(_stack[i], chain);
0628 PSSharedState::MarkObject(_closure, chain);
0629 END_MARK()
0630 }
0631
0632 void PSFunctionProto::Mark(PSCollectable **chain)
0633 {
0634 START_MARK()
0635 for(PSInteger i = 0; i < _nliterals; i++) PSSharedState::MarkObject(_literals[i], chain);
0636 for(PSInteger k = 0; k < _nfunctions; k++) PSSharedState::MarkObject(_functions[k], chain);
0637 END_MARK()
0638 }
0639
0640 void PSClosure::Mark(PSCollectable **chain)
0641 {
0642 START_MARK()
0643 if(_base) _base->Mark(chain);
0644 PSFunctionProto *fp = _function;
0645 fp->Mark(chain);
0646 for(PSInteger i = 0; i < fp->_noutervalues; i++) PSSharedState::MarkObject(_outervalues[i], chain);
0647 for(PSInteger k = 0; k < fp->_ndefaultparams; k++) PSSharedState::MarkObject(_defaultparams[k], chain);
0648 END_MARK()
0649 }
0650
0651 void PSNativeClosure::Mark(PSCollectable **chain)
0652 {
0653 START_MARK()
0654 for(PSUnsignedInteger i = 0; i < _noutervalues; i++) PSSharedState::MarkObject(_outervalues[i], chain);
0655 END_MARK()
0656 }
0657
0658 void PSOuter::Mark(PSCollectable **chain)
0659 {
0660 START_MARK()
0661
0662 if(_valptr == &_value) {
0663 PSSharedState::MarkObject(_value, chain);
0664 }
0665 END_MARK()
0666 }
0667
0668 void PSUserData::Mark(PSCollectable **chain){
0669 START_MARK()
0670 if(_delegate) _delegate->Mark(chain);
0671 END_MARK()
0672 }
0673
0674 void PSCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
0675
0676 #endif
0677