internal static Instruction FixReturns(this ILProcessor ilProcessor) { var methodDefinition = ilProcessor.Body.Method; if (methodDefinition.ReturnType == methodDefinition.Module.TypeSystem.Void) { var instructions = ilProcessor.Body.Instructions.ToArray(); var newReturnInstruction = ilProcessor.Create(OpCodes.Ret); ilProcessor.Append(newReturnInstruction); foreach (var instruction in instructions) { if (instruction.OpCode == OpCodes.Ret) { var leaveInstruction = ilProcessor.Create(OpCodes.Leave, newReturnInstruction); ilProcessor.Replace(instruction, leaveInstruction); ilProcessor.ReplaceInstructionReferences(instruction, leaveInstruction); } } return(newReturnInstruction); } else { var instructions = ilProcessor.Body.Instructions.ToArray(); var returnVariable = new VariableDefinition(methodDefinition.ReturnType); ilProcessor.Body.Variables.Add(returnVariable); var loadResultInstruction = ilProcessor.Create(OpCodes.Ldloc, returnVariable); ilProcessor.Append(loadResultInstruction); var newReturnInstruction = ilProcessor.Create(OpCodes.Ret); ilProcessor.Append(newReturnInstruction); foreach (var instruction in instructions) { if (instruction.OpCode == OpCodes.Ret) { var saveResultInstruction = ilProcessor.Create(OpCodes.Stloc, returnVariable); ilProcessor.Replace(instruction, saveResultInstruction); var leaveInstruction = ilProcessor.Create(OpCodes.Leave, loadResultInstruction); ilProcessor.InsertAfter(saveResultInstruction, leaveInstruction); ilProcessor.ReplaceInstructionReferences(instruction, leaveInstruction); } } return(loadResultInstruction); } }
internal static void RemoveTailInstructions(this ILProcessor ilProcessor) { foreach (var instruction in ilProcessor.Body.Instructions.ToArray()) { if (instruction.OpCode == OpCodes.Tail) { var noOpInstruction = ilProcessor.Create(OpCodes.Nop); ilProcessor.Replace(instruction, noOpInstruction); ilProcessor.ReplaceInstructionReferences(instruction, noOpInstruction); } } }
public static Instruction InsertBefore( this ILProcessor ilProcessor, Instruction target, IEnumerable <Instruction> newInstructions, bool updateReferences) { var newTarget = target; foreach (var instruction in newInstructions.Reverse()) { ilProcessor.InsertBefore(newTarget, instruction); newTarget = instruction; } if (updateReferences) { ilProcessor.ReplaceInstructionReferences(target, newTarget); } return(newTarget); }