4 #include "sqpcheader.h"     5 #include "sqcompiler.h"     6 #include "sqfuncproto.h"    10 #include "sqfuncstate.h"    17     {_SC(
"_OP_LOADFLOAT")},
    19     {_SC(
"_OP_TAILCALL")},
    21     {_SC(
"_OP_PREPCALL")},
    22     {_SC(
"_OP_PREPCALLK")},
    34     {_SC(
"_OP_LOADNULLS")},
    35     {_SC(
"_OP_LOADROOTTABLE")},
    36     {_SC(
"_OP_LOADBOOL")},
    41     {_SC(
"_OP_LOADFREEVAR")},
    43     {_SC(
"_OP_GETVARGV")},
    44     {_SC(
"_OP_NEWTABLE")},
    45     {_SC(
"_OP_NEWARRAY")},
    46     {_SC(
"_OP_APPENDARRAY")},
    47     {_SC(
"_OP_GETPARENT")},
    48     {_SC(
"_OP_COMPARITH")},
    49     {_SC(
"_OP_COMPARITHL")},
    56     {_SC(
"_OP_INSTANCEOF")},
    66     {_SC(
"_OP_POSTFOREACH")},
    67     {_SC(
"_OP_DELEGATE")},
    70     {_SC(
"_OP_PUSHTRAP")},
    80         case OT_STRING: scprintf(_SC(
"\"%s\""),_stringval(o));
break;
    81         case OT_FLOAT: scprintf(_SC(
"{%f}"),_float(o));
break;
    85             scprintf(_SC(
"{%I64d}"),_integer(o));
    88             scprintf(_SC(
"{%ld}"),_integer(o));
    90             scprintf(_SC(
"{%d}"),_integer(o));
    93         case OT_BOOL: scprintf(_SC(
"%s"),_integer(o)?_SC(
"true"):_SC(
"false"));
break;
    95         default: scprintf(_SC(
"(%s %p)"),
GetTypeName(o),(
void*)_rawval(o));
break; 
break; 
    99 SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,
void *ed)
   102         _literals = SQTable::Create(ss,0);
   103         _strings =  SQTable::Create(ss,0);
   106         _optimization = 
