Beispiel #1
0
        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;
        }
Beispiel #2
0
        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]);
        }
Beispiel #3
0
 /// <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());
 }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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;
        }
Beispiel #6
0
public static string Decompile(LuaFile file)
{
    LASMDecompiler.file = file;
    decompile(file.Main);
    return s;
}
Beispiel #7
0
 /// <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();
 }
Beispiel #8
0
        /// <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;
        }
Beispiel #9
0
 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];
 }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 public static string Decompile(LuaFile file)
 {
     LASMDecompiler.file = file;
     decompile(file.Main);
     return s;
 }
Beispiel #12
0
        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;
        }
Beispiel #13
0
        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);
        }