The Squirrel interpreter. See http://www.squirrel-lang.org/
squirrel/sqobject.cpp@3:7268a3ceaffc, 2014-12-16 (annotated)
- Committer:
- jhnwkmn
- Date:
- Tue Dec 16 11:39:42 2014 +0000
- Revision:
- 3:7268a3ceaffc
- Parent:
- 0:97a4f8cc534c
Accepts \r as line terminator as well.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jhnwkmn | 0:97a4f8cc534c | 1 | /* |
jhnwkmn | 0:97a4f8cc534c | 2 | see copyright notice in squirrel.h |
jhnwkmn | 0:97a4f8cc534c | 3 | */ |
jhnwkmn | 0:97a4f8cc534c | 4 | #include "sqpcheader.h" |
jhnwkmn | 0:97a4f8cc534c | 5 | #include "sqvm.h" |
jhnwkmn | 0:97a4f8cc534c | 6 | #include "sqstring.h" |
jhnwkmn | 0:97a4f8cc534c | 7 | #include "sqarray.h" |
jhnwkmn | 0:97a4f8cc534c | 8 | #include "sqtable.h" |
jhnwkmn | 0:97a4f8cc534c | 9 | #include "squserdata.h" |
jhnwkmn | 0:97a4f8cc534c | 10 | #include "sqfuncproto.h" |
jhnwkmn | 0:97a4f8cc534c | 11 | #include "sqclass.h" |
jhnwkmn | 0:97a4f8cc534c | 12 | #include "sqclosure.h" |
jhnwkmn | 0:97a4f8cc534c | 13 | |
jhnwkmn | 0:97a4f8cc534c | 14 | |
jhnwkmn | 0:97a4f8cc534c | 15 | const SQChar *IdType2Name(SQObjectType type) |
jhnwkmn | 0:97a4f8cc534c | 16 | { |
jhnwkmn | 0:97a4f8cc534c | 17 | switch(_RAW_TYPE(type)) |
jhnwkmn | 0:97a4f8cc534c | 18 | { |
jhnwkmn | 0:97a4f8cc534c | 19 | case _RT_NULL:return _SC("null"); |
jhnwkmn | 0:97a4f8cc534c | 20 | case _RT_INTEGER:return _SC("integer"); |
jhnwkmn | 0:97a4f8cc534c | 21 | case _RT_FLOAT:return _SC("float"); |
jhnwkmn | 0:97a4f8cc534c | 22 | case _RT_BOOL:return _SC("bool"); |
jhnwkmn | 0:97a4f8cc534c | 23 | case _RT_STRING:return _SC("string"); |
jhnwkmn | 0:97a4f8cc534c | 24 | case _RT_TABLE:return _SC("table"); |
jhnwkmn | 0:97a4f8cc534c | 25 | case _RT_ARRAY:return _SC("array"); |
jhnwkmn | 0:97a4f8cc534c | 26 | case _RT_GENERATOR:return _SC("generator"); |
jhnwkmn | 0:97a4f8cc534c | 27 | case _RT_CLOSURE: |
jhnwkmn | 0:97a4f8cc534c | 28 | case _RT_NATIVECLOSURE: |
jhnwkmn | 0:97a4f8cc534c | 29 | return _SC("function"); |
jhnwkmn | 0:97a4f8cc534c | 30 | case _RT_USERDATA: |
jhnwkmn | 0:97a4f8cc534c | 31 | case _RT_USERPOINTER: |
jhnwkmn | 0:97a4f8cc534c | 32 | return _SC("userdata"); |
jhnwkmn | 0:97a4f8cc534c | 33 | case _RT_THREAD: return _SC("thread"); |
jhnwkmn | 0:97a4f8cc534c | 34 | case _RT_FUNCPROTO: return _SC("function"); |
jhnwkmn | 0:97a4f8cc534c | 35 | case _RT_CLASS: return _SC("class"); |
jhnwkmn | 0:97a4f8cc534c | 36 | case _RT_INSTANCE: return _SC("instance"); |
jhnwkmn | 0:97a4f8cc534c | 37 | case _RT_WEAKREF: return _SC("weakref"); |
jhnwkmn | 0:97a4f8cc534c | 38 | case _RT_OUTER: return _SC("outer"); |
jhnwkmn | 0:97a4f8cc534c | 39 | default: |
jhnwkmn | 0:97a4f8cc534c | 40 | return NULL; |
jhnwkmn | 0:97a4f8cc534c | 41 | } |
jhnwkmn | 0:97a4f8cc534c | 42 | } |
jhnwkmn | 0:97a4f8cc534c | 43 | |
jhnwkmn | 0:97a4f8cc534c | 44 | const SQChar *GetTypeName(const SQObjectPtr &obj1) |
jhnwkmn | 0:97a4f8cc534c | 45 | { |
jhnwkmn | 0:97a4f8cc534c | 46 | return IdType2Name(type(obj1)); |
jhnwkmn | 0:97a4f8cc534c | 47 | } |
jhnwkmn | 0:97a4f8cc534c | 48 | |
jhnwkmn | 0:97a4f8cc534c | 49 | SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) |
jhnwkmn | 0:97a4f8cc534c | 50 | { |
jhnwkmn | 0:97a4f8cc534c | 51 | SQString *str=ADD_STRING(ss,s,len); |
jhnwkmn | 0:97a4f8cc534c | 52 | return str; |
jhnwkmn | 0:97a4f8cc534c | 53 | } |
jhnwkmn | 0:97a4f8cc534c | 54 | |
jhnwkmn | 0:97a4f8cc534c | 55 | void SQString::Release() |
jhnwkmn | 0:97a4f8cc534c | 56 | { |
jhnwkmn | 0:97a4f8cc534c | 57 | REMOVE_STRING(_sharedstate,this); |
jhnwkmn | 0:97a4f8cc534c | 58 | } |
jhnwkmn | 0:97a4f8cc534c | 59 | |
jhnwkmn | 0:97a4f8cc534c | 60 | SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) |
jhnwkmn | 0:97a4f8cc534c | 61 | { |
jhnwkmn | 0:97a4f8cc534c | 62 | SQInteger idx = (SQInteger)TranslateIndex(refpos); |
jhnwkmn | 0:97a4f8cc534c | 63 | while(idx < _len){ |
jhnwkmn | 0:97a4f8cc534c | 64 | outkey = (SQInteger)idx; |
jhnwkmn | 0:97a4f8cc534c | 65 | outval = (SQInteger)((SQUnsignedInteger)_val[idx]); |
jhnwkmn | 0:97a4f8cc534c | 66 | //return idx for the next iteration |
jhnwkmn | 0:97a4f8cc534c | 67 | return ++idx; |
jhnwkmn | 0:97a4f8cc534c | 68 | } |
jhnwkmn | 0:97a4f8cc534c | 69 | //nothing to iterate anymore |
jhnwkmn | 0:97a4f8cc534c | 70 | return -1; |
jhnwkmn | 0:97a4f8cc534c | 71 | } |
jhnwkmn | 0:97a4f8cc534c | 72 | |
jhnwkmn | 0:97a4f8cc534c | 73 | SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) |
jhnwkmn | 0:97a4f8cc534c | 74 | { |
jhnwkmn | 0:97a4f8cc534c | 75 | switch(type(idx)){ |
jhnwkmn | 0:97a4f8cc534c | 76 | case OT_NULL: |
jhnwkmn | 0:97a4f8cc534c | 77 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 78 | case OT_INTEGER: |
jhnwkmn | 0:97a4f8cc534c | 79 | return (SQUnsignedInteger)_integer(idx); |
jhnwkmn | 0:97a4f8cc534c | 80 | default: assert(0); break; |
jhnwkmn | 0:97a4f8cc534c | 81 | } |
jhnwkmn | 0:97a4f8cc534c | 82 | return 0; |
jhnwkmn | 0:97a4f8cc534c | 83 | } |
jhnwkmn | 0:97a4f8cc534c | 84 | |
jhnwkmn | 0:97a4f8cc534c | 85 | SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) |
jhnwkmn | 0:97a4f8cc534c | 86 | { |
jhnwkmn | 0:97a4f8cc534c | 87 | if(!_weakref) { |
jhnwkmn | 0:97a4f8cc534c | 88 | sq_new(_weakref,SQWeakRef); |
jhnwkmn | 0:97a4f8cc534c | 89 | _weakref->_obj._type = type; |
jhnwkmn | 0:97a4f8cc534c | 90 | _weakref->_obj._unVal.pRefCounted = this; |
jhnwkmn | 0:97a4f8cc534c | 91 | } |
jhnwkmn | 0:97a4f8cc534c | 92 | return _weakref; |
jhnwkmn | 0:97a4f8cc534c | 93 | } |
jhnwkmn | 0:97a4f8cc534c | 94 | |
jhnwkmn | 0:97a4f8cc534c | 95 | SQRefCounted::~SQRefCounted() |
jhnwkmn | 0:97a4f8cc534c | 96 | { |
jhnwkmn | 0:97a4f8cc534c | 97 | if(_weakref) { |
jhnwkmn | 0:97a4f8cc534c | 98 | _weakref->_obj._type = OT_NULL; |
jhnwkmn | 0:97a4f8cc534c | 99 | _weakref->_obj._unVal.pRefCounted = NULL; |
jhnwkmn | 0:97a4f8cc534c | 100 | } |
jhnwkmn | 0:97a4f8cc534c | 101 | } |
jhnwkmn | 0:97a4f8cc534c | 102 | |
jhnwkmn | 0:97a4f8cc534c | 103 | void SQWeakRef::Release() { |
jhnwkmn | 0:97a4f8cc534c | 104 | if(ISREFCOUNTED(_obj._type)) { |
jhnwkmn | 0:97a4f8cc534c | 105 | _obj._unVal.pRefCounted->_weakref = NULL; |
jhnwkmn | 0:97a4f8cc534c | 106 | } |
jhnwkmn | 0:97a4f8cc534c | 107 | sq_delete(this,SQWeakRef); |
jhnwkmn | 0:97a4f8cc534c | 108 | } |
jhnwkmn | 0:97a4f8cc534c | 109 | |
jhnwkmn | 0:97a4f8cc534c | 110 | bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { |
jhnwkmn | 0:97a4f8cc534c | 111 | if(_delegate) { |
jhnwkmn | 0:97a4f8cc534c | 112 | return _delegate->Get((*_ss(v)->_metamethods)[mm],res); |
jhnwkmn | 0:97a4f8cc534c | 113 | } |
jhnwkmn | 0:97a4f8cc534c | 114 | return false; |
jhnwkmn | 0:97a4f8cc534c | 115 | } |
jhnwkmn | 0:97a4f8cc534c | 116 | |
jhnwkmn | 0:97a4f8cc534c | 117 | bool SQDelegable::SetDelegate(SQTable *mt) |
jhnwkmn | 0:97a4f8cc534c | 118 | { |
jhnwkmn | 0:97a4f8cc534c | 119 | SQTable *temp = mt; |
jhnwkmn | 0:97a4f8cc534c | 120 | if(temp == this) return false; |
jhnwkmn | 0:97a4f8cc534c | 121 | while (temp) { |
jhnwkmn | 0:97a4f8cc534c | 122 | if (temp->_delegate == this) return false; //cycle detected |
jhnwkmn | 0:97a4f8cc534c | 123 | temp = temp->_delegate; |
jhnwkmn | 0:97a4f8cc534c | 124 | } |
jhnwkmn | 0:97a4f8cc534c | 125 | if (mt) __ObjAddRef(mt); |
jhnwkmn | 0:97a4f8cc534c | 126 | __ObjRelease(_delegate); |
jhnwkmn | 0:97a4f8cc534c | 127 | _delegate = mt; |
jhnwkmn | 0:97a4f8cc534c | 128 | return true; |
jhnwkmn | 0:97a4f8cc534c | 129 | } |
jhnwkmn | 0:97a4f8cc534c | 130 | |
jhnwkmn | 0:97a4f8cc534c | 131 | bool SQGenerator::Yield(SQVM *v,SQInteger target) |
jhnwkmn | 0:97a4f8cc534c | 132 | { |
jhnwkmn | 0:97a4f8cc534c | 133 | if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} |
jhnwkmn | 0:97a4f8cc534c | 134 | if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } |
jhnwkmn | 0:97a4f8cc534c | 135 | SQInteger size = v->_top-v->_stackbase; |
jhnwkmn | 0:97a4f8cc534c | 136 | |
jhnwkmn | 0:97a4f8cc534c | 137 | _stack.resize(size); |
jhnwkmn | 0:97a4f8cc534c | 138 | SQObject _this = v->_stack[v->_stackbase]; |
jhnwkmn | 0:97a4f8cc534c | 139 | _stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this; |
jhnwkmn | 0:97a4f8cc534c | 140 | for(SQInteger n =1; n<target; n++) { |
jhnwkmn | 0:97a4f8cc534c | 141 | _stack._vals[n] = v->_stack[v->_stackbase+n]; |
jhnwkmn | 0:97a4f8cc534c | 142 | } |
jhnwkmn | 0:97a4f8cc534c | 143 | for(SQInteger j =0; j < size; j++) |
jhnwkmn | 0:97a4f8cc534c | 144 | { |
jhnwkmn | 0:97a4f8cc534c | 145 | v->_stack[v->_stackbase+j].Null(); |
jhnwkmn | 0:97a4f8cc534c | 146 | } |
jhnwkmn | 0:97a4f8cc534c | 147 | |
jhnwkmn | 0:97a4f8cc534c | 148 | _ci = *v->ci; |
jhnwkmn | 0:97a4f8cc534c | 149 | _ci._generator=NULL; |
jhnwkmn | 0:97a4f8cc534c | 150 | for(SQInteger i=0;i<_ci._etraps;i++) { |
jhnwkmn | 0:97a4f8cc534c | 151 | _etraps.push_back(v->_etraps.top()); |
jhnwkmn | 0:97a4f8cc534c | 152 | v->_etraps.pop_back(); |
jhnwkmn | 0:97a4f8cc534c | 153 | } |
jhnwkmn | 0:97a4f8cc534c | 154 | _state=eSuspended; |
jhnwkmn | 0:97a4f8cc534c | 155 | return true; |
jhnwkmn | 0:97a4f8cc534c | 156 | } |
jhnwkmn | 0:97a4f8cc534c | 157 | |
jhnwkmn | 0:97a4f8cc534c | 158 | bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) |
jhnwkmn | 0:97a4f8cc534c | 159 | { |
jhnwkmn | 0:97a4f8cc534c | 160 | if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } |
jhnwkmn | 0:97a4f8cc534c | 161 | if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } |
jhnwkmn | 0:97a4f8cc534c | 162 | SQInteger size = _stack.size(); |
jhnwkmn | 0:97a4f8cc534c | 163 | SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); |
jhnwkmn | 0:97a4f8cc534c | 164 | assert(target>=0 && target<=255); |
jhnwkmn | 0:97a4f8cc534c | 165 | if(!v->EnterFrame(v->_top, v->_top + size, false)) |
jhnwkmn | 0:97a4f8cc534c | 166 | return false; |
jhnwkmn | 0:97a4f8cc534c | 167 | v->ci->_generator = this; |
jhnwkmn | 0:97a4f8cc534c | 168 | v->ci->_target = (SQInt32)target; |
jhnwkmn | 0:97a4f8cc534c | 169 | v->ci->_closure = _ci._closure; |
jhnwkmn | 0:97a4f8cc534c | 170 | v->ci->_ip = _ci._ip; |
jhnwkmn | 0:97a4f8cc534c | 171 | v->ci->_literals = _ci._literals; |
jhnwkmn | 0:97a4f8cc534c | 172 | v->ci->_ncalls = _ci._ncalls; |
jhnwkmn | 0:97a4f8cc534c | 173 | v->ci->_etraps = _ci._etraps; |
jhnwkmn | 0:97a4f8cc534c | 174 | v->ci->_root = _ci._root; |
jhnwkmn | 0:97a4f8cc534c | 175 | |
jhnwkmn | 0:97a4f8cc534c | 176 | |
jhnwkmn | 0:97a4f8cc534c | 177 | for(SQInteger i=0;i<_ci._etraps;i++) { |
jhnwkmn | 0:97a4f8cc534c | 178 | v->_etraps.push_back(_etraps.top()); |
jhnwkmn | 0:97a4f8cc534c | 179 | _etraps.pop_back(); |
jhnwkmn | 0:97a4f8cc534c | 180 | } |
jhnwkmn | 0:97a4f8cc534c | 181 | SQObject _this = _stack._vals[0]; |
jhnwkmn | 0:97a4f8cc534c | 182 | v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; |
jhnwkmn | 0:97a4f8cc534c | 183 | |
jhnwkmn | 0:97a4f8cc534c | 184 | for(SQInteger n = 1; n<size; n++) { |
jhnwkmn | 0:97a4f8cc534c | 185 | v->_stack[v->_stackbase+n] = _stack._vals[n]; |
jhnwkmn | 0:97a4f8cc534c | 186 | _stack._vals[n].Null(); |
jhnwkmn | 0:97a4f8cc534c | 187 | } |
jhnwkmn | 0:97a4f8cc534c | 188 | |
jhnwkmn | 0:97a4f8cc534c | 189 | _state=eRunning; |
jhnwkmn | 0:97a4f8cc534c | 190 | if (v->_debughook) |
jhnwkmn | 0:97a4f8cc534c | 191 | v->CallDebugHook(_SC('c')); |
jhnwkmn | 0:97a4f8cc534c | 192 | |
jhnwkmn | 0:97a4f8cc534c | 193 | return true; |
jhnwkmn | 0:97a4f8cc534c | 194 | } |
jhnwkmn | 0:97a4f8cc534c | 195 | |
jhnwkmn | 0:97a4f8cc534c | 196 | void SQArray::Extend(const SQArray *a){ |
jhnwkmn | 0:97a4f8cc534c | 197 | SQInteger xlen; |
jhnwkmn | 0:97a4f8cc534c | 198 | if((xlen=a->Size())) |
jhnwkmn | 0:97a4f8cc534c | 199 | for(SQInteger i=0;i<xlen;i++) |
jhnwkmn | 0:97a4f8cc534c | 200 | Append(a->_values[i]); |
jhnwkmn | 0:97a4f8cc534c | 201 | } |
jhnwkmn | 0:97a4f8cc534c | 202 | |
jhnwkmn | 0:97a4f8cc534c | 203 | const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) |
jhnwkmn | 0:97a4f8cc534c | 204 | { |
jhnwkmn | 0:97a4f8cc534c | 205 | SQUnsignedInteger nvars=_nlocalvarinfos; |
jhnwkmn | 0:97a4f8cc534c | 206 | const SQChar *res=NULL; |
jhnwkmn | 0:97a4f8cc534c | 207 | if(nvars>=nseq){ |
jhnwkmn | 0:97a4f8cc534c | 208 | for(SQUnsignedInteger i=0;i<nvars;i++){ |
jhnwkmn | 0:97a4f8cc534c | 209 | if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop) |
jhnwkmn | 0:97a4f8cc534c | 210 | { |
jhnwkmn | 0:97a4f8cc534c | 211 | if(nseq==0){ |
jhnwkmn | 0:97a4f8cc534c | 212 | vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); |
jhnwkmn | 0:97a4f8cc534c | 213 | res=_stringval(_localvarinfos[i]._name); |
jhnwkmn | 0:97a4f8cc534c | 214 | break; |
jhnwkmn | 0:97a4f8cc534c | 215 | } |
jhnwkmn | 0:97a4f8cc534c | 216 | nseq--; |
jhnwkmn | 0:97a4f8cc534c | 217 | } |
jhnwkmn | 0:97a4f8cc534c | 218 | } |
jhnwkmn | 0:97a4f8cc534c | 219 | } |
jhnwkmn | 0:97a4f8cc534c | 220 | return res; |
jhnwkmn | 0:97a4f8cc534c | 221 | } |
jhnwkmn | 0:97a4f8cc534c | 222 | |
jhnwkmn | 0:97a4f8cc534c | 223 | |
jhnwkmn | 0:97a4f8cc534c | 224 | SQInteger SQFunctionProto::GetLine(SQInstruction *curr) |
jhnwkmn | 0:97a4f8cc534c | 225 | { |
jhnwkmn | 0:97a4f8cc534c | 226 | SQInteger op = (SQInteger)(curr-_instructions); |
jhnwkmn | 0:97a4f8cc534c | 227 | SQInteger line=_lineinfos[0]._line; |
jhnwkmn | 0:97a4f8cc534c | 228 | SQInteger low = 0; |
jhnwkmn | 0:97a4f8cc534c | 229 | SQInteger high = _nlineinfos - 1; |
jhnwkmn | 0:97a4f8cc534c | 230 | SQInteger mid = 0; |
jhnwkmn | 0:97a4f8cc534c | 231 | while(low <= high) |
jhnwkmn | 0:97a4f8cc534c | 232 | { |
jhnwkmn | 0:97a4f8cc534c | 233 | mid = low + ((high - low) >> 1); |
jhnwkmn | 0:97a4f8cc534c | 234 | SQInteger curop = _lineinfos[mid]._op; |
jhnwkmn | 0:97a4f8cc534c | 235 | if(curop > op) |
jhnwkmn | 0:97a4f8cc534c | 236 | { |
jhnwkmn | 0:97a4f8cc534c | 237 | high = mid - 1; |
jhnwkmn | 0:97a4f8cc534c | 238 | } |
jhnwkmn | 0:97a4f8cc534c | 239 | else if(curop < op) { |
jhnwkmn | 0:97a4f8cc534c | 240 | if(mid < (_nlineinfos - 1) |
jhnwkmn | 0:97a4f8cc534c | 241 | && _lineinfos[mid + 1]._op >= op) { |
jhnwkmn | 0:97a4f8cc534c | 242 | break; |
jhnwkmn | 0:97a4f8cc534c | 243 | } |
jhnwkmn | 0:97a4f8cc534c | 244 | low = mid + 1; |
jhnwkmn | 0:97a4f8cc534c | 245 | } |
jhnwkmn | 0:97a4f8cc534c | 246 | else { //equal |
jhnwkmn | 0:97a4f8cc534c | 247 | break; |
jhnwkmn | 0:97a4f8cc534c | 248 | } |
jhnwkmn | 0:97a4f8cc534c | 249 | } |
jhnwkmn | 0:97a4f8cc534c | 250 | |
jhnwkmn | 0:97a4f8cc534c | 251 | line = _lineinfos[mid]._line; |
jhnwkmn | 0:97a4f8cc534c | 252 | return line; |
jhnwkmn | 0:97a4f8cc534c | 253 | } |
jhnwkmn | 0:97a4f8cc534c | 254 | |
jhnwkmn | 0:97a4f8cc534c | 255 | SQClosure::~SQClosure() |
jhnwkmn | 0:97a4f8cc534c | 256 | { |
jhnwkmn | 0:97a4f8cc534c | 257 | __ObjRelease(_env); |
jhnwkmn | 0:97a4f8cc534c | 258 | __ObjRelease(_base); |
jhnwkmn | 0:97a4f8cc534c | 259 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); |
jhnwkmn | 0:97a4f8cc534c | 260 | } |
jhnwkmn | 0:97a4f8cc534c | 261 | |
jhnwkmn | 0:97a4f8cc534c | 262 | #define _CHECK_IO(exp) { if(!exp)return false; } |
jhnwkmn | 0:97a4f8cc534c | 263 | bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 264 | { |
jhnwkmn | 0:97a4f8cc534c | 265 | if(write(up,dest,size) != size) { |
jhnwkmn | 0:97a4f8cc534c | 266 | v->Raise_Error(_SC("io error (write function failure)")); |
jhnwkmn | 0:97a4f8cc534c | 267 | return false; |
jhnwkmn | 0:97a4f8cc534c | 268 | } |
jhnwkmn | 0:97a4f8cc534c | 269 | return true; |
jhnwkmn | 0:97a4f8cc534c | 270 | } |
jhnwkmn | 0:97a4f8cc534c | 271 | |
jhnwkmn | 0:97a4f8cc534c | 272 | bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 273 | { |
jhnwkmn | 0:97a4f8cc534c | 274 | if(size && read(up,dest,size) != size) { |
jhnwkmn | 0:97a4f8cc534c | 275 | v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); |
jhnwkmn | 0:97a4f8cc534c | 276 | return false; |
jhnwkmn | 0:97a4f8cc534c | 277 | } |
jhnwkmn | 0:97a4f8cc534c | 278 | return true; |
jhnwkmn | 0:97a4f8cc534c | 279 | } |
jhnwkmn | 0:97a4f8cc534c | 280 | |
jhnwkmn | 0:97a4f8cc534c | 281 | bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) |
jhnwkmn | 0:97a4f8cc534c | 282 | { |
jhnwkmn | 0:97a4f8cc534c | 283 | return SafeWrite(v,write,up,&tag,sizeof(tag)); |
jhnwkmn | 0:97a4f8cc534c | 284 | } |
jhnwkmn | 0:97a4f8cc534c | 285 | |
jhnwkmn | 0:97a4f8cc534c | 286 | bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) |
jhnwkmn | 0:97a4f8cc534c | 287 | { |
jhnwkmn | 0:97a4f8cc534c | 288 | SQUnsignedInteger32 t; |
jhnwkmn | 0:97a4f8cc534c | 289 | _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); |
jhnwkmn | 0:97a4f8cc534c | 290 | if(t != tag){ |
jhnwkmn | 0:97a4f8cc534c | 291 | v->Raise_Error(_SC("invalid or corrupted closure stream")); |
jhnwkmn | 0:97a4f8cc534c | 292 | return false; |
jhnwkmn | 0:97a4f8cc534c | 293 | } |
jhnwkmn | 0:97a4f8cc534c | 294 | return true; |
jhnwkmn | 0:97a4f8cc534c | 295 | } |
jhnwkmn | 0:97a4f8cc534c | 296 | |
jhnwkmn | 0:97a4f8cc534c | 297 | bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) |
jhnwkmn | 0:97a4f8cc534c | 298 | { |
jhnwkmn | 0:97a4f8cc534c | 299 | SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o); |
jhnwkmn | 0:97a4f8cc534c | 300 | _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); |
jhnwkmn | 0:97a4f8cc534c | 301 | switch(type(o)){ |
jhnwkmn | 0:97a4f8cc534c | 302 | case OT_STRING: |
jhnwkmn | 0:97a4f8cc534c | 303 | _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); |
jhnwkmn | 0:97a4f8cc534c | 304 | _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len))); |
jhnwkmn | 0:97a4f8cc534c | 305 | break; |
jhnwkmn | 0:97a4f8cc534c | 306 | case OT_BOOL: |
jhnwkmn | 0:97a4f8cc534c | 307 | case OT_INTEGER: |
jhnwkmn | 0:97a4f8cc534c | 308 | _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; |
jhnwkmn | 0:97a4f8cc534c | 309 | case OT_FLOAT: |
jhnwkmn | 0:97a4f8cc534c | 310 | _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; |
jhnwkmn | 0:97a4f8cc534c | 311 | case OT_NULL: |
jhnwkmn | 0:97a4f8cc534c | 312 | break; |
jhnwkmn | 0:97a4f8cc534c | 313 | default: |
jhnwkmn | 0:97a4f8cc534c | 314 | v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); |
jhnwkmn | 0:97a4f8cc534c | 315 | return false; |
jhnwkmn | 0:97a4f8cc534c | 316 | } |
jhnwkmn | 0:97a4f8cc534c | 317 | return true; |
jhnwkmn | 0:97a4f8cc534c | 318 | } |
jhnwkmn | 0:97a4f8cc534c | 319 | |
jhnwkmn | 0:97a4f8cc534c | 320 | bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) |
jhnwkmn | 0:97a4f8cc534c | 321 | { |
jhnwkmn | 0:97a4f8cc534c | 322 | SQUnsignedInteger32 _type; |
jhnwkmn | 0:97a4f8cc534c | 323 | _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); |
jhnwkmn | 0:97a4f8cc534c | 324 | SQObjectType t = (SQObjectType)_type; |
jhnwkmn | 0:97a4f8cc534c | 325 | switch(t){ |
jhnwkmn | 0:97a4f8cc534c | 326 | case OT_STRING:{ |
jhnwkmn | 0:97a4f8cc534c | 327 | SQInteger len; |
jhnwkmn | 0:97a4f8cc534c | 328 | _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); |
jhnwkmn | 0:97a4f8cc534c | 329 | _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len))); |
jhnwkmn | 0:97a4f8cc534c | 330 | o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); |
jhnwkmn | 0:97a4f8cc534c | 331 | } |
jhnwkmn | 0:97a4f8cc534c | 332 | break; |
jhnwkmn | 0:97a4f8cc534c | 333 | case OT_INTEGER:{ |
jhnwkmn | 0:97a4f8cc534c | 334 | SQInteger i; |
jhnwkmn | 0:97a4f8cc534c | 335 | _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; |
jhnwkmn | 0:97a4f8cc534c | 336 | } |
jhnwkmn | 0:97a4f8cc534c | 337 | case OT_BOOL:{ |
jhnwkmn | 0:97a4f8cc534c | 338 | SQInteger i; |
jhnwkmn | 0:97a4f8cc534c | 339 | _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break; |
jhnwkmn | 0:97a4f8cc534c | 340 | } |
jhnwkmn | 0:97a4f8cc534c | 341 | case OT_FLOAT:{ |
jhnwkmn | 0:97a4f8cc534c | 342 | SQFloat f; |
jhnwkmn | 0:97a4f8cc534c | 343 | _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; |
jhnwkmn | 0:97a4f8cc534c | 344 | } |
jhnwkmn | 0:97a4f8cc534c | 345 | case OT_NULL: |
jhnwkmn | 0:97a4f8cc534c | 346 | o.Null(); |
jhnwkmn | 0:97a4f8cc534c | 347 | break; |
jhnwkmn | 0:97a4f8cc534c | 348 | default: |
jhnwkmn | 0:97a4f8cc534c | 349 | v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); |
jhnwkmn | 0:97a4f8cc534c | 350 | return false; |
jhnwkmn | 0:97a4f8cc534c | 351 | } |
jhnwkmn | 0:97a4f8cc534c | 352 | return true; |
jhnwkmn | 0:97a4f8cc534c | 353 | } |
jhnwkmn | 0:97a4f8cc534c | 354 | |
jhnwkmn | 0:97a4f8cc534c | 355 | bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) |
jhnwkmn | 0:97a4f8cc534c | 356 | { |
jhnwkmn | 0:97a4f8cc534c | 357 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); |
jhnwkmn | 0:97a4f8cc534c | 358 | _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); |
jhnwkmn | 0:97a4f8cc534c | 359 | _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); |
jhnwkmn | 0:97a4f8cc534c | 360 | _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); |
jhnwkmn | 0:97a4f8cc534c | 361 | _CHECK_IO(_function->Save(v,up,write)); |
jhnwkmn | 0:97a4f8cc534c | 362 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); |
jhnwkmn | 0:97a4f8cc534c | 363 | return true; |
jhnwkmn | 0:97a4f8cc534c | 364 | } |
jhnwkmn | 0:97a4f8cc534c | 365 | |
jhnwkmn | 0:97a4f8cc534c | 366 | bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) |
jhnwkmn | 0:97a4f8cc534c | 367 | { |
jhnwkmn | 0:97a4f8cc534c | 368 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); |
jhnwkmn | 0:97a4f8cc534c | 369 | _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); |
jhnwkmn | 0:97a4f8cc534c | 370 | _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); |
jhnwkmn | 0:97a4f8cc534c | 371 | _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); |
jhnwkmn | 0:97a4f8cc534c | 372 | SQObjectPtr func; |
jhnwkmn | 0:97a4f8cc534c | 373 | _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); |
jhnwkmn | 0:97a4f8cc534c | 374 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); |
jhnwkmn | 0:97a4f8cc534c | 375 | ret = SQClosure::Create(_ss(v),_funcproto(func)); |
jhnwkmn | 0:97a4f8cc534c | 376 | return true; |
jhnwkmn | 0:97a4f8cc534c | 377 | } |
jhnwkmn | 0:97a4f8cc534c | 378 | |
jhnwkmn | 0:97a4f8cc534c | 379 | SQFunctionProto::SQFunctionProto(SQSharedState *ss) |
jhnwkmn | 0:97a4f8cc534c | 380 | { |
jhnwkmn | 0:97a4f8cc534c | 381 | _stacksize=0; |
jhnwkmn | 0:97a4f8cc534c | 382 | _bgenerator=false; |
jhnwkmn | 0:97a4f8cc534c | 383 | INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); |
jhnwkmn | 0:97a4f8cc534c | 384 | } |
jhnwkmn | 0:97a4f8cc534c | 385 | |
jhnwkmn | 0:97a4f8cc534c | 386 | SQFunctionProto::~SQFunctionProto() |
jhnwkmn | 0:97a4f8cc534c | 387 | { |
jhnwkmn | 0:97a4f8cc534c | 388 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); |
jhnwkmn | 0:97a4f8cc534c | 389 | } |
jhnwkmn | 0:97a4f8cc534c | 390 | |
jhnwkmn | 0:97a4f8cc534c | 391 | bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) |
jhnwkmn | 0:97a4f8cc534c | 392 | { |
jhnwkmn | 0:97a4f8cc534c | 393 | SQInteger i,nliterals = _nliterals,nparameters = _nparameters; |
jhnwkmn | 0:97a4f8cc534c | 394 | SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; |
jhnwkmn | 0:97a4f8cc534c | 395 | SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; |
jhnwkmn | 0:97a4f8cc534c | 396 | SQInteger ndefaultparams = _ndefaultparams; |
jhnwkmn | 0:97a4f8cc534c | 397 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 398 | _CHECK_IO(WriteObject(v,up,write,_sourcename)); |
jhnwkmn | 0:97a4f8cc534c | 399 | _CHECK_IO(WriteObject(v,up,write,_name)); |
jhnwkmn | 0:97a4f8cc534c | 400 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 401 | _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); |
jhnwkmn | 0:97a4f8cc534c | 402 | _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); |
jhnwkmn | 0:97a4f8cc534c | 403 | _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); |
jhnwkmn | 0:97a4f8cc534c | 404 | _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); |
jhnwkmn | 0:97a4f8cc534c | 405 | _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); |
jhnwkmn | 0:97a4f8cc534c | 406 | _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); |
jhnwkmn | 0:97a4f8cc534c | 407 | _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); |
jhnwkmn | 0:97a4f8cc534c | 408 | _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); |
jhnwkmn | 0:97a4f8cc534c | 409 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 410 | for(i=0;i<nliterals;i++){ |
jhnwkmn | 0:97a4f8cc534c | 411 | _CHECK_IO(WriteObject(v,up,write,_literals[i])); |
jhnwkmn | 0:97a4f8cc534c | 412 | } |
jhnwkmn | 0:97a4f8cc534c | 413 | |
jhnwkmn | 0:97a4f8cc534c | 414 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 415 | for(i=0;i<nparameters;i++){ |
jhnwkmn | 0:97a4f8cc534c | 416 | _CHECK_IO(WriteObject(v,up,write,_parameters[i])); |
jhnwkmn | 0:97a4f8cc534c | 417 | } |
jhnwkmn | 0:97a4f8cc534c | 418 | |
jhnwkmn | 0:97a4f8cc534c | 419 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 420 | for(i=0;i<noutervalues;i++){ |
jhnwkmn | 0:97a4f8cc534c | 421 | _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 422 | _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src)); |
jhnwkmn | 0:97a4f8cc534c | 423 | _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name)); |
jhnwkmn | 0:97a4f8cc534c | 424 | } |
jhnwkmn | 0:97a4f8cc534c | 425 | |
jhnwkmn | 0:97a4f8cc534c | 426 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 427 | for(i=0;i<nlocalvarinfos;i++){ |
jhnwkmn | 0:97a4f8cc534c | 428 | SQLocalVarInfo &lvi=_localvarinfos[i]; |
jhnwkmn | 0:97a4f8cc534c | 429 | _CHECK_IO(WriteObject(v,up,write,lvi._name)); |
jhnwkmn | 0:97a4f8cc534c | 430 | _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 431 | _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 432 | _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 433 | } |
jhnwkmn | 0:97a4f8cc534c | 434 | |
jhnwkmn | 0:97a4f8cc534c | 435 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 436 | _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos)); |
jhnwkmn | 0:97a4f8cc534c | 437 | |
jhnwkmn | 0:97a4f8cc534c | 438 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 439 | _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams)); |
jhnwkmn | 0:97a4f8cc534c | 440 | |
jhnwkmn | 0:97a4f8cc534c | 441 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 442 | _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions)); |
jhnwkmn | 0:97a4f8cc534c | 443 | |
jhnwkmn | 0:97a4f8cc534c | 444 | _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 445 | for(i=0;i<nfunctions;i++){ |
jhnwkmn | 0:97a4f8cc534c | 446 | _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write)); |
jhnwkmn | 0:97a4f8cc534c | 447 | } |
jhnwkmn | 0:97a4f8cc534c | 448 | _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); |
jhnwkmn | 0:97a4f8cc534c | 449 | _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); |
jhnwkmn | 0:97a4f8cc534c | 450 | _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); |
jhnwkmn | 0:97a4f8cc534c | 451 | return true; |
jhnwkmn | 0:97a4f8cc534c | 452 | } |
jhnwkmn | 0:97a4f8cc534c | 453 | |
jhnwkmn | 0:97a4f8cc534c | 454 | bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) |
jhnwkmn | 0:97a4f8cc534c | 455 | { |
jhnwkmn | 0:97a4f8cc534c | 456 | SQInteger i, nliterals,nparameters; |
jhnwkmn | 0:97a4f8cc534c | 457 | SQInteger noutervalues ,nlocalvarinfos ; |
jhnwkmn | 0:97a4f8cc534c | 458 | SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; |
jhnwkmn | 0:97a4f8cc534c | 459 | SQObjectPtr sourcename, name; |
jhnwkmn | 0:97a4f8cc534c | 460 | SQObjectPtr o; |
jhnwkmn | 0:97a4f8cc534c | 461 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 462 | _CHECK_IO(ReadObject(v, up, read, sourcename)); |
jhnwkmn | 0:97a4f8cc534c | 463 | _CHECK_IO(ReadObject(v, up, read, name)); |
jhnwkmn | 0:97a4f8cc534c | 464 | |
jhnwkmn | 0:97a4f8cc534c | 465 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 466 | _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); |
jhnwkmn | 0:97a4f8cc534c | 467 | _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); |
jhnwkmn | 0:97a4f8cc534c | 468 | _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); |
jhnwkmn | 0:97a4f8cc534c | 469 | _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); |
jhnwkmn | 0:97a4f8cc534c | 470 | _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); |
jhnwkmn | 0:97a4f8cc534c | 471 | _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); |
jhnwkmn | 0:97a4f8cc534c | 472 | _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); |
jhnwkmn | 0:97a4f8cc534c | 473 | _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); |
jhnwkmn | 0:97a4f8cc534c | 474 | |
jhnwkmn | 0:97a4f8cc534c | 475 | |
jhnwkmn | 0:97a4f8cc534c | 476 | SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, |
jhnwkmn | 0:97a4f8cc534c | 477 | nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); |
jhnwkmn | 0:97a4f8cc534c | 478 | SQObjectPtr proto = f; //gets a ref in case of failure |
jhnwkmn | 0:97a4f8cc534c | 479 | f->_sourcename = sourcename; |
jhnwkmn | 0:97a4f8cc534c | 480 | f->_name = name; |
jhnwkmn | 0:97a4f8cc534c | 481 | |
jhnwkmn | 0:97a4f8cc534c | 482 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 483 | |
jhnwkmn | 0:97a4f8cc534c | 484 | for(i = 0;i < nliterals; i++){ |
jhnwkmn | 0:97a4f8cc534c | 485 | _CHECK_IO(ReadObject(v, up, read, o)); |
jhnwkmn | 0:97a4f8cc534c | 486 | f->_literals[i] = o; |
jhnwkmn | 0:97a4f8cc534c | 487 | } |
jhnwkmn | 0:97a4f8cc534c | 488 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 489 | |
jhnwkmn | 0:97a4f8cc534c | 490 | for(i = 0; i < nparameters; i++){ |
jhnwkmn | 0:97a4f8cc534c | 491 | _CHECK_IO(ReadObject(v, up, read, o)); |
jhnwkmn | 0:97a4f8cc534c | 492 | f->_parameters[i] = o; |
jhnwkmn | 0:97a4f8cc534c | 493 | } |
jhnwkmn | 0:97a4f8cc534c | 494 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 495 | |
jhnwkmn | 0:97a4f8cc534c | 496 | for(i = 0; i < noutervalues; i++){ |
jhnwkmn | 0:97a4f8cc534c | 497 | SQUnsignedInteger type; |
jhnwkmn | 0:97a4f8cc534c | 498 | SQObjectPtr name; |
jhnwkmn | 0:97a4f8cc534c | 499 | _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 500 | _CHECK_IO(ReadObject(v, up, read, o)); |
jhnwkmn | 0:97a4f8cc534c | 501 | _CHECK_IO(ReadObject(v, up, read, name)); |
jhnwkmn | 0:97a4f8cc534c | 502 | f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); |
jhnwkmn | 0:97a4f8cc534c | 503 | } |
jhnwkmn | 0:97a4f8cc534c | 504 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 505 | |
jhnwkmn | 0:97a4f8cc534c | 506 | for(i = 0; i < nlocalvarinfos; i++){ |
jhnwkmn | 0:97a4f8cc534c | 507 | SQLocalVarInfo lvi; |
jhnwkmn | 0:97a4f8cc534c | 508 | _CHECK_IO(ReadObject(v, up, read, lvi._name)); |
jhnwkmn | 0:97a4f8cc534c | 509 | _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 510 | _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 511 | _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); |
jhnwkmn | 0:97a4f8cc534c | 512 | f->_localvarinfos[i] = lvi; |
jhnwkmn | 0:97a4f8cc534c | 513 | } |
jhnwkmn | 0:97a4f8cc534c | 514 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 515 | _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); |
jhnwkmn | 0:97a4f8cc534c | 516 | |
jhnwkmn | 0:97a4f8cc534c | 517 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 518 | _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); |
jhnwkmn | 0:97a4f8cc534c | 519 | |
jhnwkmn | 0:97a4f8cc534c | 520 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 521 | _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); |
jhnwkmn | 0:97a4f8cc534c | 522 | |
jhnwkmn | 0:97a4f8cc534c | 523 | _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); |
jhnwkmn | 0:97a4f8cc534c | 524 | for(i = 0; i < nfunctions; i++){ |
jhnwkmn | 0:97a4f8cc534c | 525 | _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); |
jhnwkmn | 0:97a4f8cc534c | 526 | f->_functions[i] = o; |
jhnwkmn | 0:97a4f8cc534c | 527 | } |
jhnwkmn | 0:97a4f8cc534c | 528 | _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); |
jhnwkmn | 0:97a4f8cc534c | 529 | _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); |
jhnwkmn | 0:97a4f8cc534c | 530 | _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); |
jhnwkmn | 0:97a4f8cc534c | 531 | |
jhnwkmn | 0:97a4f8cc534c | 532 | ret = f; |
jhnwkmn | 0:97a4f8cc534c | 533 | return true; |
jhnwkmn | 0:97a4f8cc534c | 534 | } |
jhnwkmn | 0:97a4f8cc534c | 535 | |
jhnwkmn | 0:97a4f8cc534c | 536 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 537 | |
jhnwkmn | 0:97a4f8cc534c | 538 | #define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ |
jhnwkmn | 0:97a4f8cc534c | 539 | _uiRef|=MARK_FLAG; |
jhnwkmn | 0:97a4f8cc534c | 540 | |
jhnwkmn | 0:97a4f8cc534c | 541 | #define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ |
jhnwkmn | 0:97a4f8cc534c | 542 | AddToChain(chain, this); } |
jhnwkmn | 0:97a4f8cc534c | 543 | |
jhnwkmn | 0:97a4f8cc534c | 544 | void SQVM::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 545 | { |
jhnwkmn | 0:97a4f8cc534c | 546 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 547 | SQSharedState::MarkObject(_lasterror,chain); |
jhnwkmn | 0:97a4f8cc534c | 548 | SQSharedState::MarkObject(_errorhandler,chain); |
jhnwkmn | 0:97a4f8cc534c | 549 | SQSharedState::MarkObject(_debughook_closure,chain); |
jhnwkmn | 0:97a4f8cc534c | 550 | SQSharedState::MarkObject(_roottable, chain); |
jhnwkmn | 0:97a4f8cc534c | 551 | SQSharedState::MarkObject(temp_reg, chain); |
jhnwkmn | 0:97a4f8cc534c | 552 | for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 553 | for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); |
jhnwkmn | 0:97a4f8cc534c | 554 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 555 | } |
jhnwkmn | 0:97a4f8cc534c | 556 | |
jhnwkmn | 0:97a4f8cc534c | 557 | void SQArray::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 558 | { |
jhnwkmn | 0:97a4f8cc534c | 559 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 560 | SQInteger len = _values.size(); |
jhnwkmn | 0:97a4f8cc534c | 561 | for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 562 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 563 | } |
jhnwkmn | 0:97a4f8cc534c | 564 | void SQTable::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 565 | { |
jhnwkmn | 0:97a4f8cc534c | 566 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 567 | if(_delegate) _delegate->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 568 | SQInteger len = _numofnodes; |
jhnwkmn | 0:97a4f8cc534c | 569 | for(SQInteger i = 0; i < len; i++){ |
jhnwkmn | 0:97a4f8cc534c | 570 | SQSharedState::MarkObject(_nodes[i].key, chain); |
jhnwkmn | 0:97a4f8cc534c | 571 | SQSharedState::MarkObject(_nodes[i].val, chain); |
jhnwkmn | 0:97a4f8cc534c | 572 | } |
jhnwkmn | 0:97a4f8cc534c | 573 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 574 | } |
jhnwkmn | 0:97a4f8cc534c | 575 | |
jhnwkmn | 0:97a4f8cc534c | 576 | void SQClass::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 577 | { |
jhnwkmn | 0:97a4f8cc534c | 578 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 579 | _members->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 580 | if(_base) _base->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 581 | SQSharedState::MarkObject(_attributes, chain); |
jhnwkmn | 0:97a4f8cc534c | 582 | for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { |
jhnwkmn | 0:97a4f8cc534c | 583 | SQSharedState::MarkObject(_defaultvalues[i].val, chain); |
jhnwkmn | 0:97a4f8cc534c | 584 | SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); |
jhnwkmn | 0:97a4f8cc534c | 585 | } |
jhnwkmn | 0:97a4f8cc534c | 586 | for(SQUnsignedInteger j =0; j< _methods.size(); j++) { |
jhnwkmn | 0:97a4f8cc534c | 587 | SQSharedState::MarkObject(_methods[j].val, chain); |
jhnwkmn | 0:97a4f8cc534c | 588 | SQSharedState::MarkObject(_methods[j].attrs, chain); |
jhnwkmn | 0:97a4f8cc534c | 589 | } |
jhnwkmn | 0:97a4f8cc534c | 590 | for(SQUnsignedInteger k =0; k< MT_LAST; k++) { |
jhnwkmn | 0:97a4f8cc534c | 591 | SQSharedState::MarkObject(_metamethods[k], chain); |
jhnwkmn | 0:97a4f8cc534c | 592 | } |
jhnwkmn | 0:97a4f8cc534c | 593 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 594 | } |
jhnwkmn | 0:97a4f8cc534c | 595 | |
jhnwkmn | 0:97a4f8cc534c | 596 | void SQInstance::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 597 | { |
jhnwkmn | 0:97a4f8cc534c | 598 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 599 | _class->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 600 | SQUnsignedInteger nvalues = _class->_defaultvalues.size(); |
jhnwkmn | 0:97a4f8cc534c | 601 | for(SQUnsignedInteger i =0; i< nvalues; i++) { |
jhnwkmn | 0:97a4f8cc534c | 602 | SQSharedState::MarkObject(_values[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 603 | } |
jhnwkmn | 0:97a4f8cc534c | 604 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 605 | } |
jhnwkmn | 0:97a4f8cc534c | 606 | |
jhnwkmn | 0:97a4f8cc534c | 607 | void SQGenerator::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 608 | { |
jhnwkmn | 0:97a4f8cc534c | 609 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 610 | for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 611 | SQSharedState::MarkObject(_closure, chain); |
jhnwkmn | 0:97a4f8cc534c | 612 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 613 | } |
jhnwkmn | 0:97a4f8cc534c | 614 | |
jhnwkmn | 0:97a4f8cc534c | 615 | void SQFunctionProto::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 616 | { |
jhnwkmn | 0:97a4f8cc534c | 617 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 618 | for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 619 | for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); |
jhnwkmn | 0:97a4f8cc534c | 620 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 621 | } |
jhnwkmn | 0:97a4f8cc534c | 622 | |
jhnwkmn | 0:97a4f8cc534c | 623 | void SQClosure::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 624 | { |
jhnwkmn | 0:97a4f8cc534c | 625 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 626 | if(_base) _base->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 627 | SQFunctionProto *fp = _function; |
jhnwkmn | 0:97a4f8cc534c | 628 | fp->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 629 | for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 630 | for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); |
jhnwkmn | 0:97a4f8cc534c | 631 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 632 | } |
jhnwkmn | 0:97a4f8cc534c | 633 | |
jhnwkmn | 0:97a4f8cc534c | 634 | void SQNativeClosure::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 635 | { |
jhnwkmn | 0:97a4f8cc534c | 636 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 637 | for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); |
jhnwkmn | 0:97a4f8cc534c | 638 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 639 | } |
jhnwkmn | 0:97a4f8cc534c | 640 | |
jhnwkmn | 0:97a4f8cc534c | 641 | void SQOuter::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 642 | { |
jhnwkmn | 0:97a4f8cc534c | 643 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 644 | /* If the valptr points to a closed value, that value is alive */ |
jhnwkmn | 0:97a4f8cc534c | 645 | if(_valptr == &_value) { |
jhnwkmn | 0:97a4f8cc534c | 646 | SQSharedState::MarkObject(_value, chain); |
jhnwkmn | 0:97a4f8cc534c | 647 | } |
jhnwkmn | 0:97a4f8cc534c | 648 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 649 | } |
jhnwkmn | 0:97a4f8cc534c | 650 | |
jhnwkmn | 0:97a4f8cc534c | 651 | void SQUserData::Mark(SQCollectable **chain){ |
jhnwkmn | 0:97a4f8cc534c | 652 | START_MARK() |
jhnwkmn | 0:97a4f8cc534c | 653 | if(_delegate) _delegate->Mark(chain); |
jhnwkmn | 0:97a4f8cc534c | 654 | END_MARK() |
jhnwkmn | 0:97a4f8cc534c | 655 | } |
jhnwkmn | 0:97a4f8cc534c | 656 | |
jhnwkmn | 0:97a4f8cc534c | 657 | void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } |
jhnwkmn | 0:97a4f8cc534c | 658 | |
jhnwkmn | 0:97a4f8cc534c | 659 | #endif |
jhnwkmn | 0:97a4f8cc534c | 660 |