Ejemplo n.º 1
0
    private void ProcessBody(MethodDefinition method)
    {
        if (method.IsAsyncStateMachine())
        {
            LogTo.Information("Async method '{0}' cannot be modified by Usable.", method.FullName);
            return;
        }

        method.Body.SimplifyMacros();

        var ilProcessor = method.Body.GetILProcessor();

        if (method.Body.Instructions.Last().OpCode == OpCodes.Throw)
        {
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));
        }

        method.Body.OptimizeMacros();
        method.Body.SimplifyMacros();

        var ilMethod = Decompile(method);

        var visitor = new UsableVisitor(method);

        visitor.Visit(ilMethod);

        if (!visitor.UsingRanges.Any())
        {
            method.Body.OptimizeMacros();
            return;
        }

        // Convert early returns to branches to the last return
        if (visitor.EarlyReturns.Any() && method.Body.Instructions.Last().OpCode == OpCodes.Ret)
        {
            FixEarlyReturns(method.Body, visitor.EarlyReturns);
        }

        // Inserts nops to ensure nested trys are not overlapping
        var usingBlocks = FixUsingBlocks(ilProcessor,
                                         visitor.UsingRanges
                                         .Select(r => Tuple.Create(method.Body.Instructions.AtOffset(r.From), method.Body.Instructions.BeforeOffset(r.To)))
                                         .ToList());

        // Add the usings
        foreach (var usingBlock in usingBlocks.OrderBy(u => u.Item1.Offset))
        {
            AddUsing(method.Body, usingBlock);
        }

        method.Body.OptimizeMacros();
        method.Body.SimplifyMacros();

        // Sort exception handlers so inner trys are before outer ones
        method.Body.ExceptionHandlers.ReplaceCollection(method.Body.ExceptionHandlers.OrderBy(x => x, new ExceptionHandlerComparer()));

        // Any branches in a try branching to outside must be converted to leaves
        foreach (var handler in method.Body.ExceptionHandlers)
        {
            ReplaceBranchesWithLeaves(ilProcessor, handler);
        }

        method.Body.OptimizeMacros();
    }
Ejemplo n.º 2
0
    private void ProcessBody(MethodDefinition method)
    {
        if (method.IsAsyncStateMachine())
        {
            LogTo.Information("Async method '{0}' cannot be modified by Usable.", method.FullName);
            return;
        }

        method.Body.SimplifyMacros();

        var ilProcessor = method.Body.GetILProcessor();

        if (method.Body.Instructions.Last().OpCode == OpCodes.Throw)
            ilProcessor.Append(ilProcessor.Create(OpCodes.Ret));

        method.Body.OptimizeMacros();
        method.Body.SimplifyMacros();

        var ilMethod = Decompile(method);

        var visitor = new UsableVisitor(method);
        visitor.Visit(ilMethod);

        if (!visitor.UsingRanges.Any())
        {
            method.Body.OptimizeMacros();
            return;
        }

        // Convert early returns to branches to the last return
        if (visitor.EarlyReturns.Any() && method.Body.Instructions.Last().OpCode == OpCodes.Ret)
            FixEarlyReturns(method.Body, visitor.EarlyReturns);

        // Inserts nops to ensure nested trys are not overlapping
        var usingBlocks = FixUsingBlocks(ilProcessor,
            visitor.UsingRanges
                .Select(r => Tuple.Create(method.Body.Instructions.AtOffset(r.From), method.Body.Instructions.BeforeOffset(r.To)))
                .ToList());

        // Add the usings
        foreach (var usingBlock in usingBlocks.OrderBy(u => u.Item1.Offset))
            AddUsing(method.Body, usingBlock);

        method.Body.OptimizeMacros();
        method.Body.SimplifyMacros();

        // Sort exception handlers so inner trys are before outer ones
        method.Body.ExceptionHandlers.ReplaceCollection(method.Body.ExceptionHandlers.OrderBy(x => x, new ExceptionHandlerComparer()));

        // Any branches in a try branching to outside must be converted to leaves
        foreach (var handler in method.Body.ExceptionHandlers)
            ReplaceBranchesWithLeaves(ilProcessor, handler);

        method.Body.OptimizeMacros();
    }