Пример #1
0
 public Block(Block parent)
 {
     K = new K2Reg(this);
     //parent.PreviousBlock = this;
     this.PreviousBlock = parent;
     V = new Var2Reg(parent.V);
     Chunk = parent.Chunk;
 }
Пример #2
0
        static Chunk ReadFunction()
        {
            Chunk c = new Chunk();
            c.Name = ReadString();
            c.FirstLine = (uint)ReadInt32();
            c.LastLine = (ulong)ReadInt32();
            c.UpvalueCount = ReadInt8(); // Upvalues
            c.ArgumentCount = ReadInt8();
            c.Vararg = ReadInt8();
            c.MaxStackSize = (uint)ReadInt8();

            // Instructions
            long count = ReadInt32();
            for (int i = 0; i < count; i++)
            {
                uint op = (uint)ReadInt32();
                int opcode = (int)Lua.GET_OPCODE(op);
                //(int)Bit.Get(op, 1, 6);
                Instruction instr = Instruction.From(op);
                instr.Number = i;
                c.Instructions.Add(instr);
            }

            // Constants

            count = ReadInt32();
            for (int i = 0; i < count; i++)
            {
                Constant cnst = new Constant(0, null);
                int t = ReadInt8();

                cnst.Number = i;

                if (t == 0)
                {
                    cnst.Type = ConstantType.Nil;
                    cnst.Value = null;
                }
                else if (t == 1)
                {
                    cnst.Type = ConstantType.Bool;
                    cnst.Value = ReadInt8() != 0;
                }
                else if (t == 3)
                {
                    cnst.Type = ConstantType.Number;
                    cnst.Value = ReadNumber();
                }
                else if (t == 4)
                {
                    cnst.Type = ConstantType.String;
                    cnst.Value = ReadString();
                }
                c.Constants.Add(cnst);
            }

            // Protos

            count = ReadInt32();
            for (int i = 0; i < count; i++)
                c.Protos.Add(ReadFunction());

            // Line numbers
            count = ReadInt32();
            for (int i = 0; i < count; i++)
                c.Instructions[i].LineNumber = ReadInt32();

            // Locals
            count = ReadInt32();
            for (int i = 0; i < count; i++)
                c.Locals.Add(new Local(ReadString(), ReadInt32(), ReadInt32()));

            // Upvalues
            count = ReadInt32();
            for (int i = 0; i < count; i++)
                c.Upvalues.Add(new Upvalue(ReadString()));

            return c;
        }
Пример #3
0
 public LuaFile(Lua.Proto p)
 {
     Main = new Chunk(p);
 }
Пример #4
0
        static void decompile(Chunk chunk)
        {
            if (chunk != file.Main)
            {
                write("; Function " + chunk.Name);
                write(".func");
                indent = indent + 1;
            }
            else
                write("; Main code");

            write(".name \"" + chunk.Name + "\"");
            write(".options " + chunk.UpvalueCount + " " + chunk.ArgumentCount + " " + chunk.Vararg + " " + chunk.MaxStackSize);
            write("; Above contains: Upvalue count, Argument count, Vararg flag, Max Stack Size");
            write("");
            if (chunk.Constants.Count > 0)
            {
                write("; Constants");
                foreach (Constant c in chunk.Constants)
                {
                    if (c.Type == ConstantType.Nil)
                        write(".const nil");
                    else if (c.Type == ConstantType.Bool)
                        write(".const " + ((bool)c.Value ? "true" : "false"));
                    else if (c.Type == ConstantType.Number)
                        write(".const " + c.Value);
                    else if (c.Type == ConstantType.String)
                    {
                        // escape string
                        string v = "";
                        foreach (char c2 in (string)c.Value)
                        {
                            int ch = (int)c2;
                            char nC = '\0';
                            // other chars with values > 31 are '"' (34), '\' (92) and > 126
                            if (ch < 32 || ch == 34 || ch == 92 || ch > 126)
                            {
                                if (ch >= 7 && ch <= 13)
                                    nC = "abtnvfr".Substring(ch - 6, 1)[0];
                                else if (ch == 34 || ch == 92)
                                    nC = c2;
                                v = v + "\\" + nC;
                            }
                            else// 32 <= v <= 126 (NOT 255)
                                v = v + c2;
                        }
                        write(".const \"" + v + "\"");
                    }
                }
            }

            if (chunk.Locals.Count > 0)
            {
                write("; Locals");
                foreach (Local l in chunk.Locals)
                    write(".local " + l.Name);
            }

            if (chunk.Upvalues.Count > 0)
            {
                write("; Upvalues");
                foreach (Upvalue u in chunk.Upvalues)
                    write(".upval " + u.Name);
            }

            write("; Instructions");
            foreach (Instruction instr in chunk.Instructions)
            {

                if (instr.OpcodeType == OpcodeType.ABC)
                    write(instr.OpcodeName.ToLower() + " " + instr.A + " " + instr.B + " " + instr.C);
                else if (instr.OpcodeType == OpcodeType.ABx)
                    write(instr.OpcodeName.ToLower() + " " + instr.A + " " + instr.Bx);
                else if (instr.OpcodeType == OpcodeType.AsBx)
                    write(instr.OpcodeName.ToLower() + " " + instr.A + " " + instr.sBx);
            }

            if (chunk.Protos.Count > 0)
            {
                write("; Protos");
                write("");
                foreach (Chunk chunk2 in chunk.Protos)
                    decompile(chunk2);

            }

            if (chunk != file.Main)
            {
                indent--;
                write(".end");
            }
        }
