fixed warnings in squirrel
[supertux.git] / src / squirrel / squirrel / sqstate.cpp
index e352e25..038f28a 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqopcodes.h"\r
-#include "sqvm.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "sqarray.h"\r
-#include "squserdata.h"\r
-#include "sqclass.h"\r
-\r
-SQObjectPtr _null_;\r
-SQObjectPtr _true_(true);\r
-SQObjectPtr _false_(false);\r
-SQObjectPtr _one_(1);\r
-SQObjectPtr _minusone_(-1);\r
-\r
-SQSharedState::SQSharedState()\r
-{\r
-       _compilererrorhandler = NULL;\r
-       _printfunc = NULL;\r
-       _debuginfo = false;\r
-}\r
-\r
-#define newsysstring(s) {      \\r
-       _systemstrings->push_back(SQString::Create(this,s));    \\r
-       }\r
-\r
-#define newmetamethod(s) {     \\r
-       _metamethods->push_back(SQString::Create(this,s));      \\r
-       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \\r
-       }\r
-\r
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)\r
-{\r
-       int i = 0;\r
-       \r
-       int mask = 0;\r
-       while(typemask[i] != 0) {\r
-               \r
-               switch(typemask[i]){\r
-                               case 'i': mask |= _RT_INTEGER; break;\r
-                               case 'f': mask |= _RT_FLOAT; break;\r
-                               case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;\r
-                               case 's': mask |= _RT_STRING; break;\r
-                               case 't': mask |= _RT_TABLE; break;\r
-                               case 'a': mask |= _RT_ARRAY; break;\r
-                               case 'u': mask |= _RT_USERDATA; break;\r
-                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;\r
-                               case 'b': mask |= _RT_BOOL; break;\r
-                               case 'g': mask |= _RT_GENERATOR; break;\r
-                               case 'p': mask |= _RT_USERPOINTER; break;\r
-                               case 'v': mask |= _RT_THREAD; break;\r
-                               case 'x': mask |= _RT_INSTANCE; break;\r
-                               case 'y': mask |= _RT_CLASS; break;\r
-                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;\r
-                               case ' ': i++; continue; //ignores spaces\r
-                               default:\r
-                                       return false;\r
-               }\r
-               i++;\r
-               if(typemask[i] == '|') { \r
-                       i++; \r
-                       if(typemask[i] == 0)\r
-                               return false;\r
-                       continue; \r
-               }\r
-               res.push_back(mask);\r
-               mask = 0;\r
-               \r
-       }\r
-       return true;\r
-}\r
-\r
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)\r
-{\r
-       int i=0;\r
-       SQTable *t=SQTable::Create(ss,0);\r
-       while(funcz[i].name!=0){\r
-               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);\r
-               nc->_nparamscheck = funcz[i].nparamscheck;\r
-               nc->_name = SQString::Create(ss,funcz[i].name);\r
-               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))\r
-                       return NULL;\r
-               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);\r
-               i++;\r
-       }\r
-       return t;\r
-}\r
-\r
-void SQSharedState::Init()\r
-{      \r
-       _scratchpad=NULL;\r
-       _scratchpadsize=0;\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       _gc_chain=NULL;\r
-#endif\r
-       sq_new(_stringtable,StringTable);\r
-       sq_new(_metamethods,SQObjectPtrVec);\r
-       sq_new(_systemstrings,SQObjectPtrVec);\r
-       sq_new(_types,SQObjectPtrVec);\r
-       _metamethodsmap = SQTable::Create(this,MT_LAST-1);\r
-       //adding type strings to avoid memory trashing\r
-       //types names\r
-       newsysstring(_SC("null"));\r
-       newsysstring(_SC("table"));\r
-       newsysstring(_SC("array"));\r
-       newsysstring(_SC("closure"));\r
-       newsysstring(_SC("string"));\r
-       newsysstring(_SC("userdata"));\r
-       newsysstring(_SC("integer"));\r
-       newsysstring(_SC("float"));\r
-       newsysstring(_SC("userpointer"));\r
-       newsysstring(_SC("function"));\r
-       newsysstring(_SC("generator"));\r
-       newsysstring(_SC("thread"));\r
-       newsysstring(_SC("class"));\r
-       newsysstring(_SC("instance"));\r
-       newsysstring(_SC("bool"));\r
-       //meta methods\r
-       newmetamethod(MM_ADD);\r
-       newmetamethod(MM_SUB);\r
-       newmetamethod(MM_MUL);\r
-       newmetamethod(MM_DIV);\r
-       newmetamethod(MM_UNM);\r
-       newmetamethod(MM_MODULO);\r
-       newmetamethod(MM_SET);\r
-       newmetamethod(MM_GET);\r
-       newmetamethod(MM_TYPEOF);\r
-       newmetamethod(MM_NEXTI);\r
-       newmetamethod(MM_CMP);\r
-       newmetamethod(MM_CALL);\r
-       newmetamethod(MM_CLONED);\r
-       newmetamethod(MM_NEWSLOT);\r
-       newmetamethod(MM_DELSLOT);\r
-\r
-       _constructoridx = SQString::Create(this,_SC("constructor"));\r
-       _refs_table = SQTable::Create(this,0);\r
-       _registry = SQTable::Create(this,0);\r
-       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);\r
-       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);\r
-       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);\r
-       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);\r
-       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);\r
-       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);\r
-       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);\r
-       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);\r
-       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);\r
-\r
-}\r
-\r
-SQSharedState::~SQSharedState()\r
-{\r
-       _constructoridx = _null_;\r
-       _table(_refs_table)->Finalize();\r
-       _table(_registry)->Finalize();\r
-       _table(_metamethodsmap)->Finalize();\r
-       _refs_table = _null_;\r
-       _registry = _null_;\r
-       _metamethodsmap = _null_;\r
-       while(!_systemstrings->empty()){\r
-               _systemstrings->back()=_null_;\r
-               _systemstrings->pop_back();\r
-       }\r
-       _thread(_root_vm)->Finalize();\r
-       _root_vm = _null_;\r
-       _table_default_delegate=_null_;\r
-       _array_default_delegate=_null_;\r
-       _string_default_delegate=_null_;\r
-       _number_default_delegate=_null_;\r
-       _closure_default_delegate=_null_;\r
-       _generator_default_delegate=_null_;\r
-       _thread_default_delegate=_null_;\r
-       _class_default_delegate=_null_;\r
-       _instance_default_delegate=_null_;\r
-       \r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       \r
-       \r
-       SQCollectable *t=_gc_chain;\r
-       SQCollectable *nx=NULL;\r
-       while(t){\r
-               t->_uiRef++;\r
-               t->Finalize();\r
-               nx=t->_next;\r
-               if(--t->_uiRef==0)\r
-                       t->Release();\r
-               t=nx;\r
-       }\r
-       assert(_gc_chain==NULL); //just to proove a theory\r
-       while(_gc_chain){\r
-               _gc_chain->_uiRef++;\r
-               _gc_chain->Release();\r
-       }\r
-#endif\r
-       sq_delete(_types,SQObjectPtrVec);\r
-       sq_delete(_systemstrings,SQObjectPtrVec);\r
-       sq_delete(_metamethods,SQObjectPtrVec);\r
-       sq_delete(_stringtable,StringTable);\r
-       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);\r
-}\r
-\r
-\r
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)\r
-{\r
-       if(type(name) != OT_STRING)\r
-               return -1;\r
-       SQObjectPtr ret;\r
-       if(_table(_metamethodsmap)->Get(name,ret)) {\r
-               return _integer(ret);\r
-       }\r
-       return -1;\r
-}\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-\r
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)\r
-{\r
-       switch(type(o)){\r
-       case OT_TABLE:_table(o)->Mark(chain);break;\r
-       case OT_ARRAY:_array(o)->Mark(chain);break;\r
-       case OT_USERDATA:_userdata(o)->Mark(chain);break;\r
-       case OT_CLOSURE:_closure(o)->Mark(chain);break;\r
-       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;\r
-       case OT_GENERATOR:_generator(o)->Mark(chain);break;\r
-       case OT_THREAD:_thread(o)->Mark(chain);break;\r
-       case OT_CLASS:_class(o)->Mark(chain);break;\r
-       case OT_INSTANCE:_instance(o)->Mark(chain);break;\r
-       }\r
-}\r
-\r
-\r
-int SQSharedState::CollectGarbage(SQVM *vm)\r
-{\r
-       int n=0;\r
-       SQCollectable *tchain=NULL;\r
-       SQVM *vms=_thread(_root_vm);\r
-       \r
-       vms->Mark(&tchain);\r
-       int x = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
-       MarkObject(_refs_table,&tchain);\r
-       MarkObject(_registry,&tchain);\r
-       MarkObject(_metamethodsmap,&tchain);\r
-       MarkObject(_table_default_delegate,&tchain);\r
-       MarkObject(_array_default_delegate,&tchain);\r
-       MarkObject(_string_default_delegate,&tchain);\r
-       MarkObject(_number_default_delegate,&tchain);\r
-       MarkObject(_generator_default_delegate,&tchain);\r
-       MarkObject(_thread_default_delegate,&tchain);\r
-       MarkObject(_closure_default_delegate,&tchain);\r
-       MarkObject(_class_default_delegate,&tchain);\r
-       MarkObject(_instance_default_delegate,&tchain);\r
-       \r
-       SQCollectable *t=_gc_chain;\r
-       SQCollectable *nx=NULL;\r
-       while(t){\r
-               t->_uiRef++;\r
-               t->Finalize();\r
-               nx=t->_next;\r
-               if(--t->_uiRef==0)\r
-                       t->Release();\r
-               t=nx;\r
-               n++;\r
-       }\r
-\r
-       t=tchain;\r
-       while(t){\r
-               t->UnMark();\r
-               t=t->_next;\r
-       }\r
-       _gc_chain=tchain;\r
-       int z = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
-       assert(z == x);\r
-       return n;\r
-}\r
-#endif\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)\r
-{\r
-    c->_prev=NULL;\r
-       c->_next=*chain;\r
-       if(*chain) (*chain)->_prev=c;\r
-       *chain=c;\r
-}\r
-\r
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)\r
-{\r
-       if(c->_prev) c->_prev->_next=c->_next;\r
-       else *chain=c->_next;\r
-       if(c->_next)\r
-               c->_next->_prev=c->_prev;\r
-       c->_next=NULL;\r
-       c->_prev=NULL;\r
-}\r
-#endif\r
-\r
-SQChar* SQSharedState::GetScratchPad(int size)\r
-{\r
-       int newsize;\r
-       if(size>0){\r
-               if(_scratchpadsize<size){\r
-                       newsize=size+(size>>1);\r
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
-                       _scratchpadsize=newsize;\r
-\r
-               }else if(_scratchpadsize>=(size<<5)){\r
-                       newsize=_scratchpadsize>>1;\r
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
-                       _scratchpadsize=newsize;\r
-               }\r
-       }\r
-       return _scratchpad;\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////////\r
-//StringTable\r
-/*\r
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
-* http://www.lua.org/copyright.html#4\r
-* http://www.lua.org/source/4.0.1/src_lstring.c.html\r
-*/\r
-\r
-int SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
-{\r
-       int idx = (int)TranslateIndex(refpos);\r
-       while(idx < _len){\r
-               outkey = (SQInteger)idx;\r
-               outval = SQInteger(_val[idx]);\r
-               //return idx for the next iteration\r
-               return ++idx;\r
-       }\r
-       //nothing to iterate anymore\r
-       return -1;\r
-}\r
-\r
-StringTable::StringTable()\r
-{\r
-       AllocNodes(4);\r
-       _slotused = 0;\r
-}\r
-\r
-StringTable::~StringTable()\r
-{\r
-       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);\r
-       _strings=NULL;\r
-}\r
-\r
-void StringTable::AllocNodes(int size)\r
-{\r
-       _numofslots=size;\r
-       //_slotused=0;\r
-       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);\r
-       memset(_strings,0,sizeof(SQString*)*_numofslots);\r
-}\r
-\r
-SQString *StringTable::Add(const SQChar *news,int len)\r
-{\r
-       if(len<0)\r
-               len=scstrlen(news);\r
-       unsigned int h=::_hashstr(news,len)&(_numofslots-1);\r
-       SQString *s;\r
-       for (s = _strings[h]; s; s = s->_next){\r
-               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))\r
-                       return s; //found\r
-       }\r
-\r
-       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));\r
-       new (t) SQString;\r
-       memcpy(t->_val,news,rsl(len));\r
-       t->_val[len]=_SC('\0');\r
-       t->_len=len;\r
-       t->_hash=::_hashstr(news,len);\r
-       t->_next=_strings[h];\r
-       t->_uiRef=0;\r
-       _strings[h]=t;\r
-       _slotused++;\r
-       if (_slotused > _numofslots)  /* too crowded? */\r
-               Resize(_numofslots*2);\r
-       return t;\r
-}\r
-\r
-void StringTable::Resize(int size)\r
-{\r
-       int oldsize=_numofslots;\r
-       SQString **oldtable=_strings;\r
-       AllocNodes(size);\r
-       for (int i=0; i<oldsize; i++){\r
-               SQString *p = oldtable[i];\r
-               while(p){\r
-                       SQString *next = p->_next;\r
-                       unsigned int h=p->_hash&(_numofslots-1);\r
-                       p->_next=_strings[h];\r
-                       _strings[h] = p;\r
-                       p=next;\r
-               }\r
-       }\r
-       SQ_FREE(oldtable,oldsize*sizeof(SQString*));\r
-}\r
-\r
-void StringTable::Remove(SQString *bs)\r
-{\r
-       SQString *s;\r
-       SQString *prev=NULL;\r
-       unsigned int h=bs->_hash&(_numofslots-1);\r
-       \r
-       for (s = _strings[h]; s; ){\r
-               if(s == bs){\r
-                       if(prev)\r
-                               prev->_next = s->_next;\r
-                       else\r
-                               _strings[h] = s->_next;\r
-                       _slotused--;\r
-                       int slen=s->_len;\r
-                       s->~SQString();\r
-                       SQ_FREE(s,sizeof(SQString)+rsl(slen));\r
-                       return;\r
-               }\r
-               prev = s;\r
-               s = s->_next;\r
-       }\r
-       assert(0);//if this fail something is wrong\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqopcodes.h"
+#include "sqvm.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "squserdata.h"
+#include "sqclass.h"
+
+SQObjectPtr _null_;
+SQObjectPtr _true_(true);
+SQObjectPtr _false_(false);
+SQObjectPtr _one_(1);
+SQObjectPtr _minusone_(-1);
+
+SQSharedState::SQSharedState()
+{
+       _compilererrorhandler = NULL;
+       _printfunc = NULL;
+       _debuginfo = false;
+}
+
+#define newsysstring(s) {      \
+       _systemstrings->push_back(SQString::Create(this,s));    \
+       }
+
+#define newmetamethod(s) {     \
+       _metamethods->push_back(SQString::Create(this,s));      \
+       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
+       }
+
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
+{
+       int i = 0;
+       
+       int mask = 0;
+       while(typemask[i] != 0) {
+               
+               switch(typemask[i]){
+                               case 'i': mask |= _RT_INTEGER; break;
+                               case 'f': mask |= _RT_FLOAT; break;
+                               case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
+                               case 's': mask |= _RT_STRING; break;
+                               case 't': mask |= _RT_TABLE; break;
+                               case 'a': mask |= _RT_ARRAY; break;
+                               case 'u': mask |= _RT_USERDATA; break;
+                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
+                               case 'b': mask |= _RT_BOOL; break;
+                               case 'g': mask |= _RT_GENERATOR; break;
+                               case 'p': mask |= _RT_USERPOINTER; break;
+                               case 'v': mask |= _RT_THREAD; break;
+                               case 'x': mask |= _RT_INSTANCE; break;
+                               case 'y': mask |= _RT_CLASS; break;
+                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
+                               case ' ': i++; continue; //ignores spaces
+                               default:
+                                       return false;
+               }
+               i++;
+               if(typemask[i] == '|') { 
+                       i++; 
+                       if(typemask[i] == 0)
+                               return false;
+                       continue; 
+               }
+               res.push_back(mask);
+               mask = 0;
+               
+       }
+       return true;
+}
+
+SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
+{
+       int i=0;
+       SQTable *t=SQTable::Create(ss,0);
+       while(funcz[i].name!=0){
+               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
+               nc->_nparamscheck = funcz[i].nparamscheck;
+               nc->_name = SQString::Create(ss,funcz[i].name);
+               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
+                       return NULL;
+               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
+               i++;
+       }
+       return t;
+}
+
+void SQSharedState::Init()
+{      
+       _scratchpad=NULL;
+       _scratchpadsize=0;
+#ifndef NO_GARBAGE_COLLECTOR
+       _gc_chain=NULL;
+#endif
+       sq_new(_stringtable,StringTable);
+       sq_new(_metamethods,SQObjectPtrVec);
+       sq_new(_systemstrings,SQObjectPtrVec);
+       sq_new(_types,SQObjectPtrVec);
+       _metamethodsmap = SQTable::Create(this,MT_LAST-1);
+       //adding type strings to avoid memory trashing
+       //types names
+       newsysstring(_SC("null"));
+       newsysstring(_SC("table"));
+       newsysstring(_SC("array"));
+       newsysstring(_SC("closure"));
+       newsysstring(_SC("string"));
+       newsysstring(_SC("userdata"));
+       newsysstring(_SC("integer"));
+       newsysstring(_SC("float"));
+       newsysstring(_SC("userpointer"));
+       newsysstring(_SC("function"));
+       newsysstring(_SC("generator"));
+       newsysstring(_SC("thread"));
+       newsysstring(_SC("class"));
+       newsysstring(_SC("instance"));
+       newsysstring(_SC("bool"));
+       //meta methods
+       newmetamethod(MM_ADD);
+       newmetamethod(MM_SUB);
+       newmetamethod(MM_MUL);
+       newmetamethod(MM_DIV);
+       newmetamethod(MM_UNM);
+       newmetamethod(MM_MODULO);
+       newmetamethod(MM_SET);
+       newmetamethod(MM_GET);
+       newmetamethod(MM_TYPEOF);
+       newmetamethod(MM_NEXTI);
+       newmetamethod(MM_CMP);
+       newmetamethod(MM_CALL);
+       newmetamethod(MM_CLONED);
+       newmetamethod(MM_NEWSLOT);
+       newmetamethod(MM_DELSLOT);
+
+       _constructoridx = SQString::Create(this,_SC("constructor"));
+       _refs_table = SQTable::Create(this,0);
+       _registry = SQTable::Create(this,0);
+       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
+       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
+       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
+       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
+       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
+       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
+       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
+       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
+       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
+
+}
+
+SQSharedState::~SQSharedState()
+{
+       _constructoridx = _null_;
+       _table(_refs_table)->Finalize();
+       _table(_registry)->Finalize();
+       _table(_metamethodsmap)->Finalize();
+       _refs_table = _null_;
+       _registry = _null_;
+       _metamethodsmap = _null_;
+       while(!_systemstrings->empty()){
+               _systemstrings->back()=_null_;
+               _systemstrings->pop_back();
+       }
+       _thread(_root_vm)->Finalize();
+       _root_vm = _null_;
+       _table_default_delegate=_null_;
+       _array_default_delegate=_null_;
+       _string_default_delegate=_null_;
+       _number_default_delegate=_null_;
+       _closure_default_delegate=_null_;
+       _generator_default_delegate=_null_;
+       _thread_default_delegate=_null_;
+       _class_default_delegate=_null_;
+       _instance_default_delegate=_null_;
+       
+#ifndef NO_GARBAGE_COLLECTOR
+       
+       
+       SQCollectable *t=_gc_chain;
+       SQCollectable *nx=NULL;
+       while(t){
+               t->_uiRef++;
+               t->Finalize();
+               nx=t->_next;
+               if(--t->_uiRef==0)
+                       t->Release();
+               t=nx;
+       }
+       assert(_gc_chain==NULL); //just to proove a theory
+       while(_gc_chain){
+               _gc_chain->_uiRef++;
+               _gc_chain->Release();
+       }
+#endif
+       sq_delete(_types,SQObjectPtrVec);
+       sq_delete(_systemstrings,SQObjectPtrVec);
+       sq_delete(_metamethods,SQObjectPtrVec);
+       sq_delete(_stringtable,StringTable);
+       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
+}
+
+
+SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
+{
+       if(type(name) != OT_STRING)
+               return -1;
+       SQObjectPtr ret;
+       if(_table(_metamethodsmap)->Get(name,ret)) {
+               return _integer(ret);
+       }
+       return -1;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
+{
+       switch(type(o)){
+       case OT_TABLE:_table(o)->Mark(chain);break;
+       case OT_ARRAY:_array(o)->Mark(chain);break;
+       case OT_USERDATA:_userdata(o)->Mark(chain);break;
+       case OT_CLOSURE:_closure(o)->Mark(chain);break;
+       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
+       case OT_GENERATOR:_generator(o)->Mark(chain);break;
+       case OT_THREAD:_thread(o)->Mark(chain);break;
+       case OT_CLASS:_class(o)->Mark(chain);break;
+       case OT_INSTANCE:_instance(o)->Mark(chain);break;
+       default: break;
+       }
+}
+
+
+int SQSharedState::CollectGarbage(SQVM *vm)
+{
+       (void) vm;
+       int n=0;
+       SQCollectable *tchain=NULL;
+       SQVM *vms=_thread(_root_vm);
+       
+       vms->Mark(&tchain);
+       int x = _table(_thread(_root_vm)->_roottable)->CountUsed();
+       MarkObject(_refs_table,&tchain);
+       MarkObject(_registry,&tchain);
+       MarkObject(_metamethodsmap,&tchain);
+       MarkObject(_table_default_delegate,&tchain);
+       MarkObject(_array_default_delegate,&tchain);
+       MarkObject(_string_default_delegate,&tchain);
+       MarkObject(_number_default_delegate,&tchain);
+       MarkObject(_generator_default_delegate,&tchain);
+       MarkObject(_thread_default_delegate,&tchain);
+       MarkObject(_closure_default_delegate,&tchain);
+       MarkObject(_class_default_delegate,&tchain);
+       MarkObject(_instance_default_delegate,&tchain);
+       
+       SQCollectable *t=_gc_chain;
+       SQCollectable *nx=NULL;
+       while(t){
+               t->_uiRef++;
+               t->Finalize();
+               nx=t->_next;
+               if(--t->_uiRef==0)
+                       t->Release();
+               t=nx;
+               n++;
+       }
+
+       t=tchain;
+       while(t){
+               t->UnMark();
+               t=t->_next;
+       }
+       _gc_chain=tchain;
+       int z = _table(_thread(_root_vm)->_roottable)->CountUsed();
+       assert(z == x);
+       return n;
+}
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
+{
+    c->_prev=NULL;
+       c->_next=*chain;
+       if(*chain) (*chain)->_prev=c;
+       *chain=c;
+}
+
+void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
+{
+       if(c->_prev) c->_prev->_next=c->_next;
+       else *chain=c->_next;
+       if(c->_next)
+               c->_next->_prev=c->_prev;
+       c->_next=NULL;
+       c->_prev=NULL;
+}
+#endif
+
+SQChar* SQSharedState::GetScratchPad(int size)
+{
+       int newsize;
+       if(size>0){
+               if(_scratchpadsize<size){
+                       newsize=size+(size>>1);
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+                       _scratchpadsize=newsize;
+
+               }else if(_scratchpadsize>=(size<<5)){
+                       newsize=_scratchpadsize>>1;
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+                       _scratchpadsize=newsize;
+               }
+       }
+       return _scratchpad;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//StringTable
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_lstring.c.html
+*/
+
+int SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+       int idx = (int)TranslateIndex(refpos);
+       while(idx < _len){
+               outkey = (SQInteger)idx;
+               outval = SQInteger(_val[idx]);
+               //return idx for the next iteration
+               return ++idx;
+       }
+       //nothing to iterate anymore
+       return -1;
+}
+
+StringTable::StringTable()
+{
+       AllocNodes(4);
+       _slotused = 0;
+}
+
+StringTable::~StringTable()
+{
+       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
+       _strings=NULL;
+}
+
+void StringTable::AllocNodes(int size)
+{
+       _numofslots=size;
+       //_slotused=0;
+       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
+       memset(_strings,0,sizeof(SQString*)*_numofslots);
+}
+
+SQString *StringTable::Add(const SQChar *news,int len)
+{
+       if(len<0)
+               len=scstrlen(news);
+       unsigned int h=::_hashstr(news,len)&(_numofslots-1);
+       SQString *s;
+       for (s = _strings[h]; s; s = s->_next){
+               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
+                       return s; //found
+       }
+
+       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
+       new (t) SQString;
+       memcpy(t->_val,news,rsl(len));
+       t->_val[len]=_SC('\0');
+       t->_len=len;
+       t->_hash=::_hashstr(news,len);
+       t->_next=_strings[h];
+       t->_uiRef=0;
+       _strings[h]=t;
+       _slotused++;
+       if (_slotused > _numofslots)  /* too crowded? */
+               Resize(_numofslots*2);
+       return t;
+}
+
+void StringTable::Resize(int size)
+{
+       int oldsize=_numofslots;
+       SQString **oldtable=_strings;
+       AllocNodes(size);
+       for (int i=0; i<oldsize; i++){
+               SQString *p = oldtable[i];
+               while(p){
+                       SQString *next = p->_next;
+                       unsigned int h=p->_hash&(_numofslots-1);
+                       p->_next=_strings[h];
+                       _strings[h] = p;
+                       p=next;
+               }
+       }
+       SQ_FREE(oldtable,oldsize*sizeof(SQString*));
+}
+
+void StringTable::Remove(SQString *bs)
+{
+       SQString *s;
+       SQString *prev=NULL;
+       unsigned int h=bs->_hash&(_numofslots-1);
+       
+       for (s = _strings[h]; s; ){
+               if(s == bs){
+                       if(prev)
+                               prev->_next = s->_next;
+                       else
+                               _strings[h] = s->_next;
+                       _slotused--;
+                       int slen=s->_len;
+                       s->~SQString();
+                       SQ_FREE(s,sizeof(SQString)+rsl(slen));
+                       return;
+               }
+               prev = s;
+               s = s->_next;
+       }
+       assert(0);//if this fail something is wrong
+}