4 #include "sqpcheader.h"     7 #include "sqfuncproto.h"    12 #include "squserdata.h"    18 SQObjectPtr 
_one_((SQInteger)1);
    21 SQSharedState::SQSharedState()
    23     _compilererrorhandler = 
NULL;
    26     _notifyallexceptions = 
false;
    29 #define newsysstring(s) {   \    30     _systemstrings->push_back(SQString::Create(this,s));    \    33 #define newmetamethod(s) {  \    34     _metamethods->push_back(SQString::Create(this,s));  \    35     _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \    43     while(typemask[i] != 0) {
    46                 case 'o': mask |= _RT_NULL; 
break;
    47                 case 'i': mask |= _RT_INTEGER; 
break;
    48                 case 'f': mask |= _RT_FLOAT; 
break;
    49                 case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); 
break;
    50                 case 's': mask |= _RT_STRING; 
break;
    51                 case 't': mask |= _RT_TABLE; 
break;
    52                 case 'a': mask |= _RT_ARRAY; 
break;
    53                 case 'u': mask |= _RT_USERDATA; 
break;
    54                 case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); 
break;
    55                 case 'b': mask |= _RT_BOOL; 
break;
    56                 case 'g': mask |= _RT_GENERATOR; 
break;
    57                 case 'p': mask |= _RT_USERPOINTER; 
break;
    58                 case 'v': mask |= _RT_THREAD; 
break;
    59                 case 'x': mask |= _RT_INSTANCE; 
break;
    60                 case 'y': mask |= _RT_CLASS; 
break;
    61                 case 'r': mask |= _RT_WEAKREF; 
break;
    62                 case '.': mask = -1; res.push_back(mask); i++; mask = 0; 
continue;
    63                 case ' ': i++; 
