/// <summary>
        /// Checks whether the specified block is a state controller block generated by the C# compiler in debug mode.
        /// </summary>
        /// <remarks>
        /// Pattern:
        /// ldc.i4.1
        /// stloc* doFinallyVariable
        /// ldarg.0
        /// ldfld stateField
        /// ...
        /// ldc.i4.s -3
        /// (sub) - missing if next is beq*
        /// switch || beq*
        ///
        /// There is only one such block generated at the begining of the MoveNext method.
        /// </remarks>
        /// <param name="theBlock"></param>
        /// <returns></returns>
        private bool IsDebugCheckStateBlock(InstructionBlock theBlock)
        {
            if (!BeginsWithDoFinallySet(theBlock) || !ContainsStateFieldLoad(theBlock))
            {
                return(false);
            }

            Instruction currentInstruction = theBlock.Last;

            if (!this.IsBeqInstruction(currentInstruction))
            {
                if (currentInstruction.OpCode.Code != Code.Switch)
                {
                    return(false);
                }

                currentInstruction = currentInstruction.Previous;
                if (currentInstruction.OpCode.Code != Code.Sub)
                {
                    return(false);
                }
            }

            currentInstruction = currentInstruction.Previous;
            int operand;

            if (!StateMachineUtilities.TryGetOperandOfLdc(currentInstruction, out operand) || operand > -3)
            {
                return(false);
            }

            debugStateCheckBlock = theBlock;
            stateCheckOffset     = -operand;
            return(true);
        }
Пример #2
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);
        }
Пример #3
0
        protected override bool IsFinallyCheckBlock(InstructionBlock finallyEntry)
        {
            Instruction       current = finallyEntry.First;
            VariableReference loadedVariable;

            if (!StateMachineUtilities.TryGetVariableFromInstruction(current, methodVariables, out loadedVariable) ||
                loadedVariable != this.stateVariable)
            {
                return(false);
            }

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

            current = current.Next;
            if (current.OpCode.Code != Code.Bge && current.OpCode.Code != Code.Bge_S)
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        private void GetStateVariable()
        {
            Instruction current = theCFG.Blocks[0].First;

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

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

            FieldReference loadedField = current.Operand as FieldReference;

            if (loadedField == null || loadedField.Resolve() != this.stateField)
            {
                return;
            }

            current = current.Next;
            StateMachineUtilities.TryGetVariableFromInstruction(current, methodVariables, out stateVariable);
        }
 protected override bool IsFinallyCheckBlock(InstructionBlock theBlock)
 {
     V_0 = theBlock.get_First();
     while (V_0.get_OpCode().get_Code() == null)
     {
         if ((object)V_0 == (object)theBlock.get_Last())
         {
             return(false);
         }
         V_0 = V_0.get_Next();
     }
     if ((object)V_0 == (object)theBlock.get_Last() || !StateMachineUtilities.TryGetVariableFromInstruction(V_0, this.methodVariables, out V_1) || (object)V_1 != (object)this.doFinallyVariable)
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() == 56 || V_0.get_OpCode().get_Code() == 43)
     {
         return(true);
     }
     if (this.IsCSharpDebugCheck(theBlock, V_0))
     {
         return(true);
     }
     return(this.IsVisualBasicDebugCheck(theBlock, V_0));
 }
        /// <summary>
        /// Checks whether <paramref name="theBlock"/> is a do-finally-check block.
        /// </summary>
        /// <remarks>
        /// Pattern:
        /// (nop) - sequence of nop blocks
        /// ldloc* doFinallyVariable
        /// brfalse* - branch to endfinally - this check varies between compilers
        /// original handler:
        /// ...............
        /// </remarks>
        /// <param name="theBlock"></param>
        /// <returns></returns>
        protected override bool IsFinallyCheckBlock(InstructionBlock theBlock)
        {
            Instruction currentInstruction = theBlock.First;

            while (currentInstruction.OpCode.Code == Code.Nop)
            {
                if (currentInstruction == theBlock.Last)
                {
                    return(false);
                }
                currentInstruction = currentInstruction.Next;
            }

            VariableReference loadedVariable;

            if (currentInstruction == theBlock.Last ||
                !StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction, methodVariables, out loadedVariable) ||
                loadedVariable != doFinallyVariable)
            {
                return(false);
            }
            currentInstruction = currentInstruction.Next;

            if (currentInstruction.OpCode.Code == Code.Brfalse || currentInstruction.OpCode.Code == Code.Brfalse_S)
            {
                return(true);
            }

            return(IsCSharpDebugCheck(theBlock, currentInstruction) || IsVisualBasicDebugCheck(theBlock, currentInstruction));
        }
