Пример #1
0
        private static void ConnectNodesWithExceptionHandlers(ControlFlowGraph cfg, IEnumerable <ProtectedBlock> protectedBlocks, IDictionary <string, CFGNode> leaders)
        {
            var activeProtectedBlocks = new HashSet <ProtectedBlock>();
            var protectedBlocksStart  = protectedBlocks.ToLookup(pb => pb.Start);
            var protectedBlocksEnd    = protectedBlocks.ToLookup(pb => pb.End);

            foreach (var entry in leaders)
            {
                var label = entry.Key;
                var node  = entry.Value;

                if (protectedBlocksStart.Contains(label))
                {
                    var startingProtectedBlocks = protectedBlocksStart[label];
                    activeProtectedBlocks.UnionWith(startingProtectedBlocks);
                }

                if (protectedBlocksEnd.Contains(label))
                {
                    var endingProtectedBlocks = protectedBlocksEnd[label];
                    activeProtectedBlocks.ExceptWith(endingProtectedBlocks);
                }

                // Connect each node inside a try block to the first corresponding handler block
                foreach (var block in activeProtectedBlocks)
                {
                    var target = leaders[block.Handler.Start];
                    cfg.ConnectNodes(node, target);
                }
            }
        }
Пример #2
0
        public static ControlFlowGraph GenerateNormalControlFlow(MethodBody method)
        {
            var instructions = ControlFlowGraph.FilterExceptionHandlers(method);
            var leaders      = ControlFlowGraph.CreateNodes(instructions);
            var cfg          = ControlFlowGraph.ConnectNodes(instructions, leaders);

            return(cfg);
        }
Пример #3
0
        public static ControlFlowGraph GenerateExceptionalControlFlow(MethodBody method)
        {
            var instructions = method.Instructions;
            var leaders      = ControlFlowGraph.CreateNodes(instructions);
            var cfg          = ControlFlowGraph.ConnectNodes(instructions, leaders);

            ControlFlowGraph.ConnectNodesWithExceptionHandlers(cfg, method.ProtectedBlocks, leaders);

            return(cfg);
        }
Пример #4
0
        private static ControlFlowGraph ConnectNodes(IEnumerable <Instruction> instructions, IDictionary <string, CFGNode> leaders)
        {
            var     cfg = new ControlFlowGraph();
            var     connectWithPreviousNode = true;
            var     current = cfg.Entry;
            CFGNode previous;

            foreach (var instruction in instructions)
            {
                if (leaders.ContainsKey(instruction.Label))
                {
                    previous = current;
                    current  = leaders[instruction.Label];

                    // A node cannot fallthrough itself,
                    // unless it contains another
                    // instruction with the same label
                    // of the node's leader instruction
                    if (connectWithPreviousNode && previous.Id != current.Id)
                    {
                        cfg.ConnectNodes(previous, current);
                    }
                }

                connectWithPreviousNode = true;
                current.Instructions.Add(instruction);

                if (instruction is BranchInstruction)
                {
                    var branch = instruction as BranchInstruction;
                    var target = leaders[branch.Target];

                    cfg.ConnectNodes(current, target);

                    if (branch is UnconditionalBranchInstruction)
                    {
                        connectWithPreviousNode = false;
                    }
                }
                else if (instruction is SwitchInstruction)
                {
                    var branch = instruction as SwitchInstruction;

                    foreach (var label in branch.Targets)
                    {
                        var target = leaders[label];

                        cfg.ConnectNodes(current, target);
                    }
                }
                else if (instruction is ReturnInstruction ||
                         instruction is ThrowInstruction)
                {
                    //TODO: not always connect to exit, could exists a catch or finally block
                    cfg.ConnectNodes(current, cfg.Exit);
                }
            }

            cfg.ConnectNodes(current, cfg.Exit);
            return(cfg);
        }