X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fsquirrel%2Fsquirrel%2Fsqfuncstate.cpp;h=962a6cd7a21001ac39718e37edeb39493e015ee8;hb=fea3446f05e1e7673607b835c269d3e8d1929ab3;hp=d9b3585d58a10232b007f233695c0a5a238dde7f;hpb=c81e5d255303f56a3fc33bef1fd0124c4b62cfcf;p=supertux.git diff --git a/src/squirrel/squirrel/sqfuncstate.cpp b/src/squirrel/squirrel/sqfuncstate.cpp index d9b3585d5..962a6cd7a 100644 --- a/src/squirrel/squirrel/sqfuncstate.cpp +++ b/src/squirrel/squirrel/sqfuncstate.cpp @@ -13,6 +13,9 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_LINE")}, {_SC("_OP_LOAD")}, + {_SC("_OP_LOADINT")}, + {_SC("_OP_LOADFLOAT")}, + {_SC("_OP_DLOAD")}, {_SC("_OP_TAILCALL")}, {_SC("_OP_CALL")}, {_SC("_OP_PREPCALL")}, @@ -30,6 +33,7 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_RETURN")}, {_SC("_OP_LOADNULLS")}, {_SC("_OP_LOADROOTTABLE")}, + {_SC("_OP_LOADBOOL")}, {_SC("_OP_DMOVE")}, {_SC("_OP_JMP")}, {_SC("_OP_JNZ")}, @@ -59,6 +63,7 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_YIELD")}, {_SC("_OP_RESUME")}, {_SC("_OP_FOREACH")}, + {_SC("_OP_POSTFOREACH")}, {_SC("_OP_DELEGATE")}, {_SC("_OP_CLONE")}, {_SC("_OP_TYPEOF")}, @@ -66,8 +71,7 @@ SQInstructionDesc g_InstrDesc[]={ {_SC("_OP_POPTRAP")}, {_SC("_OP_THROW")}, {_SC("_OP_CLASS")}, - {_SC("_OP_NEWSLOTA")}, - {_SC("_OP_LOADBOOL")} + {_SC("_OP_NEWSLOTA")} }; #endif void DumpLiteral(SQObjectPtr &o) @@ -76,30 +80,39 @@ void DumpLiteral(SQObjectPtr &o) case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break; - default: break; + default: assert(0); break; //shut up compiler } } -SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent) +SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) { _nliterals = 0; _literals = SQTable::Create(ss,0); + _strings = SQTable::Create(ss,0); _sharedstate = ss; _lastline = 0; _optimization = true; - _func = func; _parent = parent; _stacksize = 0; _traps = 0; _returnexp = 0; _varparams = false; + _errfunc = efunc; + _errtarget = ed; + _bgenerator = false; + +} + +void SQFuncState::Error(const SQChar *err) +{ + _errfunc(_errtarget,err); } #ifdef _DEBUG_DUMP -void SQFuncState::Dump() +void SQFuncState::Dump(SQFunctionProto *func) { - unsigned int n=0,i; - SQFunctionProto *func=_funcproto(_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")); @@ -109,7 +122,7 @@ void SQFuncState::Dump() SQInteger idx; SQObjectPtrVec templiterals; templiterals.resize(_nliterals); - while((idx=_table(_literals)->Next(refidx,key,val))!=-1) { + while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { refidx=idx; templiterals[_integer(val)]=key; } @@ -130,8 +143,8 @@ void SQFuncState::Dump() n++; } scprintf(_SC("-----LOCALS\n")); - for(i=0;i_localvarinfos.size();i++){ - SQLocalVarInfo lvi=func->_localvarinfos[i]; + for(si=0;si_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++; } @@ -145,21 +158,41 @@ void SQFuncState::Dump() n=0; for(i=0;i<_instructions.size();i++){ SQInstruction &inst=_instructions[i]; - if(inst.op==_OP_LOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ + if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ - int lidx = inst._arg1; + SQInteger lidx = inst._arg1; scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0); if(lidx >= 0xFFFFFFFF) scprintf(_SC("null")); else { - int refidx; + SQInteger refidx; SQObjectPtr val,key,refo; - while(((refidx=_table(_literals)->Next(refo,key,val))!= -1) && (_integer(val) != lidx)) { + while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { refo = refidx; } DumpLiteral(key); } - scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); + 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); @@ -173,66 +206,63 @@ void SQFuncState::Dump() scprintf(_SC("--------------------------------------------------------------------\n\n")); } #endif -int SQFuncState::GetStringConstant(const SQChar *cons) -{ - return GetConstant(SQString::Create(_sharedstate,cons)); -} -int SQFuncState::GetNumericConstant(const SQInteger cons) +SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) { - return GetConstant(cons); + return GetConstant(SQObjectPtr(cons)); } -int SQFuncState::GetNumericConstant(const SQFloat cons) +SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) { - return GetConstant(cons); + return GetConstant(SQObjectPtr(cons)); } -int SQFuncState::GetConstant(SQObjectPtr cons) +SQInteger SQFuncState::GetConstant(const SQObject &cons) { - // int n=0; SQObjectPtr val; if(!_table(_literals)->Get(cons,val)) { val = _nliterals; _table(_literals)->NewSlot(cons,val); _nliterals++; - if(_nliterals > MAX_LITERALS) throw ParserException(_SC("internal compiler error: too many literals")); + if(_nliterals > MAX_LITERALS) { + val.Null(); + Error(_SC("internal compiler error: too many literals")); + } } return _integer(val); } -void SQFuncState::SetIntructionParams(int pos,int arg0,int arg1,int arg2,int arg3) +void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) { - _instructions[pos]._arg0=*((unsigned int *)&arg0); - _instructions[pos]._arg1=*((unsigned int *)&arg1); - _instructions[pos]._arg2=*((unsigned int *)&arg2); - _instructions[pos]._arg3=*((unsigned int *)&arg3); + _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); + _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); + _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); + _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); } -void SQFuncState::SetIntructionParam(int pos,int arg,int val) +void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val) { switch(arg){ - case 0:_instructions[pos]._arg0=*((unsigned int *)&val);break; - case 1:_instructions[pos]._arg1=*((unsigned int *)&val);break; - case 2:_instructions[pos]._arg2=*((unsigned int *)&val);break; - case 3:_instructions[pos]._arg3=*((unsigned int *)&val);break; - case 4:_instructions[pos]._arg1=*((unsigned int *)&val);break; + case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; + case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; + case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; }; } -int SQFuncState::AllocStackPos() +SQInteger SQFuncState::AllocStackPos() { - int npos=_vlocals.size(); + SQInteger npos=_vlocals.size(); _vlocals.push_back(SQLocalVarInfo()); - if(_vlocals.size()>((unsigned int)_stacksize)) { - if(_stacksize>MAX_FUNC_STACKSIZE) throw ParserException(_SC("internal compiler error: too many locals")); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { + if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); _stacksize=_vlocals.size(); } return npos; } -int SQFuncState::PushTarget(int n) +SQInteger SQFuncState::PushTarget(SQInteger n) { if(n!=-1){ _targetstack.push_back(n); @@ -243,16 +273,16 @@ int SQFuncState::PushTarget(int n) return n; } -int SQFuncState::GetUpTarget(int n){ +SQInteger SQFuncState::GetUpTarget(SQInteger n){ return _targetstack[((_targetstack.size()-1)-n)]; } -int SQFuncState::TopTarget(){ +SQInteger SQFuncState::TopTarget(){ return _targetstack.back(); } -int SQFuncState::PopTarget() +SQInteger SQFuncState::PopTarget() { - int npos=_targetstack.back(); + SQInteger npos=_targetstack.back(); SQLocalVarInfo t=_vlocals[_targetstack.back()]; if(type(t._name)==OT_NULL){ _vlocals.pop_back(); @@ -261,14 +291,14 @@ int SQFuncState::PopTarget() return npos; } -int SQFuncState::GetStackSize() +SQInteger SQFuncState::GetStackSize() { return _vlocals.size(); } -void SQFuncState::SetStackSize(int n) +void SQFuncState::SetStackSize(SQInteger n) { - int size=_vlocals.size(); + SQInteger size=_vlocals.size(); while(size>n){ size--; SQLocalVarInfo lvi=_vlocals.back(); @@ -280,29 +310,29 @@ void SQFuncState::SetStackSize(int n) } } -bool SQFuncState::IsLocal(unsigned int stkpos) +bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) { if(stkpos>=_vlocals.size())return false; else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true; return false; } -int SQFuncState::PushLocalVariable(const SQObjectPtr &name) +SQInteger SQFuncState::PushLocalVariable(const SQObject &name) { - int pos=_vlocals.size(); + SQInteger pos=_vlocals.size(); SQLocalVarInfo lvi; lvi._name=name; lvi._start_op=GetCurrentPos()+1; lvi._pos=_vlocals.size(); _vlocals.push_back(lvi); - if(_vlocals.size()>((unsigned int)_stacksize))_stacksize=_vlocals.size(); + if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); return pos; } -int SQFuncState::GetLocalVariable(const SQObjectPtr &name) +SQInteger SQFuncState::GetLocalVariable(const SQObject &name) { - int locals=_vlocals.size(); + SQInteger locals=_vlocals.size(); while(locals>=1){ if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){ return locals-1; @@ -312,20 +342,19 @@ int SQFuncState::GetLocalVariable(const SQObjectPtr &name) return -1; } -int SQFuncState::GetOuterVariable(const SQObjectPtr &name) +SQInteger SQFuncState::GetOuterVariable(const SQObject &name) { - int outers = _outervalues.size(); - for(int i = 0; iGetLocalVariable(name); if(pos == -1) { @@ -343,13 +372,13 @@ void SQFuncState::AddOuterValue(const SQObjectPtr &name) _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global } -void SQFuncState::AddParameter(const SQObjectPtr &name) +void SQFuncState::AddParameter(const SQObject &name) { PushLocalVariable(name); _parameters.push_back(name); } -void SQFuncState::AddLineInfos(int line,bool lineop,bool force) +void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) { if(_lastline!=line || force){ SQLineInfo li; @@ -362,7 +391,7 @@ void SQFuncState::AddLineInfos(int line,bool lineop,bool force) void SQFuncState::AddInstruction(SQInstruction &i) { - int size = _instructions.size(); + SQInteger size = _instructions.size(); if(size > 0 && _optimization){ //simple optimizer SQInstruction &pi = _instructions[size-1];//previous instruction switch(i.op) { @@ -417,7 +446,14 @@ void SQFuncState::AddInstruction(SQInstruction &i) return; } break; - + case _OP_LOAD: + if(pi.op == _OP_LOAD && i._arg1 < 256) { + pi.op = _OP_DLOAD; + pi._arg2 = i._arg0; + pi._arg3 = (unsigned char)i._arg1; + return; + } + break; case _OP_EQ:case _OP_NE: if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) { @@ -430,7 +466,6 @@ void SQFuncState::AddInstruction(SQInstruction &i) } break; case _OP_LOADNULLS: - //case _OP_LOADNULL: if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { pi._arg1 = pi._arg1 + 1; @@ -450,34 +485,64 @@ void SQFuncState::AddInstruction(SQInstruction &i) _instructions.push_back(i); } -SQObject SQFuncState::CreateString(const SQChar *s) +SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) { - SQObjectPtr ns(SQString::Create(_sharedstate,s)); - _stringrefs.push_back(ns); + SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); + _table(_strings)->NewSlot(ns,(SQInteger)1); return ns; } -void SQFuncState::Finalize() +SQFunctionProto *SQFuncState::BuildProto() { - SQFunctionProto *f=_funcproto(_func); - f->_literals.resize(_nliterals); + SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(), + _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), + _lineinfos.size(),_localvarinfos.size()); + SQObjectPtr refidx,key,val; SQInteger idx; - while((idx=_table(_literals)->Next(refidx,key,val))!=-1) { + + 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; } - f->_functions.resize(_functions.size()); - f->_functions.copy(_functions); - f->_parameters.resize(_parameters.size()); - f->_parameters.copy(_parameters); - f->_outervalues.resize(_outervalues.size()); - f->_outervalues.copy(_outervalues); - f->_instructions.resize(_instructions.size()); - f->_instructions.copy(_instructions); - f->_localvarinfos.resize(_localvarinfos.size()); - f->_localvarinfos.copy(_localvarinfos); - f->_lineinfos.resize(_lineinfos.size()); - f->_lineinfos.copy(_lineinfos); + + 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 no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no]; + for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no]; + + memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); + f->_varparams = _varparams; + + return f; +} + +SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) +{ + SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); + new (child) SQFuncState(ss,this,_errfunc,_errtarget); + _childstates.push_back(child); + return child; +} + +void SQFuncState::PopChildState() +{ + SQFuncState *child = _childstates.back(); + sq_delete(child,SQFuncState); + _childstates.pop_back(); +} + +SQFuncState::~SQFuncState() +{ + while(_childstates.size() > 0) + { + PopChildState(); + } }