diff --git a/Torch/Managers/PatchManager/MSIL/MsilInstruction.cs b/Torch/Managers/PatchManager/MSIL/MsilInstruction.cs index e6ae140..b4f6281 100644 --- a/Torch/Managers/PatchManager/MSIL/MsilInstruction.cs +++ b/Torch/Managers/PatchManager/MSIL/MsilInstruction.cs @@ -171,6 +171,70 @@ namespace Torch.Managers.PatchManager.MSIL private static Func _stackChange; #pragma warning restore 169 + + /// + /// Gets an instruction that represents the inverse of this load or store instruction. + /// + /// + /// + /// new MsilInstruction(OpCodes.Ldloc_0).StoreLoadInverse().OpCode == OpCodes.Stloc_0 + /// + /// + /// Inverse + public MsilInstruction StoreLoadInverse() + { + if (OpCode == OpCodes.Ldloc) + return new MsilInstruction(OpCodes.Stloc).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Ldloc_S) + return new MsilInstruction(OpCodes.Stloc_S).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Ldloc_0) + return new MsilInstruction(OpCodes.Stloc_0); + if (OpCode == OpCodes.Ldloc_1) + return new MsilInstruction(OpCodes.Stloc_1); + if (OpCode == OpCodes.Ldloc_2) + return new MsilInstruction(OpCodes.Stloc_2); + if (OpCode == OpCodes.Ldloc_3) + return new MsilInstruction(OpCodes.Stloc_3); + + if (OpCode == OpCodes.Stloc) + return new MsilInstruction(OpCodes.Ldloc).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Stloc_S) + return new MsilInstruction(OpCodes.Ldloc_S).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Stloc_0) + return new MsilInstruction(OpCodes.Ldloc_0); + if (OpCode == OpCodes.Stloc_1) + return new MsilInstruction(OpCodes.Ldloc_1); + if (OpCode == OpCodes.Stloc_2) + return new MsilInstruction(OpCodes.Ldloc_2); + if (OpCode == OpCodes.Stloc_3) + return new MsilInstruction(OpCodes.Ldloc_3); + + if (OpCode == OpCodes.Ldarg) + return new MsilInstruction(OpCodes.Starg).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Ldarg_S) + return new MsilInstruction(OpCodes.Starg_S).InlineValue( + ((MsilOperandInline)Operand).Value); + // TODO Ldarg_0 etc + + if (OpCode == OpCodes.Starg) + return new MsilInstruction(OpCodes.Ldarg).InlineValue( + ((MsilOperandInline)Operand).Value); + if (OpCode == OpCodes.Starg_S) + return new MsilInstruction(OpCodes.Ldarg_S).InlineValue( + ((MsilOperandInline)Operand).Value); + + throw new ArgumentException($"Can't invert the instruction {this}"); + } + + /// + /// Estimates the stack delta for this instruction. + /// + /// Stack delta public int StackChange() { int num = _stackChange.Invoke(OpCode);