コード例 #1
0
    public static (ControlFlowGraph, string) Decompile(ControlFlowGraph graph /*, RecordFunc recordFunc = null*/)
    {
        if (graph == null)
        {
            throw new ArgumentNullException(nameof(graph));
        }
        var regions = graph.GetAllSeseRegions();

        // Do smallest regions first, as they may be nested in a larger one
        foreach (var(region, regionEntry, regionExit) in regions.OrderBy(x => x.nodes.Count))
        {
            if (regionEntry == graph.EntryIndex)
            {
                continue; // Don't try and reduce the 'sequence' of start node -> actual entry point nodes when there's only one entry
            }

            /* Func<string> vis = () => // For VS Code debug visualisation
             * {
             *   var d = graph.ToVis();
             *   foreach(var n in d.Nodes)
             *      if (region.Contains(int.Parse(n.Id, CultureInfo.InvariantCulture)))
             *          n.Color = "#4040b0";
             *   return d.ToString();
             * }; */
            bool containsOther = regions.Any(x => x.nodes != region && !x.nodes.Except(region).Any());
            if (containsOther)
            {
                continue;
            }

            // If either end is a loop header then leave it alone and let the loop rule handle it.
            if (graph.GetBackEdges().Any(x => x.end == regionEntry || x.end == regionExit))
            {
                continue;
            }

            var cut = graph.Cut(region, regionEntry, regionExit);

            if (cut.Cut.IsCyclic()) // Loop reduction comes later
            {
                continue;
            }

            return(cut.Merge(ReduceSese(cut.Cut)), Description);
        }

        return(graph, null);
    }