private void KName(LuaProto proto, int pc, int c, out string name) { if (Instruction.ISK(c)) // is `c' a constant { var val = proto.K[Instruction.INDEXK(c)]; if (val.V.TtIsString()) // literal constant? { name = val.V.SValue(); return; } // else no reasonable name found } else // `c' is a register { string what = GetObjName(proto, pc, c, out name); if (what == "constant") // found a constant name { return; // `name' already filled } // else no reasonable name found } name = "?"; // no reasonable name found }
public static void ListingToFile( LuaProto proto, string filename ) { using( var writer = new StreamWriter( filename ) ) { _ListFunc( proto, (output) => { // Debug.Log( output ); writer.Write( output ); }); } }
public static void ListingToFile(LuaProto proto, string filename) { using (var writer = new StreamWriter(filename)) { _ListFunc(proto, (output) => { // Debug.Log( output ); writer.Write(output); }); } }
public LuaLClosureValue(LuaProto p) { Proto = p; Upvals = new LuaUpvalue[p.Upvalues.Count]; for (int i = 0; i < p.Upvalues.Count; ++i) { Upvals[i] = new LuaUpvalue(); } }
private static void _ListFunc(LuaProto p, ListFuncDelegate outputEvent) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); string s = (p.Source != null) ? p.Source : "=?"; if (s[0] == '@' || s[0] == '=') { s = s.Substring(1); } else if ((int)s[0] == 27) { s = "(bstring)"; } else { s = "(string)"; } sb.Append(string.Format("{0} <{1}:{2},{3}> ({4} instructions)", p.LineDefined == 0 ? "main" : "function", s, p.LineDefined, p.LastLineDefined, p.Code.Count)).Append("\n"); sb.Append(string.Format( "{0}{1} params, {2} slots, {3} upvalue, {4} locals, {5} constants, {6} functions", p.NumParams, p.IsVarArg ? "+" : "", p.MaxStackSize, p.Upvalues.Count, p.LocVars.Count, p.K.Count, p.P.Count)).Append("\n"); for (int i = 0; i < p.Code.Count; ++i) { var ins = p.Code[i]; var line = p.LineInfo[i]; sb.Append((i + 1).ToString()).Append("\t") .Append("[" + line + "]").Append("\t") .Append(ins.ToString()).Append("\t") .Append("; ").Append(line).Append("\n"); } if (outputEvent != null) { outputEvent(sb.ToString()); } //foreach( var child in p.P ) for (int i = 0; i < p.P.Count; i++) { //_ListFunc( child, outputEvent ); _ListFunc(p.P[i], outputEvent); } }
protected override void SetHeader(LuaProto Pr) { for (int S = 0; S < LuaSignature.Length; S++) { DumpByte(LuaSignature[S]); } DumpByte(Pr.Version); for (int S = 0; S < Pr.Header.Length; S++) { DumpByte(Pr.Header[S]); } }
protected override void Ser(LuaProto Pr) { DumpString(Pr.Name); DumpInt(Pr.LineBegin); // Start DumpInt(Pr.LineEnd); // End DumpByte(Pr.Nups); DumpByte(Pr.Numparams); DumpByte(Pr.Vararg); DumpByte(Pr.Stack); DumpInstructions(Pr.Instructs); DumpConstants(Pr.Consts); DumpProtos(Pr.Protos); DumpLines(Pr.Lines); DumpLocals(Pr.Locals); DumpUpvalues(Pr.Upvalues); }
public static void DumpingToFile(LuaProto proto, string filename, bool strip) { using (var writer = new BinaryWriter(File.Open( filename, FileMode.Create))) { LuaWriter writeFunc = delegate(byte[] bytes, int start, int length) { try { writer.Write(bytes, start, length); return(DumpStatus.OK); } catch (Exception) { return(DumpStatus.ERROR); } }; DumpState.Dump(proto, writeFunc, strip); } }
public static void DumpingToFile( LuaProto proto, string filename, bool strip ) { using( var writer = new BinaryWriter( File.Open( filename, FileMode.Create ) ) ) { LuaWriter writeFunc = delegate(byte[] bytes, int start, int length) { try { writer.Write( bytes, start, length ); return DumpStatus.OK; } catch( Exception ) { return DumpStatus.ERROR; } }; DumpState.Dump( proto, writeFunc, strip ); } }
private string GetObjName(LuaProto proto, int lastpc, int reg, out string name) { name = F_GetLocalName(proto, reg + 1, lastpc); if (name != null) // is a local? { return("local"); } // else try symbolic execution var pc = FindSetReg(proto, lastpc, reg); if (pc != -1) { var ins = proto.Code[pc]; var op = ins.GET_OPCODE(); switch (op) { case OpCode.OP_MOVE: { var b = ins.GETARG_B(); // move from `b' to `a' if (b < ins.GETARG_A()) { return(GetObjName(proto, pc, b, out name)); } break; } case OpCode.OP_GETTABUP: case OpCode.OP_GETTABLE: { var k = ins.GETARG_C(); var t = ins.GETARG_B(); var vn = (op == OpCode.OP_GETTABLE) ? F_GetLocalName(proto, t + 1, pc) : UpvalName(proto, t); KName(proto, pc, k, out name); return((vn == LuaDef.LUA_ENV) ? "global" : "field"); } case OpCode.OP_GETUPVAL: { name = UpvalName(proto, ins.GETARG_B()); return("upvalue"); } case OpCode.OP_LOADK: case OpCode.OP_LOADKX: { var b = (op == OpCode.OP_LOADK) ? ins.GETARG_Bx() : proto.Code[pc + 1].GETARG_Ax(); var val = proto.K[b]; if (val.V.TtIsString()) { name = val.V.SValue(); return("constant"); } break; } case OpCode.OP_SELF: { var k = ins.GETARG_C(); // key index KName(proto, pc, k, out name); return("method"); } default: break; // go through to return null } } return(null); // could not find reasonable name }
private int FindSetReg(LuaProto proto, int lastpc, int reg) { var setreg = -1; // keep last instruction that changed `reg' for (int pc = 0; pc < lastpc; ++pc) { var ins = proto.Code[pc]; var op = ins.GET_OPCODE(); var a = ins.GETARG_A(); switch (op) { case OpCode.OP_LOADNIL: { var b = ins.GETARG_B(); // set registers from `a' to `a+b' if (a <= reg && reg <= a + b) { setreg = pc; } break; } case OpCode.OP_TFORCALL: { // effect all regs above its base if (reg >= a + 2) { setreg = pc; } break; } case OpCode.OP_CALL: case OpCode.OP_TAILCALL: { // effect all registers above base if (reg >= a) { setreg = pc; } break; } case OpCode.OP_JMP: { var b = ins.GETARG_sBx(); var dest = pc + 1 + b; // jump is forward and do not skip `lastpc' if (pc < dest && dest <= lastpc) { pc += b; // do the jump } break; } case OpCode.OP_TEST: { // jumped code can change `a' if (reg == a) { setreg = pc; } break; } default: { // any instruction that set A if (Coder.TestAMode(op) && reg == a) { setreg = pc; } break; } } } return(setreg); }
private string GetObjName( LuaProto proto, int lastpc, int reg, out string name ) { name = F_GetLocalName( proto, reg+1, lastpc ); if( name != null ) // is a local? return "local"; // else try symbolic execution var pc = FindSetReg( proto, lastpc, reg ); if( pc != -1 ) { var ins = proto.Code[pc]; var op = ins.GET_OPCODE(); switch( op ) { case OpCode.OP_MOVE: { var b = ins.GETARG_B(); // move from `b' to `a' if( b < ins.GETARG_A() ) return GetObjName(proto, pc, b, out name); break; } case OpCode.OP_GETTABUP: case OpCode.OP_GETTABLE: { var k = ins.GETARG_C(); var t = ins.GETARG_B(); var vn = (op == OpCode.OP_GETTABLE) ? F_GetLocalName( proto, t+1, pc ) : UpvalName( proto, t ); KName( proto, pc, k, out name ); return (vn == LuaDef.LUA_ENV) ? "global" : "field"; } case OpCode.OP_GETUPVAL: { name = UpvalName( proto, ins.GETARG_B() ); return "upvalue"; } case OpCode.OP_LOADK: case OpCode.OP_LOADKX: { var b = (op == OpCode.OP_LOADK) ? ins.GETARG_Bx() : proto.Code[pc+1].GETARG_Ax(); var val = proto.K[b]; if( val.IsString ) { name = (val as LuaString).Value; return "constant"; } break; } case OpCode.OP_SELF: { var k = ins.GETARG_C(); // key index KName( proto, pc, k, out name ); return "method"; } default: break; // go through to return null } } return null; // could not find reasonable name }
private string UpvalName(LuaProto p, int uv) { // TODO return("(UpvalName:NotImplemented)"); }
private static void _ListFunc( LuaProto p, ListFuncDelegate outputEvent ) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); string s = (p.Source != null) ? p.Source : "=?"; if( s[0] == '@' || s[0] == '=' ) s = s.Substring(1); else if( (int)s[0] == 27 ) s = "(bstring)"; else s = "(string)"; sb.Append( string.Format("{0} <{1}:{2},{3}> ({4} instructions)", p.LineDefined==0 ? "main" : "function", s, p.LineDefined, p.LastLineDefined, p.Code.Count) ).Append("\n"); sb.Append( string.Format( "{0}{1} params, {2} slots, {3} upvalue, {4} locals, {5} constants, {6} functions", p.NumParams, p.IsVarArg ? "+" : "", p.MaxStackSize, p.Upvalues.Count, p.LocVars.Count, p.K.Count, p.P.Count ) ).Append("\n"); for( int i=0; i<p.Code.Count; ++i ) { var ins = p.Code[i]; var line = p.LineInfo[i]; sb.Append( (i+1).ToString() ).Append( "\t" ) .Append( "["+line+"]" ).Append( "\t" ) .Append( ins.ToString() ).Append( "\t" ) .Append( "; " ).Append(line).Append("\n"); } if( outputEvent != null ) outputEvent( sb.ToString() ); foreach( var child in p.P ) { _ListFunc( child, outputEvent ); } }
private void KName( LuaProto proto, int pc, int c, out string name ) { if( Instruction.ISK(c) ) { // is `c' a constant var val = proto.K[Instruction.INDEXK(c)]; if( val.IsString ) { // literal constant? name = (val as LuaString).Value; return; } // else no reasonable name found } else { // `c' is a register string what = GetObjName( proto, pc, c, out name ); if( what == "constant" ) { // found a constant name return; // `name' already filled } // else no reasonable name found } name = "?"; // no reasonable name found }
private string UpvalName( LuaProto p, int uv ) { // TODO return "(UpvalName:NotImplemented)"; }
private int FindSetReg( LuaProto proto, int lastpc, int reg ) { var setreg = -1; // keep last instruction that changed `reg' for( int pc=0; pc<lastpc; ++pc ) { var ins = proto.Code[pc]; var op = ins.GET_OPCODE(); var a = ins.GETARG_A(); switch( op ) { case OpCode.OP_LOADNIL: { var b = ins.GETARG_B(); // set registers from `a' to `a+b' if( a <= reg && reg <= a + b ) setreg = pc; break; } case OpCode.OP_TFORCALL: { // effect all regs above its base if( reg >= a+2 ) setreg = pc; break; } case OpCode.OP_CALL: case OpCode.OP_TAILCALL: { // effect all registers above base if( reg >= a ) setreg = pc; break; } case OpCode.OP_JMP: { var b = ins.GETARG_sBx(); var dest = pc + 1 + b; // jump is forward and do not skip `lastpc' if( pc < dest && dest <= lastpc ) pc += b; // do the jump break; } case OpCode.OP_TEST: { // jumped code can change `a' if( reg == a ) setreg = pc; break; } default: { // any instruction that set A if( Coder.TestAMode( op ) && reg == a ) { setreg = pc; } break; } } } return setreg; }