Ejemplo n.º 1
0
        private static void ProcessEachMethod(MethodDefinition methodDefinition)
        {
            var body     = methodDefinition.Body;
            var handlers = body.ExceptionHandlers;

            if (handlers.Any(x => x.HandlerType != ExceptionHandlerType.Finally))
            {
                Debug.LogWarning(methodDefinition.FullName + " contains not finally clause!");
                return;
            }
            using (ScopedProcessor processor = body.GetILProcessor())
            {
                processor.Simplify();
                processor.PreProcessOptimization();
                var exceptionHandlerTrees = ExceptionHandlerTree.Create(body);
                var totalDepth            = exceptionHandlerTrees.Max(x => x.TotalDepth);
                for (var i = 0; i < totalDepth; i++)
                {
                    body.Variables.Add(new VariableDefinition(methodDefinition.Module.TypeSystem.Int32));
                }
                foreach (var exceptionHandlerTree in exceptionHandlerTrees)
                {
                    ProcessComplexTree(processor, exceptionHandlerTree);
                }
            }
            handlers.Clear();
        }
Ejemplo n.º 2
0
        private static void ProcessHandler(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree)
        {
            var iterator = exceptionHandlerTree.Handler.HandlerStart;

            for (var end = exceptionHandlerTree.Handler.HandlerEnd; iterator != end; iterator = iterator.Next)
            {
                if (iterator.OpCode.Code == Code.Endfinally)
                {
                    break;
                }
            }

            if (iterator is null)
            {
                return;
            }

            var variableDefinitions = processor.Processor.Body.Variables;

            if (exceptionHandlerTree.IsRelay)
            {
                ProcessRelayHandler(processor, exceptionHandlerTree, variableDefinitions, exceptionHandlerTree.CurrentDepth, iterator);
            }
            else
            {
                ProcessSingleHandler(processor, exceptionHandlerTree, variableDefinitions, exceptionHandlerTree.CurrentDepth, iterator);
            }
        }
Ejemplo n.º 3
0
 private static void ProcessComplexTree(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree)
 {
     foreach (var tree in exceptionHandlerTree.Trees)
     {
         ProcessComplexTree(processor, tree);
     }
     if (exceptionHandlerTree.Handler is null)
     {
         return;
     }
     ProcessSimpleTree(processor, exceptionHandlerTree);
 }
Ejemplo n.º 4
0
        private static void ProcessRelayHandler(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree, Collection <VariableDefinition> variables, int currentDepth, Instruction iterator)
        {
            var         ld = variables.LoadLocal(variables.Count - 1 - currentDepth);
            Instruction @switch;

            if (exceptionHandlerTree.Parent?.Handler is null)
            {
                @switch = Instruction.Create(OpCodes.Switch, exceptionHandlerTree.EndDestinations);
            }
            else
            {
                @switch = Instruction.Create(OpCodes.Switch, exceptionHandlerTree.EndDestinations.Append(exceptionHandlerTree.Parent.Handler.HandlerStart).ToArray());
            }
            processor.Replace(iterator, ld).InsertAfter(ld, @switch);
        }
Ejemplo n.º 5
0
        private static void ProcessSingleHandler(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree, Collection <VariableDefinition> variables, int currentDepth, Instruction iterator)
        {
            switch (exceptionHandlerTree.EndDestinations.Length)
            {
            case 1:
            {
                processor.Replace(iterator, Instruction.Create(OpCodes.Br, exceptionHandlerTree.EndDestinations[0]));
            }
            break;

            case 2:
                if (ReferenceEquals(exceptionHandlerTree.EndDestinations[0], exceptionHandlerTree.EndDestinations[1]))
                {
                    processor.Replace(iterator, Instruction.Create(OpCodes.Br, exceptionHandlerTree.EndDestinations[0]));
                }
                else
                {
                    var ld      = variables.LoadLocal(variables.Count - 1 - currentDepth);
                    var brFalse = Instruction.Create(OpCodes.Brfalse, exceptionHandlerTree.EndDestinations[0]);
                    processor
                    .Replace(iterator, ld)
                    .InsertAfter(ld, brFalse)
                    .InsertAfter(brFalse, Instruction.Create(OpCodes.Br, exceptionHandlerTree.EndDestinations[1]));
                }
                break;

            default:
            {
                var ld = variables.LoadLocal(variables.Count - 1 - currentDepth);
                processor
                .Replace(iterator, ld)
                .InsertAfter(ld, Instruction.Create(OpCodes.Switch, exceptionHandlerTree.EndDestinations));
            }
            break;
            }
        }
Ejemplo n.º 6
0
 private static void ProcessSimpleTree(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree)
 {
     ProcessHandler(processor, exceptionHandlerTree);
     ProcessTry(processor, exceptionHandlerTree);
 }
Ejemplo n.º 7
0
        private static void ProcessTry(ScopedProcessor processor, ExceptionHandlerTree exceptionHandlerTree)
        {
            var handler   = exceptionHandlerTree.Handler;
            var variables = processor.Processor.Body.Variables;

            for (Instruction iterator = handler.TryStart, end = handler.TryEnd; !(iterator is null) && !ReferenceEquals(iterator, end);)