示例#1
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());
 }
示例#2
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);
        }
示例#3
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);
        }