/// <summary>
        /// Determines the follow nodes in the given subgraph.
        /// </summary>
        /// <remarks>
        /// Every node can follow only one node.
        /// Everey node can be followed by only one node.
        /// The follow node relation cannot form a back edge. (i.e. B can be the follow node of A <=> (A, B) is not a backedge)
        /// Let G = (V, E) be the original graph.
        /// Let G' = (V, E') be the subgraph of G, where E' = E \ { e | e is from E && e is backedge in the DFS traversal }.
        ///
        /// The solution is to find a cover of vertex-disjoint paths of G' that will yield the minimum number of gotos.
        /// The gotos will be the edges that are not in the cover. So we want the edges that will yeild the greatest number of gotos to
        /// be in the cover. If we find a good weight function for the edges in the graph (i.e. correctly determines how much gotos there will be between
        /// two nodes), then all we have to do is find a cover of vertex-disjoint paths of G' with maximum total weight.
        /// </remarks>
        /// <param name="theGraph"></param>
        private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph)
        {
            //Creates the adjacency matrix for the mentioned subgraph - G'.
            GetVerticesAndAdjacencyMatrix(theGraph);

            //Since no back edge is left in G', then G' is a DAG.
            List <KeyValuePair <int, int> > followEdges = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(adjacencyMatrix);

            foreach (KeyValuePair <int, int> followEdge in followEdges)
            {
                orderedVertexArray[followEdge.Key].CFGFollowNode = orderedVertexArray[followEdge.Value].FirstBlock;
                if (orderedVertexArray[followEdge.Key] is ConditionLogicalConstruct)
                {
                    ConditionLogicalConstruct theCondition = orderedVertexArray[followEdge.Key] as ConditionLogicalConstruct;
                    if (theCondition.CFGFollowNode == theCondition.TrueCFGSuccessor)
                    {
                        //If the follow node of a condition construct is the true successor, then we need to negate the condition construct.
                        theCondition.Negate(typeSystem);
                    }
                }
            }
        }
        /// <summary>
        /// Creates a new loop construct and attaches it to the logical tree.
        /// </summary>
        /// <param name="entry">The entry to the loop construct.</param>
        /// <param name="loopBody">Collection containing all of the constructs in the loop body.</param>
        /// <param name="loopType">The type of the loop.</param>
        /// <param name="loopCondition">The condition of the loop.</param>
        public LoopLogicalConstruct(ILogicalConstruct entry,
                                    HashSet <ILogicalConstruct> loopBody, LoopType loopType, ConditionLogicalConstruct loopCondition, TypeSystem typeSystem)
        {
            if (loopCondition != null)
            {
                loopCondition.LogicalContainer = this;
            }

            LoopType      = loopType;
            LoopCondition = loopCondition;

            if (this.LoopType != LoopType.InfiniteLoop)
            {
                loopBody.Remove(LoopCondition);
            }

            DetermineLoopBodyBlock(entry, loopBody);

            RedirectChildrenToNewParent(GetLoopChildrenCollection());

            FixLoopCondition(typeSystem);
        }
예제 #3
0
        private void ProcessLogicalConstruct(ILogicalConstruct theConstruct)
        {
            if (theConstruct is BlockLogicalConstruct)
            {
                ILogicalConstruct current = (ILogicalConstruct)theConstruct.Entry;
                while (current != null)
                {
                    ProcessLogicalConstruct(current);
                    if (visitedConstructs.Contains(current.FollowNode))
                    {
                        current.CFGFollowNode = null;
                    }
                    current = current.FollowNode;
                }

                ProcessGotoFlowConstructs(theConstruct as BlockLogicalConstruct);
            }
            else if (theConstruct is ExceptionHandlingLogicalConstruct)
            {
                ProcessLogicalConstruct((theConstruct as ExceptionHandlingLogicalConstruct).Try);
                if (theConstruct is TryCatchFilterLogicalConstruct)
                {
                    foreach (IFilteringExceptionHandler handler in (theConstruct as TryCatchFilterLogicalConstruct).Handlers)
                    {
                        if (handler.HandlerType == FilteringExceptionHandlerType.Filter)
                        {
                            ProcessLogicalConstruct((handler as ExceptionHandlingBlockFilter).Filter);
                            ProcessLogicalConstruct((handler as ExceptionHandlingBlockFilter).Handler);
                        }
                        else if (handler.HandlerType == FilteringExceptionHandlerType.Catch)
                        {
                            ProcessLogicalConstruct((handler as ExceptionHandlingBlockCatch));
                        }
                    }
                }
                else if (theConstruct is TryFaultLogicalConstruct)
                {
                    ProcessLogicalConstruct((theConstruct as TryFaultLogicalConstruct).Fault);
                }
                else if (theConstruct is TryFinallyLogicalConstruct)
                {
                    ProcessLogicalConstruct((theConstruct as TryFinallyLogicalConstruct).Finally);
                }
            }
            else if (theConstruct is IfLogicalConstruct)
            {
                IfLogicalConstruct theIf = theConstruct as IfLogicalConstruct;
                ProcessLogicalConstruct(theIf.Then);
                if (theIf.Else != null)
                {
                    ProcessLogicalConstruct(theIf.Else);
                }
            }
            else if (theConstruct is LoopLogicalConstruct)
            {
                LoopLogicalConstruct theLogicalLoop = theConstruct as LoopLogicalConstruct;
                ProcessLogicalConstruct(theLogicalLoop.LoopBodyBlock);
                ProcessLogicalConstruct(theLogicalLoop.LoopCondition);
            }
            else if (theConstruct is SwitchLogicalConstruct)
            {
                SwitchLogicalConstruct theLogicalSwitch = theConstruct as SwitchLogicalConstruct;
                foreach (CaseLogicalConstruct @case in theLogicalSwitch.ConditionCases)
                {
                    ProcessLogicalConstruct(@case);
                }
                ProcessLogicalConstruct(theLogicalSwitch.DefaultCase);
            }
            else if (theConstruct is ConditionLogicalConstruct)
            {
                ConditionLogicalConstruct clc = theConstruct as ConditionLogicalConstruct;
                ProcessLogicalConstruct(clc.FirstBlock);
            }

            visitedConstructs.Add(theConstruct);
        }
