Exemple #1
0
 public void SplitConditionalCFGBlocks()
 {
     V_0 = (new List <KeyValuePair <InstructionBlock, CFGBlockLogicalConstruct[]> >(this.logicalContext.get_CFGBlockToLogicalConstructMap())).GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             if ((int)V_1.get_Key().get_Successors().Length <= 1)
             {
                 continue;
             }
             V_2 = V_1.get_Value()[(int)V_1.get_Value().Length - 1];
             if (V_2.get_LogicalConstructExpressions().get_Count() <= 1)
             {
                 continue;
             }
             dummyVar0 = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_2, V_2.get_LogicalConstructExpressions().get_Count() - 1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
        /// <summary>
        /// Gets the first found entry CFGBlockLogicalConstruct for a state from the tryStates.
        /// </summary>
        /// <remarks>
        /// We try to get the first CFGBlockLC, that is going to be reached by the control flow, in which the state field is assigned to a state of the
        /// <paramref name="tryStates"/>. If the assignment is not at the begining of the CFGConstruct then we need to split it, since the try begins
        /// at the assignment.
        /// </remarks>
        /// <param name="tryStates"></param>
        /// <returns></returns>
        private CFGBlockLogicalConstruct GetStateBeginBlockConstruct(HashSet <int> tryStates)
        {
            for (int i = 0; i < this.orderedCFGNodes.Count; i++)
            {
                CFGBlockLogicalConstruct currentCFGConstruct = this.orderedCFGNodes[i];

                List <Expression> blockExpressions = currentCFGConstruct.LogicalConstructExpressions;
                for (int j = 0; j < blockExpressions.Count; j++)
                {
                    int value;
                    if (TryGetStateAssignValue(blockExpressions[j], out value) && tryStates.Contains(value))
                    {
                        if (j != 0)
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> newCFGConstructsPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, currentCFGConstruct, j);

                            this.orderedCFGNodes[i] = newCFGConstructsPair.Key;
                            this.orderedCFGNodes.Insert(i + 1, newCFGConstructsPair.Value);

                            return(newCFGConstructsPair.Value);
                        }
                        else
                        {
                            return(currentCFGConstruct);
                        }
                    }
                }
            }

            throw new Exception("Invalid state value");
        }
 private CFGBlockLogicalConstruct GetStateBeginBlockConstruct(HashSet <int> tryStates)
 {
     V_0 = 0;
     while (V_0 < this.orderedCFGNodes.get_Count())
     {
         V_1 = this.orderedCFGNodes.get_Item(V_0);
         V_2 = V_1.get_LogicalConstructExpressions();
         V_3 = 0;
         while (V_3 < V_2.get_Count())
         {
             if (this.TryGetStateAssignValue(V_2.get_Item(V_3), out V_4) && tryStates.Contains(V_4))
             {
                 if (V_3 == 0)
                 {
                     return(V_1);
                 }
                 V_5 = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_1, V_3);
                 this.orderedCFGNodes.set_Item(V_0, V_5.get_Key());
                 this.orderedCFGNodes.Insert(V_0 + 1, V_5.get_Value());
                 return(V_5.get_Value());
             }
             V_3 = V_3 + 1;
         }
         V_0 = V_0 + 1;
     }
     throw new Exception("Invalid state value");
 }