Пример #5
0
 public Block()
 {
     Chunk = new Chunk();
     K = new K2Reg(this);
 }
Пример #6
0
        public static void VerifyChunk(Chunk c)
        {
            foreach (Instruction i in c.Instructions)
            {
                switch (i.Opcode)
                {
                    case Instruction.LuaOpcode.MOVE:
                        assert(i.C == 0, "MOVE.C must equal 0");
                        assert(i.A < c.MaxStackSize, "MOVE.A out of bounds");
                        assert(i.B < c.MaxStackSize, "MOVE.B out of bounds");
                        break;

                    case Instruction.LuaOpcode.LOADK:
                        assert(i.A < c.MaxStackSize, "LOADK.A out of bounds");
                        assert(i.Bx < c.Constants.Count, "LOADK.Bx out of bounds");
                        break;

                    case Instruction.LuaOpcode.LOADBOOL:
                        assert(i.A < c.MaxStackSize, "LOADBOOL.A out of bounds");
                        assert(i.B < 2, "LOADBOOL.B invalid value");
                        assert(i.C < 2, "LOADBOOL.C invalid value");
                        break;

                    case Instruction.LuaOpcode.LOADNIL:
                        assert(i.A < c.MaxStackSize, "LOADNIL.A out of bounds");
                        assert(i.B < c.MaxStackSize, "LOADNIL.B out of bounds");
                        break;

                    case Instruction.LuaOpcode.GETUPVAL:
                        assert(i.A < c.MaxStackSize, "GETUPVAL.A out of bounds");
                        assert(i.B < c.Upvalues.Count, "GETUPVAL.B out of bounds");
                        break;

                    case Instruction.LuaOpcode.GETGLOBAL:
                        break;

                    case Instruction.LuaOpcode.GETTABLE:
                        break;

                    case Instruction.LuaOpcode.SETGLOBAL:
                        break;

                    case Instruction.LuaOpcode.SETUPVAL:
                        break;

                    case Instruction.LuaOpcode.SETTABLE:
                        break;

                    case Instruction.LuaOpcode.NEWTABLE:
                        break;

                    case Instruction.LuaOpcode.SELF:
                        break;

                    case Instruction.LuaOpcode.ADD:
                        break;

                    case Instruction.LuaOpcode.SUB:
                        break;

                    case Instruction.LuaOpcode.MUL:
                        break;

                    case Instruction.LuaOpcode.DIV:
                        break;

                    case Instruction.LuaOpcode.MOD:
                        break;

                    case Instruction.LuaOpcode.POW:
                        break;

                    case Instruction.LuaOpcode.UNM:
                        break;

                    case Instruction.LuaOpcode.NOT:
                        break;

                    case Instruction.LuaOpcode.LEN:
                        break;

                    case Instruction.LuaOpcode.CONCAT:
                        break;

                    case Instruction.LuaOpcode.JMP:
                        break;

                    case Instruction.LuaOpcode.EQ:
                        break;

                    case Instruction.LuaOpcode.LT:
                        break;

                    case Instruction.LuaOpcode.LE:
                        break;

                    case Instruction.LuaOpcode.TEST:
                        break;

                    case Instruction.LuaOpcode.TESTSET:
                        break;

                    case Instruction.LuaOpcode.CALL:
                        break;

                    case Instruction.LuaOpcode.TAILCALL:
                        break;

                    case Instruction.LuaOpcode.RETURN:
                        break;

                    case Instruction.LuaOpcode.FORLOOP:
                        break;

                    case Instruction.LuaOpcode.FORPREP:
                        break;

                    case Instruction.LuaOpcode.TFORLOOP:
                        break;

                    case Instruction.LuaOpcode.SETLIST:
                        break;

                    case Instruction.LuaOpcode.CLOSE:
                        break;

                    case Instruction.LuaOpcode.CLOSURE:
                        break;

                    case Instruction.LuaOpcode.VARARG:
                        break;

                    default:
                        break;
                }
            }
        }
