예제 #1
0
        public override void WriteLua(TLuaState state)
        {
            //handle writing variable declaration for a constant.
            switch (state.curII.originalOp)
            {
            case dis.OpCodes.KSHORT:
                HandleKShort(state);
                break;

            case dis.OpCodes.KCDATA:
                HandleKCData(state);
                break;

            case dis.OpCodes.KSTR:
                HandleKStr(state);
                break;

            case dis.OpCodes.KNUM:
                HandleKNum(state);
                break;

            case dis.OpCodes.KPRI:
                HandleKPri(state);
                break;

            case dis.OpCodes.KNIL:
                HandleKNil(state);
                break;
            }
        }
예제 #2
0
        private void HandleNot(TLuaState state)
        {
            //slot operation: slot[A] = !slot[D]
            if (state.slots[state.regs.regD].GetType() == typeof(CBool))
            {
                state.slots[state.regs.regA] = !(CBool)state.slots[state.regs.regD]; //bug here currently
            }
            else
            {
                throw new Exception("NOT declared on non-boolean operand.");
            }

            //source
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);
            var           src  = state.CheckGetVarName(state.regs.regD);

            state.CheckLocal(dst, ref line);
            line.Append(dst.Item2 + " = not " + src.Item2);
            line.AppendLine(" --NOT");
            state.decompLines.Add(line.ToString());

            //debugging
            //FileManager.WriteDebug(line.ToString());
        }
예제 #3
0
        private string HandleVV(TLuaState state, Tuple <bool, string> dst, string op)
        {
            var opC = state.CheckGetVarName(state.regs.regC);
            var opB = state.CheckGetVarName(state.regs.regB);

            return(opC.Item2 + op + opB.Item2);
        }
예제 #4
0
        //TODO: Handle if it is accessing a global OR a slot value.
        //Handle non-inline length operations.
        private void HandleLength(TLuaState state)
        {
            StringBuilder line = new StringBuilder();

            //Length operator # is indicated by registers A and D being the same as the previous line's constant's A register.
            //If these conditions are met, we inline a length operator and the constant.

            var pReg = state.prevII.registers;
            var dst  = state.CheckGetVarName(state.regs.regA);                                                       //should be the same destiation as the last line...

            if (pReg.regA == state.curII.registers.regA && state.curII.registers.regA == state.curII.registers.regD) //inline check
            {
                state.decompLines.RemoveAt(state.decompLines.Count - 1);                                             //remove last entry.

                line.Append("local " + dst.Item2 + " = " + "#" + state.slots[state.regs.regD].GetValue());           //might want to ensure that we are really working with a new variable declaration for length later...and we assume global constants table here too.

                //debugging
                //FileManager.WriteDebug(line.ToString());
            }
            else
            {
                state.CheckLocal(dst, ref line);
                line.Append(dst.Item2 + " = " + "#" + state.slots[state.regs.regD].GetValue());
            }
            line.AppendLine(" --LEN");
            state.decompLines.Add(line.ToString());
        }
예제 #5
0
        //We do not write any lua in this state. We just manage the other states.
        public override void WriteLua(TLuaState state)
        {
            backToBeginState = false;
            state.NextII();
            switch (state.curII.iROp)
            {
            case IRMap.Concat:
                new ConcatState(state);
                break;

            case IRMap.GTGet:     //global table get.
                new GTGetState(state);
                break;

            case IRMap.GetUV:     //get upvalue from upvalue table.
                new GetUVState(state);
                break;

            case IRMap.GTSet:
                new GTSetState(state);
                break;

            case IRMap.Unary:
                new UnaryState(state);
                break;

            case IRMap.Const:
                new ConstState(state);
                break;

            case IRMap.TGet:
                new TableGetState(state);
                break;

            case IRMap.MathNV:
            case IRMap.MathVN:
            case IRMap.MathVV:
                new ArithmeticState(state);
                break;

            case IRMap.EndOfIIStream:
                FileManager.ClearDebug();
                foreach (string line in state.decompLines)
                {
                    FileManager.WriteDebug(line);
                }
                state = null;
                break;

                #region Skip over these instructions
            case IRMap.Goto:           //we do not worry about jumps anymore since Cfg has the control flow recorded.
            default:
                new BeginState(state); //skip over...
                break;
                #endregion
            }
        }