Пример #7
0
        /// <summary>
        /// Tries to get the state to which the current block leads.
        /// </summary>
        /// <remarks>
        /// We are searching for this pattern at the end of the block:
        /// .....
        /// load currentItemValue
        /// stfld currentItemField
        /// ldarg.0   --this
        /// ldc.i4. nextStateNumber
        /// stfld stateField
        /// .....
        /// </remarks>
        /// <param name="theBlock"></param>
        /// <param name="newStateNumber"></param>
        /// <returns></returns>
        private NextStateNumberSearchResult TryGetNextStateNumber(InstructionBlock theBlock, out int newStateNumber)
        {
            Instruction currentInstruction = theBlock.Last;

            while (currentInstruction != theBlock.First)
            {
                if (currentInstruction.OpCode.Code == Code.Stfld && stateField == ((FieldReference)currentInstruction.Operand).Resolve())
                {
                    currentInstruction = currentInstruction.Previous;
                    if (!StateMachineUtilities.TryGetOperandOfLdc(currentInstruction, out newStateNumber))
                    {
                        return(NextStateNumberSearchResult.PatternFailed);
                    }

                    //currentInstruction == ldc.i4. ; currentInstruction.Previous == ldarg.0 ; currentInstruction.Previous.Previous == stfld currentItemField
                    currentInstruction = currentInstruction.Previous.Previous;
                    if (currentInstruction.OpCode.Code != Code.Stfld || !CheckAndSaveCurrentItemField((FieldReference)currentInstruction.Operand))
                    {
                        return(NextStateNumberSearchResult.PatternFailed);
                    }

                    return(NextStateNumberSearchResult.StateNumberFound);
                }

                currentInstruction = currentInstruction.Previous;
            }

            newStateNumber = 0;
            return(NextStateNumberSearchResult.StateWasNotSet);
        }
Пример #8
0
 private bool DetermineExceptionHandlingStatesFromSwitchData(SwitchData switchBlockInfo)
 {
     V_0 = 0;
     V_1 = switchBlockInfo.get_SwitchBlock().get_Last().get_Previous();
     if (V_1.get_OpCode().get_Code() == 88)
     {
         V_1 = V_1.get_Previous();
         if (!StateMachineUtilities.TryGetOperandOfLdc(V_1, out V_0))
         {
             return(false);
         }
         V_1 = V_1.get_Previous();
     }
     V_2 = switchBlockInfo.get_OrderedCasesArray();
     V_4 = 0;
     while (V_4 < (int)V_2.Length)
     {
         if (this.TryGetExceptionHandler(this.GetActualCase(V_2[V_4]), out V_6))
         {
             if (!this.handlerToStatesMap.ContainsKey(V_6))
             {
                 this.handlerToStatesMap.Add(V_6, new HashSet <int>());
             }
             dummyVar0 = this.handlerToStatesMap.get_Item(V_6).Add(V_4 + V_0);
         }
         V_4 = V_4 + 1;
     }
     return(true);
 }
Пример #9
0
 private bool IsDebugCheckStateBlock(InstructionBlock theBlock)
 {
     if (!this.BeginsWithDoFinallySet(theBlock) || !this.ContainsStateFieldLoad(theBlock))
     {
         return(false);
     }
     V_0 = theBlock.get_Last();
     if (!this.IsBeqInstruction(V_0))
     {
         if (V_0.get_OpCode().get_Code() != 68)
         {
             return(false);
         }
         V_0 = V_0.get_Previous();
         if (V_0.get_OpCode().get_Code() != 88)
         {
             return(false);
         }
     }
     V_0 = V_0.get_Previous();
     if (!StateMachineUtilities.TryGetOperandOfLdc(V_0, out V_1) || V_1 > -3)
     {
         return(false);
     }
     this.debugStateCheckBlock = theBlock;
     this.stateCheckOffset     = -V_1;
     return(true);
 }
 private bool GetDoFinallyVariable()
 {
     V_0 = this.theCFG.get_Blocks()[0].get_First();
     if (V_0.get_OpCode().get_Code() != 23)
     {
         return(false);
     }
     return(StateMachineUtilities.TryGetVariableFromInstruction(V_0.get_Next(), this.methodVariables, out this.doFinallyVariable));
 }
