The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Committer:
jhnwkmn
Date:
Tue Dec 16 11:39:42 2014 +0000
Revision:
3:7268a3ceaffc
Parent:
0:97a4f8cc534c
Accepts \r as line terminator as well.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jhnwkmn 0:97a4f8cc534c 1 /*
jhnwkmn 0:97a4f8cc534c 2 see copyright notice in squirrel.h
jhnwkmn 0:97a4f8cc534c 3 */
jhnwkmn 0:97a4f8cc534c 4 #include "sqpcheader.h"
jhnwkmn 0:97a4f8cc534c 5 #ifndef NO_COMPILER
jhnwkmn 0:97a4f8cc534c 6 #include "sqcompiler.h"
jhnwkmn 0:97a4f8cc534c 7 #include "sqstring.h"
jhnwkmn 0:97a4f8cc534c 8 #include "sqfuncproto.h"
jhnwkmn 0:97a4f8cc534c 9 #include "sqtable.h"
jhnwkmn 0:97a4f8cc534c 10 #include "sqopcodes.h"
jhnwkmn 0:97a4f8cc534c 11 #include "sqfuncstate.h"
jhnwkmn 0:97a4f8cc534c 12
jhnwkmn 0:97a4f8cc534c 13 #ifdef _DEBUG_DUMP
jhnwkmn 0:97a4f8cc534c 14 SQInstructionDesc g_InstrDesc[]={
jhnwkmn 0:97a4f8cc534c 15 {_SC("_OP_LINE")},
jhnwkmn 0:97a4f8cc534c 16 {_SC("_OP_LOAD")},
jhnwkmn 0:97a4f8cc534c 17 {_SC("_OP_LOADINT")},
jhnwkmn 0:97a4f8cc534c 18 {_SC("_OP_LOADFLOAT")},
jhnwkmn 0:97a4f8cc534c 19 {_SC("_OP_DLOAD")},
jhnwkmn 0:97a4f8cc534c 20 {_SC("_OP_TAILCALL")},
jhnwkmn 0:97a4f8cc534c 21 {_SC("_OP_CALL")},
jhnwkmn 0:97a4f8cc534c 22 {_SC("_OP_PREPCALL")},
jhnwkmn 0:97a4f8cc534c 23 {_SC("_OP_PREPCALLK")},
jhnwkmn 0:97a4f8cc534c 24 {_SC("_OP_GETK")},
jhnwkmn 0:97a4f8cc534c 25 {_SC("_OP_MOVE")},
jhnwkmn 0:97a4f8cc534c 26 {_SC("_OP_NEWSLOT")},
jhnwkmn 0:97a4f8cc534c 27 {_SC("_OP_DELETE")},
jhnwkmn 0:97a4f8cc534c 28 {_SC("_OP_SET")},
jhnwkmn 0:97a4f8cc534c 29 {_SC("_OP_GET")},
jhnwkmn 0:97a4f8cc534c 30 {_SC("_OP_EQ")},
jhnwkmn 0:97a4f8cc534c 31 {_SC("_OP_NE")},
jhnwkmn 0:97a4f8cc534c 32 {_SC("_OP_ADD")},
jhnwkmn 0:97a4f8cc534c 33 {_SC("_OP_SUB")},
jhnwkmn 0:97a4f8cc534c 34 {_SC("_OP_MUL")},
jhnwkmn 0:97a4f8cc534c 35 {_SC("_OP_DIV")},
jhnwkmn 0:97a4f8cc534c 36 {_SC("_OP_MOD")},
jhnwkmn 0:97a4f8cc534c 37 {_SC("_OP_BITW")},
jhnwkmn 0:97a4f8cc534c 38 {_SC("_OP_RETURN")},
jhnwkmn 0:97a4f8cc534c 39 {_SC("_OP_LOADNULLS")},
jhnwkmn 0:97a4f8cc534c 40 {_SC("_OP_LOADROOT")},
jhnwkmn 0:97a4f8cc534c 41 {_SC("_OP_LOADBOOL")},
jhnwkmn 0:97a4f8cc534c 42 {_SC("_OP_DMOVE")},
jhnwkmn 0:97a4f8cc534c 43 {_SC("_OP_JMP")},
jhnwkmn 0:97a4f8cc534c 44 {_SC("_OP_JCMP")},
jhnwkmn 0:97a4f8cc534c 45 {_SC("_OP_JZ")},
jhnwkmn 0:97a4f8cc534c 46 {_SC("_OP_SETOUTER")},
jhnwkmn 0:97a4f8cc534c 47 {_SC("_OP_GETOUTER")},
jhnwkmn 0:97a4f8cc534c 48 {_SC("_OP_NEWOBJ")},
jhnwkmn 0:97a4f8cc534c 49 {_SC("_OP_APPENDARRAY")},
jhnwkmn 0:97a4f8cc534c 50 {_SC("_OP_COMPARITH")},
jhnwkmn 0:97a4f8cc534c 51 {_SC("_OP_INC")},
jhnwkmn 0:97a4f8cc534c 52 {_SC("_OP_INCL")},
jhnwkmn 0:97a4f8cc534c 53 {_SC("_OP_PINC")},
jhnwkmn 0:97a4f8cc534c 54 {_SC("_OP_PINCL")},
jhnwkmn 0:97a4f8cc534c 55 {_SC("_OP_CMP")},
jhnwkmn 0:97a4f8cc534c 56 {_SC("_OP_EXISTS")},
jhnwkmn 0:97a4f8cc534c 57 {_SC("_OP_INSTANCEOF")},
jhnwkmn 0:97a4f8cc534c 58 {_SC("_OP_AND")},
jhnwkmn 0:97a4f8cc534c 59 {_SC("_OP_OR")},
jhnwkmn 0:97a4f8cc534c 60 {_SC("_OP_NEG")},
jhnwkmn 0:97a4f8cc534c 61 {_SC("_OP_NOT")},
jhnwkmn 0:97a4f8cc534c 62 {_SC("_OP_BWNOT")},
jhnwkmn 0:97a4f8cc534c 63 {_SC("_OP_CLOSURE")},
jhnwkmn 0:97a4f8cc534c 64 {_SC("_OP_YIELD")},
jhnwkmn 0:97a4f8cc534c 65 {_SC("_OP_RESUME")},
jhnwkmn 0:97a4f8cc534c 66 {_SC("_OP_FOREACH")},
jhnwkmn 0:97a4f8cc534c 67 {_SC("_OP_POSTFOREACH")},
jhnwkmn 0:97a4f8cc534c 68 {_SC("_OP_CLONE")},
jhnwkmn 0:97a4f8cc534c 69 {_SC("_OP_TYPEOF")},
jhnwkmn 0:97a4f8cc534c 70 {_SC("_OP_PUSHTRAP")},
jhnwkmn 0:97a4f8cc534c 71 {_SC("_OP_POPTRAP")},
jhnwkmn 0:97a4f8cc534c 72 {_SC("_OP_THROW")},
jhnwkmn 0:97a4f8cc534c 73 {_SC("_OP_NEWSLOTA")},
jhnwkmn 0:97a4f8cc534c 74 {_SC("_OP_GETBASE")},
jhnwkmn 0:97a4f8cc534c 75 {_SC("_OP_CLOSE")},
jhnwkmn 0:97a4f8cc534c 76 {_SC("_OP_JCMP")}
jhnwkmn 0:97a4f8cc534c 77 };
jhnwkmn 0:97a4f8cc534c 78 #endif
jhnwkmn 0:97a4f8cc534c 79 void DumpLiteral(SQObjectPtr &o)
jhnwkmn 0:97a4f8cc534c 80 {
jhnwkmn 0:97a4f8cc534c 81 switch(type(o)){
jhnwkmn 0:97a4f8cc534c 82 case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
jhnwkmn 0:97a4f8cc534c 83 case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
jhnwkmn 0:97a4f8cc534c 84 case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break;
jhnwkmn 0:97a4f8cc534c 85 case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
jhnwkmn 0:97a4f8cc534c 86 default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
jhnwkmn 0:97a4f8cc534c 87 }
jhnwkmn 0:97a4f8cc534c 88 }
jhnwkmn 0:97a4f8cc534c 89
jhnwkmn 0:97a4f8cc534c 90 SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
jhnwkmn 0:97a4f8cc534c 91 {
jhnwkmn 0:97a4f8cc534c 92 _nliterals = 0;
jhnwkmn 0:97a4f8cc534c 93 _literals = SQTable::Create(ss,0);
jhnwkmn 0:97a4f8cc534c 94 _strings = SQTable::Create(ss,0);
jhnwkmn 0:97a4f8cc534c 95 _sharedstate = ss;
jhnwkmn 0:97a4f8cc534c 96 _lastline = 0;
jhnwkmn 0:97a4f8cc534c 97 _optimization = true;
jhnwkmn 0:97a4f8cc534c 98 _parent = parent;
jhnwkmn 0:97a4f8cc534c 99 _stacksize = 0;
jhnwkmn 0:97a4f8cc534c 100 _traps = 0;
jhnwkmn 0:97a4f8cc534c 101 _returnexp = 0;
jhnwkmn 0:97a4f8cc534c 102 _varparams = false;
jhnwkmn 0:97a4f8cc534c 103 _errfunc = efunc;
jhnwkmn 0:97a4f8cc534c 104 _errtarget = ed;
jhnwkmn 0:97a4f8cc534c 105 _bgenerator = false;
jhnwkmn 0:97a4f8cc534c 106 _outers = 0;
jhnwkmn 0:97a4f8cc534c 107 _ss = ss;
jhnwkmn 0:97a4f8cc534c 108
jhnwkmn 0:97a4f8cc534c 109 }
jhnwkmn 0:97a4f8cc534c 110
jhnwkmn 0:97a4f8cc534c 111 void SQFuncState::Error(const SQChar *err)
jhnwkmn 0:97a4f8cc534c 112 {
jhnwkmn 0:97a4f8cc534c 113 _errfunc(_errtarget,err);
jhnwkmn 0:97a4f8cc534c 114 }
jhnwkmn 0:97a4f8cc534c 115
jhnwkmn 0:97a4f8cc534c 116 #ifdef _DEBUG_DUMP
jhnwkmn 0:97a4f8cc534c 117 void SQFuncState::Dump(SQFunctionProto *func)
jhnwkmn 0:97a4f8cc534c 118 {
jhnwkmn 0:97a4f8cc534c 119 SQUnsignedInteger n=0,i;
jhnwkmn 0:97a4f8cc534c 120 SQInteger si;
jhnwkmn 0:97a4f8cc534c 121 scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
jhnwkmn 0:97a4f8cc534c 122 scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
jhnwkmn 0:97a4f8cc534c 123 scprintf(_SC("--------------------------------------------------------------------\n"));
jhnwkmn 0:97a4f8cc534c 124 scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
jhnwkmn 0:97a4f8cc534c 125 scprintf(_SC("-----LITERALS\n"));
jhnwkmn 0:97a4f8cc534c 126 SQObjectPtr refidx,key,val;
jhnwkmn 0:97a4f8cc534c 127 SQInteger idx;
jhnwkmn 0:97a4f8cc534c 128 SQObjectPtrVec templiterals;
jhnwkmn 0:97a4f8cc534c 129 templiterals.resize(_nliterals);
jhnwkmn 0:97a4f8cc534c 130 while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
jhnwkmn 0:97a4f8cc534c 131 refidx=idx;
jhnwkmn 0:97a4f8cc534c 132 templiterals[_integer(val)]=key;
jhnwkmn 0:97a4f8cc534c 133 }
jhnwkmn 0:97a4f8cc534c 134 for(i=0;i<templiterals.size();i++){
jhnwkmn 0:97a4f8cc534c 135 scprintf(_SC("[%d] "),n);
jhnwkmn 0:97a4f8cc534c 136 DumpLiteral(templiterals[i]);
jhnwkmn 0:97a4f8cc534c 137 scprintf(_SC("\n"));
jhnwkmn 0:97a4f8cc534c 138 n++;
jhnwkmn 0:97a4f8cc534c 139 }
jhnwkmn 0:97a4f8cc534c 140 scprintf(_SC("-----PARAMS\n"));
jhnwkmn 0:97a4f8cc534c 141 if(_varparams)
jhnwkmn 0:97a4f8cc534c 142 scprintf(_SC("<<VARPARAMS>>\n"));
jhnwkmn 0:97a4f8cc534c 143 n=0;
jhnwkmn 0:97a4f8cc534c 144 for(i=0;i<_parameters.size();i++){
jhnwkmn 0:97a4f8cc534c 145 scprintf(_SC("[%d] "),n);
jhnwkmn 0:97a4f8cc534c 146 DumpLiteral(_parameters[i]);
jhnwkmn 0:97a4f8cc534c 147 scprintf(_SC("\n"));
jhnwkmn 0:97a4f8cc534c 148 n++;
jhnwkmn 0:97a4f8cc534c 149 }
jhnwkmn 0:97a4f8cc534c 150 scprintf(_SC("-----LOCALS\n"));
jhnwkmn 0:97a4f8cc534c 151 for(si=0;si<func->_nlocalvarinfos;si++){
jhnwkmn 0:97a4f8cc534c 152 SQLocalVarInfo lvi=func->_localvarinfos[si];
jhnwkmn 0:97a4f8cc534c 153 scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
jhnwkmn 0:97a4f8cc534c 154 n++;
jhnwkmn 0:97a4f8cc534c 155 }
jhnwkmn 0:97a4f8cc534c 156 scprintf(_SC("-----LINE INFO\n"));
jhnwkmn 0:97a4f8cc534c 157 for(i=0;i<_lineinfos.size();i++){
jhnwkmn 0:97a4f8cc534c 158 SQLineInfo li=_lineinfos[i];
jhnwkmn 0:97a4f8cc534c 159 scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
jhnwkmn 0:97a4f8cc534c 160 n++;
jhnwkmn 0:97a4f8cc534c 161 }
jhnwkmn 0:97a4f8cc534c 162 scprintf(_SC("-----dump\n"));
jhnwkmn 0:97a4f8cc534c 163 n=0;
jhnwkmn 0:97a4f8cc534c 164 for(i=0;i<_instructions.size();i++){
jhnwkmn 0:97a4f8cc534c 165 SQInstruction &inst=_instructions[i];
jhnwkmn 0:97a4f8cc534c 166 if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
jhnwkmn 0:97a4f8cc534c 167
jhnwkmn 0:97a4f8cc534c 168 SQInteger lidx = inst._arg1;
jhnwkmn 0:97a4f8cc534c 169 scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
jhnwkmn 0:97a4f8cc534c 170 if(lidx >= 0xFFFFFFFF)
jhnwkmn 0:97a4f8cc534c 171 scprintf(_SC("null"));
jhnwkmn 0:97a4f8cc534c 172 else {
jhnwkmn 0:97a4f8cc534c 173 SQInteger refidx;
jhnwkmn 0:97a4f8cc534c 174 SQObjectPtr val,key,refo;
jhnwkmn 0:97a4f8cc534c 175 while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
jhnwkmn 0:97a4f8cc534c 176 refo = refidx;
jhnwkmn 0:97a4f8cc534c 177 }
jhnwkmn 0:97a4f8cc534c 178 DumpLiteral(key);
jhnwkmn 0:97a4f8cc534c 179 }
jhnwkmn 0:97a4f8cc534c 180 if(inst.op != _OP_DLOAD) {
jhnwkmn 0:97a4f8cc534c 181 scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
jhnwkmn 0:97a4f8cc534c 182 }
jhnwkmn 0:97a4f8cc534c 183 else {
jhnwkmn 0:97a4f8cc534c 184 scprintf(_SC(" %d "),inst._arg2);
jhnwkmn 0:97a4f8cc534c 185 lidx = inst._arg3;
jhnwkmn 0:97a4f8cc534c 186 if(lidx >= 0xFFFFFFFF)
jhnwkmn 0:97a4f8cc534c 187 scprintf(_SC("null"));
jhnwkmn 0:97a4f8cc534c 188 else {
jhnwkmn 0:97a4f8cc534c 189 SQInteger refidx;
jhnwkmn 0:97a4f8cc534c 190 SQObjectPtr val,key,refo;
jhnwkmn 0:97a4f8cc534c 191 while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
jhnwkmn 0:97a4f8cc534c 192 refo = refidx;
jhnwkmn 0:97a4f8cc534c 193 }
jhnwkmn 0:97a4f8cc534c 194 DumpLiteral(key);
jhnwkmn 0:97a4f8cc534c 195 scprintf(_SC("\n"));
jhnwkmn 0:97a4f8cc534c 196 }
jhnwkmn 0:97a4f8cc534c 197 }
jhnwkmn 0:97a4f8cc534c 198 }
jhnwkmn 0:97a4f8cc534c 199 else if(inst.op==_OP_LOADFLOAT) {
jhnwkmn 0:97a4f8cc534c 200 scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
jhnwkmn 0:97a4f8cc534c 201 }
jhnwkmn 0:97a4f8cc534c 202 /* else if(inst.op==_OP_ARITH){
jhnwkmn 0:97a4f8cc534c 203 scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
jhnwkmn 0:97a4f8cc534c 204 }*/
jhnwkmn 0:97a4f8cc534c 205 else {
jhnwkmn 0:97a4f8cc534c 206 scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
jhnwkmn 0:97a4f8cc534c 207 }
jhnwkmn 0:97a4f8cc534c 208 n++;
jhnwkmn 0:97a4f8cc534c 209 }
jhnwkmn 0:97a4f8cc534c 210 scprintf(_SC("-----\n"));
jhnwkmn 0:97a4f8cc534c 211 scprintf(_SC("stack size[%d]\n"),func->_stacksize);
jhnwkmn 0:97a4f8cc534c 212 scprintf(_SC("--------------------------------------------------------------------\n\n"));
jhnwkmn 0:97a4f8cc534c 213 }
jhnwkmn 0:97a4f8cc534c 214 #endif
jhnwkmn 0:97a4f8cc534c 215
jhnwkmn 0:97a4f8cc534c 216 SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
jhnwkmn 0:97a4f8cc534c 217 {
jhnwkmn 0:97a4f8cc534c 218 return GetConstant(SQObjectPtr(cons));
jhnwkmn 0:97a4f8cc534c 219 }
jhnwkmn 0:97a4f8cc534c 220
jhnwkmn 0:97a4f8cc534c 221 SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
jhnwkmn 0:97a4f8cc534c 222 {
jhnwkmn 0:97a4f8cc534c 223 return GetConstant(SQObjectPtr(cons));
jhnwkmn 0:97a4f8cc534c 224 }
jhnwkmn 0:97a4f8cc534c 225
jhnwkmn 0:97a4f8cc534c 226 SQInteger SQFuncState::GetConstant(const SQObject &cons)
jhnwkmn 0:97a4f8cc534c 227 {
jhnwkmn 0:97a4f8cc534c 228 SQObjectPtr val;
jhnwkmn 0:97a4f8cc534c 229 if(!_table(_literals)->Get(cons,val))
jhnwkmn 0:97a4f8cc534c 230 {
jhnwkmn 0:97a4f8cc534c 231 val = _nliterals;
jhnwkmn 0:97a4f8cc534c 232 _table(_literals)->NewSlot(cons,val);
jhnwkmn 0:97a4f8cc534c 233 _nliterals++;
jhnwkmn 0:97a4f8cc534c 234 if(_nliterals > MAX_LITERALS) {
jhnwkmn 0:97a4f8cc534c 235 val.Null();
jhnwkmn 0:97a4f8cc534c 236 Error(_SC("internal compiler error: too many literals"));
jhnwkmn 0:97a4f8cc534c 237 }
jhnwkmn 0:97a4f8cc534c 238 }
jhnwkmn 0:97a4f8cc534c 239 return _integer(val);
jhnwkmn 0:97a4f8cc534c 240 }
jhnwkmn 0:97a4f8cc534c 241
jhnwkmn 0:97a4f8cc534c 242 void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
jhnwkmn 0:97a4f8cc534c 243 {
jhnwkmn 0:97a4f8cc534c 244 _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
jhnwkmn 0:97a4f8cc534c 245 _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
jhnwkmn 0:97a4f8cc534c 246 _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
jhnwkmn 0:97a4f8cc534c 247 _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
jhnwkmn 0:97a4f8cc534c 248 }
jhnwkmn 0:97a4f8cc534c 249
jhnwkmn 0:97a4f8cc534c 250 void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
jhnwkmn 0:97a4f8cc534c 251 {
jhnwkmn 0:97a4f8cc534c 252 switch(arg){
jhnwkmn 0:97a4f8cc534c 253 case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
jhnwkmn 0:97a4f8cc534c 254 case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
jhnwkmn 0:97a4f8cc534c 255 case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
jhnwkmn 0:97a4f8cc534c 256 case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
jhnwkmn 0:97a4f8cc534c 257 };
jhnwkmn 0:97a4f8cc534c 258 }
jhnwkmn 0:97a4f8cc534c 259
jhnwkmn 0:97a4f8cc534c 260 SQInteger SQFuncState::AllocStackPos()
jhnwkmn 0:97a4f8cc534c 261 {
jhnwkmn 0:97a4f8cc534c 262 SQInteger npos=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 263 _vlocals.push_back(SQLocalVarInfo());
jhnwkmn 0:97a4f8cc534c 264 if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
jhnwkmn 0:97a4f8cc534c 265 if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
jhnwkmn 0:97a4f8cc534c 266 _stacksize=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 267 }
jhnwkmn 0:97a4f8cc534c 268 return npos;
jhnwkmn 0:97a4f8cc534c 269 }
jhnwkmn 0:97a4f8cc534c 270
jhnwkmn 0:97a4f8cc534c 271 SQInteger SQFuncState::PushTarget(SQInteger n)
jhnwkmn 0:97a4f8cc534c 272 {
jhnwkmn 0:97a4f8cc534c 273 if(n!=-1){
jhnwkmn 0:97a4f8cc534c 274 _targetstack.push_back(n);
jhnwkmn 0:97a4f8cc534c 275 return n;
jhnwkmn 0:97a4f8cc534c 276 }
jhnwkmn 0:97a4f8cc534c 277 n=AllocStackPos();
jhnwkmn 0:97a4f8cc534c 278 _targetstack.push_back(n);
jhnwkmn 0:97a4f8cc534c 279 return n;
jhnwkmn 0:97a4f8cc534c 280 }
jhnwkmn 0:97a4f8cc534c 281
jhnwkmn 0:97a4f8cc534c 282 SQInteger SQFuncState::GetUpTarget(SQInteger n){
jhnwkmn 0:97a4f8cc534c 283 return _targetstack[((_targetstack.size()-1)-n)];
jhnwkmn 0:97a4f8cc534c 284 }
jhnwkmn 0:97a4f8cc534c 285
jhnwkmn 0:97a4f8cc534c 286 SQInteger SQFuncState::TopTarget(){
jhnwkmn 0:97a4f8cc534c 287 return _targetstack.back();
jhnwkmn 0:97a4f8cc534c 288 }
jhnwkmn 0:97a4f8cc534c 289 SQInteger SQFuncState::PopTarget()
jhnwkmn 0:97a4f8cc534c 290 {
jhnwkmn 0:97a4f8cc534c 291 SQUnsignedInteger npos=_targetstack.back();
jhnwkmn 0:97a4f8cc534c 292 assert(npos < _vlocals.size());
jhnwkmn 0:97a4f8cc534c 293 SQLocalVarInfo &t = _vlocals[npos];
jhnwkmn 0:97a4f8cc534c 294 if(type(t._name)==OT_NULL){
jhnwkmn 0:97a4f8cc534c 295 _vlocals.pop_back();
jhnwkmn 0:97a4f8cc534c 296 }
jhnwkmn 0:97a4f8cc534c 297 _targetstack.pop_back();
jhnwkmn 0:97a4f8cc534c 298 return npos;
jhnwkmn 0:97a4f8cc534c 299 }
jhnwkmn 0:97a4f8cc534c 300
jhnwkmn 0:97a4f8cc534c 301 SQInteger SQFuncState::GetStackSize()
jhnwkmn 0:97a4f8cc534c 302 {
jhnwkmn 0:97a4f8cc534c 303 return _vlocals.size();
jhnwkmn 0:97a4f8cc534c 304 }
jhnwkmn 0:97a4f8cc534c 305
jhnwkmn 0:97a4f8cc534c 306 SQInteger SQFuncState::CountOuters(SQInteger stacksize)
jhnwkmn 0:97a4f8cc534c 307 {
jhnwkmn 0:97a4f8cc534c 308 SQInteger outers = 0;
jhnwkmn 0:97a4f8cc534c 309 SQInteger k = _vlocals.size() - 1;
jhnwkmn 0:97a4f8cc534c 310 while(k >= stacksize) {
jhnwkmn 0:97a4f8cc534c 311 SQLocalVarInfo &lvi = _vlocals[k];
jhnwkmn 0:97a4f8cc534c 312 k--;
jhnwkmn 0:97a4f8cc534c 313 if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
jhnwkmn 0:97a4f8cc534c 314 outers++;
jhnwkmn 0:97a4f8cc534c 315 }
jhnwkmn 0:97a4f8cc534c 316 }
jhnwkmn 0:97a4f8cc534c 317 return outers;
jhnwkmn 0:97a4f8cc534c 318 }
jhnwkmn 0:97a4f8cc534c 319
jhnwkmn 0:97a4f8cc534c 320 void SQFuncState::SetStackSize(SQInteger n)
jhnwkmn 0:97a4f8cc534c 321 {
jhnwkmn 0:97a4f8cc534c 322 SQInteger size=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 323 while(size>n){
jhnwkmn 0:97a4f8cc534c 324 size--;
jhnwkmn 0:97a4f8cc534c 325 SQLocalVarInfo lvi = _vlocals.back();
jhnwkmn 0:97a4f8cc534c 326 if(type(lvi._name)!=OT_NULL){
jhnwkmn 0:97a4f8cc534c 327 if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
jhnwkmn 0:97a4f8cc534c 328 _outers--;
jhnwkmn 0:97a4f8cc534c 329 }
jhnwkmn 0:97a4f8cc534c 330 lvi._end_op = GetCurrentPos();
jhnwkmn 0:97a4f8cc534c 331 _localvarinfos.push_back(lvi);
jhnwkmn 0:97a4f8cc534c 332 }
jhnwkmn 0:97a4f8cc534c 333 _vlocals.pop_back();
jhnwkmn 0:97a4f8cc534c 334 }
jhnwkmn 0:97a4f8cc534c 335 }
jhnwkmn 0:97a4f8cc534c 336
jhnwkmn 0:97a4f8cc534c 337 bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
jhnwkmn 0:97a4f8cc534c 338 {
jhnwkmn 0:97a4f8cc534c 339 SQObjectPtr val;
jhnwkmn 0:97a4f8cc534c 340 if(_table(_sharedstate->_consts)->Get(name,val)) {
jhnwkmn 0:97a4f8cc534c 341 e = val;
jhnwkmn 0:97a4f8cc534c 342 return true;
jhnwkmn 0:97a4f8cc534c 343 }
jhnwkmn 0:97a4f8cc534c 344 return false;
jhnwkmn 0:97a4f8cc534c 345 }
jhnwkmn 0:97a4f8cc534c 346
jhnwkmn 0:97a4f8cc534c 347 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
jhnwkmn 0:97a4f8cc534c 348 {
jhnwkmn 0:97a4f8cc534c 349 if(stkpos>=_vlocals.size())return false;
jhnwkmn 0:97a4f8cc534c 350 else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
jhnwkmn 0:97a4f8cc534c 351 return false;
jhnwkmn 0:97a4f8cc534c 352 }
jhnwkmn 0:97a4f8cc534c 353
jhnwkmn 0:97a4f8cc534c 354 SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
jhnwkmn 0:97a4f8cc534c 355 {
jhnwkmn 0:97a4f8cc534c 356 SQInteger pos=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 357 SQLocalVarInfo lvi;
jhnwkmn 0:97a4f8cc534c 358 lvi._name=name;
jhnwkmn 0:97a4f8cc534c 359 lvi._start_op=GetCurrentPos()+1;
jhnwkmn 0:97a4f8cc534c 360 lvi._pos=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 361 _vlocals.push_back(lvi);
jhnwkmn 0:97a4f8cc534c 362 if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 363 return pos;
jhnwkmn 0:97a4f8cc534c 364 }
jhnwkmn 0:97a4f8cc534c 365
jhnwkmn 0:97a4f8cc534c 366
jhnwkmn 0:97a4f8cc534c 367
jhnwkmn 0:97a4f8cc534c 368 SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
jhnwkmn 0:97a4f8cc534c 369 {
jhnwkmn 0:97a4f8cc534c 370 SQInteger locals=_vlocals.size();
jhnwkmn 0:97a4f8cc534c 371 while(locals>=1){
jhnwkmn 0:97a4f8cc534c 372 SQLocalVarInfo &lvi = _vlocals[locals-1];
jhnwkmn 0:97a4f8cc534c 373 if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){
jhnwkmn 0:97a4f8cc534c 374 return locals-1;
jhnwkmn 0:97a4f8cc534c 375 }
jhnwkmn 0:97a4f8cc534c 376 locals--;
jhnwkmn 0:97a4f8cc534c 377 }
jhnwkmn 0:97a4f8cc534c 378 return -1;
jhnwkmn 0:97a4f8cc534c 379 }
jhnwkmn 0:97a4f8cc534c 380
jhnwkmn 0:97a4f8cc534c 381 void SQFuncState::MarkLocalAsOuter(SQInteger pos)
jhnwkmn 0:97a4f8cc534c 382 {
jhnwkmn 0:97a4f8cc534c 383 SQLocalVarInfo &lvi = _vlocals[pos];
jhnwkmn 0:97a4f8cc534c 384 lvi._end_op = UINT_MINUS_ONE;
jhnwkmn 0:97a4f8cc534c 385 _outers++;
jhnwkmn 0:97a4f8cc534c 386 }
jhnwkmn 0:97a4f8cc534c 387
jhnwkmn 0:97a4f8cc534c 388 SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
jhnwkmn 0:97a4f8cc534c 389 {
jhnwkmn 0:97a4f8cc534c 390 SQInteger outers = _outervalues.size();
jhnwkmn 0:97a4f8cc534c 391 for(SQInteger i = 0; i<outers; i++) {
jhnwkmn 0:97a4f8cc534c 392 if(_string(_outervalues[i]._name) == _string(name))
jhnwkmn 0:97a4f8cc534c 393 return i;
jhnwkmn 0:97a4f8cc534c 394 }
jhnwkmn 0:97a4f8cc534c 395 SQInteger pos=-1;
jhnwkmn 0:97a4f8cc534c 396 if(_parent) {
jhnwkmn 0:97a4f8cc534c 397 pos = _parent->GetLocalVariable(name);
jhnwkmn 0:97a4f8cc534c 398 if(pos == -1) {
jhnwkmn 0:97a4f8cc534c 399 pos = _parent->GetOuterVariable(name);
jhnwkmn 0:97a4f8cc534c 400 if(pos != -1) {
jhnwkmn 0:97a4f8cc534c 401 _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
jhnwkmn 0:97a4f8cc534c 402 return _outervalues.size() - 1;
jhnwkmn 0:97a4f8cc534c 403 }
jhnwkmn 0:97a4f8cc534c 404 }
jhnwkmn 0:97a4f8cc534c 405 else {
jhnwkmn 0:97a4f8cc534c 406 _parent->MarkLocalAsOuter(pos);
jhnwkmn 0:97a4f8cc534c 407 _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
jhnwkmn 0:97a4f8cc534c 408 return _outervalues.size() - 1;
jhnwkmn 0:97a4f8cc534c 409
jhnwkmn 0:97a4f8cc534c 410
jhnwkmn 0:97a4f8cc534c 411 }
jhnwkmn 0:97a4f8cc534c 412 }
jhnwkmn 0:97a4f8cc534c 413 return -1;
jhnwkmn 0:97a4f8cc534c 414 }
jhnwkmn 0:97a4f8cc534c 415
jhnwkmn 0:97a4f8cc534c 416 void SQFuncState::AddParameter(const SQObject &name)
jhnwkmn 0:97a4f8cc534c 417 {
jhnwkmn 0:97a4f8cc534c 418 PushLocalVariable(name);
jhnwkmn 0:97a4f8cc534c 419 _parameters.push_back(name);
jhnwkmn 0:97a4f8cc534c 420 }
jhnwkmn 0:97a4f8cc534c 421
jhnwkmn 0:97a4f8cc534c 422 void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
jhnwkmn 0:97a4f8cc534c 423 {
jhnwkmn 0:97a4f8cc534c 424 if(_lastline!=line || force){
jhnwkmn 0:97a4f8cc534c 425 SQLineInfo li;
jhnwkmn 0:97a4f8cc534c 426 li._line=line;li._op=(GetCurrentPos()+1);
jhnwkmn 0:97a4f8cc534c 427 if(lineop)AddInstruction(_OP_LINE,0,line);
jhnwkmn 0:97a4f8cc534c 428 if(_lastline!=line) {
jhnwkmn 0:97a4f8cc534c 429 _lineinfos.push_back(li);
jhnwkmn 0:97a4f8cc534c 430 }
jhnwkmn 0:97a4f8cc534c 431 _lastline=line;
jhnwkmn 0:97a4f8cc534c 432 }
jhnwkmn 0:97a4f8cc534c 433 }
jhnwkmn 0:97a4f8cc534c 434
jhnwkmn 0:97a4f8cc534c 435 void SQFuncState::DiscardTarget()
jhnwkmn 0:97a4f8cc534c 436 {
jhnwkmn 0:97a4f8cc534c 437 SQInteger discardedtarget = PopTarget();
jhnwkmn 0:97a4f8cc534c 438 SQInteger size = _instructions.size();
jhnwkmn 0:97a4f8cc534c 439 if(size > 0 && _optimization){
jhnwkmn 0:97a4f8cc534c 440 SQInstruction &pi = _instructions[size-1];//previous instruction
jhnwkmn 0:97a4f8cc534c 441 switch(pi.op) {
jhnwkmn 0:97a4f8cc534c 442 case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL:
jhnwkmn 0:97a4f8cc534c 443 if(pi._arg0 == discardedtarget) {
jhnwkmn 0:97a4f8cc534c 444 pi._arg0 = 0xFF;
jhnwkmn 0:97a4f8cc534c 445 }
jhnwkmn 0:97a4f8cc534c 446 }
jhnwkmn 0:97a4f8cc534c 447 }
jhnwkmn 0:97a4f8cc534c 448 }
jhnwkmn 0:97a4f8cc534c 449
jhnwkmn 0:97a4f8cc534c 450 void SQFuncState::AddInstruction(SQInstruction &i)
jhnwkmn 0:97a4f8cc534c 451 {
jhnwkmn 0:97a4f8cc534c 452 SQInteger size = _instructions.size();
jhnwkmn 0:97a4f8cc534c 453 if(size > 0 && _optimization){ //simple optimizer
jhnwkmn 0:97a4f8cc534c 454 SQInstruction &pi = _instructions[size-1];//previous instruction
jhnwkmn 0:97a4f8cc534c 455 switch(i.op) {
jhnwkmn 0:97a4f8cc534c 456 case _OP_JZ:
jhnwkmn 0:97a4f8cc534c 457 if( pi.op == _OP_CMP && pi._arg1 < 0xFF) {
jhnwkmn 0:97a4f8cc534c 458 pi.op = _OP_JCMP;
jhnwkmn 0:97a4f8cc534c 459 pi._arg0 = (unsigned char)pi._arg1;
jhnwkmn 0:97a4f8cc534c 460 pi._arg1 = i._arg1;
jhnwkmn 0:97a4f8cc534c 461 return;
jhnwkmn 0:97a4f8cc534c 462 }
jhnwkmn 0:97a4f8cc534c 463 case _OP_SET:
jhnwkmn 0:97a4f8cc534c 464 case _OP_NEWSLOT:
jhnwkmn 0:97a4f8cc534c 465 if(i._arg0 == i._arg3) {
jhnwkmn 0:97a4f8cc534c 466 i._arg0 = 0xFF;
jhnwkmn 0:97a4f8cc534c 467 }
jhnwkmn 0:97a4f8cc534c 468 break;
jhnwkmn 0:97a4f8cc534c 469 case _OP_SETOUTER:
jhnwkmn 0:97a4f8cc534c 470 if(i._arg0 == i._arg2) {
jhnwkmn 0:97a4f8cc534c 471 i._arg0 = 0xFF;
jhnwkmn 0:97a4f8cc534c 472 }
jhnwkmn 0:97a4f8cc534c 473 break;
jhnwkmn 0:97a4f8cc534c 474 case _OP_RETURN:
jhnwkmn 0:97a4f8cc534c 475 if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
jhnwkmn 0:97a4f8cc534c 476 pi.op = _OP_TAILCALL;
jhnwkmn 0:97a4f8cc534c 477 } else if(pi.op == _OP_CLOSE){
jhnwkmn 0:97a4f8cc534c 478 pi = i;
jhnwkmn 0:97a4f8cc534c 479 return;
jhnwkmn 0:97a4f8cc534c 480 }
jhnwkmn 0:97a4f8cc534c 481 break;
jhnwkmn 0:97a4f8cc534c 482 case _OP_GET:
jhnwkmn 0:97a4f8cc534c 483 if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
jhnwkmn 0:97a4f8cc534c 484 pi._arg1 = pi._arg1;
jhnwkmn 0:97a4f8cc534c 485 pi._arg2 = (unsigned char)i._arg1;
jhnwkmn 0:97a4f8cc534c 486 pi.op = _OP_GETK;
jhnwkmn 0:97a4f8cc534c 487 pi._arg0 = i._arg0;
jhnwkmn 0:97a4f8cc534c 488
jhnwkmn 0:97a4f8cc534c 489 return;
jhnwkmn 0:97a4f8cc534c 490 }
jhnwkmn 0:97a4f8cc534c 491 break;
jhnwkmn 0:97a4f8cc534c 492 case _OP_PREPCALL:
jhnwkmn 0:97a4f8cc534c 493 if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
jhnwkmn 0:97a4f8cc534c 494 pi.op = _OP_PREPCALLK;
jhnwkmn 0:97a4f8cc534c 495 pi._arg0 = i._arg0;
jhnwkmn 0:97a4f8cc534c 496 pi._arg1 = pi._arg1;
jhnwkmn 0:97a4f8cc534c 497 pi._arg2 = i._arg2;
jhnwkmn 0:97a4f8cc534c 498 pi._arg3 = i._arg3;
jhnwkmn 0:97a4f8cc534c 499 return;
jhnwkmn 0:97a4f8cc534c 500 }
jhnwkmn 0:97a4f8cc534c 501 break;
jhnwkmn 0:97a4f8cc534c 502 case _OP_APPENDARRAY: {
jhnwkmn 0:97a4f8cc534c 503 SQInteger aat = -1;
jhnwkmn 0:97a4f8cc534c 504 switch(pi.op) {
jhnwkmn 0:97a4f8cc534c 505 case _OP_LOAD: aat = AAT_LITERAL; break;
jhnwkmn 0:97a4f8cc534c 506 case _OP_LOADINT: aat = AAT_INT; break;
jhnwkmn 0:97a4f8cc534c 507 case _OP_LOADBOOL: aat = AAT_BOOL; break;
jhnwkmn 0:97a4f8cc534c 508 case _OP_LOADFLOAT: aat = AAT_FLOAT; break;
jhnwkmn 0:97a4f8cc534c 509 default: break;
jhnwkmn 0:97a4f8cc534c 510 }
jhnwkmn 0:97a4f8cc534c 511 if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
jhnwkmn 0:97a4f8cc534c 512 pi.op = _OP_APPENDARRAY;
jhnwkmn 0:97a4f8cc534c 513 pi._arg0 = i._arg0;
jhnwkmn 0:97a4f8cc534c 514 pi._arg1 = pi._arg1;
jhnwkmn 0:97a4f8cc534c 515 pi._arg2 = (unsigned char)aat;
jhnwkmn 0:97a4f8cc534c 516 pi._arg3 = MAX_FUNC_STACKSIZE;
jhnwkmn 0:97a4f8cc534c 517 return;
jhnwkmn 0:97a4f8cc534c 518 }
jhnwkmn 0:97a4f8cc534c 519 }
jhnwkmn 0:97a4f8cc534c 520 break;
jhnwkmn 0:97a4f8cc534c 521 case _OP_MOVE:
jhnwkmn 0:97a4f8cc534c 522 switch(pi.op) {
jhnwkmn 0:97a4f8cc534c 523 case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW:
jhnwkmn 0:97a4f8cc534c 524 case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD:
jhnwkmn 0:97a4f8cc534c 525
jhnwkmn 0:97a4f8cc534c 526 if(pi._arg0 == i._arg1)
jhnwkmn 0:97a4f8cc534c 527 {
jhnwkmn 0:97a4f8cc534c 528 pi._arg0 = i._arg0;
jhnwkmn 0:97a4f8cc534c 529 _optimization = false;
jhnwkmn 0:97a4f8cc534c 530 //_result_elimination = false;
jhnwkmn 0:97a4f8cc534c 531 return;
jhnwkmn 0:97a4f8cc534c 532 }
jhnwkmn 0:97a4f8cc534c 533 }
jhnwkmn 0:97a4f8cc534c 534
jhnwkmn 0:97a4f8cc534c 535 if(pi.op == _OP_MOVE)
jhnwkmn 0:97a4f8cc534c 536 {
jhnwkmn 0:97a4f8cc534c 537 pi.op = _OP_DMOVE;
jhnwkmn 0:97a4f8cc534c 538 pi._arg2 = i._arg0;
jhnwkmn 0:97a4f8cc534c 539 pi._arg3 = (unsigned char)i._arg1;
jhnwkmn 0:97a4f8cc534c 540 return;
jhnwkmn 0:97a4f8cc534c 541 }
jhnwkmn 0:97a4f8cc534c 542 break;
jhnwkmn 0:97a4f8cc534c 543 case _OP_LOAD:
jhnwkmn 0:97a4f8cc534c 544 if(pi.op == _OP_LOAD && i._arg1 < 256) {
jhnwkmn 0:97a4f8cc534c 545 pi.op = _OP_DLOAD;
jhnwkmn 0:97a4f8cc534c 546 pi._arg2 = i._arg0;
jhnwkmn 0:97a4f8cc534c 547 pi._arg3 = (unsigned char)i._arg1;
jhnwkmn 0:97a4f8cc534c 548 return;
jhnwkmn 0:97a4f8cc534c 549 }
jhnwkmn 0:97a4f8cc534c 550 break;
jhnwkmn 0:97a4f8cc534c 551 case _OP_EQ:case _OP_NE:
jhnwkmn 0:97a4f8cc534c 552 if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
jhnwkmn 0:97a4f8cc534c 553 {
jhnwkmn 0:97a4f8cc534c 554 pi.op = i.op;
jhnwkmn 0:97a4f8cc534c 555 pi._arg0 = i._arg0;
jhnwkmn 0:97a4f8cc534c 556 pi._arg1 = pi._arg1;
jhnwkmn 0:97a4f8cc534c 557 pi._arg2 = i._arg2;
jhnwkmn 0:97a4f8cc534c 558 pi._arg3 = MAX_FUNC_STACKSIZE;
jhnwkmn 0:97a4f8cc534c 559 return;
jhnwkmn 0:97a4f8cc534c 560 }
jhnwkmn 0:97a4f8cc534c 561 break;
jhnwkmn 0:97a4f8cc534c 562 case _OP_LOADNULLS:
jhnwkmn 0:97a4f8cc534c 563 if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
jhnwkmn 0:97a4f8cc534c 564
jhnwkmn 0:97a4f8cc534c 565 pi._arg1 = pi._arg1 + 1;
jhnwkmn 0:97a4f8cc534c 566 pi.op = _OP_LOADNULLS;
jhnwkmn 0:97a4f8cc534c 567 return;
jhnwkmn 0:97a4f8cc534c 568 }
jhnwkmn 0:97a4f8cc534c 569 break;
jhnwkmn 0:97a4f8cc534c 570 case _OP_LINE:
jhnwkmn 0:97a4f8cc534c 571 if(pi.op == _OP_LINE) {
jhnwkmn 0:97a4f8cc534c 572 _instructions.pop_back();
jhnwkmn 0:97a4f8cc534c 573 _lineinfos.pop_back();
jhnwkmn 0:97a4f8cc534c 574 }
jhnwkmn 0:97a4f8cc534c 575 break;
jhnwkmn 0:97a4f8cc534c 576 }
jhnwkmn 0:97a4f8cc534c 577 }
jhnwkmn 0:97a4f8cc534c 578 _optimization = true;
jhnwkmn 0:97a4f8cc534c 579 _instructions.push_back(i);
jhnwkmn 0:97a4f8cc534c 580 }
jhnwkmn 0:97a4f8cc534c 581
jhnwkmn 0:97a4f8cc534c 582 SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
jhnwkmn 0:97a4f8cc534c 583 {
jhnwkmn 0:97a4f8cc534c 584 SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
jhnwkmn 0:97a4f8cc534c 585 _table(_strings)->NewSlot(ns,(SQInteger)1);
jhnwkmn 0:97a4f8cc534c 586 return ns;
jhnwkmn 0:97a4f8cc534c 587 }
jhnwkmn 0:97a4f8cc534c 588
jhnwkmn 0:97a4f8cc534c 589 SQObject SQFuncState::CreateTable()
jhnwkmn 0:97a4f8cc534c 590 {
jhnwkmn 0:97a4f8cc534c 591 SQObjectPtr nt(SQTable::Create(_sharedstate,0));
jhnwkmn 0:97a4f8cc534c 592 _table(_strings)->NewSlot(nt,(SQInteger)1);
jhnwkmn 0:97a4f8cc534c 593 return nt;
jhnwkmn 0:97a4f8cc534c 594 }
jhnwkmn 0:97a4f8cc534c 595
jhnwkmn 0:97a4f8cc534c 596 SQFunctionProto *SQFuncState::BuildProto()
jhnwkmn 0:97a4f8cc534c 597 {
jhnwkmn 0:97a4f8cc534c 598
jhnwkmn 0:97a4f8cc534c 599 SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(),
jhnwkmn 0:97a4f8cc534c 600 _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
jhnwkmn 0:97a4f8cc534c 601 _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
jhnwkmn 0:97a4f8cc534c 602
jhnwkmn 0:97a4f8cc534c 603 SQObjectPtr refidx,key,val;
jhnwkmn 0:97a4f8cc534c 604 SQInteger idx;
jhnwkmn 0:97a4f8cc534c 605
jhnwkmn 0:97a4f8cc534c 606 f->_stacksize = _stacksize;
jhnwkmn 0:97a4f8cc534c 607 f->_sourcename = _sourcename;
jhnwkmn 0:97a4f8cc534c 608 f->_bgenerator = _bgenerator;
jhnwkmn 0:97a4f8cc534c 609 f->_name = _name;
jhnwkmn 0:97a4f8cc534c 610
jhnwkmn 0:97a4f8cc534c 611 while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
jhnwkmn 0:97a4f8cc534c 612 f->_literals[_integer(val)]=key;
jhnwkmn 0:97a4f8cc534c 613 refidx=idx;
jhnwkmn 0:97a4f8cc534c 614 }
jhnwkmn 0:97a4f8cc534c 615
jhnwkmn 0:97a4f8cc534c 616 for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
jhnwkmn 0:97a4f8cc534c 617 for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
jhnwkmn 0:97a4f8cc534c 618 for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
jhnwkmn 0:97a4f8cc534c 619 for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl];
jhnwkmn 0:97a4f8cc534c 620 for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni];
jhnwkmn 0:97a4f8cc534c 621 for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd];
jhnwkmn 0:97a4f8cc534c 622
jhnwkmn 0:97a4f8cc534c 623 memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
jhnwkmn 0:97a4f8cc534c 624
jhnwkmn 0:97a4f8cc534c 625 f->_varparams = _varparams;
jhnwkmn 0:97a4f8cc534c 626
jhnwkmn 0:97a4f8cc534c 627 return f;
jhnwkmn 0:97a4f8cc534c 628 }
jhnwkmn 0:97a4f8cc534c 629
jhnwkmn 0:97a4f8cc534c 630 SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
jhnwkmn 0:97a4f8cc534c 631 {
jhnwkmn 0:97a4f8cc534c 632 SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
jhnwkmn 0:97a4f8cc534c 633 new (child) SQFuncState(ss,this,_errfunc,_errtarget);
jhnwkmn 0:97a4f8cc534c 634 _childstates.push_back(child);
jhnwkmn 0:97a4f8cc534c 635 return child;
jhnwkmn 0:97a4f8cc534c 636 }
jhnwkmn 0:97a4f8cc534c 637
jhnwkmn 0:97a4f8cc534c 638 void SQFuncState::PopChildState()
jhnwkmn 0:97a4f8cc534c 639 {
jhnwkmn 0:97a4f8cc534c 640 SQFuncState *child = _childstates.back();
jhnwkmn 0:97a4f8cc534c 641 sq_delete(child,SQFuncState);
jhnwkmn 0:97a4f8cc534c 642 _childstates.pop_back();
jhnwkmn 0:97a4f8cc534c 643 }
jhnwkmn 0:97a4f8cc534c 644
jhnwkmn 0:97a4f8cc534c 645 SQFuncState::~SQFuncState()
jhnwkmn 0:97a4f8cc534c 646 {
jhnwkmn 0:97a4f8cc534c 647 while(_childstates.size() > 0)
jhnwkmn 0:97a4f8cc534c 648 {
jhnwkmn 0:97a4f8cc534c 649 PopChildState();
jhnwkmn 0:97a4f8cc534c 650 }
jhnwkmn 0:97a4f8cc534c 651 }
jhnwkmn 0:97a4f8cc534c 652
jhnwkmn 0:97a4f8cc534c 653 #endif