/// <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");
        }
Exemplo n.º 2
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;
 }
 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");
 }
        /// <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);
            }
        }
 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;
 }