true;
   118 void SQFuncState::Error(
const SQChar *err)
   120     _errfunc(_errtarget,err);
   124 void SQFuncState::Dump(SQFunctionProto *func)
   126     SQUnsignedInteger n=0,i;
   128     scprintf(_SC(
"SQInstruction sizeof %d\n"),
sizeof(SQInstruction));
   129     scprintf(_SC(
"SQObject sizeof %d\n"),
sizeof(SQObject));
   130     scprintf(_SC(
"--------------------------------------------------------------------\n"));
   131     scprintf(_SC(
"*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC(
"unknown"));
   132     scprintf(_SC(
"-----LITERALS\n"));
   133     SQObjectPtr refidx,key,val;
   135     SQObjectPtrVec templiterals;
   136     templiterals.resize(_nliterals);
   137     while((idx=_table(_literals)->Next(
false,refidx,key,val))!=-1) {
   139         templiterals[_integer(val)]=key;
   141     for(i=0;i<templiterals.size();i++){
   142         scprintf(_SC(
"[%d] "),n);
   147     scprintf(_SC(
"-----PARAMS\n"));
   149         scprintf(_SC(
"<<VARPARAMS>>\n"));
   151     for(i=0;i<_parameters.size();i++){
   152         scprintf(_SC(
"[%d] "),n);
   157     scprintf(_SC(
"-----LOCALS\n"));
   158     for(si=0;si<func->_nlocalvarinfos;si++){
   159         SQLocalVarInfo lvi=func->_localvarinfos[si];
   160         scprintf(_SC(
"[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
   163     scprintf(_SC(
"-----LINE INFO\n"));
   164     for(i=0;i<_lineinfos.size();i++){
   165         SQLineInfo li=_lineinfos[i];
   166         scprintf(_SC(
"op [%d] line [%d] \n"),li._op,li._line);
   169     scprintf(_SC(
"-----dump\n"));
   171     for(i=0;i<_instructions.size();i++){
   172         SQInstruction &inst=_instructions[i];
   173         if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
   175             SQInteger lidx = inst._arg1;
   176             scprintf(_SC(
"[%03d] %15s %d "),n,
g_InstrDesc[inst.op].name,inst._arg0);
   177             if(lidx >= 0xFFFFFFFF)
   178                 scprintf(_SC(
"null"));
   181                 SQObjectPtr val,key,refo;
   182                 while(((refidx=_table(_literals)->Next(
false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
   187             if(inst.op != _OP_DLOAD) {
   188                 scprintf(_SC(
" %d %d \n"),inst._arg2,inst._arg3);
   191                 scprintf(_SC(
" %d "),inst._arg2);
   193                 if(lidx >= 0xFFFFFFFF)
   194                     scprintf(_SC(
"null"));
   197                     SQObjectPtr val,key,refo;
   198                     while(((refidx=_table(_literals)->Next(
false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
   206         else if(inst.op==_OP_LOADFLOAT) {
   207             scprintf(_SC(
"[%03d] %15s %d %f %d %d\n"),n,
g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
   209         else if(inst.op==_OP_ARITH){
   210             scprintf(_SC(
"[%03d] %15s %d %d %d %c\n"),n,
g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
   213             scprintf(_SC(
"[%03d] %15s %d %d %d %d\n"),n,
g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
   216     scprintf(_SC(
"-----\n"));
   217     scprintf(_SC(
"stack size[%d]\n"),func->_stacksize);
   218     scprintf(_SC(
"--------------------------------------------------------------------\n\n"));
   222 SQInteger SQFuncState::GetNumericConstant(
const SQInteger cons)
   224     return GetConstant(SQObjectPtr(cons));
   227 SQInteger SQFuncState::GetNumericConstant(
const SQFloat cons)
   229     return GetConstant(SQObjectPtr(cons));
   232 SQInteger SQFuncState::GetConstant(
const SQObject &cons)
   235     if(!_table(_literals)->Get(cons,val))
   238         _table(_literals)->NewSlot(cons,val);
   240         if(_nliterals > MAX_LITERALS) {
   242             Error(_SC(
"internal compiler error: too many literals"));
   245     return _integer(val);
   248 void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger 
arg0,SQInteger 
arg1,SQInteger 
arg2,SQInteger 
arg3)
   250     _instructions[pos]._arg0=(
unsigned char)*((SQUnsignedInteger *)&
arg0);
   251     _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&
arg1);
   252     _instructions[pos]._arg2=(
unsigned char)*((SQUnsignedInteger *)&
arg2);
   253     _instructions[pos]._arg3=(
unsigned char)*((SQUnsignedInteger *)&
arg3);
   256 void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
   259         case 0:_instructions[pos]._arg0=(
unsigned char)*((SQUnsignedInteger *)&val);
break;
   260         case 1:
case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);
break;
   261         case 2:_instructions[pos]._arg2=(
unsigned char)*((SQUnsignedInteger *)&val);
break;
   262         case 3:_instructions[pos]._arg3=(
unsigned char)*((SQUnsignedInteger *)&val);
break;
   266 SQInteger SQFuncState::AllocStackPos()
   268     SQInteger npos=_vlocals.size();
   269     _vlocals.push_back(SQLocalVarInfo());
   270     if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
   271         if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC(
"internal compiler error: too many locals"));
   272         _stacksize=_vlocals.size();
   277 SQInteger SQFuncState::PushTarget(SQInteger n)
   280         _targetstack.push_back(n);
   284     _targetstack.push_back(n);
   288 SQInteger SQFuncState::GetUpTarget(SQInteger n){
   289     return _targetstack[((_targetstack.size()-1)-n)];
   292 SQInteger SQFuncState::TopTarget(){
   293     return _targetstack.back();
   295 SQInteger SQFuncState::PopTarget()
   297     SQInteger npos=_targetstack.back();
   298     SQLocalVarInfo t=_vlocals[_targetstack.back()];
   299     if(type(t._name)==OT_NULL){
   302     _targetstack.pop_back();
   306 SQInteger SQFuncState::GetStackSize()
   308     return _vlocals.size();
   311 void SQFuncState::SetStackSize(SQInteger n)
   313     SQInteger size=_vlocals.size();
   316         SQLocalVarInfo lvi=_vlocals.back();
   317         if(type(lvi._name)!=OT_NULL){
   318             lvi._end_op=GetCurrentPos();
   319             _localvarinfos.push_back(lvi);
   325 bool SQFuncState::IsConstant(
const SQObject &name,SQObject &e)
   328     if(_table(_sharedstate->_consts)->Get(name,val)) {
   335 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
   337     if(stkpos>=_vlocals.size())
return false;
   338     else if(type(_vlocals[stkpos]._name)!=OT_NULL)
return true;
   342 SQInteger SQFuncState::PushLocalVariable(
const SQObject &name)
   344     SQInteger pos=_vlocals.size();
   347     lvi._start_op=GetCurrentPos()+1;
   348     lvi._pos=_vlocals.size();
   349     _vlocals.push_back(lvi);
   350     if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
   355 SQInteger SQFuncState::GetLocalVariable(
const SQObject &name)
   357     SQInteger locals=_vlocals.size();
   359         if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
   367 SQInteger SQFuncState::GetOuterVariable(
const SQObject &name)
   369     SQInteger outers = _outervalues.size();
   370     for(SQInteger i = 0; i<outers; i++) {
   371         if(_string(_outervalues[i]._name) == _string(name))
   377 void SQFuncState::AddOuterValue(
const SQObject &name)
   381         pos = _parent->GetLocalVariable(name);
   383             pos = _parent->GetOuterVariable(name);
   385                 _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); 
   390             _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); 
   394     _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); 
   397 void SQFuncState::AddParameter(
const SQObject &name)
   399     PushLocalVariable(name);
   400     _parameters.push_back(name);
   403 void SQFuncState::AddLineInfos(SQInteger line,
bool lineop,
bool force)
   405     if(_lastline!=line || force){
   407         li._line=line;li._op=(GetCurrentPos()+1);
   408         if(lineop)AddInstruction(_OP_LINE,0,line);
   409         _lineinfos.push_back(li);
   414 void SQFuncState::AddInstruction(SQInstruction &i)
   416     SQInteger size = _instructions.size();
   417     if(size > 0 && _optimization){ 
   418         SQInstruction &pi = _instructions[size-1];
   421             if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
   422                 pi.op = _OP_TAILCALL;
   426             if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
   428                 pi._arg2 = (
unsigned char)i._arg1;
   436             if( pi.op == _OP_LOAD  && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
   437                 pi.op = _OP_PREPCALLK;
   445         case _OP_APPENDARRAY:
   446             if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
   447                 pi.op = _OP_APPENDARRAY;
   450                 pi._arg2 = MAX_FUNC_STACKSIZE;
   451                 pi._arg3 = MAX_FUNC_STACKSIZE;
   456             if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
   459                 _optimization = 
false;
   463             if(pi.op == _OP_MOVE)
   467                 pi._arg3 = (
unsigned char)i._arg1;
   472             if(pi.op == _OP_LOAD && i._arg1 < 256) {
   475                 pi._arg3 = (
unsigned char)i._arg1;
   479         case _OP_EQ:
case _OP_NE:
   480             if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
   486                 pi._arg3 = MAX_FUNC_STACKSIZE;
   491             if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
   493                 pi._arg1 = pi._arg1 + 1;
   494                 pi.op = _OP_LOADNULLS;
   499             if(pi.op == _OP_LINE) {
   500                 _instructions.pop_back();
   501                 _lineinfos.pop_back();
   506     _optimization = 
true;
   507     _instructions.push_back(i);
   510 SQObject SQFuncState::CreateString(
const SQChar *s,SQInteger len)
   512     SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
   513     _table(_strings)->NewSlot(ns,(SQInteger)1);
   517 SQObject SQFuncState::CreateTable()
   519     SQObjectPtr nt(SQTable::Create(_sharedstate,0));
   520     _table(_strings)->NewSlot(nt,(SQInteger)1);
   524 SQFunctionProto *SQFuncState::BuildProto()
   526     SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
   527         _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
   528         _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
   530     SQObjectPtr refidx,key,val;
   533     f->_stacksize = _stacksize;
   534     f->_sourcename = _sourcename;
   535     f->_bgenerator = _bgenerator;
   538     while((idx=_table(_literals)->Next(
false,refidx,key,val))!=-1) {
   539         f->_literals[_integer(val)]=key;
   543     for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
   544     for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
   545     for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
   546     for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
   547     for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
   548     for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no];
   550     memcpy(f->_instructions,&_instructions[0],_instructions.size()*
sizeof(SQInstruction));
   552     f->_varparams = _varparams;
   557 SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
   559     SQFuncState *child = (SQFuncState *)
sq_malloc(
sizeof(SQFuncState));
   560     new (child) SQFuncState(ss,
this,_errfunc,_errtarget);
   561     _childstates.push_back(child);
   565 void SQFuncState::PopChildState()
   567     SQFuncState *child = _childstates.back();
   568     sq_delete(child,SQFuncState);
   569     _childstates.pop_back();
   572 SQFuncState::~SQFuncState()
   574     while(_childstates.size() > 0)
 
void * sq_malloc(SQUnsignedInteger size)
void DumpLiteral(SQObjectPtr &o)
SQInstructionDesc g_InstrDesc[]
const SQChar * GetTypeName(const SQObjectPtr &obj1)