Example #1
0
        public ScopeBlock CreateBlock()
        {
            var rootScope = new ScopeBlock();

            TraverseNode(rootScope, _cfg.Nodes, _cfg.Entrypoint);
            return(rootScope);
        }
Example #2
0
 private void TraverseUnprocessedNodes(ScopeBlock parentScope, ICollection <Node> scope, List <Node> unprocessedNodes)
 {
     foreach (var node in unprocessedNodes.ToArray().Where(scope.Contains))
     {
         unprocessedNodes.Remove(node);
         unprocessedNodes.AddRange(TraverseNode(parentScope, scope, node));
     }
 }
Example #3
0
        private IList <Node> TraverseNode(ScopeBlock parentScope, ICollection <Node> scope, Node node)
        {
            var unprocessedNodes = new List <Node>();

            var basicBlock = CreateBasicBlock(node);

            parentScope.Blocks.Add(basicBlock);

            var children = GetTreeNode(node).OutgoingEdges
                           .Select(e => GetCfgNode(e.Target))
                           .Where(n => n.IncomingEdges.All(IsNormalEdge))
                           .ToArray();

            var directChildren = children
                                 .Where(c => c.GetPredecessors().Contains(node))
                                 .OrderByDescending(n => _nodeToComponent[n].Count)
                                 .ToArray();

            var indirectChildren = children
                                   .Except(directChildren)
                                   .OrderByDescending(n => _nodeToComponent[n].Count)
                                   .ToArray();

            foreach (var child in directChildren.Union(indirectChildren))
            {
                if (!scope.Contains(child))
                {
                    unprocessedNodes.Add(child);
                }
                else
                {
                    var ehScope = child.SubGraphs.Except(node.SubGraphs).ToArray();
                    switch (ehScope.Length)
                    {
                    case 0:
                        unprocessedNodes.AddRange(TraverseNode(parentScope, scope, child));
                        break;

                    case 1:
                        unprocessedNodes.AddRange(TraverseEHNode(parentScope, ehScope[0].Nodes, child, ehScope[0]));
                        break;

                    default:
                        // This would mean we enter multiple EHs at once, which is impossible in vanilla KoiVM.
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }

            TraverseUnprocessedNodes(parentScope, scope, unprocessedNodes);

            return(unprocessedNodes);
        }
Example #4
0
        public ScopeBlock CreateBlock()
        {
            var sorter = new TopologicalSorter(n =>
            {
                return(n.OutgoingEdges
                       .OrderByDescending(IsNormalEdge)
                       .Select(e => e.Target)
                       .ToList());
            });

            var sorting = sorter.GetTopologicalSorting(_cfg.Entrypoint);

            var rootScope = new ScopeBlock();

            foreach (var node in sorting.Reverse())
            {
                rootScope.Blocks.Add(CreateBasicBlock(node));
            }

            return(rootScope);
        }
Example #5
0
        private IList <Node> TraverseEHNode(ScopeBlock parentScope, ICollection <Node> scope, Node tryStart, SubGraph ehCluster)
        {
            var frame       = (EHFrame)ehCluster.UserData[EHFrame.EHFrameProperty];
            var tryBody     = (ICollection <Node>)ehCluster.UserData[ControlFlowGraph.TryBlockProperty];
            var handlerBody = (ICollection <Node>)ehCluster.UserData[ControlFlowGraph.HandlerBlockProperty];

            var handlerStart = _cfg.Nodes[_cfg.GetNodeName((long)frame.HandlerAddress)];

            var unprocessedNodes = new List <Node>();

            var ehBlock = new ExceptionHandlerBlock
            {
                TryBlock     = new ScopeBlock(),
                HandlerBlock = new ScopeBlock()
            };

            parentScope.Blocks.Add(ehBlock);

            unprocessedNodes.AddRange(TraverseNode(ehBlock.TryBlock, tryBody, tryStart));
            unprocessedNodes.AddRange(TraverseNode(ehBlock.HandlerBlock, handlerBody, handlerStart));

            return(unprocessedNodes);
        }