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; } }
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()); }
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); }
//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()); }
//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 } }
//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()); }
//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()); }
//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; } }
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"); }
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()); }
/// <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()); }
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); }
private void HandleKCData(TLuaState state) { state.UnimplementedOpcode(state.curII); }
public UnaryState(TLuaState state) : base(state) { }
private void HandleKNum(TLuaState state) { state.UnimplementedOpcode(state.curII); //throw new NotImplementedException(); }
public ArithmeticState(TLuaState state) : base(state) { }
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()); }
public BeginState(TLuaState state) : base(state) { }
public ConcatState(TLuaState state) : base(state) { }