예제 #4
0
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes, IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            V_0       = interval.get_Entry() as ILogicalConstruct;
            V_1       = new HashSet <ILogicalConstruct>(latchingNodes);
            dummyVar0 = V_1.Add(V_0);
            V_2       = DFSTBuilder.BuildTree(V_0.get_Parent() as ILogicalConstruct);
            V_3       = new HashSet <ILogicalConstruct>();
            V_4       = loopBody.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_5 = V_4.get_Current();
                    V_6 = dominatorTree.GetDominanceFrontier(V_5).GetEnumerator();
                    try
                    {
                        while (V_6.MoveNext())
                        {
                            V_7 = (ILogicalConstruct)V_6.get_Current();
                            if (!interval.get_Children().Contains(V_7) || loopBody.Contains(V_7))
                            {
                                continue;
                            }
                            dummyVar1 = V_3.Add(V_7);
                        }
                    }
                    finally
                    {
                        ((IDisposable)V_6).Dispose();
                    }
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            if (V_3.get_Count() == 0)
            {
                V_8 = V_2.get_ReversePostOrder().GetEnumerator();
                try
                {
                    while (V_8.MoveNext())
                    {
                        V_9 = V_8.get_Current().get_Construct() as ILogicalConstruct;
                        if (loopBody.Contains(V_9))
                        {
                            continue;
                        }
                        loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_9);
                        if (loopCondition == null)
                        {
                            continue;
                        }
                        this.ExpandLoopBody(interval, loopBody, V_9);
                        if (loopCondition != V_0)
                        {
                            V_10 = 2;
                            goto Label1;
                        }
                        else
                        {
                            V_10 = 1;
                            goto Label1;
                        }
                    }
                    goto Label0;
                }
                finally
                {
                    ((IDisposable)V_8).Dispose();
                }
Label1:
                return(V_10);
            }
            V_11 = V_2.get_ReversePostOrder().get_Count();
            V_4  = V_3.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_13 = V_4.get_Current();
                    V_14 = V_2.get_ConstructToNodeMap().get_Item(V_13).get_ReversePostOrderIndex();
                    if (V_14 >= V_11)
                    {
                        continue;
                    }
                    V_11 = V_14;
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            V_12          = V_2.get_ReversePostOrder().get_Item(V_11).get_Construct() as ILogicalConstruct;
            loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_12);
            this.ExpandLoopBody(interval, loopBody, V_12);
            if (loopCondition == null)
            {
                return(0);
            }
            if (loopCondition == V_0)
            {
                return(1);
            }
            return(2);

Label0:
            if (!this.CanBeLoopCondition(V_0, loopBody))
            {
                loopCondition = null;
                return(0);
            }
            loopCondition = V_0 as ConditionLogicalConstruct;
            return(1);
        }
 public LoopLogicalConstruct(ILogicalConstruct entry, HashSet <ILogicalConstruct> loopBody, Telerik.JustDecompiler.Decompiler.LogicFlow.Loops.LoopType loopType, ConditionLogicalConstruct loopCondition, TypeSystem typeSystem)
 {
     base();
     if (loopCondition != null)
     {
         loopCondition.set_LogicalContainer(this);
     }
     this.set_LoopType(loopType);
     this.set_LoopCondition(loopCondition);
     if (this.get_LoopType() != Telerik.JustDecompiler.Decompiler.LogicFlow.Loops.LoopType.InfiniteLoop)
     {
         dummyVar0 = loopBody.Remove(this.get_LoopCondition());
     }
     this.DetermineLoopBodyBlock(entry, loopBody);
     this.RedirectChildrenToNewParent(this.GetLoopChildrenCollection());
     this.FixLoopCondition(typeSystem);
     return;
 }