Пример #11
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>
        /// Gets the doFinallyBodies variable from the first block of the MoveNext method.
        /// </summary>
        /// <returns>True on success, otherwise false.</returns>
        private bool GetDoFinallyVariable()
        {
            Instruction entry = theCFG.Blocks[0].First;

            if (entry.OpCode.Code != Code.Ldc_I4_1)
            {
                return(false);
            }

            return(StateMachineUtilities.TryGetVariableFromInstruction(entry.Next, methodVariables, out doFinallyVariable));
        }
Пример #13
0
 private void GetStateVariable()
 {
     V_0 = this.theCFG.get_Blocks()[0].get_First();
     if (V_0.get_OpCode().get_Code() != 2)
     {
         return;
     }
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() != 120)
     {
         return;
     }
     V_1 = V_0.get_Operand() as FieldReference;
     if (V_1 == null || (object)V_1.Resolve() != (object)this.stateField)
     {
         return;
     }
     V_0       = V_0.get_Next();
     dummyVar0 = StateMachineUtilities.TryGetVariableFromInstruction(V_0, this.methodVariables, out this.stateVariable);
     if ((object)V_0 == (object)this.theCFG.get_Blocks()[0].get_Last())
     {
         return;
     }
     V_0 = V_0.get_Next();
     V_2 = true;
     while (V_2)
     {
         if (V_0.get_OpCode().get_Code() == 2)
         {
             V_0 = V_0.get_Next();
             if (V_0.get_OpCode().get_Code() == 120)
             {
                 V_4 = V_0.get_Operand() as FieldReference;
                 if (V_4 != null)
                 {
                     V_0 = V_0.get_Next();
                     if (StateMachineUtilities.TryGetVariableFromInstruction(V_0, this.methodVariables, out V_5))
                     {
                         this.variableToFieldMap.Add(V_5, V_4);
                         if ((object)V_0 == (object)this.theCFG.get_Blocks()[0].get_Last())
                         {
                             break;
                         }
                         V_0 = V_0.get_Next();
                         continue;
                     }
                 }
             }
         }
         V_2 = false;
     }
     return;
 }
        /// <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);
        }
Пример #15
0
        /// <summary>
        /// Process the specified block, which ends with ret instruction.
        /// </summary>
        /// <remarks>
        /// The block should end with: return true, return false or return flagVariable.
        /// If the block ends with "return flagVariable", then we mark the block as yield break and we search for all of the predecessors of
        /// the block that set the flagVariable to true to mark them as yield returns.
        /// </remarks>
        /// <param name="theBlock"></param>
        private bool TryProcessEndBlock(InstructionBlock theBlock)
        {
            VariableReference flagVarReference = null;

            Instruction beforeRet = theBlock.Last.Previous;
            int         returnValue;

            if (StateMachineUtilities.TryGetOperandOfLdc(beforeRet, out returnValue))
            {
                if (returnValue == 0) // == return false;
                {
                    yieldBreaks.Add(theBlock);
                }
                else if (returnValue == 1) // == return true;
                {
                    int stateNumber;
                    switch (TryGetNextStateNumber(theBlock, out stateNumber))
                    {
                    case NextStateNumberSearchResult.StateNumberFound:
                        yieldReturns.Add(theBlock);

                        InstructionBlock nextState = GetStateFistBlock(stateNumber);
                        theBlock.Successors = new InstructionBlock[] { nextState };
                        break;

                    case NextStateNumberSearchResult.StateWasNotSet:
                        //If we cannot find the next state number, we assume that this is a common exit for a bunch of yield return blocks.
                        //That's why we mark all the predecessors of this block as yield returns.
                        return(MarkPredecessorsAsYieldReturns(theBlock));

                    case NextStateNumberSearchResult.PatternFailed:
                        return(false);
                    }
                }
                else
                {
                    //throw new Exception("Illegal return value of MoveNext method.");
                    return(false);
                }
            }
            else if (TryGetVariableFromInstruction(beforeRet, out flagVarReference) && CheckAndSaveReturnFlagVariable(flagVarReference))
            {
                yieldBreaks.Add(theBlock);
                return(MarkTrueReturningPredecessorsAsYieldReturn(theBlock));
            }
            else
            {
                //throw new Exception("Illegal end block of yield iterator.");
                return(false);
            }

            return(true);
        }
