2 see copyright notice in squirrel.h
4 #include "sqpcheader.h"
9 #include "squserdata.h"
10 #include "sqfuncproto.h"
12 #include "sqclosure.h"
14 SQString *SQString::Create(SQSharedState *ss,const SQChar *s,int len)
16 SQString *str=ADD_STRING(ss,s,len);
21 void SQString::Release()
23 REMOVE_STRING(_sharedstate,this);
26 unsigned int TranslateIndex(const SQObjectPtr &idx)
32 return (unsigned int)_integer(idx);
40 bool SQDelegable::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res) {
42 return _delegate->Get((*_ss(this)->_metamethods)[mm],res);
47 bool SQGenerator::Yield(SQVM *v)
49 if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
50 if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
51 int size = v->_top-v->_stackbase;
54 for(int n =0; n<size; n++) {
55 _stack._vals[n] = v->_stack[v->_stackbase+n];
56 v->_stack[v->_stackbase+n] = _null_;
58 int nvargs = v->ci->_vargs.size;
59 int vargsbase = v->ci->_vargs.base;
60 for(int j = nvargs - 1; j >= 0; j--) {
61 _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
63 _ci._generator=_null_;
64 for(int i=0;i<_ci._etraps;i++) {
65 _etraps.push_back(v->_etraps.top());
66 v->_etraps.pop_back();
72 bool SQGenerator::Resume(SQVM *v,int target)
74 int size=_stack.size();
75 if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
76 if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
77 int prevtop=v->_top-v->_stackbase;
79 int oldstackbase=v->_stackbase;
80 v->_stackbase=v->_top;
81 v->ci->_target=target;
82 v->ci->_generator=SQObjectPtr(this);
83 v->ci->_vargs.size = _vargsstack.size();
85 for(int i=0;i<_ci._etraps;i++) {
86 v->_etraps.push_back(_etraps.top());
89 for(int n =0; n<size; n++) {
90 v->_stack[v->_stackbase+n] = _stack._vals[n];
91 _stack._vals[0] = _null_;
93 while(_vargsstack.size()) {
94 v->_vargsstack.push_back(_vargsstack.back());
95 _vargsstack.pop_back();
97 v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;
98 v->_top=v->_stackbase+size;
99 v->ci->_prevtop=prevtop;
100 v->ci->_prevstkbase=v->_stackbase-oldstackbase;
105 void SQArray::Extend(const SQArray *a){
108 for(int i=0;i<xlen;i++)
109 Append(a->_values[i]);
112 const SQChar* SQFunctionProto::GetLocal(SQVM *vm,unsigned int stackbase,unsigned int nseq,unsigned int nop)
114 unsigned int nvars=_localvarinfos.size();
115 const SQChar *res=NULL;
117 for(unsigned int i=0;i<nvars;i++){
118 if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
121 vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
122 res=_stringval(_localvarinfos[i]._name);
132 int SQFunctionProto::GetLine(SQInstruction *curr)
134 int op=(curr-_instructions._vals);
135 int line=_lineinfos[0]._line;
136 for(unsigned int i=1;i<_lineinfos.size();i++){
137 if(_lineinfos[i]._op>=op)
139 line=_lineinfos[i]._line;
144 //#define _ERROR_TRAP() error_trap:
145 #define _CHECK_IO(exp) { if(!exp)return false; }
146 bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,int size)
148 if(write(up,dest,size) != size) {
149 v->Raise_Error(_SC("io error (write function failure)"));
155 bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,int size)
157 if(size && read(up,dest,size) != size) {
158 v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
164 bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,int tag)
166 return SafeWrite(v,write,up,&tag,sizeof(tag));
169 bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,int tag)
172 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
174 v->Raise_Error(_SC("invalid or corrupted closure stream"));
180 bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
182 _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
185 _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
186 _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
189 _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
191 _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
195 v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
201 bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
204 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
208 _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
209 _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
210 o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
215 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
219 _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
225 v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
231 bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
233 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
234 _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
235 _CHECK_IO(_funcproto(_function)->Save(v,up,write));
236 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
240 bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
242 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
243 _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
244 _CHECK_IO(_funcproto(_function)->Load(v,up,read));
245 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
249 bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
251 int i,nsize=_literals.size();
252 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
253 _CHECK_IO(WriteObject(v,up,write,_sourcename));
254 _CHECK_IO(WriteObject(v,up,write,_name));
255 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
256 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
257 for(i=0;i<nsize;i++){
258 _CHECK_IO(WriteObject(v,up,write,_literals[i]));
260 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
261 nsize=_parameters.size();
262 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
263 for(i=0;i<nsize;i++){
264 _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
266 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
267 nsize=_outervalues.size();
268 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
269 for(i=0;i<nsize;i++){
270 _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(unsigned int)));
271 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
272 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
274 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
275 nsize=_localvarinfos.size();
276 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
277 for(i=0;i<nsize;i++){
278 SQLocalVarInfo &lvi=_localvarinfos[i];
279 _CHECK_IO(WriteObject(v,up,write,lvi._name));
280 _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(unsigned int)));
281 _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(unsigned int)));
282 _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(unsigned int)));
284 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
285 nsize=_lineinfos.size();
286 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
287 _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));
288 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
289 nsize=_instructions.size();
290 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
291 _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));
292 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
293 nsize=_functions.size();
294 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
295 for(i=0;i<nsize;i++){
296 _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
298 _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
299 _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
300 _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
304 bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
306 int i, nsize = _literals.size();
308 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
309 _CHECK_IO(ReadObject(v, up, read, _sourcename));
310 _CHECK_IO(ReadObject(v, up, read, _name));
311 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
312 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
313 for(i = 0;i < nsize; i++){
314 _CHECK_IO(ReadObject(v, up, read, o));
315 _literals.push_back(o);
317 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
318 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
319 for(i = 0; i < nsize; i++){
320 _CHECK_IO(ReadObject(v, up, read, o));
321 _parameters.push_back(o);
323 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
324 _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize)));
325 for(i = 0; i < nsize; i++){
328 _CHECK_IO(SafeRead(v,read,up, &type, sizeof(unsigned int)));
329 _CHECK_IO(ReadObject(v, up, read, o));
330 _CHECK_IO(ReadObject(v, up, read, name));
331 _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type));
333 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
334 _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize)));
335 for(i = 0; i < nsize; i++){
337 _CHECK_IO(ReadObject(v, up, read, lvi._name));
338 _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(unsigned int)));
339 _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(unsigned int)));
340 _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(unsigned int)));
341 _localvarinfos.push_back(lvi);
343 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
344 _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize)));
345 _lineinfos.resize(nsize);
346 _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize));
347 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
348 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
349 _instructions.resize(nsize);
350 _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize));
351 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
352 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
353 for(i = 0; i < nsize; i++){
354 o = SQFunctionProto::Create();
355 _CHECK_IO(_funcproto(o)->Load(v, up, read));
356 _functions.push_back(o);
358 _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize)));
359 _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator)));
360 _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams)));
364 #ifndef NO_GARBAGE_COLLECTOR
366 #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
369 #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
370 AddToChain(chain, this); }
372 void SQVM::Mark(SQCollectable **chain)
375 SQSharedState::MarkObject(_lasterror,chain);
376 SQSharedState::MarkObject(_errorhandler,chain);
377 SQSharedState::MarkObject(_debughook,chain);
378 SQSharedState::MarkObject(_roottable, chain);
379 SQSharedState::MarkObject(temp_reg, chain);
380 for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
381 for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
385 void SQArray::Mark(SQCollectable **chain)
388 int len = _values.size();
389 for(int i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
392 void SQTable::Mark(SQCollectable **chain)
395 if(_delegate) _delegate->Mark(chain);
396 int len = _numofnodes;
397 for(int i = 0; i < len; i++){
398 SQSharedState::MarkObject(_nodes[i].key, chain);
399 SQSharedState::MarkObject(_nodes[i].val, chain);
404 void SQClass::Mark(SQCollectable **chain)
407 _members->Mark(chain);
408 if(_base) _base->Mark(chain);
409 SQSharedState::MarkObject(_attributes, chain);
410 for(unsigned int i =0; i< _defaultvalues.size(); i++) {
411 SQSharedState::MarkObject(_defaultvalues[i].val, chain);
412 SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
414 for(unsigned int j =0; j< _methods.size(); j++) {
415 SQSharedState::MarkObject(_methods[j].val, chain);
416 SQSharedState::MarkObject(_methods[j].attrs, chain);
418 for(unsigned int k =0; k< _metamethods.size(); k++) {
419 SQSharedState::MarkObject(_metamethods[k], chain);
424 void SQInstance::Mark(SQCollectable **chain)
428 for(unsigned int i =0; i< _values.size(); i++) {
429 SQSharedState::MarkObject(_values[i], chain);
434 void SQGenerator::Mark(SQCollectable **chain)
437 for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
438 for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
439 SQSharedState::MarkObject(_closure, chain);
443 void SQClosure::Mark(SQCollectable **chain)
446 for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
450 void SQNativeClosure::Mark(SQCollectable **chain)
453 for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
457 void SQUserData::Mark(SQCollectable **chain){
459 if(_delegate) _delegate->Mark(chain);
463 void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }