public ScopeBlock CreateBlock() { var rootScope = new ScopeBlock(); TraverseNode(rootScope, _cfg.Nodes, _cfg.Entrypoint); return(rootScope); }
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)); } }
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); }
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); }
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); }