예제 #6
0
        //TODO: troublemaking function...try to figure out if we need to access from slot index or from global table.
        //We also need to handle in-lining any LEN operators as well, but that is handled in LEN function.
        private void HandleKStr(TLuaState state)
        {
            //slot operation: slot[A] = string_G[D]
            state.slots[state.regs.regA] = state.string_G[state.regs.regD];

            //source
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);

            state.CheckLocal(dst, ref line);
            line.Append(dst.Item2 + " = " + "\"" + state.string_G[state.regs.regD].GetValue() + "\"");
            line.AppendLine(" --KSTR");
            state.decompLines.Add(line.ToString());

            //debugging
            //FileManager.WriteDebug(line.ToString());
        }
예제 #7
0
        //TODO: Handle Unsigned shorts as well if necessary.
        //Set A to 16 bit signed integer D.
        private void HandleKShort(TLuaState state)
        {
            //slot operation: slot[A] = num_G[D]
            state.slots[state.regs.regA] = new CShort((short)state.regs.regD);

            //source
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);

            state.CheckLocal(dst, ref line);
            line.Append(dst.Item2 + " = " + state.regs.regD);
            line.AppendLine(" --KSHORT");
            state.decompLines.Add(line.ToString());

            //debugging
            //FileManager.WriteDebug(line.ToString());
        }
예제 #8
0
        //More slot operations...these probably have lua translations associated with them...
        public override void WriteLua(TLuaState state) //write the code first then handle the back end in the constructor...
        {
            switch (state.curII.originalOp)
            {
            case dis.OpCodes.MOV:
                HandleMov(state);
                break;

            case dis.OpCodes.NOT:
                HandleNot(state);
                break;

            case dis.OpCodes.UNM:
                HandleUnaryMinus(state);
                break;

            case dis.OpCodes.LEN:
                HandleLength(state);
                break;
            }
        }
예제 #9
0
        public override void WriteLua(TLuaState state)
        {
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);
            var           b    = state.CheckGetVarName(state.regs.regB);

            state.CheckLocal(dst, ref line);
            line.Append(dst.Item2 + " = " + b.Item2 + " .. ");

            //concatenate variables in slots B->C INCLUSIVE -- Lua string concat operator is ".."
            for (int i = state.regs.regB + 1; i <= state.regs.regC; i++)
            {
                var nextCat = state.CheckGetVarName(i); //I guess we assume all the slots for the concat operation are loaded?
                line.Append(nextCat.Item2);
                if (i + 1 <= state.regs.regC)
                {
                    line.Append(" .. ");
                }
            }
            line.Append(" --CAT");
            state.decompLines.Add(line.ToString() + "\n");
        }
예제 #10
0
        private void HandleUnaryMinus(TLuaState state)
        {
            //slot operation: slot[A] = -slot[D] //TODO: Error checking
            if (state.slots[state.regs.regD].GetType() == typeof(CInt))
            {
                state.slots[state.regs.regA] = -(CInt)state.slots[state.regs.regD];
            }

            else if (state.slots[state.regs.regD].GetType() == typeof(CShort))
            {
                state.slots[state.regs.regA] = -(CShort)state.slots[state.regs.regD];
            }

            else if (state.slots[state.regs.regD].GetType() == typeof(CLuaNumber))
            {
                //state.slots[state.regs.regA] = -(CLuaNumber)state.slots[state.regs.regD];
                throw new NotImplementedException("UNM declared on a lua number. Currently unimplemented.");
            }
            else
            {
                throw new Exception("UNM declared on non-numeric data.");
            }

            //source
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);
            var           src  = state.CheckGetVarName(state.regs.regD);

            state.CheckLocal(dst, ref line);
            line.Append(dst.Item2 + " = -" + src.Item2);
            line.AppendLine(" --UNM");
            state.decompLines.Add(line.ToString());

            //debugging
            //FileManager.WriteDebug(line.ToString());
        }
