private static void InnerProcess(ModuleDefinition module, MethodDefinition method, Instruction lastcall) { UPR.Cecil.Cil.MethodBody body = method.Body; var ilProcessor = body.GetILProcessor(); var returnInstruction = FixReturns(module, method); var firstInstruction = FirstInstructionSkipCtor(method); var beforeReturn = Instruction.Create(OpCodes.Nop); ilProcessor.InsertBefore(returnInstruction, beforeReturn); ilProcessor.InsertBefore(returnInstruction, lastcall); ilProcessor.InsertBefore(returnInstruction, Instruction.Create(OpCodes.Nop)); ilProcessor.InsertBefore(returnInstruction, Instruction.Create(OpCodes.Nop)); ilProcessor.InsertBefore(returnInstruction, Instruction.Create(OpCodes.Endfinally)); var handler = new ExceptionHandler(ExceptionHandlerType.Finally) { TryStart = firstInstruction, TryEnd = beforeReturn, HandlerStart = beforeReturn, HandlerEnd = returnInstruction, }; body.ExceptionHandlers.Add(handler); body.InitLocals = true; }
private static Instruction FirstInstructionSkipCtor(MethodDefinition method) { UPR.Cecil.Cil.MethodBody body = method.Body; if (method.IsConstructor && !method.IsStatic) { return(body.Instructions.Skip(2).First()); } return(body.Instructions.First()); }
private static SequencePoint GetSequencePoint(MethodBody body) { if (body == null) { return(null); } Instruction instruction = body.Instructions.FirstOrDefault(x => x.SequencePoint != null); return(instruction == null ? null : instruction.SequencePoint); }
private static Instruction FixReturns(ModuleDefinition mod, MethodDefinition method) { UPR.Cecil.Cil.MethodBody body = method.Body; var instructions = body.Instructions; var lastRet = Instruction.Create(OpCodes.Ret); if (method.ReturnType == mod.TypeSystem.Void) { instructions.Add(lastRet); for (var index = 0; index < instructions.Count - 1; index++) { var instruction = instructions[index]; if (instruction.OpCode == OpCodes.Ret) { instructions[index] = Instruction.Create(OpCodes.Leave, lastRet); } } return(lastRet); // force ret to leave to the Endsample } else { var returnVariable = new VariableDefinition(method.ReturnType); body.Variables.Add(returnVariable); var lastLd = Instruction.Create(OpCodes.Ldloc, returnVariable); //load the local variable to the stack top instructions.Add(lastLd); instructions.Add(lastRet); for (var index = 0; index < instructions.Count - 2; index++) { var instruction = instructions[index]; if (instruction.OpCode == OpCodes.Ret) { instructions[index] = Instruction.Create(OpCodes.Leave, lastLd); instructions.Insert(index, Instruction.Create(OpCodes.Stloc, returnVariable)); index++; } } return(lastLd); } }