示例#1
0
        /// <summary>
        /// Marks the predecessors of this block as yield return. Also adds this block to the set of nodes that are to be removed.
        /// </summary>
        /// <remarks>
        /// If a predecessor of the specified block is a block with a single unconditional branch instruction, then this method is
        /// recursively called for that predecessor.
        /// </remarks>
        /// <param name="theBlock"></param>
        private bool MarkPredecessorsAsYieldReturns(InstructionBlock theBlock)
        {
            toBeRemoved.Add(theBlock);

            HashSet <InstructionBlock> predecessors = new HashSet <InstructionBlock>(theBlock.Predecessors);

            foreach (InstructionBlock predecessor in predecessors)
            {
                if (predecessor.Last == predecessor.First)
                {
                    if (StateMachineUtilities.IsUnconditionalBranch(predecessor.Last) && MarkPredecessorsAsYieldReturns(predecessor))
                    {
                        continue;
                    }
                    else
                    {
                        //throw new Exception("Illegal block");
                        return(false);
                    }
                }

                if (!TryAddToYieldReturningBlocks(predecessor))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#2
0
        /// <summary>
        /// Marks the predecessors, of the specifed instruction block, that set the return flag variable to true, as yield returns.
        /// </summary>
        /// <remarks>
        /// If a predecessor is a block that contains a single unconditional branch instruction then we recursively call the method for that
        /// predecessor and we mark it for removal.
        /// This means that the block, that we initially call this method for, will not be removed and will be left to be marked as an yield break.
        /// </remarks>
        /// <param name="theBlock"></param>
        private bool MarkTrueReturningPredecessorsAsYieldReturn(InstructionBlock theBlock)
        {
            HashSet <InstructionBlock> predecessors = new HashSet <InstructionBlock>(theBlock.Predecessors);

            foreach (InstructionBlock predecessor in predecessors)
            {
                if (predecessor.Last == predecessor.First)
                {
                    if (StateMachineUtilities.IsUnconditionalBranch(predecessor.Last))
                    {
                        toBeRemoved.Add(predecessor);
                        if (!MarkTrueReturningPredecessorsAsYieldReturn(predecessor))
                        {
                            return(false);
                        }
                        continue;
                    }
                    else
                    {
                        return(false);
                    }
                }

                VariableReference flagVarReference = null;

                Instruction lastInstruction = predecessor.Last;
                if (StateMachineUtilities.IsUnconditionalBranch(lastInstruction))
                {
                    lastInstruction = lastInstruction.Previous;
                }

                int returnValue;
                if (TryGetVariableFromInstruction(lastInstruction, out flagVarReference) && CheckAndSaveReturnFlagVariable(flagVarReference) &&
                    StateMachineUtilities.TryGetOperandOfLdc(lastInstruction.Previous, out returnValue))
                {
                    if (returnValue == 1)
                    {
                        if (!TryAddToYieldReturningBlocks(predecessor))
                        {
                            return(false);
                        }
                    }
                    else if (returnValue != 0)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Checks if the given block is block that contains only Finally method invocation. This pattern is brought by the new C#6.0 compiler.
        /// </summary>
        private bool IsFinallyMethodInvocationBlock(InstructionBlock block)
        {
            // The pattern is like so:
            // ldarg.0
            // call instance void ... (the finally method)
            // nop <- could be missing
            // leave.s ...

            Instruction current = block.First;

            if (current.OpCode.Code != Code.Ldarg_0)
            {
                return(false);
            }

            current = current.Next;
            if (current.OpCode.Code != Code.Call)
            {
                return(false);
            }

            Instruction callInstruction = current;

            current = current.Next;
            if (current.OpCode.Code == Code.Nop)
            {
                current = current.Next;
            }

            if (!StateMachineUtilities.IsUnconditionalBranch(current))
            {
                return(false);
            }

            if (block.Last != current)
            {
                return(false);
            }

            MethodReference finallyMethod = callInstruction.Operand as MethodReference;

            if (finallyMethod == null)
            {
                return(false);
            }

            if (!finallyMethod.Name.StartsWith("<>m__Finally"))
            {
                return(false);
            }

            return(true);
        }
示例#4
0
 private bool IsFalseReturnBlock(InstructionBlock theBlock)
 {
     V_0 = theBlock.get_First();
     if (V_0.get_OpCode().get_Code() != 22 || (object)V_0 == (object)theBlock.get_Last())
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if (!this.TryGetVariableFromInstruction(V_0, out V_1) || (object)V_0 == (object)theBlock.get_Last() || !this.CheckAndSaveReturnFlagVariable(V_1))
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     return(StateMachineUtilities.IsUnconditionalBranch(V_0));
 }
        /// <summary>
        /// Checks whether the block sets the returnFlag variable to false.
        /// </summary>
        /// <param name="theBlock"></param>
        /// <returns></returns>
        private bool IsFalseReturnBlock(InstructionBlock theBlock)
        {
            Instruction currentInstruction = theBlock.First;

            if (currentInstruction.OpCode.Code != Code.Ldc_I4_0 || currentInstruction == theBlock.Last)
            {
                return(false);
            }

            currentInstruction = currentInstruction.Next;
            VariableReference retFlagVariable;

            if (!TryGetVariableFromInstruction(currentInstruction, out retFlagVariable) || currentInstruction == theBlock.Last ||
                !CheckAndSaveReturnFlagVariable(retFlagVariable))
            {
                return(false);
            }

            currentInstruction = currentInstruction.Next;
            return(StateMachineUtilities.IsUnconditionalBranch(currentInstruction));
        }
示例#6
0
        private bool MarkPredecessorsAsYieldReturns(InstructionBlock theBlock)
        {
            dummyVar0 = this.toBeRemoved.Add(theBlock);
            V_0       = (new HashSet <InstructionBlock>(theBlock.get_Predecessors())).GetEnumerator();
            try
            {
                while (V_0.MoveNext())
                {
                    V_1 = V_0.get_Current();
                    if ((object)V_1.get_Last() != (object)V_1.get_First())
                    {
                        if (this.TryAddToYieldReturningBlocks(V_1))
                        {
                            continue;
                        }
                        V_2 = false;
                        goto Label1;
                    }
                    else
                    {
                        if (StateMachineUtilities.IsUnconditionalBranch(V_1.get_Last()) && this.MarkPredecessorsAsYieldReturns(V_1))
                        {
                            continue;
                        }
                        V_2 = false;
                        goto Label1;
                    }
                }
                goto Label0;
            }
            finally
            {
                ((IDisposable)V_0).Dispose();
            }
Label1:
            return(V_2);

Label0:
            return(true);
        }
示例#7
0
 private bool IsFinallyMethodInvocationBlock(InstructionBlock block)
 {
     V_0 = block.get_First();
     if (V_0.get_OpCode().get_Code() != 2)
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() != 39)
     {
         return(false);
     }
     V_1 = V_0;
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() == null)
     {
         V_0 = V_0.get_Next();
     }
     if (!StateMachineUtilities.IsUnconditionalBranch(V_0))
     {
         return(false);
     }
     if ((object)block.get_Last() != (object)V_0)
     {
         return(false);
     }
     V_2 = V_1.get_Operand() as MethodReference;
     if (V_2 == null)
     {
         return(false);
     }
     if (!V_2.get_Name().StartsWith("<>m__Finally"))
     {
         return(false);
     }
     return(true);
 }
 /// <summary>
 /// Checks whether the given block contains only an unconditional branch instruction.
 /// </summary>
 /// <param name="theBlock"></param>
 /// <returns></returns>
 protected virtual bool IsUnconditionalBranchBlock(InstructionBlock theBlock)
 {
     return(StateMachineUtilities.IsUnconditionalBranch(theBlock.First));
 }
示例#9
0
        private bool MarkTrueReturningPredecessorsAsYieldReturn(InstructionBlock theBlock)
        {
            V_0 = (new HashSet <InstructionBlock>(theBlock.get_Predecessors())).GetEnumerator();
            try
            {
                while (V_0.MoveNext())
                {
                    V_1 = V_0.get_Current();
                    if ((object)V_1.get_Last() != (object)V_1.get_First())
                    {
                        V_2 = null;
                        V_3 = V_1.get_Last();
                        if (StateMachineUtilities.IsUnconditionalBranch(V_3))
                        {
                            V_3 = V_3.get_Previous();
                        }
                        if (!this.IsFinallyMethodInvocationBlock(V_1))
                        {
                            if (!this.TryGetVariableFromInstruction(V_3, out V_2) || !this.CheckAndSaveReturnFlagVariable(V_2) || !StateMachineUtilities.TryGetOperandOfLdc(V_3.get_Previous(), out V_4))
                            {
                                V_5 = false;
                                goto Label1;
                            }
                            else
                            {
                                if (V_4 != 1)
                                {
                                    if (V_4 == 0)
                                    {
                                        continue;
                                    }
                                    V_5 = false;
                                    goto Label1;
                                }
                                else
                                {
                                    if (this.TryAddToYieldReturningBlocks(V_1))
                                    {
                                        continue;
                                    }
                                    V_5 = false;
                                    goto Label1;
                                }
                            }
                        }
                        else
                        {
                            if (this.MarkTrueReturningPredecessorsAsYieldReturn(V_1))
                            {
                                continue;
                            }
                            V_5 = false;
                            goto Label1;
                        }
                    }
                    else
                    {
                        if (!StateMachineUtilities.IsUnconditionalBranch(V_1.get_Last()))
                        {
                            V_5 = false;
                            goto Label1;
                        }
                        else
                        {
                            dummyVar0 = this.toBeRemoved.Add(V_1);
                            if (this.MarkTrueReturningPredecessorsAsYieldReturn(V_1))
                            {
                                continue;
                            }
                            V_5 = false;
                            goto Label1;
                        }
                    }
                }
                goto Label0;
            }
            finally
            {
                ((IDisposable)V_0).Dispose();
            }
Label1:
            return(V_5);

Label0:
            return(true);
        }