예제 #11
0
        /// <summary>
        /// Sets register A to one of the following from register D: nil, true, false.
        /// Note: A single nil value is set with KPRI. KNIL is only used when multiple values need to be set to nil.
        /// Potential register D values:
        ///     nil = 0
        ///     false = 1
        ///     true = 2
        /// </summary>
        /// <param name="state"></param>
        private void HandleKPri(TLuaState state)
        {
            //slot operation: slot[A] = regD->(CBool, CNil)
            if (state.regs.regD == 0)
            {
                state.slots[state.regs.regA] = new CNil();
            }
            else
            {
                state.slots[state.regs.regA] = state.regs.regD == 1 ? new CBool(false) : new CBool(true);
            }

            //source
            StringBuilder line = new StringBuilder();

            var    dst = state.CheckGetVarName(state.regs.regA);
            string valueText;

            if (state.regs.regD == 0)
            {
                valueText = "nil";
            }
            else
            {
                valueText = state.regs.regD == 1 ? "false" : "true";
            }

            state.CheckLocal(dst, ref line);

            line.Append(dst.Item2 + " = " + valueText);
            line.AppendLine(" --KPRI");
            state.decompLines.Add(line.ToString());

            //debugging
            //FileManager.WriteDebug(line.ToString());
        }
예제 #12
0
 private string HandleNV(TLuaState state, Tuple <bool, string> dst, string op)
 {
     return(state.num_G[state.regs.regC].GetValue() + op + state.CheckGetVarName(state.regs.regB).Item2);
 }
예제 #13
0
 private void HandleKCData(TLuaState state)
 {
     state.UnimplementedOpcode(state.curII);
 }
예제 #14
0
 public UnaryState(TLuaState state) : base(state)
 {
 }
예제 #15
0
 private void HandleKNum(TLuaState state)
 {
     state.UnimplementedOpcode(state.curII);
     //throw new NotImplementedException();
 }
예제 #16
0
 public ArithmeticState(TLuaState state) : base(state)
 {
 }
예제 #17
0
        public override void WriteLua(TLuaState state)
        {
            DelOperandOrder OperandOrder = null;

            switch (state.curII.iROp)
            {
            case IRMap.MathNV:
                OperandOrder = HandleNV;
                break;

            case IRMap.MathVN:
                OperandOrder = HandleVN;
                break;

            case IRMap.MathVV:
                OperandOrder = HandleVV;
                break;
            }
            StringBuilder line = new StringBuilder();
            var           dst  = state.CheckGetVarName(state.regs.regA);

            state.CheckLocal(dst, ref line);

            line.Append(dst.Item2 + " = ");

            //operator...might want to redesign this into the IRmap or something?
            string op = "!@#$%"; //junk value to begin with in case of error.

            switch (state.curII.originalOp)
            {
            case OpCodes.ADDNV:
            case OpCodes.ADDVN:
            case OpCodes.ADDVV:
                op = " + ";
                break;

            case OpCodes.SUBNV:
            case OpCodes.SUBVN:
            case OpCodes.SUBVV:
                op = " - ";
                break;

            case OpCodes.MULNV:
            case OpCodes.MULVN:
            case OpCodes.MULVV:
                op = " * ";
                break;

            case OpCodes.DIVNV:
            case OpCodes.DIVVN:
            case OpCodes.DIVVV:
                op = " / ";
                break;

            case OpCodes.MODNV:
            case OpCodes.MODVN:
            case OpCodes.MODVV:
                op = " % ";
                break;

            case OpCodes.POW:
                op = " ^ ";
                break;
            }

            line.Append(OperandOrder(state, dst, op));
            line.AppendLine(" --ARITHMETIC");
            state.decompLines.Add(line.ToString());
        }
예제 #18
0
 public BeginState(TLuaState state) : base(state)
 {
 }
예제 #19
0
 public ConcatState(TLuaState state) : base(state)
 {
 }