Exemple #4
0
 protected virtual string ToString(string constructName, HashSet <CFGBlockLogicalConstruct> printedCFGBlocks, LogicalFlowBuilderContext context)
 {
     V_0       = new StringBuilder();
     dummyVar0 = V_0.AppendLine(constructName);
     dummyVar1 = V_0.AppendLine("{");
     V_1       = this.GetSortedArrayFromCollection <CFGBlockLogicalConstruct>(this.get_CFGBlocks());
     V_2       = new Stack <CFGBlockLogicalConstruct>();
     V_4       = 0;
     while (V_4 < (int)V_1.Length)
     {
         V_5 = V_1[V_4] as CFGBlockLogicalConstruct;
         if (!printedCFGBlocks.Contains(V_5))
         {
             V_2.Push(V_5);
             while (V_2.get_Count() > 0)
             {
                 V_6 = V_2.Pop();
                 if (printedCFGBlocks.Contains(V_6) || !LogicalFlowUtilities.TryGetParentConstructWithGivenParent(V_6, this, out V_7))
                 {
                     continue;
                 }
                 stackVariable48    = ((LogicalConstructBase)V_7).ToString(V_7.GetType().get_Name(), printedCFGBlocks, context);
                 stackVariable50    = new String[1];
                 stackVariable50[0] = Environment.get_NewLine();
                 V_9  = stackVariable48.Split(stackVariable50, 1);
                 V_10 = 0;
                 while (V_10 < (int)V_9.Length)
                 {
                     V_11      = V_9[V_10];
                     dummyVar2 = V_0.AppendLine(String.Format("\t{0}", V_11));
                     V_10      = V_10 + 1;
                 }
                 V_8  = this.GetSortedArrayFromCollection <ISingleEntrySubGraph>(V_7.get_SameParentSuccessors());
                 V_12 = (int)V_8.Length - 1;
                 while (V_12 >= 0)
                 {
                     if (!printedCFGBlocks.Contains(V_8[V_12].get_FirstBlock()))
                     {
                         V_2.Push(V_8[V_12].get_FirstBlock());
                     }
                     V_12 = V_12 - 1;
                 }
             }
         }
         V_4 = V_4 + 1;
     }
     V_3       = String.Format("\tFollowNode: {0}", this.NodeILOffset(context, this.get_CFGFollowNode()));
     dummyVar3 = V_0.AppendLine(V_3);
     dummyVar4 = V_0.AppendLine("}");
     return(V_0.ToString());
 }
        /// <summary>
        /// Splits each CFG construct that has more than one successor (i.e. condition block) and holds more than one expression.
        /// </summary>
        public void SplitConditionalCFGBlocks()
        {
            //We need to copy the dictionary, since the LogicalFlowUtilities.SplitCFGBlockAt method modifies it (and the enumerator explodes).
            //Also we copy it in a list, since we don't need the functionality of the dictionary.
            List <KeyValuePair <InstructionBlock, CFGBlockLogicalConstruct[]> > blockToConstructsPairList =
                new List <KeyValuePair <InstructionBlock, CFGBlockLogicalConstruct[]> >(logicalContext.CFGBlockToLogicalConstructMap);

            foreach (KeyValuePair <InstructionBlock, CFGBlockLogicalConstruct[]> blockToConstructsPair in blockToConstructsPairList)
            {
                if (blockToConstructsPair.Key.Successors.Length > 1)
                {
                    //For each instruction block there can be more than one partial CFG LC, so we take the last one, since it will hold the condition expression.
                    CFGBlockLogicalConstruct cfgConstruct = blockToConstructsPair.Value[blockToConstructsPair.Value.Length - 1];
                    if (cfgConstruct.LogicalConstructExpressions.Count > 1)
                    {
                        //If the last construct for this block holds more than one expression we split it at the last expression.
                        LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, cfgConstruct, cfgConstruct.LogicalConstructExpressions.Count - 1);
                    }
                }
            }
        }
        /// <summary>
        /// Checks each a node before adding its successors to the <paramref name="bfsQueue"/>.
        /// </summary>
        /// <remarks>
        /// If the node is a CFGBlockLC and it contains the invocation of the finally method, or the entry of the finally block,
        /// then we should not continue the traversal.
        /// </remarks>
        /// <param name="handlerInfo"></param>
        /// <param name="bfsQueue"></param>
        /// <param name="currentNode"></param>
        private void ProcessCurrentNode(YieldExceptionHandlerInfo handlerInfo, Queue <ILogicalConstruct> bfsQueue, ILogicalConstruct currentNode)
        {
            if (currentNode is CFGBlockLogicalConstruct)
            {
                CFGBlockLogicalConstruct currentCFGNode = currentNode as CFGBlockLogicalConstruct;
                for (int i = 0; i < currentCFGNode.LogicalConstructExpressions.Count; i++)
                {
                    Expression currentExpression = currentCFGNode.LogicalConstructExpressions[i];

                    int value;
                    if (TryGetStateAssignValue(currentExpression, out value))
                    {
                        if (!handlerInfo.TryStates.Contains(value)) //sanity check
                        {
                            if (handlerInfo.HandlerType != YieldExceptionHandlerType.Method &&
                                TryProcessConditionalDisposeHandler(handlerInfo, currentCFGNode))
                            {
                                return;
                            }
                            throw new Exception("Invalid state value");
                        }
                    }
                    else if (handlerInfo.HandlerType == YieldExceptionHandlerType.Method &&
                             currentExpression.CodeNodeType == CodeNodeType.MethodInvocationExpression &&
                             (currentExpression as MethodInvocationExpression).MethodExpression.MethodDefinition == handlerInfo.FinallyMethodDefinition)
                    {
                        //For the finally block we need the CFGBlockLC that contains only the invocation of the finally method.
                        //That's why we need to split the CFGBlockLC, if there are other expressions besides the invocation.
                        CFGBlockLogicalConstruct currentFinallyBlock;
                        if (currentCFGNode.LogicalConstructExpressions.Count == 1)
                        {
                            if (newFinallyBody == null)
                            {
                                newFinallyBody = currentCFGNode;
                            }
                            finallyBlocks.Add(newFinallyBody);
                            orderedCFGNodes.Remove(currentCFGNode);
                            return;
                        }

                        if (i == 0)
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> newConstructsPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i + 1);

                            currentFinallyBlock = newConstructsPair.Key;
                            orderedCFGNodes[orderedCFGNodes.IndexOf(currentCFGNode)] = newConstructsPair.Value;
                        }
                        else if (i < currentCFGNode.LogicalConstructExpressions.Count - 1)
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> endOfTryPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i);
                            newTryBody.Add(endOfTryPair.Key);

                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> finallyRestOfBlockPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, endOfTryPair.Value, 1);

                            currentFinallyBlock = finallyRestOfBlockPair.Key;
                            orderedCFGNodes[orderedCFGNodes.IndexOf(currentCFGNode)] = finallyRestOfBlockPair.Value;
                        }
                        else // i == count - 1
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> tryFinallyPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i);

                            newTryBody.Add(tryFinallyPair.Key);
                            currentFinallyBlock = tryFinallyPair.Value;

                            orderedCFGNodes.Remove(currentCFGNode);
                        }

                        if (newFinallyBody == null)
                        {
                            newFinallyBody = currentFinallyBlock;
                        }
                        finallyBlocks.Add(currentFinallyBlock);

                        return;
                    }
                }
            }
            else if (currentNode is TryFinallyLogicalConstruct)
            {
                TryFinallyLogicalConstruct tryFinallyConstruct = currentNode as TryFinallyLogicalConstruct;
                YieldExceptionHandlerInfo  oldHandlerInfo;
                if (createdConstructsToIntervalMap.TryGetValue(tryFinallyConstruct, out oldHandlerInfo) &&
                    oldHandlerInfo.TryStates.IsProperSupersetOf(handlerInfo.TryStates))
                {
                    throw new Exception("This try/finally construct cannot be nested in the current construct");
                }
            }

            newTryBody.Add(currentNode);
            foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors)
            {
                bfsQueue.Enqueue(successor);
            }
        }
