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);
38 bool SQDelegable::GetMetaMethod(SQMetaMethod mm,SQObjectPtr &res) {
40 return _delegate->Get((*_ss(this)->_metamethods)[mm],res);
45 bool SQGenerator::Yield(SQVM *v)
47 if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
48 if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
49 int size = v->_top-v->_stackbase;
52 for(int n =0; n<size; n++) {
53 _stack._vals[n] = v->_stack[v->_stackbase+n];
54 v->_stack[v->_stackbase+n] = _null_;
56 int nvargs = v->ci->_vargs.size;
57 int vargsbase = v->ci->_vargs.base;
58 for(int j = nvargs - 1; j >= 0; j--) {
59 _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
61 _ci._generator=_null_;
62 for(int i=0;i<_ci._etraps;i++) {
63 _etraps.push_back(v->_etraps.top());
64 v->_etraps.pop_back();
70 bool SQGenerator::Resume(SQVM *v,int target)
72 int size=_stack.size();
73 if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
74 if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
75 int prevtop=v->_top-v->_stackbase;
77 int oldstackbase=v->_stackbase;
78 v->_stackbase=v->_top;
79 v->ci->_target=target;
80 v->ci->_generator=SQObjectPtr(this);
81 v->ci->_vargs.size = _vargsstack.size();
83 for(int i=0;i<_ci._etraps;i++) {
84 v->_etraps.push_back(_etraps.top());
87 for(int n =0; n<size; n++) {
88 v->_stack[v->_stackbase+n] = _stack._vals[n];
89 _stack._vals[0] = _null_;
91 while(_vargsstack.size()) {
92 v->_vargsstack.push_back(_vargsstack.back());
93 _vargsstack.pop_back();
95 v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;
96 v->_top=v->_stackbase+size;
97 v->ci->_prevtop=prevtop;
98 v->ci->_prevstkbase=v->_stackbase-oldstackbase;
103 void SQArray::Extend(const SQArray *a){
106 for(int i=0;i<xlen;i++)
107 Append(a->_values[i]);
110 const SQChar* SQFunctionProto::GetLocal(SQVM *vm,unsigned int stackbase,unsigned int nseq,unsigned int nop)
112 unsigned int nvars=_localvarinfos.size();
113 const SQChar *res=NULL;
115 for(unsigned int i=0;i<nvars;i++){
116 if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
119 vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
120 res=_stringval(_localvarinfos[i]._name);
130 int SQFunctionProto::GetLine(SQInstruction *curr)
132 int op=(curr-_instructions._vals);
133 int line=_lineinfos[0]._line;
134 for(unsigned int i=1;i<_lineinfos.size();i++){
135 if(_lineinfos[i]._op>=op)
137 line=_lineinfos[i]._line;
142 //#define _ERROR_TRAP() error_trap:
143 #define _CHECK_IO(exp) { if(!exp)return false; }
144 bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,int size)
146 if(write(up,dest,size) != size) {
147 v->Raise_Error(_SC("io error (write function failure)"));
153 bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,int size)
155 if(size && read(up,dest,size) != size) {
156 v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
162 bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,int tag)
164 return SafeWrite(v,write,up,&tag,sizeof(tag));
167 bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,int tag)
170 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
172 v->Raise_Error(_SC("invalid or corrupted closure stream"));
178 bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
180 _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
183 _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
184 _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
187 _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
189 _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
193 v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
199 bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
202 _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
206 _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
207 _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
208 o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
213 _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
217 _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
223 v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
229 bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
231 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
232 _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
233 _CHECK_IO(_funcproto(_function)->Save(v,up,write));
234 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
238 bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
240 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
241 _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
242 _CHECK_IO(_funcproto(_function)->Load(v,up,read));
243 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
247 bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
249 int i,nsize=_literals.size();
250 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
251 _CHECK_IO(WriteObject(v,up,write,_sourcename));
252 _CHECK_IO(WriteObject(v,up,write,_name));
253 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
254 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
255 for(i=0;i<nsize;i++){
256 _CHECK_IO(WriteObject(v,up,write,_literals[i]));
258 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
259 nsize=_parameters.size();
260 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
261 for(i=0;i<nsize;i++){
262 _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
264 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
265 nsize=_outervalues.size();
266 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
267 for(i=0;i<nsize;i++){
268 _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(unsigned int)));
269 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
270 _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
272 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
273 nsize=_localvarinfos.size();
274 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
275 for(i=0;i<nsize;i++){
276 SQLocalVarInfo &lvi=_localvarinfos[i];
277 _CHECK_IO(WriteObject(v,up,write,lvi._name));
278 _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(unsigned int)));
279 _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(unsigned int)));
280 _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(unsigned int)));
282 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
283 nsize=_lineinfos.size();
284 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
285 _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));
286 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
287 nsize=_instructions.size();
288 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
289 _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));
290 _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
291 nsize=_functions.size();
292 _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
293 for(i=0;i<nsize;i++){
294 _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
296 _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
297 _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
298 _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
302 bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
304 int i, nsize = _literals.size();
306 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
307 _CHECK_IO(ReadObject(v, up, read, _sourcename));
308 _CHECK_IO(ReadObject(v, up, read, _name));
309 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
310 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
311 for(i = 0;i < nsize; i++){
312 _CHECK_IO(ReadObject(v, up, read, o));
313 _literals.push_back(o);
315 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
316 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
317 for(i = 0; i < nsize; i++){
318 _CHECK_IO(ReadObject(v, up, read, o));
319 _parameters.push_back(o);
321 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
322 _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize)));
323 for(i = 0; i < nsize; i++){
326 _CHECK_IO(SafeRead(v,read,up, &type, sizeof(unsigned int)));
327 _CHECK_IO(ReadObject(v, up, read, o));
328 _CHECK_IO(ReadObject(v, up, read, name));
329 _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type));
331 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
332 _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize)));
333 for(i = 0; i < nsize; i++){
335 _CHECK_IO(ReadObject(v, up, read, lvi._name));
336 _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(unsigned int)));
337 _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(unsigned int)));
338 _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(unsigned int)));
339 _localvarinfos.push_back(lvi);
341 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
342 _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize)));
343 _lineinfos.resize(nsize);
344 _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize));
345 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
346 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
347 _instructions.resize(nsize);
348 _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize));
349 _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
350 _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
351 for(i = 0; i < nsize; i++){
352 o = SQFunctionProto::Create();
353 _CHECK_IO(_funcproto(o)->Load(v, up, read));
354 _functions.push_back(o);
356 _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize)));
357 _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator)));
358 _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams)));
362 #ifndef NO_GARBAGE_COLLECTOR
364 #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
367 #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
368 AddToChain(chain, this); }
370 void SQVM::Mark(SQCollectable **chain)
373 SQSharedState::MarkObject(_lasterror,chain);
374 SQSharedState::MarkObject(_errorhandler,chain);
375 SQSharedState::MarkObject(_debughook,chain);
376 SQSharedState::MarkObject(_roottable, chain);
377 SQSharedState::MarkObject(temp_reg, chain);
378 for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
379 for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
383 void SQArray::Mark(SQCollectable **chain)
386 int len = _values.size();
387 for(int i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
390 void SQTable::Mark(SQCollectable **chain)
393 if(_delegate) _delegate->Mark(chain);
394 int len = _numofnodes;
395 for(int i = 0; i < len; i++){
396 SQSharedState::MarkObject(_nodes[i].key, chain);
397 SQSharedState::MarkObject(_nodes[i].val, chain);
402 void SQClass::Mark(SQCollectable **chain)
405 _members->Mark(chain);
406 if(_base) _base->Mark(chain);
407 SQSharedState::MarkObject(_attributes, chain);
408 for(unsigned int i =0; i< _defaultvalues.size(); i++) {
409 SQSharedState::MarkObject(_defaultvalues[i].val, chain);
410 SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
412 for(unsigned int j =0; j< _methods.size(); j++) {
413 SQSharedState::MarkObject(_methods[j].val, chain);
414 SQSharedState::MarkObject(_methods[j].attrs, chain);
416 for(unsigned int k =0; k< _metamethods.size(); k++) {
417 SQSharedState::MarkObject(_metamethods[k], chain);
422 void SQInstance::Mark(SQCollectable **chain)
426 for(unsigned int i =0; i< _values.size(); i++) {
427 SQSharedState::MarkObject(_values[i], chain);
432 void SQGenerator::Mark(SQCollectable **chain)
435 for(unsigned int i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
436 for(unsigned int j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
437 SQSharedState::MarkObject(_closure, chain);
441 void SQClosure::Mark(SQCollectable **chain)
444 for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
448 void SQNativeClosure::Mark(SQCollectable **chain)
451 for(unsigned int i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
455 void SQUserData::Mark(SQCollectable **chain){
457 if(_delegate) _delegate->Mark(chain);
461 void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }