예제 #1
0
        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);
            }
        }
예제 #2
0
 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);
         }
     }
 }
예제 #3
0
        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);
        }