/// <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); }
/// <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); }
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); }
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)); }
/// <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); }
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); }
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)); }
/// <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)); }
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); }
/// <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); }
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); }
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)); }
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); }
/// <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); }
/// <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)); }
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)); }
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); }
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); }