ReturnFixer.MakeLastStatementReturn C# (CSharp) Method

MakeLastStatementReturn() public static method

public static MakeLastStatementReturn ( this method ) : void
method this
return void
    public static void MakeLastStatementReturn(this MethodBody method)
    {
        var instructions = method.Instructions;
        var last = instructions.Last();

        var count = method.Instructions.Count;
        count--;
        var secondLastInstruction = method.Instructions[count];

        if (secondLastInstruction.OpCode != OpCodes.Nop)
        {
            secondLastInstruction = Instruction.Create(OpCodes.Nop);
            instructions.BeforeLast(secondLastInstruction);
        }
        else
        {
            count--;
        }

        foreach (var exceptionHandler in method.ExceptionHandlers)
        {
            if (exceptionHandler.HandlerEnd == last)
            {
                exceptionHandler.HandlerEnd = secondLastInstruction;
            }
        }
        for (var index = 0; index < count; index++)
        {
            var instruction = instructions[index];
            if (instruction.OpCode == OpCodes.Ret)
            {
                instructions[index] = Instruction.Create(OpCodes.Br, secondLastInstruction);
            }
            if (instruction.Operand == last)
            {
                instructions[index] = Instruction.Create(instruction.OpCode, secondLastInstruction);
            }
        }
    }

Usage Example

コード例 #1
0
    public void Process()
    {
        if (Method.Body.Instructions.Count > 0)
        {
            var ilProcessor = Method.Body.GetILProcessor();
            var body        = Method.Body;
            FoundUsageInType();
            string eventName = string.Empty;
            foreach (var attribute in Method.CustomAttributes)
            {
                if (attribute.AttributeType.FullName.Equals("EventLogger.EventNameAttribute"))
                {
                    eventName = attribute.ConstructorArguments[0].Value.ToString();
                    Method.CustomAttributes.Remove(attribute);
                    break;
                }
            }

            Instruction firstInstruction = Method.Body.Instructions.FirstOrDefault();
            var         returnFixer      = new ReturnFixer
            {
                Method = Method
            };
            returnFixer.MakeLastStatementReturn();

            List <Instruction> startingInstructions = new List <Instruction>();
            List <Instruction> endingInstructions   = new List <Instruction>();

            endingInstructions.AddRange(GetEventInstruction("Method calling Finished."));

            if (!string.IsNullOrEmpty(eventName))
            {
                startingInstructions.AddRange(SetEventNameInstruction(eventName));
                endingInstructions.AddRange(SetEventNameInstruction(""));
            }
            startingInstructions.AddRange(GetEventInstruction("Method calling started."));

            var tryLeaveInstructions = Instruction.Create(OpCodes.Leave_S, returnFixer.NopBeforeReturn);
            var finallyInstructions  = Instruction.Create(OpCodes.Endfinally);
            ilProcessor.InsertBefore(firstInstruction, startingInstructions);

            ilProcessor.InsertBefore(returnFixer.NopBeforeReturn, tryLeaveInstructions);
            ilProcessor.InsertBefore(returnFixer.NopBeforeReturn, endingInstructions);
            ilProcessor.InsertBefore(returnFixer.NopBeforeReturn, finallyInstructions);

            var beforeReturn = Instruction.Create(OpCodes.Nop);
            var handler      = new ExceptionHandler(ExceptionHandlerType.Finally)
            {
                TryStart     = firstInstruction,
                TryEnd       = tryLeaveInstructions.Next,
                HandlerStart = endingInstructions.FirstOrDefault(),
                HandlerEnd   = finallyInstructions.Next
            };

            body.ExceptionHandlers.Add(handler);
            body.InitLocals = true;
            body.OptimizeMacros();
        }
    }
All Usage Examples Of ReturnFixer::MakeLastStatementReturn