Пример #7
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;
        }
Пример #8
0
        void parseControl(string line)
        {
            string ll = line.ToLower();
            if (ll.Substring(0, 6) == ".const")
            {
                string l = line.Substring(6);
                l = l.Trim();
                object value = readValue(l);
                if (value == null)
                    func.Constants.Add(new Constant(ConstantType.Nil, null));
                else if (value is bool)
                    func.Constants.Add(new Constant(ConstantType.Bool, (bool)value));
                else if (value is double)
                    func.Constants.Add(new Constant(ConstantType.Number, (double)value));
                else if (value is string)
                    func.Constants.Add(new Constant(ConstantType.String, (string)value));
            }
            else if (ll.Substring(0, 5) == ".name")
            {
                /// Im lazy :P
                string l = line.Substring(5);
                l = l.Trim();
                if (l[0] == '"')
                    func.Name = (string)readValue(l);
                else
                    func.Name = l;
            }
            else if (ll.Substring(0, 8) == ".options")
            {
                string l = line.Substring(8);
                l = l.Trim();
                List<int> nums = new List<int>();
                // Pattern matching time!
                Regex r = new Regex("\\d+");
                foreach (Match m in r.Matches(l))
                    nums.Add(int.Parse(m.Value));
                func.UpvalueCount = nums.Count > 0 ? nums[0] : func.UpvalueCount;
                func.ArgumentCount = nums.Count > 1 ? nums[1] : func.ArgumentCount;
                func.Vararg = nums.Count > 2 ? nums[2] : func.Vararg;
                func.MaxStackSize = nums.Count > 3 ? (uint)nums[3] : func.MaxStackSize;
            }
            else if (ll.Substring(0, 6) == ".local")
            {
                string l = line.Substring(6).Trim();
                if (l[0] == '"')
                    func.Locals.Add(new Local((string)readValue(l), 0, 0));
                else
                    func.Locals.Add(new Local(l, 0, 0));
            }
            else if (ll.Substring(0, 6) == ".upval")
            {
                string l = line.Substring(6).Trim();
                if (l[0] == '"')
                    func.Upvalues.Add(new Upvalue((string)readValue(l)));
                else
                    func.Upvalues.Add(new Upvalue(l));
            }
            else if (ll.Substring(0, 8) == ".upvalue")
            {
                string l = line.Substring(8).Trim();
                if (l[0] == '"')
                    func.Upvalues.Add(new Upvalue((string)readValue(l)));
                else
                    func.Upvalues.Add(new Upvalue(l));
            }
            else if (ll.Substring(0, 10) == ".stacksize")
            {
                string l = line.Substring(10).Trim();
                uint n = uint.Parse(l);
                func.MaxStackSize = n;
            }
            else if (ll.Substring(0, 13) == ".maxstacksize")
            {
                string l = line.Substring(13).Trim();
                uint n = uint.Parse(l);
                func.MaxStackSize = n;
            }
            else if (ll.Substring(0, 7) == ".vararg")
            {
                string l = line.Substring(7).Trim();
                int n = int.Parse(l);
                func.Vararg = n;
            }
            else if (ll.Substring(0, 9) == ".function")
            {
                string l = line.Substring(9).Trim();
                Chunk n = new Chunk();
                n.FirstLine = (uint)lineNumber;
                if (l.Length > 0)
                    if (l[0] == '"')
                        n.Name = (string)readValue(l);
                    else
                        n.Name = l;
                func.Protos.Add(n);
                funcStack.Push(func);
                func = n;
            }
            else if (ll.Substring(0, 5) == ".func")
            {
                string l = line.Substring(5).Trim();
                Chunk n = new Chunk();
                n.FirstLine = (uint)lineNumber;
                if (l.Length > 0)
                    if (l[0] == '"')
                        n.Name = (string)readValue(l);
                    else
                        n.Name = l;
                func.Protos.Add(n);
                funcStack.Push(func);
                func = n;
            }
            else if (ll.Substring(0, 4) == ".end")
            {
                Chunk f = funcStack.Pop();
                func.LastLine = (ulong)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;
                if (instr1 != null && instr1.Opcode == Instruction.LuaOpcode.RETURN)
                { } //func.Instructions.Add(instr2);
                else
                    func.Instructions.Add(instr2);

                func = f;
            }
            else
                throw new Exception("Invalid Control Label");
        }
