Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sqfuncstate.cpp
00001 /* 00002 see copyright notice in squirrel.h 00003 */ 00004 #include "sqpcheader.h" 00005 #ifndef NO_COMPILER 00006 #include "sqcompiler.h" 00007 #include "sqstring.h" 00008 #include "sqfuncproto.h" 00009 #include "sqtable.h" 00010 #include "sqopcodes.h" 00011 #include "sqfuncstate.h" 00012 00013 #ifdef _DEBUG_DUMP 00014 SQInstructionDesc g_InstrDesc[]={ 00015 {_SC("_OP_LINE")}, 00016 {_SC("_OP_LOAD")}, 00017 {_SC("_OP_LOADINT")}, 00018 {_SC("_OP_LOADFLOAT")}, 00019 {_SC("_OP_DLOAD")}, 00020 {_SC("_OP_TAILCALL")}, 00021 {_SC("_OP_CALL")}, 00022 {_SC("_OP_PREPCALL")}, 00023 {_SC("_OP_PREPCALLK")}, 00024 {_SC("_OP_GETK")}, 00025 {_SC("_OP_MOVE")}, 00026 {_SC("_OP_NEWSLOT")}, 00027 {_SC("_OP_DELETE")}, 00028 {_SC("_OP_SET")}, 00029 {_SC("_OP_GET")}, 00030 {_SC("_OP_EQ")}, 00031 {_SC("_OP_NE")}, 00032 {_SC("_OP_ADD")}, 00033 {_SC("_OP_SUB")}, 00034 {_SC("_OP_MUL")}, 00035 {_SC("_OP_DIV")}, 00036 {_SC("_OP_MOD")}, 00037 {_SC("_OP_BITW")}, 00038 {_SC("_OP_RETURN")}, 00039 {_SC("_OP_LOADNULLS")}, 00040 {_SC("_OP_LOADROOT")}, 00041 {_SC("_OP_LOADBOOL")}, 00042 {_SC("_OP_DMOVE")}, 00043 {_SC("_OP_JMP")}, 00044 {_SC("_OP_JCMP")}, 00045 {_SC("_OP_JZ")}, 00046 {_SC("_OP_SETOUTER")}, 00047 {_SC("_OP_GETOUTER")}, 00048 {_SC("_OP_NEWOBJ")}, 00049 {_SC("_OP_APPENDARRAY")}, 00050 {_SC("_OP_COMPARITH")}, 00051 {_SC("_OP_INC")}, 00052 {_SC("_OP_INCL")}, 00053 {_SC("_OP_PINC")}, 00054 {_SC("_OP_PINCL")}, 00055 {_SC("_OP_CMP")}, 00056 {_SC("_OP_EXISTS")}, 00057 {_SC("_OP_INSTANCEOF")}, 00058 {_SC("_OP_AND")}, 00059 {_SC("_OP_OR")}, 00060 {_SC("_OP_NEG")}, 00061 {_SC("_OP_NOT")}, 00062 {_SC("_OP_BWNOT")}, 00063 {_SC("_OP_CLOSURE")}, 00064 {_SC("_OP_YIELD")}, 00065 {_SC("_OP_RESUME")}, 00066 {_SC("_OP_FOREACH")}, 00067 {_SC("_OP_POSTFOREACH")}, 00068 {_SC("_OP_CLONE")}, 00069 {_SC("_OP_TYPEOF")}, 00070 {_SC("_OP_PUSHTRAP")}, 00071 {_SC("_OP_POPTRAP")}, 00072 {_SC("_OP_THROW")}, 00073 {_SC("_OP_NEWSLOTA")}, 00074 {_SC("_OP_GETBASE")}, 00075 {_SC("_OP_CLOSE")}, 00076 {_SC("_OP_JCMP")} 00077 }; 00078 #endif 00079 void DumpLiteral(SQObjectPtr &o) 00080 { 00081 switch(type(o)){ 00082 case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; 00083 case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; 00084 case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; 00085 case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; 00086 default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler 00087 } 00088 } 00089 00090 SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) 00091 { 00092 _nliterals = 0; 00093 _literals = SQTable::Create(ss,0); 00094 _strings = SQTable::Create(ss,0); 00095 _sharedstate = ss; 00096 _lastline = 0; 00097 _optimization = true; 00098 _parent = parent; 00099 _stacksize = 0; 00100 _traps = 0; 00101 _returnexp = 0; 00102 _varparams = false; 00103 _errfunc = efunc; 00104 _errtarget = ed; 00105 _bgenerator = false; 00106 _outers = 0; 00107 _ss = ss; 00108 00109 } 00110 00111 void SQFuncState::Error(const SQChar *err) 00112 { 00113 _errfunc(_errtarget,err); 00114 } 00115 00116 #ifdef _DEBUG_DUMP 00117 void SQFuncState::Dump(SQFunctionProto *func) 00118 { 00119 SQUnsignedInteger n=0,i; 00120 SQInteger si; 00121 scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction)); 00122 scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject)); 00123 scprintf(_SC("--------------------------------------------------------------------\n")); 00124 scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); 00125 scprintf(_SC("-----LITERALS\n")); 00126 SQObjectPtr refidx,key,val; 00127 SQInteger idx; 00128 SQObjectPtrVec templiterals; 00129 templiterals.resize(_nliterals); 00130 while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { 00131 refidx=idx; 00132 templiterals[_integer(val)]=key; 00133 } 00134 for(i=0;i<templiterals.size();i++){ 00135 scprintf(_SC("[%d] "),n); 00136 DumpLiteral(templiterals[i]); 00137 scprintf(_SC("\n")); 00138 n++; 00139 } 00140 scprintf(_SC("-----PARAMS\n")); 00141 if(_varparams) 00142 scprintf(_SC("<<VARPARAMS>>\n")); 00143 n=0; 00144 for(i=0;i<_parameters.size();i++){ 00145 scprintf(_SC("[%d] "),n); 00146 DumpLiteral(_parameters[i]); 00147 scprintf(_SC("\n")); 00148 n++; 00149 } 00150 scprintf(_SC("-----LOCALS\n")); 00151 for(si=0;si<func->_nlocalvarinfos;si++){ 00152 SQLocalVarInfo lvi=func->_localvarinfos[si]; 00153 scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op); 00154 n++; 00155 } 00156 scprintf(_SC("-----LINE INFO\n")); 00157 for(i=0;i<_lineinfos.size();i++){ 00158 SQLineInfo li=_lineinfos[i]; 00159 scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line); 00160 n++; 00161 } 00162 scprintf(_SC("-----dump\n")); 00163 n=0; 00164 for(i=0;i<_instructions.size();i++){ 00165 SQInstruction &inst=_instructions[i]; 00166 if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ 00167 00168 SQInteger lidx = inst._arg1; 00169 scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); 00170 if(lidx >= 0xFFFFFFFF) 00171 scprintf(_SC("null")); 00172 else { 00173 SQInteger refidx; 00174 SQObjectPtr val,key,refo; 00175 while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { 00176 refo = refidx; 00177 } 00178 DumpLiteral(key); 00179 } 00180 if(inst.op != _OP_DLOAD) { 00181 scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); 00182 } 00183 else { 00184 scprintf(_SC(" %d "),inst._arg2); 00185 lidx = inst._arg3; 00186 if(lidx >= 0xFFFFFFFF) 00187 scprintf(_SC("null")); 00188 else { 00189 SQInteger refidx; 00190 SQObjectPtr val,key,refo; 00191 while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { 00192 refo = refidx; 00193 } 00194 DumpLiteral(key); 00195 scprintf(_SC("\n")); 00196 } 00197 } 00198 } 00199 else if(inst.op==_OP_LOADFLOAT) { 00200 scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); 00201 } 00202 /* else if(inst.op==_OP_ARITH){ 00203 scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); 00204 }*/ 00205 else { 00206 scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); 00207 } 00208 n++; 00209 } 00210 scprintf(_SC("-----\n")); 00211 scprintf(_SC("stack size[%d]\n"),func->_stacksize); 00212 scprintf(_SC("--------------------------------------------------------------------\n\n")); 00213 } 00214 #endif 00215 00216 SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) 00217 { 00218 return GetConstant(SQObjectPtr(cons)); 00219 } 00220 00221 SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) 00222 { 00223 return GetConstant(SQObjectPtr(cons)); 00224 } 00225 00226 SQInteger SQFuncState::GetConstant(const SQObject &cons) 00227 { 00228 SQObjectPtr val; 00229 if(!_table(_literals)->Get(cons,val)) 00230 { 00231 val = _nliterals; 00232 _table(_literals)->NewSlot(cons,val); 00233 _nliterals++; 00234 if(_nliterals > MAX_LITERALS) { 00235 val.Null(); 00236 Error(_SC("internal compiler error: too many literals")); 00237 } 00238 } 00239 return _integer(val); 00240 } 00241 00242 void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) 00243 { 00244 _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); 00245 _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); 00246 _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); 00247 _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); 00248 } 00249 00250 void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) 00251 { 00252 switch(arg){ 00253 case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; 00254 case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; 00255 case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; 00256 case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; 00257 }; 00258 } 00259 00260 SQInteger SQFuncState::AllocStackPos() 00261 { 00262 SQInteger npos=_vlocals.size(); 00263 _vlocals.push_back(SQLocalVarInfo()); 00264 if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { 00265 if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); 00266 _stacksize=_vlocals.size(); 00267 } 00268 return npos; 00269 } 00270 00271 SQInteger SQFuncState::PushTarget(SQInteger n) 00272 { 00273 if(n!=-1){ 00274 _targetstack.push_back(n); 00275 return n; 00276 } 00277 n=AllocStackPos(); 00278 _targetstack.push_back(n); 00279 return n; 00280 } 00281 00282 SQInteger SQFuncState::GetUpTarget(SQInteger n){ 00283 return _targetstack[((_targetstack.size()-1)-n)]; 00284 } 00285 00286 SQInteger SQFuncState::TopTarget(){ 00287 return _targetstack.back(); 00288 } 00289 SQInteger SQFuncState::PopTarget() 00290 { 00291 SQUnsignedInteger npos=_targetstack.back(); 00292 assert(npos < _vlocals.size()); 00293 SQLocalVarInfo &t = _vlocals[npos]; 00294 if(type(t._name)==OT_NULL){ 00295 _vlocals.pop_back(); 00296 } 00297 _targetstack.pop_back(); 00298 return npos; 00299 } 00300 00301 SQInteger SQFuncState::GetStackSize() 00302 { 00303 return _vlocals.size(); 00304 } 00305 00306 SQInteger SQFuncState::CountOuters(SQInteger stacksize) 00307 { 00308 SQInteger outers = 0; 00309 SQInteger k = _vlocals.size() - 1; 00310 while(k >= stacksize) { 00311 SQLocalVarInfo &lvi = _vlocals[k]; 00312 k--; 00313 if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer 00314 outers++; 00315 } 00316 } 00317 return outers; 00318 } 00319 00320 void SQFuncState::SetStackSize(SQInteger n) 00321 { 00322 SQInteger size=_vlocals.size(); 00323 while(size>n){ 00324 size--; 00325 SQLocalVarInfo lvi = _vlocals.back(); 00326 if(type(lvi._name)!=OT_NULL){ 00327 if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer 00328 _outers--; 00329 } 00330 lvi._end_op = GetCurrentPos(); 00331 _localvarinfos.push_back(lvi); 00332 } 00333 _vlocals.pop_back(); 00334 } 00335 } 00336 00337 bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) 00338 { 00339 SQObjectPtr val; 00340 if(_table(_sharedstate->_consts)->Get(name,val)) { 00341 e = val; 00342 return true; 00343 } 00344 return false; 00345 } 00346 00347 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) 00348 { 00349 if(stkpos>=_vlocals.size())return false; 00350 else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; 00351 return false; 00352 } 00353 00354 SQInteger SQFuncState::PushLocalVariable(const SQObject &name) 00355 { 00356 SQInteger pos=_vlocals.size(); 00357 SQLocalVarInfo lvi; 00358 lvi._name=name; 00359 lvi._start_op=GetCurrentPos()+1; 00360 lvi._pos=_vlocals.size(); 00361 _vlocals.push_back(lvi); 00362 if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); 00363 return pos; 00364 } 00365 00366 00367 00368 SQInteger SQFuncState::GetLocalVariable(const SQObject &name) 00369 { 00370 SQInteger locals=_vlocals.size(); 00371 while(locals>=1){ 00372 SQLocalVarInfo &lvi = _vlocals[locals-1]; 00373 if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ 00374 return locals-1; 00375 } 00376 locals--; 00377 } 00378 return -1; 00379 } 00380 00381 void SQFuncState::MarkLocalAsOuter(SQInteger pos) 00382 { 00383 SQLocalVarInfo &lvi = _vlocals[pos]; 00384 lvi._end_op = UINT_MINUS_ONE; 00385 _outers++; 00386 } 00387 00388 SQInteger SQFuncState::GetOuterVariable(const SQObject &name) 00389 { 00390 SQInteger outers = _outervalues.size(); 00391 for(SQInteger i = 0; i<outers; i++) { 00392 if(_string(_outervalues[i]._name) == _string(name)) 00393 return i; 00394 } 00395 SQInteger pos=-1; 00396 if(_parent) { 00397 pos = _parent->GetLocalVariable(name); 00398 if(pos == -1) { 00399 pos = _parent->GetOuterVariable(name); 00400 if(pos != -1) { 00401 _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local 00402 return _outervalues.size() - 1; 00403 } 00404 } 00405 else { 00406 _parent->MarkLocalAsOuter(pos); 00407 _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local 00408 return _outervalues.size() - 1; 00409 00410 00411 } 00412 } 00413 return -1; 00414 } 00415 00416 void SQFuncState::AddParameter(const SQObject &name) 00417 { 00418 PushLocalVariable(name); 00419 _parameters.push_back(name); 00420 } 00421 00422 void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) 00423 { 00424 if(_lastline!=line || force){ 00425 SQLineInfo li; 00426 li._line=line;li._op=(GetCurrentPos()+1); 00427 if(lineop)AddInstruction(_OP_LINE,0,line); 00428 if(_lastline!=line) { 00429 _lineinfos.push_back(li); 00430 } 00431 _lastline=line; 00432 } 00433 } 00434 00435 void SQFuncState::DiscardTarget() 00436 { 00437 SQInteger discardedtarget = PopTarget(); 00438 SQInteger size = _instructions.size(); 00439 if(size > 0 && _optimization){ 00440 SQInstruction &pi = _instructions[size-1];//previous instruction 00441 switch(pi.op) { 00442 case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: 00443 if(pi._arg0 == discardedtarget) { 00444 pi._arg0 = 0xFF; 00445 } 00446 } 00447 } 00448 } 00449 00450 void SQFuncState::AddInstruction(SQInstruction &i) 00451 { 00452 SQInteger size = _instructions.size(); 00453 if(size > 0 && _optimization){ //simple optimizer 00454 SQInstruction &pi = _instructions[size-1];//previous instruction 00455 switch(i.op) { 00456 case _OP_JZ: 00457 if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { 00458 pi.op = _OP_JCMP; 00459 pi._arg0 = (unsigned char)pi._arg1; 00460 pi._arg1 = i._arg1; 00461 return; 00462 } 00463 case _OP_SET: 00464 case _OP_NEWSLOT: 00465 if(i._arg0 == i._arg3) { 00466 i._arg0 = 0xFF; 00467 } 00468 break; 00469 case _OP_SETOUTER: 00470 if(i._arg0 == i._arg2) { 00471 i._arg0 = 0xFF; 00472 } 00473 break; 00474 case _OP_RETURN: 00475 if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { 00476 pi.op = _OP_TAILCALL; 00477 } else if(pi.op == _OP_CLOSE){ 00478 pi = i; 00479 return; 00480 } 00481 break; 00482 case _OP_GET: 00483 if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ 00484 pi._arg1 = pi._arg1; 00485 pi._arg2 = (unsigned char)i._arg1; 00486 pi.op = _OP_GETK; 00487 pi._arg0 = i._arg0; 00488 00489 return; 00490 } 00491 break; 00492 case _OP_PREPCALL: 00493 if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ 00494 pi.op = _OP_PREPCALLK; 00495 pi._arg0 = i._arg0; 00496 pi._arg1 = pi._arg1; 00497 pi._arg2 = i._arg2; 00498 pi._arg3 = i._arg3; 00499 return; 00500 } 00501 break; 00502 case _OP_APPENDARRAY: { 00503 SQInteger aat = -1; 00504 switch(pi.op) { 00505 case _OP_LOAD: aat = AAT_LITERAL; break; 00506 case _OP_LOADINT: aat = AAT_INT; break; 00507 case _OP_LOADBOOL: aat = AAT_BOOL; break; 00508 case _OP_LOADFLOAT: aat = AAT_FLOAT; break; 00509 default: break; 00510 } 00511 if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ 00512 pi.op = _OP_APPENDARRAY; 00513 pi._arg0 = i._arg0; 00514 pi._arg1 = pi._arg1; 00515 pi._arg2 = (unsigned char)aat; 00516 pi._arg3 = MAX_FUNC_STACKSIZE; 00517 return; 00518 } 00519 } 00520 break; 00521 case _OP_MOVE: 00522 switch(pi.op) { 00523 case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: 00524 case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: 00525 00526 if(pi._arg0 == i._arg1) 00527 { 00528 pi._arg0 = i._arg0; 00529 _optimization = false; 00530 //_result_elimination = false; 00531 return; 00532 } 00533 } 00534 00535 if(pi.op == _OP_MOVE) 00536 { 00537 pi.op = _OP_DMOVE; 00538 pi._arg2 = i._arg0; 00539 pi._arg3 = (unsigned char)i._arg1; 00540 return; 00541 } 00542 break; 00543 case _OP_LOAD: 00544 if(pi.op == _OP_LOAD && i._arg1 < 256) { 00545 pi.op = _OP_DLOAD; 00546 pi._arg2 = i._arg0; 00547 pi._arg3 = (unsigned char)i._arg1; 00548 return; 00549 } 00550 break; 00551 case _OP_EQ:case _OP_NE: 00552 if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) 00553 { 00554 pi.op = i.op; 00555 pi._arg0 = i._arg0; 00556 pi._arg1 = pi._arg1; 00557 pi._arg2 = i._arg2; 00558 pi._arg3 = MAX_FUNC_STACKSIZE; 00559 return; 00560 } 00561 break; 00562 case _OP_LOADNULLS: 00563 if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { 00564 00565 pi._arg1 = pi._arg1 + 1; 00566 pi.op = _OP_LOADNULLS; 00567 return; 00568 } 00569 break; 00570 case _OP_LINE: 00571 if(pi.op == _OP_LINE) { 00572 _instructions.pop_back(); 00573 _lineinfos.pop_back(); 00574 } 00575 break; 00576 } 00577 } 00578 _optimization = true; 00579 _instructions.push_back(i); 00580 } 00581 00582 SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) 00583 { 00584 SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); 00585 _table(_strings)->NewSlot(ns,(SQInteger)1); 00586 return ns; 00587 } 00588 00589 SQObject SQFuncState::CreateTable() 00590 { 00591 SQObjectPtr nt(SQTable::Create(_sharedstate,0)); 00592 _table(_strings)->NewSlot(nt,(SQInteger)1); 00593 return nt; 00594 } 00595 00596 SQFunctionProto *SQFuncState::BuildProto() 00597 { 00598 00599 SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), 00600 _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), 00601 _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); 00602 00603 SQObjectPtr refidx,key,val; 00604 SQInteger idx; 00605 00606 f->_stacksize = _stacksize; 00607 f->_sourcename = _sourcename; 00608 f->_bgenerator = _bgenerator; 00609 f->_name = _name; 00610 00611 while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { 00612 f->_literals[_integer(val)]=key; 00613 refidx=idx; 00614 } 00615 00616 for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; 00617 for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; 00618 for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; 00619 for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; 00620 for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; 00621 for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; 00622 00623 memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); 00624 00625 f->_varparams = _varparams; 00626 00627 return f; 00628 } 00629 00630 SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) 00631 { 00632 SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); 00633 new (child) SQFuncState(ss,this,_errfunc,_errtarget); 00634 _childstates.push_back(child); 00635 return child; 00636 } 00637 00638 void SQFuncState::PopChildState() 00639 { 00640 SQFuncState *child = _childstates.back(); 00641 sq_delete(child,SQFuncState); 00642 _childstates.pop_back(); 00643 } 00644 00645 SQFuncState::~SQFuncState() 00646 { 00647 while(_childstates.size() > 0) 00648 { 00649 PopChildState(); 00650 } 00651 } 00652 00653 #endif
Generated on Tue Jul 12 2022 21:35:49 by
