private bool IsAssignmentToConcreteType(StackAnalysisResult stackAnalysis) { TypeReference assignmentTargetType; if (InstrumentationUtil.IsCallInstruction(stackAnalysis.Consumer)) { assignmentTargetType = stackAnalysis.AssignedParameter().ParameterType; } else { FieldReference assignmentTarget = stackAnalysis.Consumer.Operand as FieldReference; if (assignmentTarget != null) { assignmentTargetType = assignmentTarget.FieldType; } else { VariableReference variableDefinition = stackAnalysis.Consumer.Operand as VariableReference; if (variableDefinition != null) { assignmentTargetType = variableDefinition.VariableType; } else { throw new InvalidOperationException(); } } } return(HasReplacement(assignmentTargetType.GetElementType().FullName)); }
public void TestStackAnalysisResult() { AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(GetType().Module.Assembly.Location); Type testsDeclaringType = typeof(StackAnalysisResultScenarios); StringBuilder sb = new StringBuilder(); foreach (MethodInfo testMethod in testsDeclaringType.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)) { try { MethodDefinition methodDefinition = MethodReferenceFor(testMethod, assembly).Resolve(); ExpectedStackAnalysisResultAttribute expected = ExpectedStackAnalysisResultFor(testMethod); StackAnalysisResult actual = StackAnalyzer.IsConsumedBy(IsMethodCallOnList, FindCastOrNewObj(methodDefinition), methodDefinition.DeclaringType.Module); Assert.AreEqual(expected.OpCode, actual.Consumer.OpCode.ToString()); Assert.AreEqual(expected.Offset, actual.Offset); Assert.AreEqual(expected.StackHeight, actual.StackHeight); Assert.AreEqual(expected.Match, true); } catch (Exception ex) { sb.AppendFormat("Exception while processing method {0}\r\n{1}", testMethod, ex); } } if (sb.Length > 0) { Assert.Fail(sb.ToString()); } }
private bool IsAssignmentToConcreteType(StackAnalysisResult analysisResult) { TypeReference assignmentTargetType; if (analysisResult.Consumer.IsNewObj() || analysisResult.Consumer.IsCall()) { assignmentTargetType = analysisResult.AssignedParameter().ParameterType; } else { var assignmentTarget = analysisResult.Consumer.Operand as FieldReference; if (assignmentTarget != null) { assignmentTargetType = assignmentTarget.FieldType; } else { var variableDefinition = analysisResult.Consumer.Operand as VariableReference; if (variableDefinition != null) { assignmentTargetType = variableDefinition.VariableType; } else { throw new InvalidOperationException(); } } } return(HasReplacement(assignmentTargetType.GetElementType().FullName)); }
private void InstrumentConcreteCollectionCasts(MethodDefinition methodDefinition) { foreach (Instruction cast in CastsToSupportedCollections(methodDefinition.Body)) { StackAnalysisResult result = StackAnalyzer.IsConsumedBy(MethodCallOnSupportedCollections, cast, methodDefinition.DeclaringType.Module); if (!result.Match) { throw new InvalidOperationException(string.Format("Error: [{0}] Invalid use of cast result: '{1}'.\r\nCasts to {2} are only allowed for property access/method calls.", methodDefinition, DebugInformation.InstructionInformationFor(result.Consumer, methodDefinition.Body.Instructions), cast.Operand)); } TypeReference castTarget = (TypeReference)cast.Operand; ReplaceCastAndCalleeDeclaringType(cast, result.Consumer, _collectionReplacements[castTarget.Resolve().FullName]); } }
private void InstrumentCollectionInstantiation(MethodDefinition methodDefinition) { foreach (Instruction newObj in TAEnabledCollectionInstantiations(methodDefinition.Body)) { StackAnalysisResult stackAnalysis = StackAnalyzer.IsConsumedBy(delegate { return(true); }, newObj, methodDefinition.DeclaringType.Module); if (IsAssignmentToConcreteType(stackAnalysis)) { Context.TraceWarning("[{0}] Assignment to concrete collection {1} ignored (offset: 0x{2:X2}).", methodDefinition, InstantiatedType(newObj), newObj.Next.Offset); continue; } ReplaceContructorWithConstructorFrom(newObj); } }
private void AssertStack(Type testsDeclaringType, bool expectedResult) { TypeReference typeReference = FindType(testsDeclaringType); StringBuilder sb = new StringBuilder(); foreach (MethodReference testMethod in typeReference.Resolve().Methods) { MethodDefinition methodDefinition = testMethod.Resolve(); if (!methodDefinition.IsPublic) { continue; } if (methodDefinition.IsConstructor) { continue; } try { StackAnalysisResult stackAnalysis = StackAnalyzer.IsConsumedBy(IsMethodCallOnList, FindCast(methodDefinition), methodDefinition.DeclaringType.Module); if (expectedResult != stackAnalysis.Match) { sb.AppendFormat("Method {0} contains invalid cast operations.\r\n", testMethod); } } catch (Exception ex) { sb.AppendFormat("Exception while processing method {0}\r\n{1}", testMethod, ex); } } if (sb.Length > 0) { Assert.Fail(sb.ToString()); } }