The Squirrel interpreter. See http://www.squirrel-lang.org/
squirrel/sqstate.cpp@0:97a4f8cc534c, 2014-12-16 (annotated)
- Committer:
- jhnwkmn
- Date:
- Tue Dec 16 10:20:34 2014 +0000
- Revision:
- 0:97a4f8cc534c
Initial import of Squirrel.
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 "sqopcodes.h" |
jhnwkmn | 0:97a4f8cc534c | 6 | #include "sqvm.h" |
jhnwkmn | 0:97a4f8cc534c | 7 | #include "sqfuncproto.h" |
jhnwkmn | 0:97a4f8cc534c | 8 | #include "sqclosure.h" |
jhnwkmn | 0:97a4f8cc534c | 9 | #include "sqstring.h" |
jhnwkmn | 0:97a4f8cc534c | 10 | #include "sqtable.h" |
jhnwkmn | 0:97a4f8cc534c | 11 | #include "sqarray.h" |
jhnwkmn | 0:97a4f8cc534c | 12 | #include "squserdata.h" |
jhnwkmn | 0:97a4f8cc534c | 13 | #include "sqclass.h" |
jhnwkmn | 0:97a4f8cc534c | 14 | |
jhnwkmn | 0:97a4f8cc534c | 15 | //SQObjectPtr _null_; |
jhnwkmn | 0:97a4f8cc534c | 16 | //SQObjectPtr _true_(true); |
jhnwkmn | 0:97a4f8cc534c | 17 | //SQObjectPtr _false_(false); |
jhnwkmn | 0:97a4f8cc534c | 18 | //SQObjectPtr _one_((SQInteger)1); |
jhnwkmn | 0:97a4f8cc534c | 19 | //SQObjectPtr _minusone_((SQInteger)-1); |
jhnwkmn | 0:97a4f8cc534c | 20 | |
jhnwkmn | 0:97a4f8cc534c | 21 | SQSharedState::SQSharedState() |
jhnwkmn | 0:97a4f8cc534c | 22 | { |
jhnwkmn | 0:97a4f8cc534c | 23 | _compilererrorhandler = NULL; |
jhnwkmn | 0:97a4f8cc534c | 24 | _printfunc = NULL; |
jhnwkmn | 0:97a4f8cc534c | 25 | _errorfunc = NULL; |
jhnwkmn | 0:97a4f8cc534c | 26 | _debuginfo = false; |
jhnwkmn | 0:97a4f8cc534c | 27 | _notifyallexceptions = false; |
jhnwkmn | 0:97a4f8cc534c | 28 | } |
jhnwkmn | 0:97a4f8cc534c | 29 | |
jhnwkmn | 0:97a4f8cc534c | 30 | #define newsysstring(s) { \ |
jhnwkmn | 0:97a4f8cc534c | 31 | _systemstrings->push_back(SQString::Create(this,s)); \ |
jhnwkmn | 0:97a4f8cc534c | 32 | } |
jhnwkmn | 0:97a4f8cc534c | 33 | |
jhnwkmn | 0:97a4f8cc534c | 34 | #define newmetamethod(s) { \ |
jhnwkmn | 0:97a4f8cc534c | 35 | _metamethods->push_back(SQString::Create(this,s)); \ |
jhnwkmn | 0:97a4f8cc534c | 36 | _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ |
jhnwkmn | 0:97a4f8cc534c | 37 | } |
jhnwkmn | 0:97a4f8cc534c | 38 | |
jhnwkmn | 0:97a4f8cc534c | 39 | bool CompileTypemask(SQIntVec &res,const SQChar *typemask) |
jhnwkmn | 0:97a4f8cc534c | 40 | { |
jhnwkmn | 0:97a4f8cc534c | 41 | SQInteger i = 0; |
jhnwkmn | 0:97a4f8cc534c | 42 | |
jhnwkmn | 0:97a4f8cc534c | 43 | SQInteger mask = 0; |
jhnwkmn | 0:97a4f8cc534c | 44 | while(typemask[i] != 0) { |
jhnwkmn | 0:97a4f8cc534c | 45 | |
jhnwkmn | 0:97a4f8cc534c | 46 | switch(typemask[i]){ |
jhnwkmn | 0:97a4f8cc534c | 47 | case 'o': mask |= _RT_NULL; break; |
jhnwkmn | 0:97a4f8cc534c | 48 | case 'i': mask |= _RT_INTEGER; break; |
jhnwkmn | 0:97a4f8cc534c | 49 | case 'f': mask |= _RT_FLOAT; break; |
jhnwkmn | 0:97a4f8cc534c | 50 | case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; |
jhnwkmn | 0:97a4f8cc534c | 51 | case 's': mask |= _RT_STRING; break; |
jhnwkmn | 0:97a4f8cc534c | 52 | case 't': mask |= _RT_TABLE; break; |
jhnwkmn | 0:97a4f8cc534c | 53 | case 'a': mask |= _RT_ARRAY; break; |
jhnwkmn | 0:97a4f8cc534c | 54 | case 'u': mask |= _RT_USERDATA; break; |
jhnwkmn | 0:97a4f8cc534c | 55 | case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; |
jhnwkmn | 0:97a4f8cc534c | 56 | case 'b': mask |= _RT_BOOL; break; |
jhnwkmn | 0:97a4f8cc534c | 57 | case 'g': mask |= _RT_GENERATOR; break; |
jhnwkmn | 0:97a4f8cc534c | 58 | case 'p': mask |= _RT_USERPOINTER; break; |
jhnwkmn | 0:97a4f8cc534c | 59 | case 'v': mask |= _RT_THREAD; break; |
jhnwkmn | 0:97a4f8cc534c | 60 | case 'x': mask |= _RT_INSTANCE; break; |
jhnwkmn | 0:97a4f8cc534c | 61 | case 'y': mask |= _RT_CLASS; break; |
jhnwkmn | 0:97a4f8cc534c | 62 | case 'r': mask |= _RT_WEAKREF; break; |
jhnwkmn | 0:97a4f8cc534c | 63 | case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; |
jhnwkmn | 0:97a4f8cc534c | 64 | case ' ': i++; continue; //ignores spaces |
jhnwkmn | 0:97a4f8cc534c | 65 | default: |
jhnwkmn | 0:97a4f8cc534c | 66 | return false; |
jhnwkmn | 0:97a4f8cc534c | 67 | } |
jhnwkmn | 0:97a4f8cc534c | 68 | i++; |
jhnwkmn | 0:97a4f8cc534c | 69 | if(typemask[i] == '|') { |
jhnwkmn | 0:97a4f8cc534c | 70 | i++; |
jhnwkmn | 0:97a4f8cc534c | 71 | if(typemask[i] == 0) |
jhnwkmn | 0:97a4f8cc534c | 72 | return false; |
jhnwkmn | 0:97a4f8cc534c | 73 | continue; |
jhnwkmn | 0:97a4f8cc534c | 74 | } |
jhnwkmn | 0:97a4f8cc534c | 75 | res.push_back(mask); |
jhnwkmn | 0:97a4f8cc534c | 76 | mask = 0; |
jhnwkmn | 0:97a4f8cc534c | 77 | |
jhnwkmn | 0:97a4f8cc534c | 78 | } |
jhnwkmn | 0:97a4f8cc534c | 79 | return true; |
jhnwkmn | 0:97a4f8cc534c | 80 | } |
jhnwkmn | 0:97a4f8cc534c | 81 | |
jhnwkmn | 0:97a4f8cc534c | 82 | SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz) |
jhnwkmn | 0:97a4f8cc534c | 83 | { |
jhnwkmn | 0:97a4f8cc534c | 84 | SQInteger i=0; |
jhnwkmn | 0:97a4f8cc534c | 85 | SQTable *t=SQTable::Create(ss,0); |
jhnwkmn | 0:97a4f8cc534c | 86 | while(funcz[i].name!=0){ |
jhnwkmn | 0:97a4f8cc534c | 87 | SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); |
jhnwkmn | 0:97a4f8cc534c | 88 | nc->_nparamscheck = funcz[i].nparamscheck; |
jhnwkmn | 0:97a4f8cc534c | 89 | nc->_name = SQString::Create(ss,funcz[i].name); |
jhnwkmn | 0:97a4f8cc534c | 90 | if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) |
jhnwkmn | 0:97a4f8cc534c | 91 | return NULL; |
jhnwkmn | 0:97a4f8cc534c | 92 | t->NewSlot(SQString::Create(ss,funcz[i].name),nc); |
jhnwkmn | 0:97a4f8cc534c | 93 | i++; |
jhnwkmn | 0:97a4f8cc534c | 94 | } |
jhnwkmn | 0:97a4f8cc534c | 95 | return t; |
jhnwkmn | 0:97a4f8cc534c | 96 | } |
jhnwkmn | 0:97a4f8cc534c | 97 | |
jhnwkmn | 0:97a4f8cc534c | 98 | void SQSharedState::Init() |
jhnwkmn | 0:97a4f8cc534c | 99 | { |
jhnwkmn | 0:97a4f8cc534c | 100 | _scratchpad=NULL; |
jhnwkmn | 0:97a4f8cc534c | 101 | _scratchpadsize=0; |
jhnwkmn | 0:97a4f8cc534c | 102 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 103 | _gc_chain=NULL; |
jhnwkmn | 0:97a4f8cc534c | 104 | #endif |
jhnwkmn | 0:97a4f8cc534c | 105 | _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); |
jhnwkmn | 0:97a4f8cc534c | 106 | new (_stringtable) SQStringTable(this); |
jhnwkmn | 0:97a4f8cc534c | 107 | sq_new(_metamethods,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 108 | sq_new(_systemstrings,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 109 | sq_new(_types,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 110 | _metamethodsmap = SQTable::Create(this,MT_LAST-1); |
jhnwkmn | 0:97a4f8cc534c | 111 | //adding type strings to avoid memory trashing |
jhnwkmn | 0:97a4f8cc534c | 112 | //types names |
jhnwkmn | 0:97a4f8cc534c | 113 | newsysstring(_SC("null")); |
jhnwkmn | 0:97a4f8cc534c | 114 | newsysstring(_SC("table")); |
jhnwkmn | 0:97a4f8cc534c | 115 | newsysstring(_SC("array")); |
jhnwkmn | 0:97a4f8cc534c | 116 | newsysstring(_SC("closure")); |
jhnwkmn | 0:97a4f8cc534c | 117 | newsysstring(_SC("string")); |
jhnwkmn | 0:97a4f8cc534c | 118 | newsysstring(_SC("userdata")); |
jhnwkmn | 0:97a4f8cc534c | 119 | newsysstring(_SC("integer")); |
jhnwkmn | 0:97a4f8cc534c | 120 | newsysstring(_SC("float")); |
jhnwkmn | 0:97a4f8cc534c | 121 | newsysstring(_SC("userpointer")); |
jhnwkmn | 0:97a4f8cc534c | 122 | newsysstring(_SC("function")); |
jhnwkmn | 0:97a4f8cc534c | 123 | newsysstring(_SC("generator")); |
jhnwkmn | 0:97a4f8cc534c | 124 | newsysstring(_SC("thread")); |
jhnwkmn | 0:97a4f8cc534c | 125 | newsysstring(_SC("class")); |
jhnwkmn | 0:97a4f8cc534c | 126 | newsysstring(_SC("instance")); |
jhnwkmn | 0:97a4f8cc534c | 127 | newsysstring(_SC("bool")); |
jhnwkmn | 0:97a4f8cc534c | 128 | //meta methods |
jhnwkmn | 0:97a4f8cc534c | 129 | newmetamethod(MM_ADD); |
jhnwkmn | 0:97a4f8cc534c | 130 | newmetamethod(MM_SUB); |
jhnwkmn | 0:97a4f8cc534c | 131 | newmetamethod(MM_MUL); |
jhnwkmn | 0:97a4f8cc534c | 132 | newmetamethod(MM_DIV); |
jhnwkmn | 0:97a4f8cc534c | 133 | newmetamethod(MM_UNM); |
jhnwkmn | 0:97a4f8cc534c | 134 | newmetamethod(MM_MODULO); |
jhnwkmn | 0:97a4f8cc534c | 135 | newmetamethod(MM_SET); |
jhnwkmn | 0:97a4f8cc534c | 136 | newmetamethod(MM_GET); |
jhnwkmn | 0:97a4f8cc534c | 137 | newmetamethod(MM_TYPEOF); |
jhnwkmn | 0:97a4f8cc534c | 138 | newmetamethod(MM_NEXTI); |
jhnwkmn | 0:97a4f8cc534c | 139 | newmetamethod(MM_CMP); |
jhnwkmn | 0:97a4f8cc534c | 140 | newmetamethod(MM_CALL); |
jhnwkmn | 0:97a4f8cc534c | 141 | newmetamethod(MM_CLONED); |
jhnwkmn | 0:97a4f8cc534c | 142 | newmetamethod(MM_NEWSLOT); |
jhnwkmn | 0:97a4f8cc534c | 143 | newmetamethod(MM_DELSLOT); |
jhnwkmn | 0:97a4f8cc534c | 144 | newmetamethod(MM_TOSTRING); |
jhnwkmn | 0:97a4f8cc534c | 145 | newmetamethod(MM_NEWMEMBER); |
jhnwkmn | 0:97a4f8cc534c | 146 | newmetamethod(MM_INHERITED); |
jhnwkmn | 0:97a4f8cc534c | 147 | |
jhnwkmn | 0:97a4f8cc534c | 148 | _constructoridx = SQString::Create(this,_SC("constructor")); |
jhnwkmn | 0:97a4f8cc534c | 149 | _registry = SQTable::Create(this,0); |
jhnwkmn | 0:97a4f8cc534c | 150 | _consts = SQTable::Create(this,0); |
jhnwkmn | 0:97a4f8cc534c | 151 | _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 152 | _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 153 | _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 154 | _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 155 | _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 156 | _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 157 | _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 158 | _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 159 | _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 160 | _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); |
jhnwkmn | 0:97a4f8cc534c | 161 | |
jhnwkmn | 0:97a4f8cc534c | 162 | } |
jhnwkmn | 0:97a4f8cc534c | 163 | |
jhnwkmn | 0:97a4f8cc534c | 164 | SQSharedState::~SQSharedState() |
jhnwkmn | 0:97a4f8cc534c | 165 | { |
jhnwkmn | 0:97a4f8cc534c | 166 | _constructoridx.Null(); |
jhnwkmn | 0:97a4f8cc534c | 167 | _table(_registry)->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 168 | _table(_consts)->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 169 | _table(_metamethodsmap)->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 170 | _registry.Null(); |
jhnwkmn | 0:97a4f8cc534c | 171 | _consts.Null(); |
jhnwkmn | 0:97a4f8cc534c | 172 | _metamethodsmap.Null(); |
jhnwkmn | 0:97a4f8cc534c | 173 | while(!_systemstrings->empty()) { |
jhnwkmn | 0:97a4f8cc534c | 174 | _systemstrings->back().Null(); |
jhnwkmn | 0:97a4f8cc534c | 175 | _systemstrings->pop_back(); |
jhnwkmn | 0:97a4f8cc534c | 176 | } |
jhnwkmn | 0:97a4f8cc534c | 177 | _thread(_root_vm)->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 178 | _root_vm.Null(); |
jhnwkmn | 0:97a4f8cc534c | 179 | _table_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 180 | _array_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 181 | _string_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 182 | _number_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 183 | _closure_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 184 | _generator_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 185 | _thread_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 186 | _class_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 187 | _instance_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 188 | _weakref_default_delegate.Null(); |
jhnwkmn | 0:97a4f8cc534c | 189 | _refs_table.Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 190 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 191 | SQCollectable *t = _gc_chain; |
jhnwkmn | 0:97a4f8cc534c | 192 | SQCollectable *nx = NULL; |
jhnwkmn | 0:97a4f8cc534c | 193 | if(t) { |
jhnwkmn | 0:97a4f8cc534c | 194 | t->_uiRef++; |
jhnwkmn | 0:97a4f8cc534c | 195 | while(t) { |
jhnwkmn | 0:97a4f8cc534c | 196 | t->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 197 | nx = t->_next; |
jhnwkmn | 0:97a4f8cc534c | 198 | if(nx) nx->_uiRef++; |
jhnwkmn | 0:97a4f8cc534c | 199 | if(--t->_uiRef == 0) |
jhnwkmn | 0:97a4f8cc534c | 200 | t->Release(); |
jhnwkmn | 0:97a4f8cc534c | 201 | t = nx; |
jhnwkmn | 0:97a4f8cc534c | 202 | } |
jhnwkmn | 0:97a4f8cc534c | 203 | } |
jhnwkmn | 0:97a4f8cc534c | 204 | assert(_gc_chain==NULL); //just to proove a theory |
jhnwkmn | 0:97a4f8cc534c | 205 | while(_gc_chain){ |
jhnwkmn | 0:97a4f8cc534c | 206 | _gc_chain->_uiRef++; |
jhnwkmn | 0:97a4f8cc534c | 207 | _gc_chain->Release(); |
jhnwkmn | 0:97a4f8cc534c | 208 | } |
jhnwkmn | 0:97a4f8cc534c | 209 | #endif |
jhnwkmn | 0:97a4f8cc534c | 210 | |
jhnwkmn | 0:97a4f8cc534c | 211 | sq_delete(_types,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 212 | sq_delete(_systemstrings,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 213 | sq_delete(_metamethods,SQObjectPtrVec); |
jhnwkmn | 0:97a4f8cc534c | 214 | sq_delete(_stringtable,SQStringTable); |
jhnwkmn | 0:97a4f8cc534c | 215 | if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); |
jhnwkmn | 0:97a4f8cc534c | 216 | } |
jhnwkmn | 0:97a4f8cc534c | 217 | |
jhnwkmn | 0:97a4f8cc534c | 218 | |
jhnwkmn | 0:97a4f8cc534c | 219 | SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) |
jhnwkmn | 0:97a4f8cc534c | 220 | { |
jhnwkmn | 0:97a4f8cc534c | 221 | if(type(name) != OT_STRING) |
jhnwkmn | 0:97a4f8cc534c | 222 | return -1; |
jhnwkmn | 0:97a4f8cc534c | 223 | SQObjectPtr ret; |
jhnwkmn | 0:97a4f8cc534c | 224 | if(_table(_metamethodsmap)->Get(name,ret)) { |
jhnwkmn | 0:97a4f8cc534c | 225 | return _integer(ret); |
jhnwkmn | 0:97a4f8cc534c | 226 | } |
jhnwkmn | 0:97a4f8cc534c | 227 | return -1; |
jhnwkmn | 0:97a4f8cc534c | 228 | } |
jhnwkmn | 0:97a4f8cc534c | 229 | |
jhnwkmn | 0:97a4f8cc534c | 230 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 231 | |
jhnwkmn | 0:97a4f8cc534c | 232 | void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 233 | { |
jhnwkmn | 0:97a4f8cc534c | 234 | switch(type(o)){ |
jhnwkmn | 0:97a4f8cc534c | 235 | case OT_TABLE:_table(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 236 | case OT_ARRAY:_array(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 237 | case OT_USERDATA:_userdata(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 238 | case OT_CLOSURE:_closure(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 239 | case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 240 | case OT_GENERATOR:_generator(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 241 | case OT_THREAD:_thread(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 242 | case OT_CLASS:_class(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 243 | case OT_INSTANCE:_instance(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 244 | case OT_OUTER:_outer(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 245 | case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; |
jhnwkmn | 0:97a4f8cc534c | 246 | default: break; //shutup compiler |
jhnwkmn | 0:97a4f8cc534c | 247 | } |
jhnwkmn | 0:97a4f8cc534c | 248 | } |
jhnwkmn | 0:97a4f8cc534c | 249 | |
jhnwkmn | 0:97a4f8cc534c | 250 | |
jhnwkmn | 0:97a4f8cc534c | 251 | void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain) |
jhnwkmn | 0:97a4f8cc534c | 252 | { |
jhnwkmn | 0:97a4f8cc534c | 253 | SQVM *vms = _thread(_root_vm); |
jhnwkmn | 0:97a4f8cc534c | 254 | |
jhnwkmn | 0:97a4f8cc534c | 255 | vms->Mark(tchain); |
jhnwkmn | 0:97a4f8cc534c | 256 | |
jhnwkmn | 0:97a4f8cc534c | 257 | _refs_table.Mark(tchain); |
jhnwkmn | 0:97a4f8cc534c | 258 | MarkObject(_registry,tchain); |
jhnwkmn | 0:97a4f8cc534c | 259 | MarkObject(_consts,tchain); |
jhnwkmn | 0:97a4f8cc534c | 260 | MarkObject(_metamethodsmap,tchain); |
jhnwkmn | 0:97a4f8cc534c | 261 | MarkObject(_table_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 262 | MarkObject(_array_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 263 | MarkObject(_string_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 264 | MarkObject(_number_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 265 | MarkObject(_generator_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 266 | MarkObject(_thread_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 267 | MarkObject(_closure_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 268 | MarkObject(_class_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 269 | MarkObject(_instance_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 270 | MarkObject(_weakref_default_delegate,tchain); |
jhnwkmn | 0:97a4f8cc534c | 271 | |
jhnwkmn | 0:97a4f8cc534c | 272 | } |
jhnwkmn | 0:97a4f8cc534c | 273 | |
jhnwkmn | 0:97a4f8cc534c | 274 | SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) |
jhnwkmn | 0:97a4f8cc534c | 275 | { |
jhnwkmn | 0:97a4f8cc534c | 276 | SQInteger n=0; |
jhnwkmn | 0:97a4f8cc534c | 277 | SQCollectable *tchain=NULL; |
jhnwkmn | 0:97a4f8cc534c | 278 | |
jhnwkmn | 0:97a4f8cc534c | 279 | RunMark(vm,&tchain); |
jhnwkmn | 0:97a4f8cc534c | 280 | |
jhnwkmn | 0:97a4f8cc534c | 281 | SQCollectable *resurrected = _gc_chain; |
jhnwkmn | 0:97a4f8cc534c | 282 | SQCollectable *t = resurrected; |
jhnwkmn | 0:97a4f8cc534c | 283 | //SQCollectable *nx = NULL; |
jhnwkmn | 0:97a4f8cc534c | 284 | |
jhnwkmn | 0:97a4f8cc534c | 285 | _gc_chain = tchain; |
jhnwkmn | 0:97a4f8cc534c | 286 | |
jhnwkmn | 0:97a4f8cc534c | 287 | SQArray *ret = NULL; |
jhnwkmn | 0:97a4f8cc534c | 288 | if(resurrected) { |
jhnwkmn | 0:97a4f8cc534c | 289 | ret = SQArray::Create(this,0); |
jhnwkmn | 0:97a4f8cc534c | 290 | SQCollectable *rlast = NULL; |
jhnwkmn | 0:97a4f8cc534c | 291 | while(t) { |
jhnwkmn | 0:97a4f8cc534c | 292 | rlast = t; |
jhnwkmn | 0:97a4f8cc534c | 293 | SQObjectType type = t->GetType(); |
jhnwkmn | 0:97a4f8cc534c | 294 | if(type != OT_FUNCPROTO && type != OT_OUTER) { |
jhnwkmn | 0:97a4f8cc534c | 295 | SQObject sqo; |
jhnwkmn | 0:97a4f8cc534c | 296 | sqo._type = type; |
jhnwkmn | 0:97a4f8cc534c | 297 | sqo._unVal.pRefCounted = t; |
jhnwkmn | 0:97a4f8cc534c | 298 | ret->Append(sqo); |
jhnwkmn | 0:97a4f8cc534c | 299 | } |
jhnwkmn | 0:97a4f8cc534c | 300 | t = t->_next; |
jhnwkmn | 0:97a4f8cc534c | 301 | n++; |
jhnwkmn | 0:97a4f8cc534c | 302 | } |
jhnwkmn | 0:97a4f8cc534c | 303 | |
jhnwkmn | 0:97a4f8cc534c | 304 | assert(rlast->_next == NULL); |
jhnwkmn | 0:97a4f8cc534c | 305 | rlast->_next = _gc_chain; |
jhnwkmn | 0:97a4f8cc534c | 306 | if(_gc_chain) |
jhnwkmn | 0:97a4f8cc534c | 307 | { |
jhnwkmn | 0:97a4f8cc534c | 308 | _gc_chain->_prev = rlast; |
jhnwkmn | 0:97a4f8cc534c | 309 | } |
jhnwkmn | 0:97a4f8cc534c | 310 | _gc_chain = resurrected; |
jhnwkmn | 0:97a4f8cc534c | 311 | } |
jhnwkmn | 0:97a4f8cc534c | 312 | |
jhnwkmn | 0:97a4f8cc534c | 313 | t = _gc_chain; |
jhnwkmn | 0:97a4f8cc534c | 314 | while(t) { |
jhnwkmn | 0:97a4f8cc534c | 315 | t->UnMark(); |
jhnwkmn | 0:97a4f8cc534c | 316 | t = t->_next; |
jhnwkmn | 0:97a4f8cc534c | 317 | } |
jhnwkmn | 0:97a4f8cc534c | 318 | |
jhnwkmn | 0:97a4f8cc534c | 319 | if(ret) { |
jhnwkmn | 0:97a4f8cc534c | 320 | SQObjectPtr temp = ret; |
jhnwkmn | 0:97a4f8cc534c | 321 | vm->Push(temp); |
jhnwkmn | 0:97a4f8cc534c | 322 | } |
jhnwkmn | 0:97a4f8cc534c | 323 | else { |
jhnwkmn | 0:97a4f8cc534c | 324 | vm->PushNull(); |
jhnwkmn | 0:97a4f8cc534c | 325 | } |
jhnwkmn | 0:97a4f8cc534c | 326 | return n; |
jhnwkmn | 0:97a4f8cc534c | 327 | } |
jhnwkmn | 0:97a4f8cc534c | 328 | |
jhnwkmn | 0:97a4f8cc534c | 329 | SQInteger SQSharedState::CollectGarbage(SQVM *vm) |
jhnwkmn | 0:97a4f8cc534c | 330 | { |
jhnwkmn | 0:97a4f8cc534c | 331 | SQInteger n = 0; |
jhnwkmn | 0:97a4f8cc534c | 332 | SQCollectable *tchain = NULL; |
jhnwkmn | 0:97a4f8cc534c | 333 | |
jhnwkmn | 0:97a4f8cc534c | 334 | RunMark(vm,&tchain); |
jhnwkmn | 0:97a4f8cc534c | 335 | |
jhnwkmn | 0:97a4f8cc534c | 336 | SQCollectable *t = _gc_chain; |
jhnwkmn | 0:97a4f8cc534c | 337 | SQCollectable *nx = NULL; |
jhnwkmn | 0:97a4f8cc534c | 338 | if(t) { |
jhnwkmn | 0:97a4f8cc534c | 339 | t->_uiRef++; |
jhnwkmn | 0:97a4f8cc534c | 340 | while(t) { |
jhnwkmn | 0:97a4f8cc534c | 341 | t->Finalize(); |
jhnwkmn | 0:97a4f8cc534c | 342 | nx = t->_next; |
jhnwkmn | 0:97a4f8cc534c | 343 | if(nx) nx->_uiRef++; |
jhnwkmn | 0:97a4f8cc534c | 344 | if(--t->_uiRef == 0) |
jhnwkmn | 0:97a4f8cc534c | 345 | t->Release(); |
jhnwkmn | 0:97a4f8cc534c | 346 | t = nx; |
jhnwkmn | 0:97a4f8cc534c | 347 | n++; |
jhnwkmn | 0:97a4f8cc534c | 348 | } |
jhnwkmn | 0:97a4f8cc534c | 349 | } |
jhnwkmn | 0:97a4f8cc534c | 350 | |
jhnwkmn | 0:97a4f8cc534c | 351 | t = tchain; |
jhnwkmn | 0:97a4f8cc534c | 352 | while(t) { |
jhnwkmn | 0:97a4f8cc534c | 353 | t->UnMark(); |
jhnwkmn | 0:97a4f8cc534c | 354 | t = t->_next; |
jhnwkmn | 0:97a4f8cc534c | 355 | } |
jhnwkmn | 0:97a4f8cc534c | 356 | _gc_chain = tchain; |
jhnwkmn | 0:97a4f8cc534c | 357 | |
jhnwkmn | 0:97a4f8cc534c | 358 | return n; |
jhnwkmn | 0:97a4f8cc534c | 359 | } |
jhnwkmn | 0:97a4f8cc534c | 360 | #endif |
jhnwkmn | 0:97a4f8cc534c | 361 | |
jhnwkmn | 0:97a4f8cc534c | 362 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 363 | void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) |
jhnwkmn | 0:97a4f8cc534c | 364 | { |
jhnwkmn | 0:97a4f8cc534c | 365 | c->_prev = NULL; |
jhnwkmn | 0:97a4f8cc534c | 366 | c->_next = *chain; |
jhnwkmn | 0:97a4f8cc534c | 367 | if(*chain) (*chain)->_prev = c; |
jhnwkmn | 0:97a4f8cc534c | 368 | *chain = c; |
jhnwkmn | 0:97a4f8cc534c | 369 | } |
jhnwkmn | 0:97a4f8cc534c | 370 | |
jhnwkmn | 0:97a4f8cc534c | 371 | void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) |
jhnwkmn | 0:97a4f8cc534c | 372 | { |
jhnwkmn | 0:97a4f8cc534c | 373 | if(c->_prev) c->_prev->_next = c->_next; |
jhnwkmn | 0:97a4f8cc534c | 374 | else *chain = c->_next; |
jhnwkmn | 0:97a4f8cc534c | 375 | if(c->_next) |
jhnwkmn | 0:97a4f8cc534c | 376 | c->_next->_prev = c->_prev; |
jhnwkmn | 0:97a4f8cc534c | 377 | c->_next = NULL; |
jhnwkmn | 0:97a4f8cc534c | 378 | c->_prev = NULL; |
jhnwkmn | 0:97a4f8cc534c | 379 | } |
jhnwkmn | 0:97a4f8cc534c | 380 | #endif |
jhnwkmn | 0:97a4f8cc534c | 381 | |
jhnwkmn | 0:97a4f8cc534c | 382 | SQChar* SQSharedState::GetScratchPad(SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 383 | { |
jhnwkmn | 0:97a4f8cc534c | 384 | SQInteger newsize; |
jhnwkmn | 0:97a4f8cc534c | 385 | if(size>0) { |
jhnwkmn | 0:97a4f8cc534c | 386 | if(_scratchpadsize < size) { |
jhnwkmn | 0:97a4f8cc534c | 387 | newsize = size + (size>>1); |
jhnwkmn | 0:97a4f8cc534c | 388 | _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); |
jhnwkmn | 0:97a4f8cc534c | 389 | _scratchpadsize = newsize; |
jhnwkmn | 0:97a4f8cc534c | 390 | |
jhnwkmn | 0:97a4f8cc534c | 391 | }else if(_scratchpadsize >= (size<<5)) { |
jhnwkmn | 0:97a4f8cc534c | 392 | newsize = _scratchpadsize >> 1; |
jhnwkmn | 0:97a4f8cc534c | 393 | _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); |
jhnwkmn | 0:97a4f8cc534c | 394 | _scratchpadsize = newsize; |
jhnwkmn | 0:97a4f8cc534c | 395 | } |
jhnwkmn | 0:97a4f8cc534c | 396 | } |
jhnwkmn | 0:97a4f8cc534c | 397 | return _scratchpad; |
jhnwkmn | 0:97a4f8cc534c | 398 | } |
jhnwkmn | 0:97a4f8cc534c | 399 | |
jhnwkmn | 0:97a4f8cc534c | 400 | RefTable::RefTable() |
jhnwkmn | 0:97a4f8cc534c | 401 | { |
jhnwkmn | 0:97a4f8cc534c | 402 | AllocNodes(4); |
jhnwkmn | 0:97a4f8cc534c | 403 | } |
jhnwkmn | 0:97a4f8cc534c | 404 | |
jhnwkmn | 0:97a4f8cc534c | 405 | void RefTable::Finalize() |
jhnwkmn | 0:97a4f8cc534c | 406 | { |
jhnwkmn | 0:97a4f8cc534c | 407 | RefNode *nodes = _nodes; |
jhnwkmn | 0:97a4f8cc534c | 408 | for(SQUnsignedInteger n = 0; n < _numofslots; n++) { |
jhnwkmn | 0:97a4f8cc534c | 409 | nodes->obj.Null(); |
jhnwkmn | 0:97a4f8cc534c | 410 | nodes++; |
jhnwkmn | 0:97a4f8cc534c | 411 | } |
jhnwkmn | 0:97a4f8cc534c | 412 | } |
jhnwkmn | 0:97a4f8cc534c | 413 | |
jhnwkmn | 0:97a4f8cc534c | 414 | RefTable::~RefTable() |
jhnwkmn | 0:97a4f8cc534c | 415 | { |
jhnwkmn | 0:97a4f8cc534c | 416 | SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); |
jhnwkmn | 0:97a4f8cc534c | 417 | } |
jhnwkmn | 0:97a4f8cc534c | 418 | |
jhnwkmn | 0:97a4f8cc534c | 419 | #ifndef NO_GARBAGE_COLLECTOR |
jhnwkmn | 0:97a4f8cc534c | 420 | void RefTable::Mark(SQCollectable **chain) |
jhnwkmn | 0:97a4f8cc534c | 421 | { |
jhnwkmn | 0:97a4f8cc534c | 422 | RefNode *nodes = (RefNode *)_nodes; |
jhnwkmn | 0:97a4f8cc534c | 423 | for(SQUnsignedInteger n = 0; n < _numofslots; n++) { |
jhnwkmn | 0:97a4f8cc534c | 424 | if(type(nodes->obj) != OT_NULL) { |
jhnwkmn | 0:97a4f8cc534c | 425 | SQSharedState::MarkObject(nodes->obj,chain); |
jhnwkmn | 0:97a4f8cc534c | 426 | } |
jhnwkmn | 0:97a4f8cc534c | 427 | nodes++; |
jhnwkmn | 0:97a4f8cc534c | 428 | } |
jhnwkmn | 0:97a4f8cc534c | 429 | } |
jhnwkmn | 0:97a4f8cc534c | 430 | #endif |
jhnwkmn | 0:97a4f8cc534c | 431 | |
jhnwkmn | 0:97a4f8cc534c | 432 | void RefTable::AddRef(SQObject &obj) |
jhnwkmn | 0:97a4f8cc534c | 433 | { |
jhnwkmn | 0:97a4f8cc534c | 434 | SQHash mainpos; |
jhnwkmn | 0:97a4f8cc534c | 435 | RefNode *prev; |
jhnwkmn | 0:97a4f8cc534c | 436 | RefNode *ref = Get(obj,mainpos,&prev,true); |
jhnwkmn | 0:97a4f8cc534c | 437 | ref->refs++; |
jhnwkmn | 0:97a4f8cc534c | 438 | } |
jhnwkmn | 0:97a4f8cc534c | 439 | |
jhnwkmn | 0:97a4f8cc534c | 440 | SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) |
jhnwkmn | 0:97a4f8cc534c | 441 | { |
jhnwkmn | 0:97a4f8cc534c | 442 | SQHash mainpos; |
jhnwkmn | 0:97a4f8cc534c | 443 | RefNode *prev; |
jhnwkmn | 0:97a4f8cc534c | 444 | RefNode *ref = Get(obj,mainpos,&prev,true); |
jhnwkmn | 0:97a4f8cc534c | 445 | return ref->refs; |
jhnwkmn | 0:97a4f8cc534c | 446 | } |
jhnwkmn | 0:97a4f8cc534c | 447 | |
jhnwkmn | 0:97a4f8cc534c | 448 | |
jhnwkmn | 0:97a4f8cc534c | 449 | SQBool RefTable::Release(SQObject &obj) |
jhnwkmn | 0:97a4f8cc534c | 450 | { |
jhnwkmn | 0:97a4f8cc534c | 451 | SQHash mainpos; |
jhnwkmn | 0:97a4f8cc534c | 452 | RefNode *prev; |
jhnwkmn | 0:97a4f8cc534c | 453 | RefNode *ref = Get(obj,mainpos,&prev,false); |
jhnwkmn | 0:97a4f8cc534c | 454 | if(ref) { |
jhnwkmn | 0:97a4f8cc534c | 455 | if(--ref->refs == 0) { |
jhnwkmn | 0:97a4f8cc534c | 456 | SQObjectPtr o = ref->obj; |
jhnwkmn | 0:97a4f8cc534c | 457 | if(prev) { |
jhnwkmn | 0:97a4f8cc534c | 458 | prev->next = ref->next; |
jhnwkmn | 0:97a4f8cc534c | 459 | } |
jhnwkmn | 0:97a4f8cc534c | 460 | else { |
jhnwkmn | 0:97a4f8cc534c | 461 | _buckets[mainpos] = ref->next; |
jhnwkmn | 0:97a4f8cc534c | 462 | } |
jhnwkmn | 0:97a4f8cc534c | 463 | ref->next = _freelist; |
jhnwkmn | 0:97a4f8cc534c | 464 | _freelist = ref; |
jhnwkmn | 0:97a4f8cc534c | 465 | _slotused--; |
jhnwkmn | 0:97a4f8cc534c | 466 | ref->obj.Null(); |
jhnwkmn | 0:97a4f8cc534c | 467 | //<<FIXME>>test for shrink? |
jhnwkmn | 0:97a4f8cc534c | 468 | return SQTrue; |
jhnwkmn | 0:97a4f8cc534c | 469 | } |
jhnwkmn | 0:97a4f8cc534c | 470 | } |
jhnwkmn | 0:97a4f8cc534c | 471 | else { |
jhnwkmn | 0:97a4f8cc534c | 472 | assert(0); |
jhnwkmn | 0:97a4f8cc534c | 473 | } |
jhnwkmn | 0:97a4f8cc534c | 474 | return SQFalse; |
jhnwkmn | 0:97a4f8cc534c | 475 | } |
jhnwkmn | 0:97a4f8cc534c | 476 | |
jhnwkmn | 0:97a4f8cc534c | 477 | void RefTable::Resize(SQUnsignedInteger size) |
jhnwkmn | 0:97a4f8cc534c | 478 | { |
jhnwkmn | 0:97a4f8cc534c | 479 | RefNode **oldbucks = _buckets; |
jhnwkmn | 0:97a4f8cc534c | 480 | RefNode *t = _nodes; |
jhnwkmn | 0:97a4f8cc534c | 481 | SQUnsignedInteger oldnumofslots = _numofslots; |
jhnwkmn | 0:97a4f8cc534c | 482 | AllocNodes(size); |
jhnwkmn | 0:97a4f8cc534c | 483 | //rehash |
jhnwkmn | 0:97a4f8cc534c | 484 | SQUnsignedInteger nfound = 0; |
jhnwkmn | 0:97a4f8cc534c | 485 | for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { |
jhnwkmn | 0:97a4f8cc534c | 486 | if(type(t->obj) != OT_NULL) { |
jhnwkmn | 0:97a4f8cc534c | 487 | //add back; |
jhnwkmn | 0:97a4f8cc534c | 488 | assert(t->refs != 0); |
jhnwkmn | 0:97a4f8cc534c | 489 | RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); |
jhnwkmn | 0:97a4f8cc534c | 490 | nn->refs = t->refs; |
jhnwkmn | 0:97a4f8cc534c | 491 | t->obj.Null(); |
jhnwkmn | 0:97a4f8cc534c | 492 | nfound++; |
jhnwkmn | 0:97a4f8cc534c | 493 | } |
jhnwkmn | 0:97a4f8cc534c | 494 | t++; |
jhnwkmn | 0:97a4f8cc534c | 495 | } |
jhnwkmn | 0:97a4f8cc534c | 496 | assert(nfound == oldnumofslots); |
jhnwkmn | 0:97a4f8cc534c | 497 | SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); |
jhnwkmn | 0:97a4f8cc534c | 498 | } |
jhnwkmn | 0:97a4f8cc534c | 499 | |
jhnwkmn | 0:97a4f8cc534c | 500 | RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) |
jhnwkmn | 0:97a4f8cc534c | 501 | { |
jhnwkmn | 0:97a4f8cc534c | 502 | RefNode *t = _buckets[mainpos]; |
jhnwkmn | 0:97a4f8cc534c | 503 | RefNode *newnode = _freelist; |
jhnwkmn | 0:97a4f8cc534c | 504 | newnode->obj = obj; |
jhnwkmn | 0:97a4f8cc534c | 505 | _buckets[mainpos] = newnode; |
jhnwkmn | 0:97a4f8cc534c | 506 | _freelist = _freelist->next; |
jhnwkmn | 0:97a4f8cc534c | 507 | newnode->next = t; |
jhnwkmn | 0:97a4f8cc534c | 508 | assert(newnode->refs == 0); |
jhnwkmn | 0:97a4f8cc534c | 509 | _slotused++; |
jhnwkmn | 0:97a4f8cc534c | 510 | return newnode; |
jhnwkmn | 0:97a4f8cc534c | 511 | } |
jhnwkmn | 0:97a4f8cc534c | 512 | |
jhnwkmn | 0:97a4f8cc534c | 513 | RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) |
jhnwkmn | 0:97a4f8cc534c | 514 | { |
jhnwkmn | 0:97a4f8cc534c | 515 | RefNode *ref; |
jhnwkmn | 0:97a4f8cc534c | 516 | mainpos = ::HashObj(obj)&(_numofslots-1); |
jhnwkmn | 0:97a4f8cc534c | 517 | *prev = NULL; |
jhnwkmn | 0:97a4f8cc534c | 518 | for (ref = _buckets[mainpos]; ref; ) { |
jhnwkmn | 0:97a4f8cc534c | 519 | if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj)) |
jhnwkmn | 0:97a4f8cc534c | 520 | break; |
jhnwkmn | 0:97a4f8cc534c | 521 | *prev = ref; |
jhnwkmn | 0:97a4f8cc534c | 522 | ref = ref->next; |
jhnwkmn | 0:97a4f8cc534c | 523 | } |
jhnwkmn | 0:97a4f8cc534c | 524 | if(ref == NULL && add) { |
jhnwkmn | 0:97a4f8cc534c | 525 | if(_numofslots == _slotused) { |
jhnwkmn | 0:97a4f8cc534c | 526 | assert(_freelist == 0); |
jhnwkmn | 0:97a4f8cc534c | 527 | Resize(_numofslots*2); |
jhnwkmn | 0:97a4f8cc534c | 528 | mainpos = ::HashObj(obj)&(_numofslots-1); |
jhnwkmn | 0:97a4f8cc534c | 529 | } |
jhnwkmn | 0:97a4f8cc534c | 530 | ref = Add(mainpos,obj); |
jhnwkmn | 0:97a4f8cc534c | 531 | } |
jhnwkmn | 0:97a4f8cc534c | 532 | return ref; |
jhnwkmn | 0:97a4f8cc534c | 533 | } |
jhnwkmn | 0:97a4f8cc534c | 534 | |
jhnwkmn | 0:97a4f8cc534c | 535 | void RefTable::AllocNodes(SQUnsignedInteger size) |
jhnwkmn | 0:97a4f8cc534c | 536 | { |
jhnwkmn | 0:97a4f8cc534c | 537 | RefNode **bucks; |
jhnwkmn | 0:97a4f8cc534c | 538 | RefNode *nodes; |
jhnwkmn | 0:97a4f8cc534c | 539 | bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); |
jhnwkmn | 0:97a4f8cc534c | 540 | nodes = (RefNode *)&bucks[size]; |
jhnwkmn | 0:97a4f8cc534c | 541 | RefNode *temp = nodes; |
jhnwkmn | 0:97a4f8cc534c | 542 | SQUnsignedInteger n; |
jhnwkmn | 0:97a4f8cc534c | 543 | for(n = 0; n < size - 1; n++) { |
jhnwkmn | 0:97a4f8cc534c | 544 | bucks[n] = NULL; |
jhnwkmn | 0:97a4f8cc534c | 545 | temp->refs = 0; |
jhnwkmn | 0:97a4f8cc534c | 546 | new (&temp->obj) SQObjectPtr; |
jhnwkmn | 0:97a4f8cc534c | 547 | temp->next = temp+1; |
jhnwkmn | 0:97a4f8cc534c | 548 | temp++; |
jhnwkmn | 0:97a4f8cc534c | 549 | } |
jhnwkmn | 0:97a4f8cc534c | 550 | bucks[n] = NULL; |
jhnwkmn | 0:97a4f8cc534c | 551 | temp->refs = 0; |
jhnwkmn | 0:97a4f8cc534c | 552 | new (&temp->obj) SQObjectPtr; |
jhnwkmn | 0:97a4f8cc534c | 553 | temp->next = NULL; |
jhnwkmn | 0:97a4f8cc534c | 554 | _freelist = nodes; |
jhnwkmn | 0:97a4f8cc534c | 555 | _nodes = nodes; |
jhnwkmn | 0:97a4f8cc534c | 556 | _buckets = bucks; |
jhnwkmn | 0:97a4f8cc534c | 557 | _slotused = 0; |
jhnwkmn | 0:97a4f8cc534c | 558 | _numofslots = size; |
jhnwkmn | 0:97a4f8cc534c | 559 | } |
jhnwkmn | 0:97a4f8cc534c | 560 | ////////////////////////////////////////////////////////////////////////// |
jhnwkmn | 0:97a4f8cc534c | 561 | //SQStringTable |
jhnwkmn | 0:97a4f8cc534c | 562 | /* |
jhnwkmn | 0:97a4f8cc534c | 563 | * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) |
jhnwkmn | 0:97a4f8cc534c | 564 | * http://www.lua.org/copyright.html#4 |
jhnwkmn | 0:97a4f8cc534c | 565 | * http://www.lua.org/source/4.0.1/src_lstring.c.html |
jhnwkmn | 0:97a4f8cc534c | 566 | */ |
jhnwkmn | 0:97a4f8cc534c | 567 | |
jhnwkmn | 0:97a4f8cc534c | 568 | SQStringTable::SQStringTable(SQSharedState *ss) |
jhnwkmn | 0:97a4f8cc534c | 569 | { |
jhnwkmn | 0:97a4f8cc534c | 570 | _sharedstate = ss; |
jhnwkmn | 0:97a4f8cc534c | 571 | AllocNodes(4); |
jhnwkmn | 0:97a4f8cc534c | 572 | _slotused = 0; |
jhnwkmn | 0:97a4f8cc534c | 573 | } |
jhnwkmn | 0:97a4f8cc534c | 574 | |
jhnwkmn | 0:97a4f8cc534c | 575 | SQStringTable::~SQStringTable() |
jhnwkmn | 0:97a4f8cc534c | 576 | { |
jhnwkmn | 0:97a4f8cc534c | 577 | SQ_FREE(_strings,sizeof(SQString*)*_numofslots); |
jhnwkmn | 0:97a4f8cc534c | 578 | _strings = NULL; |
jhnwkmn | 0:97a4f8cc534c | 579 | } |
jhnwkmn | 0:97a4f8cc534c | 580 | |
jhnwkmn | 0:97a4f8cc534c | 581 | void SQStringTable::AllocNodes(SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 582 | { |
jhnwkmn | 0:97a4f8cc534c | 583 | _numofslots = size; |
jhnwkmn | 0:97a4f8cc534c | 584 | _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); |
jhnwkmn | 0:97a4f8cc534c | 585 | memset(_strings,0,sizeof(SQString*)*_numofslots); |
jhnwkmn | 0:97a4f8cc534c | 586 | } |
jhnwkmn | 0:97a4f8cc534c | 587 | |
jhnwkmn | 0:97a4f8cc534c | 588 | SQString *SQStringTable::Add(const SQChar *news,SQInteger len) |
jhnwkmn | 0:97a4f8cc534c | 589 | { |
jhnwkmn | 0:97a4f8cc534c | 590 | if(len<0) |
jhnwkmn | 0:97a4f8cc534c | 591 | len = (SQInteger)scstrlen(news); |
jhnwkmn | 0:97a4f8cc534c | 592 | SQHash newhash = ::_hashstr(news,len); |
jhnwkmn | 0:97a4f8cc534c | 593 | SQHash h = newhash&(_numofslots-1); |
jhnwkmn | 0:97a4f8cc534c | 594 | SQString *s; |
jhnwkmn | 0:97a4f8cc534c | 595 | for (s = _strings[h]; s; s = s->_next){ |
jhnwkmn | 0:97a4f8cc534c | 596 | if(s->_len == len && (!memcmp(news,s->_val,rsl(len)))) |
jhnwkmn | 0:97a4f8cc534c | 597 | return s; //found |
jhnwkmn | 0:97a4f8cc534c | 598 | } |
jhnwkmn | 0:97a4f8cc534c | 599 | |
jhnwkmn | 0:97a4f8cc534c | 600 | SQString *t = (SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString)); |
jhnwkmn | 0:97a4f8cc534c | 601 | new (t) SQString; |
jhnwkmn | 0:97a4f8cc534c | 602 | t->_sharedstate = _sharedstate; |
jhnwkmn | 0:97a4f8cc534c | 603 | memcpy(t->_val,news,rsl(len)); |
jhnwkmn | 0:97a4f8cc534c | 604 | t->_val[len] = _SC('\0'); |
jhnwkmn | 0:97a4f8cc534c | 605 | t->_len = len; |
jhnwkmn | 0:97a4f8cc534c | 606 | t->_hash = newhash; |
jhnwkmn | 0:97a4f8cc534c | 607 | t->_next = _strings[h]; |
jhnwkmn | 0:97a4f8cc534c | 608 | _strings[h] = t; |
jhnwkmn | 0:97a4f8cc534c | 609 | _slotused++; |
jhnwkmn | 0:97a4f8cc534c | 610 | if (_slotused > _numofslots) /* too crowded? */ |
jhnwkmn | 0:97a4f8cc534c | 611 | Resize(_numofslots*2); |
jhnwkmn | 0:97a4f8cc534c | 612 | return t; |
jhnwkmn | 0:97a4f8cc534c | 613 | } |
jhnwkmn | 0:97a4f8cc534c | 614 | |
jhnwkmn | 0:97a4f8cc534c | 615 | void SQStringTable::Resize(SQInteger size) |
jhnwkmn | 0:97a4f8cc534c | 616 | { |
jhnwkmn | 0:97a4f8cc534c | 617 | SQInteger oldsize=_numofslots; |
jhnwkmn | 0:97a4f8cc534c | 618 | SQString **oldtable=_strings; |
jhnwkmn | 0:97a4f8cc534c | 619 | AllocNodes(size); |
jhnwkmn | 0:97a4f8cc534c | 620 | for (SQInteger i=0; i<oldsize; i++){ |
jhnwkmn | 0:97a4f8cc534c | 621 | SQString *p = oldtable[i]; |
jhnwkmn | 0:97a4f8cc534c | 622 | while(p){ |
jhnwkmn | 0:97a4f8cc534c | 623 | SQString *next = p->_next; |
jhnwkmn | 0:97a4f8cc534c | 624 | SQHash h = p->_hash&(_numofslots-1); |
jhnwkmn | 0:97a4f8cc534c | 625 | p->_next = _strings[h]; |
jhnwkmn | 0:97a4f8cc534c | 626 | _strings[h] = p; |
jhnwkmn | 0:97a4f8cc534c | 627 | p = next; |
jhnwkmn | 0:97a4f8cc534c | 628 | } |
jhnwkmn | 0:97a4f8cc534c | 629 | } |
jhnwkmn | 0:97a4f8cc534c | 630 | SQ_FREE(oldtable,oldsize*sizeof(SQString*)); |
jhnwkmn | 0:97a4f8cc534c | 631 | } |
jhnwkmn | 0:97a4f8cc534c | 632 | |
jhnwkmn | 0:97a4f8cc534c | 633 | void SQStringTable::Remove(SQString *bs) |
jhnwkmn | 0:97a4f8cc534c | 634 | { |
jhnwkmn | 0:97a4f8cc534c | 635 | SQString *s; |
jhnwkmn | 0:97a4f8cc534c | 636 | SQString *prev=NULL; |
jhnwkmn | 0:97a4f8cc534c | 637 | SQHash h = bs->_hash&(_numofslots - 1); |
jhnwkmn | 0:97a4f8cc534c | 638 | |
jhnwkmn | 0:97a4f8cc534c | 639 | for (s = _strings[h]; s; ){ |
jhnwkmn | 0:97a4f8cc534c | 640 | if(s == bs){ |
jhnwkmn | 0:97a4f8cc534c | 641 | if(prev) |
jhnwkmn | 0:97a4f8cc534c | 642 | prev->_next = s->_next; |
jhnwkmn | 0:97a4f8cc534c | 643 | else |
jhnwkmn | 0:97a4f8cc534c | 644 | _strings[h] = s->_next; |
jhnwkmn | 0:97a4f8cc534c | 645 | _slotused--; |
jhnwkmn | 0:97a4f8cc534c | 646 | SQInteger slen = s->_len; |
jhnwkmn | 0:97a4f8cc534c | 647 | s->~SQString(); |
jhnwkmn | 0:97a4f8cc534c | 648 | SQ_FREE(s,sizeof(SQString) + rsl(slen)); |
jhnwkmn | 0:97a4f8cc534c | 649 | return; |
jhnwkmn | 0:97a4f8cc534c | 650 | } |
jhnwkmn | 0:97a4f8cc534c | 651 | prev = s; |
jhnwkmn | 0:97a4f8cc534c | 652 | s = s->_next; |
jhnwkmn | 0:97a4f8cc534c | 653 | } |
jhnwkmn | 0:97a4f8cc534c | 654 | assert(0);//if this fail something is wrong |
jhnwkmn | 0:97a4f8cc534c | 655 | } |