// Stack unwinding due to error. internal string UnwindStackTrace() { StringBuilder s = new StringBuilder(); foreach (Frame frame in UnwoundFrames) { LuaValue function = Stack[frame.FrameBase]; if (function is LuaFunction) { LuaPrototype prototype = ((LuaFunction)function).Prototype; SourceSpan location = prototype.DebugInstructionSourceSpans[frame.InstructionPointer - 1]; s.AppendFormat(" at <unknown> in {0}:line {1}\n", location.Start.SourceName, location.Start.Line); } else { s.AppendFormat(" Frame: {0} {1} {2} {3}\n", frame.FrameBase, frame.ResultCount, frame.FramePointer, frame.InstructionPointer); } StackWatermark(frame.FrameBase); } UnwoundFrames.Clear(); return(s.ToString()); }
public LuaFunction(LuaPrototype p, LuaTable environment) { upVals = new UpVal[p.UpValCount]; prototype = p; if (environment != null) { Environment = environment; } else { Environment = LuaThread.CurrentThread.Environment; } }
public static LuaPrototype Load(BinaryReader r) { // Header. CheckSByte(r, 0x1B); // <esc> CheckSByte(r, 0x4C); // 'L' CheckSByte(r, 0x75); // 'u' CheckSByte(r, 0x61); // 'a' CheckSByte(r, 0x51); // Version 5.1 CheckSByte(r, 0x00); // Format 0 CheckSByte(r, 0x01); // Little-endian CheckSByte(r, 0x04); // sizeof( int ) CheckSByte(r, 0x04); // sizeof( size_t ) CheckSByte(r, 0x04); // sizeof( Instruction ) CheckSByte(r, 0x08); // sizeof( lua_Number ) CheckSByte(r, 0x00); // Floating-point // Function. LuaPrototype result = new LuaPrototype(); result.LoadPrototype(r); return(result); }
void LoadPrototype(BinaryReader r) { // Function information. DebugName = ReadString(r); DebugSourceSpan = new SourceSpan(DebugName, r.ReadInt32(), 0, r.ReadInt32(), 0); UpValCount = r.ReadByte(); ParameterCount = r.ReadByte(); IsVararg = r.ReadByte() != 0; StackSize = r.ReadByte(); // Instructions. int instructionsLength = r.ReadInt32(); Instructions = new Instruction[instructionsLength]; for (int instruction = 0; instruction < instructionsLength; ++instruction) { Instructions[instruction] = Instruction.FromUInt32(r.ReadUInt32()); } // Constants. int constantsLength = r.ReadInt32(); Constants = new LuaValue[constantsLength]; for (int constant = 0; constant < constantsLength; ++constant) { switch (r.ReadSByte()) { case LUA_TNIL: Constants[constant] = null; break; case LUA_TBOOLEAN: Constants[constant] = r.ReadSByte() != 0; break; case LUA_TNUMBER: double d = r.ReadDouble(); int i = (int)d; if ((double)i == d) { Constants[constant] = i; } else { Constants[constant] = d; } break; case LUA_TSTRING: Constants[constant] = ReadString(r); break; default: throw new FileLoadException(); } } // Prototypes. int prototypesLength = r.ReadInt32(); Prototypes = new LuaPrototype[prototypesLength]; for (int prototype = 0; prototype < prototypesLength; ++prototype) { Prototypes[prototype] = new LuaPrototype(); Prototypes[prototype].LoadPrototype(r); } // Debug information. int debugInstructionSourceSpansLength = r.ReadInt32(); DebugInstructionSourceSpans = new SourceSpan[debugInstructionSourceSpansLength]; for (int debugInstructionSourceSpan = 0; debugInstructionSourceSpan < debugInstructionSourceSpansLength; ++debugInstructionSourceSpan) { int line = r.ReadInt32(); DebugInstructionSourceSpans[debugInstructionSourceSpan] = new SourceSpan(DebugName, line, 0, line, 0); } int debugLocalsLength = r.ReadInt32(); DebugLocals = new Symbol[debugLocalsLength]; for (int debugLocal = 0; debugLocal < debugLocalsLength; ++debugLocal) { DebugLocals[debugLocal] = new Symbol(ReadString(r), r.ReadInt32(), r.ReadInt32()); } int debugUpValNamesLength = r.ReadInt32(); DebugUpValNames = new string[debugUpValNamesLength]; for (int debugUpValName = 0; debugUpValName < debugUpValNamesLength; ++debugUpValName) { DebugUpValNames[debugUpValName] = ReadString(r); } }
public void Disassemble(TextWriter o) { // Function signature. o.Write("function "); if (DebugName != null && DebugName != String.Empty) { o.Write(DebugName); } else { o.Write("x"); o.Write(GetHashCode().ToString("X")); } o.Write("("); if (ParameterCount > 0 || IsVararg) { o.Write(" "); bool bFirst = true; for (int i = 0; i < ParameterCount; ++i) { if (!bFirst) { o.Write(", "); } bFirst = false; o.Write(DebugLocals[i].Name); } if (IsVararg) { if (!bFirst) { o.Write(", "); } bFirst = false; o.Write("..."); } o.Write(" "); } o.WriteLine(")"); // Information. o.WriteLine(" -- {0} registers, {1} constants", StackSize, Constants.Length); // Upvals. if (UpValCount > 0) { o.Write(" -- upval "); bool bFirst = true; for (int i = 0; i < UpValCount; ++i) { if (!bFirst) { o.Write(", "); } bFirst = false; o.Write(DebugUpValNames[i]); } o.WriteLine(); } // Locals. if (DebugLocals.Length > ParameterCount) { o.Write(" -- local "); bool bFirst = true; for (int i = ParameterCount; i < DebugLocals.Length; ++i) { if (!bFirst) { o.Write(", "); } bFirst = false; o.Write(DebugLocals[i].Name); } o.WriteLine(); } // Instructions. for (int ip = 0; ip < Instructions.Length; ++ip) { ip = WriteInstruction(o, ip); if (Instructions[ip].Opcode == Opcode.Closure) { LuaPrototype closure = Prototypes[Instructions[ip].Bx]; for (int upval = 0; upval < closure.UpValCount; ++upval) { Instruction i = Instructions[ip + 1 + upval]; if (i.Opcode == Opcode.Move) { o.WriteLine(" local {0} {1}", upval, OperandString(Mode.R, i.B, ip)); } else if (i.Opcode == Opcode.GetUpVal) { o.WriteLine(" upval {0} {1}", upval, OperandString(Mode.U, i.B, ip)); } } ip += closure.UpValCount; } } // Final. o.WriteLine("end"); o.WriteLine(); // Other functions. for (int i = 0; i < Prototypes.Length; ++i) { Prototypes[i].Disassemble(o); } }
public LuaFunction(LuaPrototype p) : this(p, null) { }