Utility method to invert common load and store instructions

This commit is contained in:
Westin Miller
2017-09-11 19:50:07 -07:00
parent 0810e76474
commit b1145c8926

View File

@@ -171,6 +171,70 @@ namespace Torch.Managers.PatchManager.MSIL
private static Func<OpCode, int> _stackChange; private static Func<OpCode, int> _stackChange;
#pragma warning restore 169 #pragma warning restore 169
/// <summary>
/// Gets an instruction that represents the inverse of this load or store instruction.
/// </summary>
/// <remarks>
/// <example>
/// new MsilInstruction(OpCodes.Ldloc_0).StoreLoadInverse().OpCode == OpCodes.Stloc_0
/// </example>
/// </remarks>
/// <returns>Inverse</returns>
public MsilInstruction StoreLoadInverse()
{
if (OpCode == OpCodes.Ldloc)
return new MsilInstruction(OpCodes.Stloc).InlineValue(
((MsilOperandInline<LocalVariableInfo>)Operand).Value);
if (OpCode == OpCodes.Ldloc_S)
return new MsilInstruction(OpCodes.Stloc_S).InlineValue(
((MsilOperandInline<LocalVariableInfo>)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<LocalVariableInfo>)Operand).Value);
if (OpCode == OpCodes.Stloc_S)
return new MsilInstruction(OpCodes.Ldloc_S).InlineValue(
((MsilOperandInline<LocalVariableInfo>)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<ParameterInfo>)Operand).Value);
if (OpCode == OpCodes.Ldarg_S)
return new MsilInstruction(OpCodes.Starg_S).InlineValue(
((MsilOperandInline<ParameterInfo>)Operand).Value);
// TODO Ldarg_0 etc
if (OpCode == OpCodes.Starg)
return new MsilInstruction(OpCodes.Ldarg).InlineValue(
((MsilOperandInline<ParameterInfo>)Operand).Value);
if (OpCode == OpCodes.Starg_S)
return new MsilInstruction(OpCodes.Ldarg_S).InlineValue(
((MsilOperandInline<ParameterInfo>)Operand).Value);
throw new ArgumentException($"Can't invert the instruction {this}");
}
/// <summary>
/// Estimates the stack delta for this instruction.
/// </summary>
/// <returns>Stack delta</returns>
public int StackChange() public int StackChange()
{ {
int num = _stackChange.Invoke(OpCode); int num = _stackChange.Invoke(OpCode);