Пример #16
0
 private bool BeginsWithDoFinallySet(InstructionBlock theBlock)
 {
     V_0 = theBlock.get_First();
     if ((object)V_0 == (object)theBlock.get_Last() || V_0.get_OpCode().get_Code() != 23)
     {
         return(false);
     }
     if (!StateMachineUtilities.TryGetVariableFromInstruction(V_0.get_Next(), this.methodContext.get_Body().get_Variables(), out V_1))
     {
         return(false);
     }
     return((object)V_1 == (object)this.doFinallyVariable);
 }
        /// <summary>
        /// Checks whether the specified block begins with setting the doFinallyBodies variable to true.
        /// </summary>
        /// <param name="theBlock"></param>
        /// <returns></returns>
        private bool BeginsWithDoFinallySet(InstructionBlock theBlock)
        {
            Instruction currentInstruction = theBlock.First;

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

            VariableReference foundVariable;

            return(StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction.Next, methodContext.Body.Variables, out foundVariable) &&
                   foundVariable == doFinallyVariable);
        }
Пример #18
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));
 }
Пример #19
0
        private bool TryProcessEndBlock(InstructionBlock theBlock)
        {
            V_0 = null;
            V_1 = theBlock.get_Last().get_Previous();
            if (!StateMachineUtilities.TryGetOperandOfLdc(V_1, out V_2))
            {
                if (!this.TryGetVariableFromInstruction(V_1, out V_0) || !this.CheckAndSaveReturnFlagVariable(V_0))
                {
                    return(false);
                }
                dummyVar2 = this.yieldBreaks.Add(theBlock);
                return(this.MarkTrueReturningPredecessorsAsYieldReturn(theBlock));
            }
            if (V_2 != 0)
            {
                if (V_2 != 1)
                {
                    return(false);
                }
                switch (this.TryGetNextStateNumber(theBlock, out V_3))
                {
                case 0:
                {
                    return(false);
                }

                case 1:
                {
                    dummyVar1          = this.yieldReturns.Add(theBlock);
                    V_4                = this.GetStateFistBlock(V_3);
                    stackVariable41    = new InstructionBlock[1];
                    stackVariable41[0] = V_4;
                    theBlock.set_Successors(stackVariable41);
                    break;
                }

                case 2:
                {
                    return(this.MarkPredecessorsAsYieldReturns(theBlock));
                }
                }
            }
            else
            {
                dummyVar0 = this.yieldBreaks.Add(theBlock);
            }
            return(true);
        }
Пример #20
0
        /// <summary>
        /// Process each CFG block to determine which cases lead to try/finally construct.
        /// </summary>
        private void DetermineExceptionHandlingStatesFromCFGBlocks()
        {
            foreach (InstructionBlock block in theDisposeCFG.Blocks)
            {
                int state;
                if ((!IsBeqInstruction(block.Last) && !IsBneUnInstruction(block.Last)) ||
                    !StateMachineUtilities.TryGetOperandOfLdc(block.Last.Previous, out state))
                {
                    continue;
                }

                Instruction branchTargetInstruction = null;
                if (IsBeqInstruction(block.Last))
                {
                    branchTargetInstruction = block.Last.Operand as Instruction;
                }
                else // bne.un*
                {
                    branchTargetInstruction = block.Last.Next as Instruction;
                }

                if (branchTargetInstruction == null)
                {
                    throw new Exception("branchTargetInstruction cannot be null.");
                }

                InstructionBlock targetBlock = SkipSingleNopInstructionBlock(theDisposeCFG.InstructionToBlockMapping[branchTargetInstruction.Offset]);
                ExceptionHandler theHandler;
                if (!TryGetExceptionHandler(targetBlock, out theHandler))
                {
                    continue;
                }

                //We've found an exception handler.

                if (!this.handlerToStatesMap.ContainsKey(theHandler))
                {
                    this.handlerToStatesMap.Add(theHandler, new HashSet <int>());
                }

                this.handlerToStatesMap[theHandler].Add(state);
            }
        }
 protected override bool IsFinallyCheckBlock(InstructionBlock finallyEntry)
 {
     V_0 = finallyEntry.get_First();
     if (!StateMachineUtilities.TryGetVariableFromInstruction(V_0, this.methodVariables, out V_1) || (object)V_1 != (object)this.stateVariable)
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() != 22)
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if (V_0.get_OpCode().get_Code() != 59 && V_0.get_OpCode().get_Code() != 46)
     {
         return(false);
     }
     return(true);
 }