Exemple #7
0
 private bool HasForParent(ILogicalConstruct supposedParent)
 {
     return(LogicalFlowUtilities.TryGetParentConstructWithGivenParent(this, supposedParent, out V_0));
 }
        /// <summary>
        /// Gets a string representation of this logical construct.
        /// </summary>
        /// <remarks>
        /// Used for testing purposes.
        /// </remarks>
        /// <param name="constructName">The name of the construct.</param>
        /// <param name="printedCFGBlocks">A set containing all of the CFG block logical constructs that are already traversed.</param>
        /// <param name="context">The current logical flow builder context.</param>
        /// <returns></returns>
        protected virtual string ToString(string constructName, HashSet <CFGBlockLogicalConstruct> printedCFGBlocks, LogicalFlowBuilderContext context)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(constructName);
            sb.AppendLine("{");

            ILogicalConstruct[] cfgBlocksArray = GetSortedArrayFromCollection(this.CFGBlocks);

            Stack <CFGBlockLogicalConstruct> printingStack = new Stack <CFGBlockLogicalConstruct>();

            for (int i = 0; i < cfgBlocksArray.Length; i++)
            {
                CFGBlockLogicalConstruct currentCFGBlock = cfgBlocksArray[i] as CFGBlockLogicalConstruct;

                //If the current node is already printed we skip it.
                if (printedCFGBlocks.Contains(currentCFGBlock))
                {
                    continue;
                }

                //We use a stack to print the constructs in preorder.
                printingStack.Push(currentCFGBlock);
                while (printingStack.Count > 0)
                {
                    CFGBlockLogicalConstruct blockToPrint = printingStack.Pop();
                    if (printedCFGBlocks.Contains(blockToPrint))
                    {
                        continue;
                    }

                    //Foreach CFG construct that is not printed we get the parent (not necessarily direct) logical construct that is child of this construct
                    //(i.e. childConstructToPrint is the child of this construct that contains the blockToPrint).
                    ILogicalConstruct childConstructToPrint;
                    if (!LogicalFlowUtilities.TryGetParentConstructWithGivenParent(blockToPrint, this, out childConstructToPrint))
                    {
                        continue;
                    }

                    string childString = ((LogicalConstructBase)childConstructToPrint).ToString(childConstructToPrint.GetType().Name, printedCFGBlocks, context);

                    //Indent each line of child's strings by one tab, so that they appear visually better
                    string[] childStringLines = childString.Split(new String[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string line in childStringLines)
                    {
                        sb.AppendLine(string.Format("\t{0}", line));
                    }

                    //We get a sorted array ot the child's same parent successors and we push their CFG logical construct entries in reverse order on the
                    //printing stack, so that the closest successor is going to be printed next.
                    ILogicalConstruct[] sameParentSuccessors = GetSortedArrayFromCollection(childConstructToPrint.SameParentSuccessors);

                    for (int j = sameParentSuccessors.Length - 1; j >= 0; j--)
                    {
                        if (!printedCFGBlocks.Contains(sameParentSuccessors[j].FirstBlock))
                        {
                            printingStack.Push(sameParentSuccessors[j].FirstBlock);
                        }
                    }
                }
            }

            string followNodeString = string.Format("\tFollowNode: {0}", NodeILOffset(context, CFGFollowNode));

            sb.AppendLine(followNodeString);
            sb.AppendLine("}");
            return(sb.ToString());
        }
 private void ProcessCurrentNode(YieldExceptionHandlerInfo handlerInfo, Queue <ILogicalConstruct> bfsQueue, ILogicalConstruct currentNode)
 {
     if (currentNode as CFGBlockLogicalConstruct == null)
     {
         if (currentNode as TryFinallyLogicalConstruct != null && this.createdConstructsToIntervalMap.TryGetValue(currentNode as TryFinallyLogicalConstruct, out V_10) && V_10.get_TryStates().IsProperSupersetOf(handlerInfo.get_TryStates()))
         {
             throw new Exception("This try/finally construct cannot be nested in the current construct");
         }
     }
     else
     {
         V_0 = currentNode as CFGBlockLogicalConstruct;
         V_1 = 0;
         while (V_1 < V_0.get_LogicalConstructExpressions().get_Count())
         {
             V_2 = V_0.get_LogicalConstructExpressions().get_Item(V_1);
             if (!this.TryGetStateAssignValue(V_2, out V_3))
             {
                 if (handlerInfo.get_HandlerType() == YieldExceptionHandlerType.Method && V_2.get_CodeNodeType() == 19 && (object)(V_2 as MethodInvocationExpression).get_MethodExpression().get_MethodDefinition() == (object)handlerInfo.get_FinallyMethodDefinition())
                 {
                     if (V_0.get_LogicalConstructExpressions().get_Count() == 1)
                     {
                         if (this.newFinallyBody == null)
                         {
                             this.newFinallyBody = V_0;
                         }
                         dummyVar0 = this.finallyBlocks.Add(this.newFinallyBody);
                         dummyVar1 = this.orderedCFGNodes.Remove(V_0);
                         return;
                     }
                     if (V_1 != 0)
                     {
                         if (V_1 >= V_0.get_LogicalConstructExpressions().get_Count() - 1)
                         {
                             V_8       = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_0, V_1);
                             dummyVar3 = this.newTryBody.Add(V_8.get_Key());
                             V_4       = V_8.get_Value();
                             dummyVar4 = this.orderedCFGNodes.Remove(V_0);
                         }
                         else
                         {
                             V_6       = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_0, V_1);
                             dummyVar2 = this.newTryBody.Add(V_6.get_Key());
                             V_7       = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_6.get_Value(), 1);
                             V_4       = V_7.get_Key();
                             this.orderedCFGNodes.set_Item(this.orderedCFGNodes.IndexOf(V_0), V_7.get_Value());
                         }
                     }
                     else
                     {
                         V_5 = LogicalFlowUtilities.SplitCFGBlockAt(this.logicalContext, V_0, V_1 + 1);
                         V_4 = V_5.get_Key();
                         this.orderedCFGNodes.set_Item(this.orderedCFGNodes.IndexOf(V_0), V_5.get_Value());
                     }
                     if (this.newFinallyBody == null)
                     {
                         this.newFinallyBody = V_4;
                     }
                     dummyVar5 = this.finallyBlocks.Add(V_4);
                     return;
                 }
             }
             else
             {
                 if (!handlerInfo.get_TryStates().Contains(V_3))
                 {
                     if (handlerInfo.get_HandlerType() == YieldExceptionHandlerType.Method || !this.TryProcessConditionalDisposeHandler(handlerInfo, V_0))
                     {
                         throw new Exception("Invalid state value");
                     }
                     return;
                 }
             }
             V_1 = V_1 + 1;
         }
     }
     dummyVar6 = this.newTryBody.Add(currentNode);
     V_11      = currentNode.get_SameParentSuccessors().GetEnumerator();
     try
     {
         while (V_11.MoveNext())
         {
             V_12 = (ILogicalConstruct)V_11.get_Current();
             bfsQueue.Enqueue(V_12);
         }
     }
     finally
     {
         ((IDisposable)V_11).Dispose();
     }
     return;
 }