예제 #6
0
        /// <summary>
        /// Determines the type of the loop and the condition of the loop. Adds additional nodes into the loop body.
        /// </summary>
        /// <param name="loopBody"></param>
        /// <param name="header"></param>
        /// <param name="latchingNodes"></param>
        /// <param name="interval"></param>
        /// <param name="loopCondition"></param>
        /// <returns></returns>
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes,
                                           IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            ILogicalConstruct           header     = interval.Entry as ILogicalConstruct;
            HashSet <ILogicalConstruct> legalExits = new HashSet <ILogicalConstruct>(latchingNodes);

            legalExits.Add(header);

            ILogicalConstruct parentConstruct = header.Parent as ILogicalConstruct;
            DFSTree           dfsTree         = DFSTBuilder.BuildTree(parentConstruct);

            //B - nodes in the loop body (= loopBody)
            //I - nodes in the interval (= interval.Children)
            //U - union of all of the dominance frontiers of the nodes in B
            //exitDominanceFrontier = (U n I) \ B
            //If a node is in the exitDominanceFrontier, then it is dominated by the header and is a successor (not necessarily direct) of more than one
            //node in the loop body.
            HashSet <ILogicalConstruct> exitDominanceFrontier = new HashSet <ILogicalConstruct>();

            foreach (ILogicalConstruct loopNode in loopBody)
            {
                foreach (ILogicalConstruct frontierNode in dominatorTree.GetDominanceFrontier(loopNode))
                {
                    if (interval.Children.Contains(frontierNode) && !loopBody.Contains(frontierNode))
                    {
                        exitDominanceFrontier.Add(frontierNode);
                    }
                }
            }

            //This is leftover heuristic, that was used for determining a suitable successor that is going to be follow node of the loop.
            //Changing it now will break a good number of the tests. Since the produced output is acceptable, until a better heuristic is found
            //there is no need to change it.
            if (exitDominanceFrontier.Count == 0)
            {
                //If the exit dominance frontier is empty then we look for the node, with minimum post order index, that is a successor of a condition loop exit.
                //The desired exit should be a condition in order to reduce the number of infinite loops (heuristic).
                foreach (DFSTNode dfsNode in dfsTree.ReversePostOrder)
                {
                    ILogicalConstruct construct = dfsNode.Construct as ILogicalConstruct;
                    if (loopBody.Contains(construct))
                    {
                        continue;
                    }

                    loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, construct);
                    //By taking the successor with the minimum post order index and the loop exit with the maximum post order index, we ensure that
                    //the produced construct will always be the same, since the post order in our case is a total order.
                    //There are other various ways of finding the exit-successor pair that can bring consistent output, but none of them is found to yield
                    //better results than the rest.
                    if (loopCondition != null)
                    {
                        //We expand the loop body only when we've found a condition successor of the loop.
                        //This is done in order to avoid adding all of the dominated nodes of an infinite loop to the body. (Better readability of the final code.)
                        //E.g.: An infinite loop on the top level of the logical tree (i.e. child of the method block construct). If it dominates all of its
                        //succeeding nodes then they will be in its interval, which means that they will be added to the loop. As a result there will
                        //be an infinite loop at the end of the method, that encloses a cood part of the code, for no apparent reason.
                        ExpandLoopBody(interval, loopBody, construct);

                        if (loopCondition == header)
                        {
                            return(LoopType.PreTestedLoop);
                        }
                        else
                        {
                            return(LoopType.PostTestedLoop);
                        }
                    }
                }

                if (CanBeLoopCondition(header, loopBody))
                {
                    loopCondition = header as ConditionLogicalConstruct;
                    return(LoopType.PreTestedLoop);
                }
                else
                {
                    loopCondition = null;
                    return(LoopType.InfiniteLoop);
                }
            }
            else
            {
                //If there are nodes in the exitDominanceFrontier, then we choose the one with the minimum postorder index for successor of the loop.
                //Then we try to find a condition exit of the loop, with maximum post order index, that is predecessor of the successor node.
                int minOrderIndexOfSuccessor = dfsTree.ReversePostOrder.Count;
                foreach (ILogicalConstruct successor in exitDominanceFrontier)
                {
                    int currentOrderIndex = dfsTree.ConstructToNodeMap[successor].ReversePostOrderIndex;

                    if (currentOrderIndex < minOrderIndexOfSuccessor)
                    {
                        minOrderIndexOfSuccessor = currentOrderIndex;
                    }
                }

                ILogicalConstruct loopSuccessor = dfsTree.ReversePostOrder[minOrderIndexOfSuccessor].Construct as ILogicalConstruct;

                loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, loopSuccessor);

                ExpandLoopBody(interval, loopBody, loopSuccessor);

                if (loopCondition != null)
                {
                    if (loopCondition == header)
                    {
                        return(LoopType.PreTestedLoop);
                    }
                    else
                    {
                        return(LoopType.PostTestedLoop);
                    }
                }
                else
                {
                    return(LoopType.InfiniteLoop);
                }
            }
        }