Пример #22
0
        /// <summary>
        /// Process each switch block to determine which cases lead to try/finally constructs.
        /// </summary>
        /// <param name="switchBlockInfo"></param>
        private bool DetermineExceptionHandlingStatesFromSwitchData(SwitchData switchBlockInfo)
        {
            //Since the first try/finally that this switch covers can start at state 20, the complier will optimize this by subtracting 20 from the value of
            //the state field.
            int         stateOffset        = 0;
            Instruction currentInstruction = switchBlockInfo.SwitchBlock.Last.Previous;

            if (currentInstruction.OpCode.Code == Code.Sub)
            {
                currentInstruction = currentInstruction.Previous;
                if (!StateMachineUtilities.TryGetOperandOfLdc(currentInstruction, out stateOffset))
                {
                    return(false);
                }

                currentInstruction = currentInstruction.Previous;
            }

            InstructionBlock[] orderedCases = switchBlockInfo.OrderedCasesArray;
            for (int i = 0; i < orderedCases.Length; i++)
            {
                InstructionBlock currentCase = GetActualCase(orderedCases[i]);

                ExceptionHandler theHandler;
                if (!TryGetExceptionHandler(currentCase, out theHandler))
                {
                    continue;
                }

                //We've found an exception handler.

                if (!this.handlerToStatesMap.ContainsKey(theHandler))
                {
                    this.handlerToStatesMap.Add(theHandler, new HashSet <int>());
                }

                this.handlerToStatesMap[theHandler].Add(i + stateOffset);
            }

            return(true);
        }
        /// <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));
        }
