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)