SQSharedState::~SQSharedState() { if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } _constructoridx.Null(); _table(_registry)->Finalize(); _table(_consts)->Finalize(); _table(_metamethodsmap)->Finalize(); _registry.Null(); _consts.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(); _weakref_default_delegate.Null(); _refs_table.Finalize(); #ifndef NO_GARBAGE_COLLECTOR SQCollectable *t = _gc_chain; SQCollectable *nx = NULL; if(t) { t->_uiRef++; while(t) { t->Finalize(); nx = t->_next; if(nx) nx->_uiRef++; 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,SQStringTable); if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); }
SQInteger SQFuncState::GetConstant(const SQObject &cons) { SQObjectPtr val; if(!_table(_literals)->Get(cons,val)) { val = _nliterals; _table(_literals)->NewSlot(cons,val); _nliterals++; if(_nliterals > MAX_LITERALS) { val.Null(); Error(_SC("internal compiler error: too many literals")); } } return _integer(val); }
SQFunctionProto *SQFuncState::BuildProto() { SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); SQObjectPtr refidx,key,val; SQInteger idx; f->_stacksize = _stacksize; f->_sourcename = _sourcename; f->_bgenerator = _bgenerator; f->_name = _name; while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { f->_literals[_integer(val)]=key; refidx=idx; } for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); f->_varparams = _varparams; return f; }
SQInteger SQSharedState::CollectGarbage(SQVM *vm) { SQInteger n=0; SQCollectable *tchain=NULL; SQVM *vms = _thread(_root_vm); vms->Mark(&tchain); SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed(); _refs_table.Mark(&tchain); MarkObject(_registry,&tchain); MarkObject(_consts,&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); MarkObject(_weakref_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; SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed(); assert(z == x); return n; }
bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) { SQObjectPtr val; if(_table(_sharedstate->_consts)->Get(name,val)) { e = val; return true; } return false; }
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; }
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; case OT_OUTER:_outer(o)->Mark(chain);break; default: break; //shutup compiler } }
SQObject SQFuncState::CreateTable() { SQObjectPtr nt(SQTable::Create(_sharedstate,0)); _table(_strings)->NewSlot(nt,(SQInteger)1); return nt; }
SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) { SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); _table(_strings)->NewSlot(ns,(SQInteger)1); return ns; }
SQBool SQFuncState::IsConstantExist(const SQObject &cons) { SQObjectPtr val; return _table(_literals)->Get(cons,val); }
void SQFuncState::Dump(SQFunctionProto *func) { SQUnsignedInteger n=0,i; SQInteger si; scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); scprintf(_SC("--------------------------------------------------------------------\n")); scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); scprintf(_SC("-----LITERALS\n")); SQObjectPtr refidx,key,val; SQInteger idx; SQObjectPtrVec templiterals; templiterals.resize(_nliterals); while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { refidx=idx; templiterals[_integer(val)]=key; } for(i=0;i<templiterals.size();i++){ scprintf(_SC("[%d] "),n); DumpLiteral(templiterals[i]); scprintf(_SC("\n")); n++; } scprintf(_SC("-----PARAMS\n")); if(_varparams) scprintf(_SC("<<VARPARAMS>>\n")); n=0; for(i=0;i<_parameters.size();i++){ scprintf(_SC("[%d] "),n); DumpLiteral(_parameters[i]); scprintf(_SC("\n")); n++; } scprintf(_SC("-----LOCALS\n")); for(si=0;si<func->_nlocalvarinfos;si++){ SQLocalVarInfo lvi=func->_localvarinfos[si]; scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); n++; } scprintf(_SC("-----LINE INFO\n")); for(i=0;i<_lineinfos.size();i++){ SQLineInfo li=_lineinfos[i]; scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); n++; } scprintf(_SC("-----dump\n")); n=0; for(i=0;i<_instructions.size();i++){ SQInstruction &inst=_instructions[i]; if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ SQInteger lidx = inst._arg1; scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); if(lidx >= 0xFFFFFFFF) scprintf(_SC("null")); else { SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { refo = refidx; } DumpLiteral(key); } if(inst.op != _OP_DLOAD) { scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); } else { scprintf(_SC(" %d "),inst._arg2); lidx = inst._arg3; if(lidx >= 0xFFFFFFFF) scprintf(_SC("null")); else { SQInteger refidx; SQObjectPtr val,key,refo; while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { refo = refidx; } DumpLiteral(key); scprintf(_SC("\n")); } } } else if(inst.op==_OP_LOADFLOAT) { scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); } /* else if(inst.op==_OP_ARITH){ scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); }*/ else { scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); } n++; } scprintf(_SC("-----\n")); scprintf(_SC("stack size[%d]\n"),func->_stacksize); scprintf(_SC("--------------------------------------------------------------------\n\n")); }