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); }
/// <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)); }
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)); }
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); }
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> /// 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; }
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); }
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); }
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 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)); }
/// <summary> /// Tries to get the variable that is used by the specified instruction. /// </summary> /// <param name="instruction"></param> /// <param name="varReference"></param> /// <returns>Flase if the instruction does not handle variables.</returns> private bool TryGetVariableFromInstruction(Instruction instruction, out VariableReference varReference) { return(StateMachineUtilities.TryGetVariableFromInstruction(instruction, moveNextMethodContext.Variables, out varReference)); }
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); if (current == theCFG.Blocks[0].Last) { return; } current = current.Next; bool variableSuccessfullyExtracted = true; while (variableSuccessfullyExtracted) { if (current.OpCode.Code == Code.Ldarg_0) { current = current.Next; if (current.OpCode.Code == Code.Ldfld) { FieldReference field = current.Operand as FieldReference; if (field != null) { current = current.Next; VariableReference variable; if (StateMachineUtilities.TryGetVariableFromInstruction(current, methodVariables, out variable)) { variableToFieldMap.Add(variable, field); if (current == theCFG.Blocks[0].Last) { break; } current = current.Next; continue; } } } } variableSuccessfullyExtracted = false; } }
/// <summary> /// Tries to get the variable that is used by the specified instruction. /// </summary> /// <param name="instruction"></param> /// <param name="varReference"></param> /// <returns></returns> protected bool TryGetVariableFromInstruction(Instruction instruction, out VariableReference varReference) { return(StateMachineUtilities.TryGetVariableFromInstruction(instruction, methodContext.Body.Variables, out varReference)); }
protected bool TryGetVariableFromInstruction(Instruction instruction, out VariableReference varReference) { return(StateMachineUtilities.TryGetVariableFromInstruction(instruction, this.methodContext.get_Body().get_Variables(), out varReference)); }