public LuaFile Compile(Ast.Chunk c, string name) { file = new LuaFile(); block = new Block(); block.Chunk.Name = name; block.Chunk.ArgumentCount = 0; block.Chunk.Vararg = 2; DoChunk(c); file.Main = block.Chunk; file.Main.ArgumentCount = 0; file.Main.Vararg = 2; file.Main.UpvalueCount = file.Main.Upvalues.Count; bool addRet = file.Main.Instructions.Count == 0; if (addRet == false) addRet = file.Main.Instructions[file.Main.Instructions.Count - 1].Opcode != Instruction.LuaOpcode.RETURN; if (addRet) { Instruction ret = new Instruction("RETURN"); ret.A = 0; ret.B = 1; ret.C = 0; file.Main.Instructions.Add(ret); } return file; }
public static Func <double, string> GetNumberTypeConvertTo(LuaFile file) { string nt = LuaNumberID[file.NumberSize.ToString() + (file.IsFloatingPointNumbers ? "0" : "1")]; if (nt == null) { throw new Exception("Unable to determine Number type"); } return(ConvertTo[nt]); }
/// <summary> /// Returns a decompiled chunk, with info based upon a default LuaFile /// </summary> /// <param name="chunk"></param> /// <returns></returns> public static Chunk DisassembleChunk(string c) { chunk = c; index = 0; file = new LuaFile(); loadNumber = PlatformConfig.GetNumberTypeConvertFrom(file); if (chunk == null || string.IsNullOrWhiteSpace(chunk)) { throw new Exception("chunk is empty"); } return(ReadFunction()); }
/// <summary> /// Returns a disassembled LuaFile /// </summary> /// <param name="c"></param> /// <returns></returns> public static LuaFile Disassemble(string c) { chunk = c; index = 0; file = new LuaFile(); Disassembler.loadNumber = null; if (chunk == null || string.IsNullOrWhiteSpace(chunk)) { throw new Exception("chunk is empty"); } file.Identifier = GetString(4); // \027Lua if (file.Identifier != (char)27 + "Lua") { throw new Exception("Not a valid Lua bytecode chunk"); } file.Version = ReadInt8(); // 0x51 if (file.Version != 0x51) { throw new Exception(string.Format("Invalid bytecode version, 0x51 expected, got 0x{0:X}", file.Version)); } int fmt = ReadInt8(); file.Format = fmt == 0 ? Format.Official : Format.Unofficial; file.FormatNumber = fmt; if (file.Format == Format.Unofficial) { throw new Exception("Unknown binary chunk format"); } file.BigEndian = ReadInt8() == 0; file.IntegerSize = ReadInt8(); file.SizeT = ReadInt8(); file.InstructionSize = ReadInt8(); file.NumberSize = ReadInt8(); file.IsFloatingPointNumbers = ReadInt8() == 0; loadNumber = PlatformConfig.GetNumberTypeConvertFrom(file); if (file.InstructionSize != 4) { throw new Exception("Unsupported instruction size '" + file.InstructionSize + "', expected '4'"); } file.Main = ReadFunction(); return(file); }
public string Compile(LuaFile file) { Func<double, string> DumpNumber = PlatformConfig.GetNumberTypeConvertTo(file); Func<int, string> DumpInt = new Func<int, string>(delegate(int num) { string v = ""; for (int i = 0; i < file.IntegerSize; i++) { v += (char)(num % 256); num = (int)Math.Floor((double)num / 256); } return v; }); Func<string, string> DumpString = new Func<string, string>(delegate(string s) { int len = file.SizeT; //if (s == null || s.Length == 0) // return "\0".Repeat(len); //else //{ string l = DumpInt(s.Length + 1); return l + s + "\0"; //} }); string c = ""; c += DumpString(Name); c += DumpInt((int)FirstLine); c += DumpInt((int)LastLine); c += (char)UpvalueCount; c += (char)ArgumentCount; c += (char)Vararg; c += (char)MaxStackSize; // Instructions c += DumpInt(Instructions.Count); foreach (Instruction i in Instructions) c += DumpBinary.Opcode(i); // Constants c += DumpInt(Constants.Count); foreach (Constant cnst in Constants) { if (cnst.Type == ConstantType.Nil) c += (char)0; else if (cnst.Type == ConstantType.Bool) { c += (char)1; c += (char)((bool)cnst.Value ? 1 : 0); } else if (cnst.Type == ConstantType.Number) { c += (char)3; c += DumpNumber((double)cnst.Value); } else if (cnst.Type == ConstantType.String) { c += (char)4; c += DumpString((string)cnst.Value); } else throw new Exception("Invalid constant type: " + cnst.Type.ToString()); } // Protos c += DumpInt(Protos.Count); foreach (Chunk ch in Protos) c += ch.Compile(file); // Line Numbers int ln = 0; for (int i = 0; i < Instructions.Count; i++) if (Instructions[i].LineNumber != 0) ln = i; c += DumpInt(ln); for (int i = 0; i < ln; i++) c += DumpInt(Instructions[i].LineNumber); //c += DumpInt(Instructions.Count); //foreach (Instruction i in Instructions) // c += DumpInt(i.LineNumber); // Locals c += DumpInt(Locals.Count); foreach (Local l in Locals) { c += DumpString(l.Name); c += DumpInt(l.StartPC); c += DumpInt(l.EndPC); } // Upvalues c += DumpInt(Upvalues.Count); foreach (Upvalue v in Upvalues) c += DumpString(v.Name); return c; }
public static string Decompile(LuaFile file) { LASMDecompiler.file = file; decompile(file.Main); return s; }
/// <summary> /// Returns a decompiled chunk, with info based upon a default LuaFile /// </summary> /// <param name="chunk"></param> /// <returns></returns> public static Chunk DisassembleChunk(string c) { chunk = c; index = 0; file = new LuaFile(); loadNumber = PlatformConfig.GetNumberTypeConvertFrom(file); if (chunk == null || string.IsNullOrWhiteSpace(chunk)) throw new Exception("chunk is empty"); return ReadFunction(); }
/// <summary> /// Returns a disassembled LuaFile /// </summary> /// <param name="c"></param> /// <returns></returns> public static LuaFile Disassemble(string c) { chunk = c; index = 0; file = new LuaFile(); Disassembler.loadNumber = null; if (chunk == null || string.IsNullOrWhiteSpace(chunk)) throw new Exception("chunk is empty"); file.Identifier = GetString(4); // \027Lua if (file.Identifier != (char)27 + "Lua") throw new Exception("Not a valid Lua bytecode chunk"); file.Version = ReadInt8(); // 0x51 if (file.Version != 0x51) throw new Exception(string.Format("Invalid bytecode version, 0x51 expected, got 0x{0:X}", file.Version)); int fmt = ReadInt8(); file.Format = fmt == 0 ? Format.Official : Format.Unofficial; file.FormatNumber = fmt; if (file.Format == Format.Unofficial) throw new Exception("Unknown binary chunk format"); file.BigEndian = ReadInt8() == 0; file.IntegerSize = ReadInt8(); file.SizeT = ReadInt8(); file.InstructionSize = ReadInt8(); file.NumberSize = ReadInt8(); file.IsFloatingPointNumbers = ReadInt8() == 0; loadNumber = PlatformConfig.GetNumberTypeConvertFrom(file); if (file.InstructionSize != 4) throw new Exception("Unsupported instruction size '" + file.InstructionSize + "', expected '4'"); file.Main = ReadFunction(); return file; }
public static Func<double, string> GetNumberTypeConvertTo(LuaFile file) { string nt = LuaNumberID[file.NumberSize.ToString() + (file.IsFloatingPointNumbers ? "0" : "1")]; if (nt == null) throw new Exception("Unable to determine Number type"); return ConvertTo[nt]; }
public string Compile(LuaFile file) { Func <double, string> DumpNumber = PlatformConfig.GetNumberTypeConvertTo(file); Func <int, string> DumpInt = new Func <int, string>(delegate(int num) { string v = ""; for (int i = 1; i < file.IntegerSize; i++) { v = v + (char)(num % 256); num = (int)Math.Floor((double)num / 256); } return(v); }); Func <string, string> DumpString = new Func <string, string>(delegate(string s) { int len = file.SizeT; if (s == null || s.Length == 0) { return("\0".Repeat(len)); } else { return(DumpInt(s.Length + 1) + s + "\0"); } }); string c = ""; c = c + DumpString(Name); c = c + DumpInt((int)FirstLine); c = c + DumpInt((int)LastLine); c = c + (char)UpvalueCount; c = c + (char)ArgumentCount; c = c + (char)Vararg; c = c + (char)MaxStackSize; // Instructions c = c + DumpInt(Instructions.Count); foreach (Instruction i in Instructions) { c = c + DumpBinary.Opcode(i); } // Constants c = c + DumpInt(Constants.Count); foreach (Constant cnst in Constants) { if (cnst.Type == ConstantType.Nil) { c = c + (char)0; } else if (cnst.Type == ConstantType.Bool) { c = c + (char)1; c = c + (char)((bool)cnst.Value ? 1 : 0); } else if (cnst.Type == ConstantType.Number) { c = c + (char)3; c = c + DumpNumber((long)cnst.Value); } else if (cnst.Type == ConstantType.String) { c = c + (char)4; c = c + DumpString((string)cnst.Value); } else { throw new Exception("Invalid constant type: " + cnst.Type.ToString()); } } // Protos c = c + DumpInt(Protos.Count); foreach (Chunk ch in Protos) { c = c + ch.Compile(file); } // Line Numbers c = c + DumpInt(Instructions.Count); foreach (Instruction i in Instructions) { c = c = DumpInt(i.LineNumber); } // Locals c = c + DumpInt(Locals.Count); foreach (Local l in Locals) { c = c + DumpString(l.Name); c = c + DumpInt(l.StartPC); c = c + DumpInt(l.EndPC); } // Upvalues c = c + DumpInt(Upvalues.Count); foreach (Upvalue v in Upvalues) { c = c + DumpString(v.Name); } return(c); }
public LuaFile Parse(string t) { this.text = t; file = new LuaFile(); index = 0; lineNumber = 1; func = file.Main; file.Main.Vararg = 2; file.Main.Name = "LASM Chunk"; funcStack = new Stack<Chunk>(); readWhitespace(); while (text.Length > index) { readWhitespace(); string line = ""; while (true) { if (text.Length <= index) break; char c = text[index]; if (c == '\r') { index++; if (text[index] == '\n') index++; break; } else if (c == '\n') { index++; break; } else line += c; index++; } line = line.Trim(); if (string.IsNullOrEmpty(line) || line[0] == ';') { } // do nothing. else if (line[0] == '.') parseControl(line); else { Instruction op = parseOpcode(line); op.LineNumber = lineNumber; func.Instructions.Add(op); } lineNumber++; } Instruction instr1 = func.Instructions.Count > 0 ? func.Instructions[func.Instructions.Count - 1] : null; Instruction instr2 = new Instruction("RETURN"); instr2.A = 0; instr2.B = 1; instr2.C = 0; //getmetatable(func.Instructions).__newindex(func.Instructions, func.Instructions.Count, op) if (instr1 == null || instr1.Opcode != Instruction.LuaOpcode.RETURN) func.Instructions.Add(instr2); return file; }
public LuaFile Parse(string t) { this.text = t; file = new LuaFile(); index = 0; lineNumber = 1; func = file.Main; file.Main.Vararg = 2; file.Main.Name = "LASM Chunk"; funcStack = new Stack <Chunk>(); readWhitespace(); while (text.Length > index) { readWhitespace(); string line = ""; while (true) { if (text.Length <= index) { break; } char c = text[index]; if (c == '\r') { index++; if (text[index] == '\n') { index++; } break; } else if (c == '\n') { index++; break; } else { line += c; } index++; } line = line.Trim(); if (string.IsNullOrEmpty(line) || line[0] == ';') { } // do nothing. else if (line[0] == '.') { parseControl(line); } else { Instruction op = parseOpcode(line); op.LineNumber = lineNumber; func.Instructions.Add(op); } lineNumber++; } Instruction instr1 = func.Instructions.Count > 0 ? func.Instructions[func.Instructions.Count - 1] : null; Instruction instr2 = new Instruction("RETURN"); instr2.A = 0; instr2.B = 1; instr2.C = 0; //getmetatable(func.Instructions).__newindex(func.Instructions, func.Instructions.Count, op) if (instr1 == null || instr1.Opcode != Instruction.LuaOpcode.RETURN) { func.Instructions.Add(instr2); } return(file); }