本文整理汇总了C#中Mono.Cecil.Cil.ILProcessor.Remove方法的典型用法代码示例。如果您正苦于以下问题:C# ILProcessor.Remove方法的具体用法?C# ILProcessor.Remove怎么用?C# ILProcessor.Remove使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mono.Cecil.Cil.ILProcessor
的用法示例。
在下文中一共展示了ILProcessor.Remove方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: InjectNewWriter
void InjectNewWriter(MethodDefinition sendData, ILProcessor processor, out VariableDefinition mswriter, out OpCode binaryWriter)
{
var buffer = sendData.Body.Instructions.First(
x => x.OpCode == OpCodes.Ldsfld
&& (x.Operand as FieldReference).Name == "buffer"
);
while (!(buffer.Next.OpCode == OpCodes.Callvirt
&& (buffer.Next.Operand as MethodReference).Name == "set_Position"))
{
processor.Remove(buffer.Next);
}
processor.Remove(buffer.Next);
//processor.Remove(buffer);
//VariableDefinition mswriter;
sendData.Body.Variables.Add(mswriter = new VariableDefinition("mswriter",
this.SourceDefinition.MainModule.Import(typeof(MemoryStream))
));
var res = processor.InsertBefore(buffer.Previous.Previous,
new
{
OpCodes.Newobj,
Operand = this.SourceDefinition.MainModule.Import(typeof(MemoryStream)
.GetConstructors()
.Single(x => x.GetParameters().Count() == 0)
)
},
new { OpCodes.Stloc, Operand = mswriter },
new { OpCodes.Ldloc, Operand = mswriter }
);
buffer.Previous.Previous.ReplaceTransfer(res[0], sendData);
processor.Remove(buffer.Previous);
processor.Remove(buffer.Previous);
buffer.OpCode = OpCodes.Newobj;
buffer.Operand = this.SourceDefinition.MainModule.Import(typeof(BinaryWriter)
.GetConstructors()
.Single(x => x.GetParameters().Count() == 1)
);
if (buffer.Next.OpCode != OpCodes.Ldloc_1)
{
throw new NotSupportedException("Expected Ldloc_1");
}
/*var*/
binaryWriter = buffer.Next.OpCode;
processor.InsertAfter(buffer,
new { OpCodes.Stloc_1 }
);
}
示例2: HandleOfProperty
void HandleOfProperty(Instruction instruction, ILProcessor ilProcessor, Func<PropertyDefinition, MethodDefinition> func)
{
var propertyNameInstruction = instruction.Previous;
var propertyName = GetLdString(propertyNameInstruction);
var typeNameInstruction = propertyNameInstruction.Previous;
var typeName = GetLdString(typeNameInstruction);
var assemblyNameInstruction = typeNameInstruction.Previous;
var assemblyName = GetLdString(assemblyNameInstruction);
var typeDefinition = GetTypeDefinition(assemblyName, typeName);
var property = typeDefinition.Properties.FirstOrDefault(x => x.Name == propertyName);
if (property == null)
{
throw new WeavingException($"Could not find property named '{propertyName}'.")
{
SequencePoint = instruction.SequencePoint
};
}
var methodDefinition = func(property);
if (methodDefinition == null)
{
throw new WeavingException($"Could not find property named '{propertyName}'.")
{
SequencePoint = instruction.SequencePoint
};
}
ilProcessor.Remove(typeNameInstruction);
ilProcessor.Remove(propertyNameInstruction);
assemblyNameInstruction.OpCode = OpCodes.Ldtoken;
assemblyNameInstruction.Operand = methodDefinition;
if (typeDefinition.HasGenericParameters)
{
var typeReference = ModuleDefinition.ImportReference(typeDefinition);
ilProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldtoken, typeReference));
instruction.Operand = getMethodFromHandleGeneric;
}
else
{
instruction.Operand = getMethodFromHandle;
}
ilProcessor.InsertAfter(instruction, Instruction.Create(OpCodes.Castclass, methodInfoType));
}
示例3: HandleOfParameter
void HandleOfParameter(Instruction instruction, ILProcessor ilProcessor)
{
//Info.OfMethod("AssemblyToProcess","MethodClass","InstanceMethod");
var methodNameInstruction = instruction.Previous;
var methodName = GetLdString(methodNameInstruction);
var typeNameInstruction = methodNameInstruction.Previous;
var typeName = GetLdString(typeNameInstruction);
var assemblyNameInstruction = typeNameInstruction.Previous;
var assemblyName = GetLdString(assemblyNameInstruction);
var typeDefinition = GetTypeDefinition(assemblyName, typeName);
var methodDefinition = typeDefinition.Methods.FirstOrDefault(x => x.Name == methodName);
if (methodDefinition == null)
{
throw new WeavingException($"Could not find method named '{methodName}'.");
}
var methodReference = ModuleDefinition.ImportReference(methodDefinition);
ilProcessor.Remove(typeNameInstruction);
assemblyNameInstruction.OpCode = OpCodes.Ldtoken;
assemblyNameInstruction.Operand = methodReference;
instruction.Operand = getMethodFromHandle;
ilProcessor.InsertAfter(instruction,Instruction.Create(OpCodes.Castclass,methodInfoType));
}
示例4: HandleOfField
void HandleOfField(Instruction instruction, ILProcessor ilProcessor)
{
//Info.OfField("AssemblyToProcess","MethodClass","Field");
var fieldNameInstruction = instruction.Previous;
var fieldName = GetLdString(fieldNameInstruction);
var typeNameInstruction = fieldNameInstruction.Previous;
var typeName = GetLdString(typeNameInstruction);
var assemblyNameInstruction = typeNameInstruction.Previous;
var assemblyName = GetLdString(assemblyNameInstruction);
var typeDefinition = GetTypeDefinition(assemblyName, typeName);
var fieldDefinition = typeDefinition.Fields.FirstOrDefault(x => x.Name == fieldName);
if (fieldDefinition == null)
{
throw new WeavingException($"Could not find field named '{fieldName}'.")
{
SequencePoint = instruction.SequencePoint
};
}
var fieldReference = ModuleDefinition.ImportReference(fieldDefinition);
ilProcessor.Remove(typeNameInstruction);
ilProcessor.Remove(fieldNameInstruction);
assemblyNameInstruction.OpCode = OpCodes.Ldtoken;
assemblyNameInstruction.Operand = fieldReference;
if (typeDefinition.HasGenericParameters)
{
var typeReference = ModuleDefinition.ImportReference(typeDefinition);
ilProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldtoken,typeReference));
instruction.Operand = getFieldFromHandleGeneric;
}
else
{
instruction.Operand = getFieldFromHandle;
}
}
示例5: RemoveInstructions
public static void RemoveInstructions(ILProcessor p, Instruction first, int count)
{
var cur = first;
for (int i = 0; i < count; i++)
{
if (cur == null)
break;
var n = cur.Next;
p.Remove(cur);
cur = n;
}
}
示例6: HandleOfType
void HandleOfType(Instruction instruction, ILProcessor ilProcessor)
{
//Info.OfType("AssemblyToProcess","TypeClass");
var typeNameInstruction= instruction.Previous;
var typeName = GetLdString(typeNameInstruction);
var assemblyNameInstruction = typeNameInstruction.Previous;
var assemblyName = GetLdString(assemblyNameInstruction);
var typeDefinition = GetTypeDefinition(assemblyName, typeName);
var typeReference = ModuleDefinition.ImportReference(typeDefinition);
ilProcessor.Remove(typeNameInstruction);
assemblyNameInstruction.OpCode = OpCodes.Ldtoken;
assemblyNameInstruction.Operand = typeReference;
instruction.Operand = getTypeFromHandle;
}
示例7: HandleOfMethod
void HandleOfMethod(Instruction instruction, ILProcessor ilProcessor, MethodReference ofMethodReference)
{
//Info.OfMethod("AssemblyToProcess","MethodClass","InstanceMethod");
Instruction methodNameInstruction;
List<string> parameters;
Instruction parametersInstruction = null;
if (ofMethodReference.Parameters.Count == 4)
{
parametersInstruction = instruction.Previous;
parameters = GetLdString(parametersInstruction)
.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.ToList();
methodNameInstruction = parametersInstruction.Previous;
}
else
{
methodNameInstruction = instruction.Previous;
parameters = new List<string>();
}
var methodName = GetLdString(methodNameInstruction);
var typeNameInstruction = methodNameInstruction.Previous;
var typeName = GetLdString(typeNameInstruction);
var assemblyNameInstruction = typeNameInstruction.Previous;
var assemblyName = GetLdString(assemblyNameInstruction);
var typeDefinition = GetTypeDefinition(assemblyName, typeName);
var methodDefinitions = typeDefinition.FindMethodDefinitions(methodName, parameters);
if (methodDefinitions.Count == 0)
{
throw new WeavingException($"Could not find method named '{methodName}'.")
{
SequencePoint = instruction.SequencePoint
};
}
if (methodDefinitions.Count > 1)
{
throw new WeavingException($"More than one method named '{methodName}' found.")
{
SequencePoint = instruction.SequencePoint
};
}
var methodReference = ModuleDefinition.ImportReference(methodDefinitions[0]);
ilProcessor.Remove(typeNameInstruction);
ilProcessor.Remove(methodNameInstruction);
if (parametersInstruction != null)
{
ilProcessor.Remove(parametersInstruction);
}
assemblyNameInstruction.OpCode = OpCodes.Ldtoken;
assemblyNameInstruction.Operand = methodReference;
if (typeDefinition.HasGenericParameters)
{
var typeReference = ModuleDefinition.ImportReference(typeDefinition);
ilProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldtoken, typeReference));
instruction.Operand = getMethodFromHandleGeneric;
}
else
{
instruction.Operand = getMethodFromHandle;
}
ilProcessor.InsertAfter(instruction, Instruction.Create(OpCodes.Castclass, methodInfoType));
}
示例8: OnInvocation
private InvocationResult OnInvocation (MethodDefinition method, ILProcessor processor, Instruction i, MethodReference mr)
{
Mono.Cecil.GenericParameter genPar = null;
if (!mr.FullName.Contains ("<")) {
//if(Verbosity >= 8) - shouldn't be reached
Console.WriteLine ("[UNREACHABLE] Skipping method that contains no <");
return InvocationResult.Skipped;
}
if (mr.FullName.Contains (" System.")) {
// REVIEW - does AOT somehow support some of these cases?
if (Verbosity >= Verbosities.Skipping)
Console.WriteLine ("Skipping method invocation that contains ' System.': [["
+ mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name + "]]");
return InvocationResult.Failed;
}
#if CUSTOM // Custom blacklist
if(!mr.FullName.Contains(" LionFire.") && !mr.FullName.Contains(" Dycen."))
{
if(Verbosity >= Verbosities.Skipping)Console.WriteLine("Skipping method that is not LionFire or Dycen:"
+ mr.FullName + " in " + method.DeclaringType.FullName + "."+ method.Name);
//continue;
return InvocationResult.Skipped
}
#endif
var genPars = mr.Resolve ().GenericParameters;
// Console.WriteLine("TEMP2 - " + genPars.Count);
// var genPars = mr.GetGenericParameters(method.Module);
// Console.WriteLine("TEMP " + mr.Name);
// Console.WriteLine("TEMP genPars.Count " + genPars.Count);
if (genPars.Count != 1) {
if (Verbosity >= Verbosities.Warning)
Console.WriteLine ("[NS] Replacing methods with more than 1 generic parameter not supported: " + genPars.Count + ": " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name);
return InvocationResult.Failed;
} else {
genPar = genPars [0];
// var resolved = genPar.Resolve();
// Console.WriteLine("NEW -- <" + (resolved == null ? "null" : resolved.Name) + ">");
if (Verbosity >= 10)
Console.WriteLine ("NEW |- <" + genPar + ">");
}
#region string genericParameter = ...;
string genericParameter;
Type genericTypeParameter;
TypeDefinition genericTypeParameterDefinition = null;
{
string n = mr.FullName.Split (' ') [1];
n = n.Split (new string[]{"::"}, StringSplitOptions.RemoveEmptyEntries) [1];
int startI = n.IndexOf ('<') + 1;
int stack = 0;
int endI = startI + 1;
while (stack > 0 || n[endI] != '>') {
if (n [endI] == '<')
stack++;
if (n [endI] == '>')
stack--;
endI++;
}
int length = endI - startI;
genericParameter = n.Substring (startI, length);
// if(genericParameter.StartsWith("!!"))
// {
// int genParAliasIndex = Convert.ToInt32(genericParameter.Substring(2));
//
// var genParAlias = genPars[genParAliasIndex];
//
//
// genericParameter = genParAlias.FullName;
// Console.WriteLine("NEW - Generic method alias param: " + genericParameter);
// }
// if(genericParameter.Contains("<") || genericParameter.Contains(">"))
// {
// Console.WriteLine("Unsupported generic method ("+mr.FullName+") with generic parameter: " + genericParameter);
// skipped++;
// continue;
// }
if (Verbosity >= 8)
Console.WriteLine ("Generic method param: " + genericParameter);
genericTypeParameter = Type.GetType (genericParameter, false);
//if(genericTypeParameter == null)
{
foreach (ModuleDefinition modDef in ads.SelectMany(assDef => assDef.Modules)) {
// foreach(var modType in modDef.Types)
// {
// Console.WriteLine("ccc - " + modType);
// }
genericTypeParameterDefinition = modDef.Types.Where (td => td.FullName == genericParameter
// && !td.IsGenericInstance
).FirstOrDefault ();
//.........这里部分代码省略.........
示例9: ProcessNameOfCallInstruction
private static void ProcessNameOfCallInstruction(Instruction instruction, ILProcessor ilProcessor)
{
var instructions = instruction.AsReverseEnumerable().Take(patterns.Value.First().Length).ToArray(); // Take an instruction set with a maximum size of the longest pattern.
Boolean possibleMatch = false;
PatternInstruction[] patternMatched = null;
Func<String> terminal = null;
foreach (var pattern in patterns.Value) {
possibleMatch = true;
terminal = null;
for (Int32 i = 0, j = 0; i < pattern.Length && j < instructions.Length; ++i, ++j) {
while (pattern[i] is OptionalPatternInstruction && !pattern[i].EligibleOpCodes.Contains(instructions[j].OpCode))
++i;
var patternInstruction = pattern[i];
var currentInstruction = instructions[j];
if (patternInstruction.EligibleOpCodes.Contains(currentInstruction.OpCode) && patternInstruction.IsPredicated(currentInstruction, ilProcessor)) {
if (patternInstruction.Terminal != null && terminal == null)
terminal = () => patternInstruction.Terminal(currentInstruction, ilProcessor);
if (patternInstruction.Action != null)
patternInstruction.Action(currentInstruction);
}
else {
possibleMatch = false;
break;
}
}
if (possibleMatch && pattern.Count(x => !(x is OptionalPatternInstruction)) <= instructions.Length) {
patternMatched = pattern;
break;
}
}
if (!possibleMatch)
throw GetNotSupportedException(instruction); // The usage of Name.Of is not supported
if (terminal == null)
throw new NotImplementedException("There is no terminal expression implemented for the matched pattern.");
String name;
try {
name = terminal();
if (IsNullOrWhiteSpace(name))
throw new Exception("Name not found.");
}
catch {
throw GetNotSupportedException(instruction);
}
// TODO: Remove the anonymous methods generated by lamdba expressions in some uses of Name.Of...
ilProcessor.InsertAfter(instruction, Instruction.Create(OpCodes.Ldstr, name));
for (Int32 i = 0, j = 0; i < patternMatched.Length && j < instructions.Length; ++i, ++j) {
while (patternMatched[i] is OptionalPatternInstruction && !patternMatched[i].EligibleOpCodes.Contains(instructions[j].OpCode))
++i;
ilProcessor.Remove(instructions[j]);
}
}
示例10: MoveInstructions
private static void MoveInstructions(Instruction start, Instruction end, Instruction insertionPoint, ILProcessor il)
{
IList<Instruction> toBeMoved = new List<Instruction>();
Instruction boundary = end.Next;
while(start != boundary)
{
toBeMoved.Add(start);
Instruction next = start.Next;
il.Remove(start);
start = next;
}
foreach (Instruction instruction in toBeMoved)
{
il.InsertBefore(insertionPoint, instruction);
}
}
示例11: ReplacePinStructGeneric
private void ReplacePinStructGeneric(MethodDefinition method, ILProcessor ilProcessor, Instruction pinToPatch)
{
// Next instruction should be a store to the variable that should be pinned
var nextStoreInstruction = pinToPatch.Next;
int variableIndex;
if (nextStoreInstruction.OpCode == OpCodes.Stloc_0)
{
variableIndex = 0;
}
else if (nextStoreInstruction.OpCode == OpCodes.Stloc_1)
{
variableIndex = 1;
}
else if (nextStoreInstruction.OpCode == OpCodes.Stloc_2)
{
variableIndex = 2;
}
else if (nextStoreInstruction.OpCode == OpCodes.Stloc_3)
{
variableIndex = 3;
}
else if (nextStoreInstruction.OpCode == OpCodes.Stloc_S)
{
variableIndex = ((VariableReference)nextStoreInstruction.Operand).Index;
}
else if (nextStoreInstruction.OpCode == OpCodes.Stloc)
{
variableIndex = ((VariableReference)nextStoreInstruction.Operand).Index;
}
else
{
throw new InvalidOperationException("Could not find a store operation right after Interop.Pin");
}
// Transform variable from:
// valuetype Struct s
// to:
// valuetype Struct& modopt([mscorlib]System.Runtime.CompilerServices.IsExplicitlyDereferenced) pinned s,
var variable = method.Body.Variables[variableIndex];
variable.VariableType = variable.VariableType
.MakeByReferenceType()
//.MakeOptionalModifierType(typeof(IsExplicitlyDereferenced))
.MakePinnedType();
// Remove call to Interop.Pin:
ilProcessor.Remove(pinToPatch);
// Transform all ldloca with this variable into ldloc:
for (int index = 0; index < ilProcessor.Body.Instructions.Count; index++)
{
var instruction = ilProcessor.Body.Instructions[index];
if (instruction.OpCode == OpCodes.Ldloca && ((VariableReference)instruction.Operand).Index == variableIndex)
{
instruction.OpCode = OpCodes.Ldloc;
}
else if (instruction.OpCode == OpCodes.Ldloca_S && ((VariableReference)instruction.Operand).Index == variableIndex)
{
instruction.OpCode = OpCodes.Ldloc_S;
}
}
}
示例12: ReplacePinStatement
private void ReplacePinStatement(MethodDefinition method, ILProcessor ilProcessor, Instruction fixedtoPatch)
{
var previousInstruction = fixedtoPatch.Previous;
int variableIndex;
if (previousInstruction.OpCode == OpCodes.Ldloc_0)
{
variableIndex = 0;
}
else if (previousInstruction.OpCode == OpCodes.Ldloc_1)
{
variableIndex = 1;
}
else if (previousInstruction.OpCode == OpCodes.Ldloc_2)
{
variableIndex = 2;
}
else if (previousInstruction.OpCode == OpCodes.Ldloc_3)
{
variableIndex = 3;
}
else if (previousInstruction.OpCode == OpCodes.Ldloc_S)
{
variableIndex = ((VariableReference)previousInstruction.Operand).Index;
}
else if (previousInstruction.OpCode == OpCodes.Ldloc)
{
variableIndex = ((VariableReference)previousInstruction.Operand).Index;
}
else
{
throw new InvalidOperationException("Could not find a load operation right before Interop.Pin");
}
var variable = ilProcessor.Body.Variables[variableIndex];
variable.VariableType = variable.VariableType.MakePinnedType();
ilProcessor.Remove(previousInstruction);
ilProcessor.Remove(fixedtoPatch);
}
示例13: Inject
private static void Inject(ILProcessor ilGen, IEnumerable<Instruction> instructions, Instruction instructionToReplace)
{
Instruction prevInstruction = instructionToReplace;
foreach(Instruction currInstruction in instructions)
{
ilGen.InsertAfter(prevInstruction, currInstruction);
prevInstruction = currInstruction;
}
ilGen.Remove(instructionToReplace);
}
示例14: SendWriterPacket
void SendWriterPacket(MethodDefinition sendData, ILProcessor processor, VariableDefinition mswriter, OpCode binaryWriter)
{
// inject the packet contents array after the method updates the packet id.
// our signature we look for is the last call to update the Position
var offset = sendData.Body.Instructions.Last(
x => x.OpCode == OpCodes.Callvirt
&& (x.Operand as MethodReference).Name == "set_Position"
);
VariableDefinition packetContents;
sendData.Body.Variables.Add(packetContents = new VariableDefinition("packetContents",
this.SourceDefinition.MainModule.Import(typeof(byte[]))
));
processor.InsertAfter(offset,
new { OpCodes.Ldloc, mswriter },
new
{
OpCodes.Callvirt,
Operand = this.SourceDefinition.MainModule.Import(typeof(MemoryStream)
.GetMethods()
.Single(x => x.Name == "ToArray" && x.GetParameters().Count() == 0)
)
},
new { OpCodes.Stloc, packetContents }
);
// replace all instances of NetMessage.buffer[index].writeBuffer with out new packetContents
foreach (var writeBuffer in sendData.Body.Instructions.Where(
x => x.OpCode == OpCodes.Ldfld
&& (x.Operand as FieldReference).Name == "writeBuffer"
).ToArray())
{
// now remove all calls back to the when the buffer is loaded
// remove the writeBuffer
// replace the messagebuffer instruction with our packet contents
// note: always ensure the writeBuffer is below packetContents
VariableDefinition vrbBuffer = packetContents;
if (writeBuffer.Offset < offset.Offset)
{
//Needs a local buffer that gets written into our writer
//find the first argument (ldarg.s number)
var firstInstruction = writeBuffer.Previous(
x => x.OpCode == OpCodes.Ldarg_S
&& (x.Operand as ParameterReference).Name == "number"
);
VariableDefinition localBuffer;
sendData.Body.Variables.Add(localBuffer = new VariableDefinition(
this.SourceDefinition.MainModule.Import(typeof(byte[]))
));
processor.InsertAfter(firstInstruction,
//new { OpCodes.Ldc_I4, Operand = 65536 },
new { OpCodes.Newarr, Operand = this.SourceDefinition.MainModule.TypeSystem.Byte },
new { OpCodes.Stloc, Operand = localBuffer },
new { firstInstruction.OpCode, Operand = (ParameterDefinition)firstInstruction.Operand }
);
firstInstruction.OpCode = OpCodes.Ldc_I4;
firstInstruction.Operand = 65535;
//find the position set, as we are starting from 0 with out new array
var argPosition = firstInstruction.Next(x => x.OpCode == OpCodes.Ldloc_1);
while (argPosition.Next.OpCode != OpCodes.Call)
{
processor.Remove(argPosition.Next);
}
argPosition.OpCode = OpCodes.Ldc_I4_0;
vrbBuffer = localBuffer;
// the local buffer is now in place
// we now need to send it off to the writer, instead of simply incrementing
// get the method call and skip the result variable and remove all instructions until the branch out
var call = writeBuffer.Next(
x => x.OpCode == OpCodes.Call
&& (x.Operand as MethodReference).Name == "CompressTileBlock"
).Next;
while (call.Next.OpCode != OpCodes.Br)
{
processor.Remove(call.Next);
}
processor.InsertAfter(call,
new { OpCode = binaryWriter },
new { OpCodes.Ldloc, localBuffer },
new { OpCodes.Ldc_I4_0 },
new { OpCodes.Ldloc_S, Operand = (VariableDefinition)call.Operand },
new
{
OpCodes.Callvirt,
Operand = this.SourceDefinition.MainModule.Import(typeof(BinaryWriter)
.GetMethods()
.Single(x => x.Name == "Write"
//.........这里部分代码省略.........
示例15: WeaveOnException
private void WeaveOnException(MethodDefinition targetMethod, ILProcessor ilp, VariableDefinition aspectInstance, VariableDefinition correlation, Instruction addAfter)
{
if (_onException != null)
{
targetMethod.Body.InitLocals = true;
var exceptionType = targetMethod.Module.Import(typeof(Exception));
var onExceptionInstructions = GetOnExceptionInstructions(targetMethod, ilp, aspectInstance, correlation, exceptionType).ToArray();
var tryEnd = ilp.Body.Instructions.Last();
var returns = false;
if (tryEnd.OpCode == OpCodes.Ret)
{
returns = true;
var nopOrLoad = tryEnd.Previous;
if (nopOrLoad.OpCode == OpCodes.Nop)
{
var leaveToNop = ilp.Create(OpCodes.Leave_S, nopOrLoad);
ilp.InsertBefore(nopOrLoad, leaveToNop);
tryEnd = nopOrLoad;
}
else
{
var nopOrBreak = nopOrLoad.Previous;
if (nopOrBreak.OpCode == OpCodes.Br_S)
{
var nop = ilp.Create(OpCodes.Nop);
ilp.InsertBefore(nopOrBreak, nop);
ilp.Remove(nopOrBreak);
var leave = ilp.Create(OpCodes.Leave_S, nop);
ilp.InsertBefore(nop, leave);
tryEnd = nop;
}
else
{
tryEnd = nopOrBreak;
}
}
}
else
{
var nop = ilp.Create(OpCodes.Nop);
ilp.Append(nop);
tryEnd = nop;
}
var insertPoint = tryEnd.Previous;
ilp.InsertInstructionsAfter(insertPoint, onExceptionInstructions);
if (!returns)
{
ilp.Remove(tryEnd);
}
tryEnd = insertPoint.Next;
var exceptionHandler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
TryStart = addAfter != null
? addAfter.Next
: ilp.Body.Instructions.First(),
TryEnd = tryEnd,
HandlerStart = tryEnd,
HandlerEnd = returns
? onExceptionInstructions.Last().Next
: null,
CatchType = exceptionType
};
targetMethod.Body.ExceptionHandlers.Add(exceptionHandler);
}
}