continue; 
    68         if(typemask[i] == 
'|') {
    84     SQTable *t=SQTable::Create(ss,0);
    85     while(funcz[i].name!=0){
    86         SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
    87         nc->_nparamscheck = funcz[i].nparamscheck;
    88         nc->_name = SQString::Create(ss,funcz[i].name);
    89         if(funcz[i].typemask && !
CompileTypemask(nc->_typecheck,funcz[i].typemask))
    91         t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
    97 void SQSharedState::Init()
   101 #ifndef NO_GARBAGE_COLLECTOR   104     sq_new(_stringtable,SQStringTable);
   105     sq_new(_metamethods,SQObjectPtrVec);
   106     sq_new(_systemstrings,SQObjectPtrVec);
   107     sq_new(_types,SQObjectPtrVec);
   108     _metamethodsmap = SQTable::Create(
this,MT_LAST-1);
   146     _constructoridx = SQString::Create(
this,_SC(
"constructor"));
   147     _registry = SQTable::Create(
this,0);
   148     _consts = SQTable::Create(
this,0);
   162 SQSharedState::~SQSharedState()
   165     _table(_registry)->Finalize();
   166     _table(_consts)->Finalize();
   167     _table(_metamethodsmap)->Finalize();
   171     while(!_systemstrings->empty()) {
   172         _systemstrings->back()=
_null_;
   173         _systemstrings->pop_back();
   175     _thread(_root_vm)->Finalize();
   177     _table_default_delegate = 
_null_;
   178     _array_default_delegate = 
_null_;
   179     _string_default_delegate = 
_null_;
   180     _number_default_delegate = 
_null_;
   181     _closure_default_delegate = 
_null_;
   182     _generator_default_delegate = 
_null_;
   183     _thread_default_delegate = 
_null_;
   184     _class_default_delegate = 
_null_;
   185     _instance_default_delegate = 
_null_;
   186     _weakref_default_delegate = 
_null_;
   187     _refs_table.Finalize();
   188 #ifndef NO_GARBAGE_COLLECTOR   189     SQCollectable *t = _gc_chain;
   190     SQCollectable *nx = 
NULL;
   202     assert(_gc_chain==
NULL); 
   205         _gc_chain->Release();
   209     sq_delete(_types,SQObjectPtrVec);
   210     sq_delete(_systemstrings,SQObjectPtrVec);
   211     sq_delete(_metamethods,SQObjectPtrVec);
   212     sq_delete(_stringtable,SQStringTable);
   213     if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
   217 SQInteger SQSharedState::GetMetaMethodIdxByName(
const SQObjectPtr &name)
   219     if(type(name) != OT_STRING)
   222     if(_table(_metamethodsmap)->Get(name,ret)) {
   223         return _integer(ret);
   228 #ifndef NO_GARBAGE_COLLECTOR   230 void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
   233     case OT_TABLE:_table(o)->Mark(chain);
break;
   234     case OT_ARRAY:_array(o)->Mark(chain);
break;
   235     case OT_USERDATA:_userdata(o)->Mark(chain);
break;
   236     case OT_CLOSURE:_closure(o)->Mark(chain);
break;
   237     case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);
break;
   238     case OT_GENERATOR:_generator(o)->Mark(chain);
break;
   239     case OT_THREAD:_thread(o)->Mark(chain);
break;
   240     case OT_CLASS:_class(o)->Mark(chain);
break;
   241     case OT_INSTANCE:_instance(o)->Mark(chain);
break;
   248 SQInteger SQSharedState::CollectGarbage(SQVM * )
   251     SQCollectable *tchain=
NULL;
   252     SQVM *vms = _thread(_root_vm);
   255     SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
   256     _refs_table.Mark(&tchain);
   257     MarkObject(_registry,&tchain);
   258     MarkObject(_consts,&tchain);
   259     MarkObject(_metamethodsmap,&tchain);
   260     MarkObject(_table_default_delegate,&tchain);
   261     MarkObject(_array_default_delegate,&tchain);
   262     MarkObject(_string_default_delegate,&tchain);
   263     MarkObject(_number_default_delegate,&tchain);
   264     MarkObject(_generator_default_delegate,&tchain);
   265     MarkObject(_thread_default_delegate,&tchain);
   266     MarkObject(_closure_default_delegate,&tchain);
   267     MarkObject(_class_default_delegate,&tchain);
   268     MarkObject(_instance_default_delegate,&tchain);
   269     MarkObject(_weakref_default_delegate,&tchain);
   271     SQCollectable *t = _gc_chain;
   272     SQCollectable *nx = 
NULL;
   292     SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
   298 #ifndef NO_GARBAGE_COLLECTOR   299 void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
   303     if(*chain) (*chain)->_prev = c;
   307 void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
   309     if(c->_prev) c->_prev->_next = c->_next;
   310     else *chain = c->_next;
   312         c->_next->_prev = c->_prev;
   318 SQChar* SQSharedState::GetScratchPad(SQInteger size)
   322         if(_scratchpadsize < size) {
   323             newsize = size + (size>>1);
   324             _scratchpad = (
SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
   325             _scratchpadsize = newsize;
   327         }
else if(_scratchpadsize >= (size<<5)) {
   328             newsize = _scratchpadsize >> 1;
   329             _scratchpad = (
SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
   330             _scratchpadsize = newsize;
   341 void RefTable::Finalize()
   343     RefNode *nodes = _nodes;
   344     for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
   350 RefTable::~RefTable()
   352     SQ_FREE(_buckets,(_numofslots * 
sizeof(RefNode *)) + (_numofslots * 
sizeof(RefNode)));
   355 #ifndef NO_GARBAGE_COLLECTOR   356 void RefTable::Mark(SQCollectable **chain)
   358     RefNode *nodes = (RefNode *)_nodes;
   359     for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
   360         if(type(nodes->obj) != OT_NULL) {
   361             SQSharedState::MarkObject(nodes->obj,chain);
   368 void RefTable::AddRef(SQObject &obj)
   372     RefNode *
ref = Get(obj,mainpos,&prev,
true);
   376 SQBool RefTable::Release(SQObject &obj)
   380     RefNode *
ref = Get(obj,mainpos,&prev,
false);
   382         if(--ref->refs == 0) {
   383             SQObjectPtr o = ref->obj;
   385                 prev->next = ref->next;
   388                 _buckets[mainpos] = ref->next;
   390             ref->next = _freelist;
   404 void RefTable::Resize(SQUnsignedInteger size)
   406     RefNode **oldbucks = _buckets;
   408     SQUnsignedInteger oldnumofslots = _numofslots;
   411     SQUnsignedInteger nfound = 0;
   412     for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
   413         if(type(t->obj) != OT_NULL) {
   415             assert(t->refs != 0);
   416             RefNode *nn = 
Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
   423     assert(nfound == oldnumofslots);
   424     SQ_FREE(oldbucks,(oldnumofslots * 
sizeof(RefNode *)) + (oldnumofslots * 
sizeof(RefNode)));
   427 RefTable::RefNode *
RefTable::Add(SQHash mainpos,SQObject &obj)
   429     RefNode *t = _buckets[mainpos];
   430     RefNode *newnode = _freelist;
   432     _buckets[mainpos] = newnode;
   433     _freelist = _freelist->next;
   435     assert(newnode->refs == 0);
   440 RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,
bool add)
   443     mainpos = ::HashObj(obj)&(_numofslots-1);
   445     for (ref = _buckets[mainpos]; 
ref; ) {
   446         if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
   451     if(ref == 
NULL && add) {
   452         if(_numofslots == _slotused) {
   453             assert(_freelist == 0);
   454             Resize(_numofslots*2);
   455             mainpos = ::HashObj(obj)&(_numofslots-1);
   457         ref = 
Add(mainpos,obj);
   462 void RefTable::AllocNodes(SQUnsignedInteger size)
   466     bucks = (RefNode **)SQ_MALLOC((size * 
sizeof(RefNode *)) + (size * 
sizeof(RefNode)));
   467     nodes = (RefNode *)&bucks[size];
   468     RefNode *temp = nodes;
   470     for(n = 0; n < size - 1; n++) {
   473         new (&temp->obj) SQObjectPtr;
   479     new (&temp->obj) SQObjectPtr;
   495 SQStringTable::SQStringTable()
   501 SQStringTable::~SQStringTable()
   503     SQ_FREE(_strings,
sizeof(SQString*)*_numofslots);
   507 void SQStringTable::AllocNodes(SQInteger size)
   510     _strings = (SQString**)SQ_MALLOC(
sizeof(SQString*)*_numofslots);
   511     memset(_strings,0,
sizeof(SQString*)*_numofslots);
   517         len = (SQInteger)scstrlen(news);
   518     SQHash h = ::_hashstr(news,len)&(_numofslots-1);
   520     for (s = _strings[h]; s; s = s->_next){
   521         if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
   525     SQString *t=(SQString *)SQ_MALLOC(rsl(len)+
sizeof(SQString));
   527     memcpy(t->_val,news,rsl(len));
   528     t->_val[len] = _SC(
'\0');
   530     t->_hash = ::_hashstr(news,len);
   531     t->_next = _strings[h];
   534     if (_slotused > _numofslots)  
   535         Resize(_numofslots*2);
   539 void SQStringTable::Resize(SQInteger size)
   541     SQInteger oldsize=_numofslots;
   542     SQString **oldtable=_strings;
   544     for (SQInteger i=0; i<oldsize; i++){
   545         SQString *p = oldtable[i];
   547             SQString *next = p->_next;
   548             SQHash h = p->_hash&(_numofslots-1);
   549             p->_next = _strings[h];
   554     SQ_FREE(oldtable,oldsize*
sizeof(SQString*));
   557 void SQStringTable::Remove(SQString *bs)
   561     SQHash h = bs->_hash&(_numofslots - 1);
   563     for (s = _strings[h]; s; ){
   566                 prev->_next = s->_next;
   568                 _strings[h] = s->_next;
   570             SQInteger slen = s->_len;
   572             SQ_FREE(s,
sizeof(SQString) + rsl(slen));
 DLLIMPORT bool Add(const wxString &name, const wxString &mask)
Add a new extension filter. 
SQObjectPtr _false_(false)
SQObjectPtr _one_((SQInteger) 1)
bool CompileTypemask(SQIntVec &res, const SQChar *typemask)
const wxString ref(_T("&"))
SQObjectPtr _minusone_((SQInteger) -1)
SQTable * CreateDefaultDelegate(SQSharedState *ss, SQRegFunction *funcz)