Пример #24
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);
        }
 private bool IsVisualBasicDebugCheck(InstructionBlock theBlock, Instruction currentInstruction)
 {
     if ((object)currentInstruction == (object)theBlock.get_Last() || !StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction, this.methodVariables, out V_0))
     {
         return(false);
     }
     currentInstruction = currentInstruction.get_Next();
     if ((object)currentInstruction == (object)theBlock.get_Last() || !StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction, this.methodVariables, out V_1) || (object)V_0 != (object)V_1)
     {
         return(false);
     }
     currentInstruction = currentInstruction.get_Next();
     if ((object)currentInstruction != (object)theBlock.get_Last())
     {
         return(false);
     }
     if (currentInstruction.get_OpCode().get_Code() == 56)
     {
         return(true);
     }
     return(currentInstruction.get_OpCode().get_Code() == 43);
 }
        /// <summary>
        /// Checks whether the specified block is a controller block generated by the compiler in debug mode.
        /// </summary>
        /// <remarks>
        /// Pattern:
        ///
        /// ldfld stateField
        /// ldc.i4.* stateNumber
        /// ceq
        /// ldc.i4.0
        /// .....
        /// brtrue* .....
        /// </remarks>
        /// <param name="theBlock"></param>
        /// <param name="stateNumber"></param>
        /// <returns></returns>
        private bool IsDebugControllerBlock(InstructionBlock theBlock, out int stateNumber)
        {
            if (theBlock.First == theBlock.Last)
            {
                stateNumber = -1;
                return(false);
            }

            Instruction currentInstruction = theBlock.First.Next;

            if (currentInstruction == theBlock.Last || currentInstruction.OpCode.Code != Code.Ldfld ||
                ((FieldReference)currentInstruction.Operand).Resolve() != this.stateField)
            {
                stateNumber = -1;
                return(false);
            }

            currentInstruction = currentInstruction.Next;
            if (currentInstruction == theBlock.Last || !StateMachineUtilities.TryGetOperandOfLdc(currentInstruction, out stateNumber))
            {
                stateNumber = -1;
                return(false);
            }

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

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

            return(theBlock.Last.OpCode.Code == Code.Brtrue || theBlock.Last.OpCode.Code == Code.Brtrue_S);
        }
        /// <summary>
        /// Checks whether the specified block ends as a do-finally-check block generated by the VB compiler in debug mode.
        /// </summary>
        /// <remarks>
        /// Instead of:
        /// brfalse* endfinally
        ///
        /// stloc* someVariable
        /// ldloc* someVariable
        /// brfalse* endfinally
        /// </remarks>
        /// <param name="theBlock"></param>
        /// <param name="currentInstruction"></param>
        /// <returns></returns>
        private bool IsVisualBasicDebugCheck(InstructionBlock theBlock, Instruction currentInstruction)
        {
            VariableReference storingVariable;

            if (currentInstruction == theBlock.Last ||
                !StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction, methodVariables, out storingVariable))
            {
                return(false);
            }

            currentInstruction = currentInstruction.Next;
            VariableReference loadingVariable;

            if (currentInstruction == theBlock.Last ||
                !StateMachineUtilities.TryGetVariableFromInstruction(currentInstruction, methodVariables, out loadingVariable) ||
                storingVariable != loadingVariable)
            {
                return(false);
            }

            currentInstruction = currentInstruction.Next;
            return(currentInstruction == theBlock.Last && (currentInstruction.OpCode.Code == Code.Brfalse || currentInstruction.OpCode.Code == Code.Brfalse_S));
        }
Пример #28
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);
 }
 private bool IsDebugControllerBlock(InstructionBlock theBlock, out int stateNumber)
 {
     if ((object)theBlock.get_First() == (object)theBlock.get_Last())
     {
         stateNumber = -1;
         return(false);
     }
     V_0 = theBlock.get_First().get_Next();
     if ((object)V_0 == (object)theBlock.get_Last() || V_0.get_OpCode().get_Code() != 120 || (object)((FieldReference)V_0.get_Operand()).Resolve() != (object)this.stateField)
     {
         stateNumber = -1;
         return(false);
     }
     V_0 = V_0.get_Next();
     if ((object)V_0 == (object)theBlock.get_Last() || !StateMachineUtilities.TryGetOperandOfLdc(V_0, out stateNumber))
     {
         stateNumber = -1;
         return(false);
     }
     V_0 = V_0.get_Next();
     if ((object)V_0 == (object)theBlock.get_Last() || V_0.get_OpCode().get_Code() != 192)
     {
         return(false);
     }
     V_0 = V_0.get_Next();
     if ((object)V_0 == (object)theBlock.get_Last() || V_0.get_OpCode().get_Code() != 22)
     {
         return(false);
     }
     if (theBlock.get_Last().get_OpCode().get_Code() == 57)
     {
         return(true);
     }
     V_1 = theBlock.get_Last().get_OpCode();
     return(V_1.get_Code() == 44);
 }
Пример #30
0
 private YieldStateMachineControlFlowRebuilder.NextStateNumberSearchResult TryGetNextStateNumber(InstructionBlock theBlock, out int newStateNumber)
 {
     V_0 = theBlock.get_Last();
     while ((object)V_0 != (object)theBlock.get_First())
     {
         if (V_0.get_OpCode().get_Code() == 122 && (object)this.stateField == (object)((FieldReference)V_0.get_Operand()).Resolve())
         {
             V_0 = V_0.get_Previous();
             if (!StateMachineUtilities.TryGetOperandOfLdc(V_0, out newStateNumber))
             {
                 return(0);
             }
             V_0 = V_0.get_Previous().get_Previous();
             if (V_0.get_OpCode().get_Code() == 122 && this.CheckAndSaveCurrentItemField((FieldReference)V_0.get_Operand()))
             {
                 return(1);
             }
             return(0);
         }
         V_0 = V_0.get_Previous();
     }
     newStateNumber = 0;
     return(2);
 }