SQInstructionDesc g_InstrDesc[]={\r
{_SC("_OP_LINE")},\r
{_SC("_OP_LOAD")},\r
+ {_SC("_OP_DLOAD")},\r
{_SC("_OP_TAILCALL")},\r
{_SC("_OP_CALL")},\r
{_SC("_OP_PREPCALL")},\r
{_SC("_OP_RETURN")},\r
{_SC("_OP_LOADNULLS")},\r
{_SC("_OP_LOADROOTTABLE")},\r
+ {_SC("_OP_LOADBOOL")},\r
{_SC("_OP_DMOVE")},\r
{_SC("_OP_JMP")},\r
{_SC("_OP_JNZ")},\r
{_SC("_OP_POPTRAP")},\r
{_SC("_OP_THROW")},\r
{_SC("_OP_CLASS")},\r
- {_SC("_OP_NEWSLOTA")},\r
- {_SC("_OP_LOADBOOL")}\r
+ {_SC("_OP_NEWSLOTA")}\r
};\r
#endif\r
void DumpLiteral(SQObjectPtr &o)\r
}\r
}\r
\r
-SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent)\r
+SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)\r
{\r
_nliterals = 0;\r
_literals = SQTable::Create(ss,0);\r
+ _strings = SQTable::Create(ss,0);\r
_sharedstate = ss;\r
_lastline = 0;\r
_optimization = true;\r
- _func = func;\r
_parent = parent;\r
_stacksize = 0;\r
_traps = 0;\r
_returnexp = 0;\r
_varparams = false;\r
+ _errfunc = efunc;\r
+ _errtarget = ed;\r
+ _bgenerator = false;\r
+\r
+}\r
+\r
+void SQFuncState::Error(const SQChar *err)\r
+{\r
+ _errfunc(_errtarget,err);\r
}\r
\r
#ifdef _DEBUG_DUMP\r
-void SQFuncState::Dump()\r
+void SQFuncState::Dump(SQFunctionProto *func)\r
{\r
- unsigned int n=0,i;\r
- SQFunctionProto *func=_funcproto(_func);\r
+ SQUnsignedInteger n=0,i;\r
scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));\r
scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));\r
scprintf(_SC("--------------------------------------------------------------------\n"));\r
SQInteger idx;\r
SQObjectPtrVec templiterals;\r
templiterals.resize(_nliterals);\r
- while((idx=_table(_literals)->Next(refidx,key,val))!=-1) {\r
+ while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
refidx=idx;\r
templiterals[_integer(val)]=key;\r
}\r
n=0;\r
for(i=0;i<_instructions.size();i++){\r
SQInstruction &inst=_instructions[i];\r
- if(inst.op==_OP_LOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){\r
+ if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){\r
\r
- int lidx = inst._arg1;\r
+ SQInteger lidx = inst._arg1;\r
scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);\r
if(lidx >= 0xFFFFFFFF)\r
scprintf(_SC("null"));\r
else {\r
- int refidx;\r
+ SQInteger refidx;\r
SQObjectPtr val,key,refo;\r
- while(((refidx=_table(_literals)->Next(refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
+ while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
refo = refidx; \r
}\r
DumpLiteral(key);\r
}\r
- scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);\r
+ if(inst.op != _OP_DLOAD) {\r
+ scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);\r
+ }\r
+ else {\r
+ scprintf(_SC(" %d "),inst._arg2);\r
+ lidx = inst._arg3;\r
+ if(lidx >= 0xFFFFFFFF)\r
+ scprintf(_SC("null"));\r
+ else {\r
+ SQInteger refidx;\r
+ SQObjectPtr val,key,refo;\r
+ while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
+ refo = refidx; \r
+ }\r
+ DumpLiteral(key);\r
+ scprintf(_SC("\n"));\r
+ }\r
+ }\r
}\r
else if(inst.op==_OP_ARITH){\r
scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);\r
scprintf(_SC("--------------------------------------------------------------------\n\n"));\r
}\r
#endif\r
-int SQFuncState::GetStringConstant(const SQChar *cons)\r
-{\r
- return GetConstant(SQString::Create(_sharedstate,cons));\r
-}\r
\r
-int SQFuncState::GetNumericConstant(const SQInteger cons)\r
+SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)\r
{\r
- return GetConstant(cons);\r
+ return GetConstant(SQObjectPtr(cons));\r
}\r
\r
-int SQFuncState::GetNumericConstant(const SQFloat cons)\r
+SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)\r
{\r
- return GetConstant(cons);\r
+ return GetConstant(SQObjectPtr(cons));\r
}\r
\r
-int SQFuncState::GetConstant(SQObjectPtr cons)\r
+SQInteger SQFuncState::GetConstant(const SQObject &cons)\r
{\r
- int n=0;\r
+ SQInteger n=0;\r
SQObjectPtr val;\r
if(!_table(_literals)->Get(cons,val))\r
{\r
val = _nliterals;\r
_table(_literals)->NewSlot(cons,val);\r
_nliterals++;\r
- if(_nliterals > MAX_LITERALS) throw ParserException(_SC("internal compiler error: too many literals"));\r
+ if(_nliterals > MAX_LITERALS) {\r
+ val.Null();\r
+ Error(_SC("internal compiler error: too many literals"));\r
+ }\r
}\r
return _integer(val);\r
}\r
\r
-void SQFuncState::SetIntructionParams(int pos,int arg0,int arg1,int arg2,int arg3)\r
+void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)\r
{\r
- _instructions[pos]._arg0=*((unsigned int *)&arg0);\r
- _instructions[pos]._arg1=*((unsigned int *)&arg1);\r
- _instructions[pos]._arg2=*((unsigned int *)&arg2);\r
- _instructions[pos]._arg3=*((unsigned int *)&arg3);\r
+ _instructions[pos]._arg0=*((SQUnsignedInteger *)&arg0);\r
+ _instructions[pos]._arg1=*((SQUnsignedInteger *)&arg1);\r
+ _instructions[pos]._arg2=*((SQUnsignedInteger *)&arg2);\r
+ _instructions[pos]._arg3=*((SQUnsignedInteger *)&arg3);\r
}\r
\r
-void SQFuncState::SetIntructionParam(int pos,int arg,int val)\r
+void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)\r
{\r
switch(arg){\r
- case 0:_instructions[pos]._arg0=*((unsigned int *)&val);break;\r
- case 1:_instructions[pos]._arg1=*((unsigned int *)&val);break;\r
- case 2:_instructions[pos]._arg2=*((unsigned int *)&val);break;\r
- case 3:_instructions[pos]._arg3=*((unsigned int *)&val);break;\r
- case 4:_instructions[pos]._arg1=*((unsigned int *)&val);break;\r
+ case 0:_instructions[pos]._arg0=*((SQUnsignedInteger *)&val);break;\r
+ case 1:_instructions[pos]._arg1=*((SQUnsignedInteger *)&val);break;\r
+ case 2:_instructions[pos]._arg2=*((SQUnsignedInteger *)&val);break;\r
+ case 3:_instructions[pos]._arg3=*((SQUnsignedInteger *)&val);break;\r
+ case 4:_instructions[pos]._arg1=*((SQUnsignedInteger *)&val);break;\r
};\r
}\r
\r
-int SQFuncState::AllocStackPos()\r
+SQInteger SQFuncState::AllocStackPos()\r
{\r
- int npos=_vlocals.size();\r
+ SQInteger npos=_vlocals.size();\r
_vlocals.push_back(SQLocalVarInfo());\r
- if(_vlocals.size()>((unsigned int)_stacksize)) {\r
- if(_stacksize>MAX_FUNC_STACKSIZE) throw ParserException(_SC("internal compiler error: too many locals"));\r
+ if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {\r
+ if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));\r
_stacksize=_vlocals.size();\r
}\r
return npos;\r
}\r
\r
-int SQFuncState::PushTarget(int n)\r
+SQInteger SQFuncState::PushTarget(SQInteger n)\r
{\r
if(n!=-1){\r
_targetstack.push_back(n);\r
return n;\r
}\r
\r
-int SQFuncState::GetUpTarget(int n){\r
+SQInteger SQFuncState::GetUpTarget(SQInteger n){\r
return _targetstack[((_targetstack.size()-1)-n)];\r
}\r
\r
-int SQFuncState::TopTarget(){\r
+SQInteger SQFuncState::TopTarget(){\r
return _targetstack.back();\r
}\r
-int SQFuncState::PopTarget()\r
+SQInteger SQFuncState::PopTarget()\r
{\r
- int npos=_targetstack.back();\r
+ SQInteger npos=_targetstack.back();\r
SQLocalVarInfo t=_vlocals[_targetstack.back()];\r
if(type(t._name)==OT_NULL){\r
_vlocals.pop_back();\r
return npos;\r
}\r
\r
-int SQFuncState::GetStackSize()\r
+SQInteger SQFuncState::GetStackSize()\r
{\r
return _vlocals.size();\r
}\r
\r
-void SQFuncState::SetStackSize(int n)\r
+void SQFuncState::SetStackSize(SQInteger n)\r
{\r
- int size=_vlocals.size();\r
+ SQInteger size=_vlocals.size();\r
while(size>n){\r
size--;\r
SQLocalVarInfo lvi=_vlocals.back();\r
}\r
}\r
\r
-bool SQFuncState::IsLocal(unsigned int stkpos)\r
+bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)\r
{\r
if(stkpos>=_vlocals.size())return false;\r
else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;\r
return false;\r
}\r
\r
-int SQFuncState::PushLocalVariable(const SQObjectPtr &name)\r
+SQInteger SQFuncState::PushLocalVariable(const SQObject &name)\r
{\r
- int pos=_vlocals.size();\r
+ SQInteger pos=_vlocals.size();\r
SQLocalVarInfo lvi;\r
lvi._name=name;\r
lvi._start_op=GetCurrentPos()+1;\r
lvi._pos=_vlocals.size();\r
_vlocals.push_back(lvi);\r
- if(_vlocals.size()>((unsigned int)_stacksize))_stacksize=_vlocals.size();\r
+ if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();\r
\r
return pos;\r
}\r
\r
-int SQFuncState::GetLocalVariable(const SQObjectPtr &name)\r
+SQInteger SQFuncState::GetLocalVariable(const SQObject &name)\r
{\r
- int locals=_vlocals.size();\r
+ SQInteger locals=_vlocals.size();\r
while(locals>=1){\r
if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){\r
return locals-1;\r
return -1;\r
}\r
\r
-int SQFuncState::GetOuterVariable(const SQObjectPtr &name)\r
+SQInteger SQFuncState::GetOuterVariable(const SQObject &name)\r
{\r
- int outers = _outervalues.size();\r
- for(int i = 0; i<outers; i++) {\r
+ SQInteger outers = _outervalues.size();\r
+ for(SQInteger i = 0; i<outers; i++) {\r
if(_string(_outervalues[i]._name) == _string(name))\r
return i;\r
}\r
return -1;\r
}\r
\r
-void SQFuncState::AddOuterValue(const SQObjectPtr &name)\r
+void SQFuncState::AddOuterValue(const SQObject &name)\r
{\r
- //AddParameter(name);\r
- int pos=-1;\r
+ SQInteger pos=-1;\r
if(_parent) { \r
pos = _parent->GetLocalVariable(name);\r
if(pos == -1) {\r
_outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global\r
}\r
\r
-void SQFuncState::AddParameter(const SQObjectPtr &name)\r
+void SQFuncState::AddParameter(const SQObject &name)\r
{\r
PushLocalVariable(name);\r
_parameters.push_back(name);\r
}\r
\r
-void SQFuncState::AddLineInfos(int line,bool lineop,bool force)\r
+void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)\r
{\r
if(_lastline!=line || force){\r
SQLineInfo li;\r
\r
void SQFuncState::AddInstruction(SQInstruction &i)\r
{\r
- int size = _instructions.size();\r
+ SQInteger size = _instructions.size();\r
if(size > 0 && _optimization){ //simple optimizer\r
SQInstruction &pi = _instructions[size-1];//previous instruction\r
switch(i.op) {\r
return;\r
}\r
break;\r
-\r
+ case _OP_LOAD:\r
+ if(pi.op == _OP_LOAD && i._arg1 < 256) {\r
+ pi.op = _OP_DLOAD;\r
+ pi._arg2 = i._arg0;\r
+ pi._arg3 = (unsigned char)i._arg1;\r
+ return;\r
+ }\r
+ break;\r
case _OP_EQ:case _OP_NE:\r
if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))\r
{\r
}\r
break;\r
case _OP_LOADNULLS:\r
- //case _OP_LOADNULL:\r
if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {\r
\r
pi._arg1 = pi._arg1 + 1;\r
_instructions.push_back(i);\r
}\r
\r
-SQObject SQFuncState::CreateString(const SQChar *s)\r
+SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)\r
{\r
- SQObjectPtr ns(SQString::Create(_sharedstate,s));\r
- _stringrefs.push_back(ns);\r
+ SQObjectPtr ns(SQString::Create(_sharedstate,s,len));\r
+ _table(_strings)->NewSlot(ns,1);\r
return ns;\r
}\r
\r
-void SQFuncState::Finalize()\r
+SQFunctionProto *SQFuncState::BuildProto()\r
{\r
- SQFunctionProto *f=_funcproto(_func);\r
+ SQFunctionProto *f=SQFunctionProto::Create();\r
f->_literals.resize(_nliterals);\r
SQObjectPtr refidx,key,val;\r
SQInteger idx;\r
- while((idx=_table(_literals)->Next(refidx,key,val))!=-1) {\r
+\r
+ f->_stacksize = _stacksize;\r
+ f->_sourcename = _sourcename;\r
+ f->_bgenerator = _bgenerator;\r
+ f->_name = _name;\r
+\r
+ while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
f->_literals[_integer(val)]=key;\r
refidx=idx;\r
}\r
+\r
f->_functions.resize(_functions.size());\r
f->_functions.copy(_functions);\r
f->_parameters.resize(_parameters.size());\r
f->_lineinfos.resize(_lineinfos.size());\r
f->_lineinfos.copy(_lineinfos);\r
f->_varparams = _varparams;\r
+\r
+ return f;\r
+}\r
+\r
+SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)\r
+{\r
+ SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));\r
+ new (child) SQFuncState(ss,this,_errfunc,_errtarget);\r
+ _childstates.push_back(child);\r
+ return child;\r
+}\r
+\r
+void SQFuncState::PopChildState()\r
+{\r
+ SQFuncState *child = _childstates.back();\r
+ sq_delete(child,SQFuncState);\r
+ _childstates.pop_back();\r
+}\r
+\r
+SQFuncState::~SQFuncState()\r
+{\r
+ while(_childstates.size() > 0)\r
+ {\r
+ PopChildState();\r
+ }\r
}\r