The Squirrel interpreter. See http://www.squirrel-lang.org/
squirrel/sqfuncstate.cpp@3:7268a3ceaffc, 2014-12-16 (annotated)
- 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?
User | Revision | Line number | New 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 |