Пример #9
0
        public static void VerifyChunk(Chunk c)
        {
            foreach (Instruction i in c.Instructions)
            {
                switch (i.Opcode)
                {
                case Instruction.LuaOp.MOVE:
                    assert(i.C == 0, "MOVE.C must equal 0");
                    assert(i.A < c.MaxStackSize, "MOVE.A out of bounds");
                    assert(i.B < c.MaxStackSize, "MOVE.B out of bounds");
                    break;

                case Instruction.LuaOp.LOADK:
                    assert(i.A < c.MaxStackSize, "LOADK.A out of bounds");
                    assert(i.Bx < c.Constants.Count, "LOADK.Bx out of bounds");
                    break;

                case Instruction.LuaOp.LOADBOOL:
                    assert(i.A < c.MaxStackSize, "LOADBOOL.A out of bounds");
                    assert(i.B < 2, "LOADBOOL.B invalid value");
                    assert(i.C < 2, "LOADBOOL.C invalid value");
                    break;

                case Instruction.LuaOp.LOADNIL:
                    assert(i.A < c.MaxStackSize, "LOADNIL.A out of bounds");
                    assert(i.B < c.MaxStackSize, "LOADNIL.B out of bounds");
                    break;

                case Instruction.LuaOp.GETUPVAL:
                    assert(i.A < c.MaxStackSize, "GETUPVAL.A out of bounds");
                    assert(i.B < c.Upvalues.Count, "GETUPVAL.B out of bounds");
                    break;

                case Instruction.LuaOp.GETGLOBAL:
                    break;

                case Instruction.LuaOp.GETTABLE:
                    break;

                case Instruction.LuaOp.SETGLOBAL:
                    break;

                case Instruction.LuaOp.SETUPVAL:
                    break;

                case Instruction.LuaOp.SETTABLE:
                    break;

                case Instruction.LuaOp.NEWTABLE:
                    break;

                case Instruction.LuaOp.SELF:
                    break;

                case Instruction.LuaOp.ADD:
                    break;

                case Instruction.LuaOp.SUB:
                    break;

                case Instruction.LuaOp.MUL:
                    break;

                case Instruction.LuaOp.DIV:
                    break;

                case Instruction.LuaOp.MOD:
                    break;

                case Instruction.LuaOp.POW:
                    break;

                case Instruction.LuaOp.UNM:
                    break;

                case Instruction.LuaOp.NOT:
                    break;

                case Instruction.LuaOp.LEN:
                    break;

                case Instruction.LuaOp.CONCAT:
                    break;

                case Instruction.LuaOp.JMP:
                    break;

                case Instruction.LuaOp.EQ:
                    break;

                case Instruction.LuaOp.LT:
                    break;

                case Instruction.LuaOp.LE:
                    break;

                case Instruction.LuaOp.TEST:
                    break;

                case Instruction.LuaOp.TESTSET:
                    break;

                case Instruction.LuaOp.CALL:
                    break;

                case Instruction.LuaOp.TAILCALL:
                    break;

                case Instruction.LuaOp.RETURN:
                    break;

                case Instruction.LuaOp.FORLOOP:
                    break;

                case Instruction.LuaOp.FORPREP:
                    break;

                case Instruction.LuaOp.TFORLOOP:
                    break;

                case Instruction.LuaOp.SETLIST:
                    break;

                case Instruction.LuaOp.CLOSE:
                    break;

                case Instruction.LuaOp.CLOSURE:
                    break;

                case Instruction.LuaOp.VARARG:
                    break;

                default:
                    break;
                }
            }
        }
Пример #10
0
 void dump(Chunk c)
 {
     //textBox2.Text += "; Chunk Name: " + c.Name + "\r\n";
     foreach (Instruction i in c.Instructions)
     {
         switch (i.OpcodeType)
         {
             case OpcodeType.ABC:
                 textBox2.Text += i.OpcodeName;
                 textBox2.Text += " " + i.A;
                 textBox2.Text += " " + i.B;
                 textBox2.Text += " " + i.C;
                 break;
             case OpcodeType.ABx:
                 textBox2.Text += i.OpcodeName;
                 textBox2.Text += " " + i.A;
                 textBox2.Text += " " + i.Bx;
                 break;
             case OpcodeType.AsBx:
                 textBox2.Text += i.OpcodeName;
                 textBox2.Text += " " + i.A;
                 textBox2.Text += " " + i.sBx;
                 break;
             default:
                 break;
         }
         textBox2.Text += "\r\n";
     }
     foreach (Chunk c2 in c.Protos)
     {
         //textBox2.Text += "\r\n";
         dump(c2);
     }
 }