/// <summary> /// Converts the return value into a call to Contract.Result /// </summary> public override IExpression Rewrite(IReturnValue returnValue) { var mref = contractProvider.ContractMethods.Result; var methodToCall = new GenericMethodInstanceReference { CallingConvention = CallingConvention.Generic, ContainingType = mref.ContainingType, GenericArguments = new List <ITypeReference> { returnValue.Type }, GenericMethod = mref, InternFactory = host.InternFactory, Name = mref.Name, Type = returnValue.Type }; var methodCall = new MethodCall { IsStaticCall = true, MethodToCall = methodToCall, Type = returnValue.Type, Locations = new List <ILocation>(returnValue.Locations) }; return(methodCall); }
/// <summary> /// Converts the old value into a call to Contract.OldValue /// </summary> public override IExpression Rewrite(IOldValue oldValue) { var mref = contractProvider.ContractMethods.Old; var methodToCall = new GenericMethodInstanceReference { CallingConvention = CallingConvention.Generic, ContainingType = mref.ContainingType, GenericArguments = new List <ITypeReference> { oldValue.Type }, GenericMethod = mref, InternFactory = host.InternFactory, Name = mref.Name, Parameters = new List <IParameterTypeInformation> { new ParameterTypeInformation { Type = oldValue.Type } }, Type = oldValue.Type }; var methodCall = new MethodCall { Arguments = new List <IExpression> { oldValue.Expression }, IsStaticCall = true, MethodToCall = methodToCall, Type = oldValue.Type, Locations = new List <ILocation>(oldValue.Locations) }; return(methodCall); }
internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration) { object reference; Microsoft.Cci.IMethodReference methodRef; NamedTypeSymbol container = methodSymbol.ContainingType; System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) || !methodSymbol.Equals(methodSymbol.OriginalDefinition)); if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol)) { System.Diagnostics.Debug.Assert(!needDeclaration); return(methodSymbol); } else if (!needDeclaration) { bool methodIsGeneric = methodSymbol.IsGeneric; bool typeIsGeneric = IsGenericType(container); if (methodIsGeneric || typeIsGeneric) { if (genericInstanceMap.TryGetValue(methodSymbol, out reference)) { return((Microsoft.Cci.IMethodReference)reference); } if (methodIsGeneric) { if (typeIsGeneric) { // Specialized and generic instance at the same time. throw new NotImplementedException(); } else { methodRef = new GenericMethodInstanceReference(methodSymbol); } } else { System.Diagnostics.Debug.Assert(typeIsGeneric); methodRef = new SpecializedMethodReference(methodSymbol); } genericInstanceMap.Add(methodSymbol, methodRef); return(methodRef); } } return(methodSymbol); }
public static IMethodDefinition GetInstantiatedMeth(IMethodDefinition templateMeth, IMethodDefinition instMeth) { IGenericMethodInstance genericM = instMeth as IGenericMethodInstance; IEnumerable <ITypeReference> genericArgs = genericM.GenericArguments; IList <ITypeReference> stubbedArgList = new List <ITypeReference>(); foreach (ITypeReference garg in genericArgs) { ITypeDefinition addedType = Stubber.CheckAndAdd(garg.ResolvedType); if (addedType != null) { stubbedArgList.Add(addedType); } else { stubbedArgList.Add(garg.ResolvedType); } } string argStr = GetGenericArgStr(stubbedArgList); IDictionary <string, IMethodDefinition> instMap; if (ClassAndMethodVisitor.genericMethodMap.ContainsKey(templateMeth)) { instMap = ClassAndMethodVisitor.genericMethodMap[templateMeth]; } else { instMap = new Dictionary <string, IMethodDefinition>(); ClassAndMethodVisitor.genericMethodMap[templateMeth] = instMap; } if (instMap.ContainsKey(argStr)) { return(instMap[argStr]); } else { GenericMethodInstanceReference newInstMethRef = new GenericMethodInstanceReference(templateMeth, genericArgs, internFactory); IMethodDefinition newInstMeth = newInstMethRef.ResolvedMethod; instMap[argStr] = newInstMeth; return(newInstMeth); } }
/// <summary> /// Rewrites the children of the given generic method instance reference. /// </summary> public override void RewriteChildren(GenericMethodInstanceReference genericMethodInstanceReference) { this.RewriteChildren((MethodReference)genericMethodInstanceReference); genericMethodInstanceReference.GenericArguments = this.Rewrite(genericMethodInstanceReference.GenericArguments); //do not rewrite the generic method reference, it does not contain any references to generic method type parameters of this.method //but it might have referenes to generic method type parameters, which will confuse the code below. }
internal IMethodReference/*?*/ GetMethodSpecAtRow( MetadataObject owningObject, uint methodSpecRowId ) { if (methodSpecRowId == 0 || methodSpecRowId > this.PEFileReader.MethodSpecTable.NumberOfRows) { return null; } uint ownerId = owningObject.TokenValue; GenericMethodInstanceReference/*?*/ methodSpecReference = this.ModuleMethodSpecHashtable.Find(ownerId, methodSpecRowId); if (methodSpecReference == null) { lock (GlobalLock.LockingObject) { methodSpecReference = this.ModuleMethodSpecHashtable.Find(ownerId, methodSpecRowId); if (methodSpecReference == null) { MethodSpecRow methodSpecRow = this.PEFileReader.MethodSpecTable[methodSpecRowId]; uint methToken = methodSpecRow.Method; uint tokenKind = methToken & TokenTypeIds.TokenTypeMask; uint rowId = methToken & TokenTypeIds.RIDMask; IModuleMethodReference/*?*/ moduleMethod; if (tokenKind == TokenTypeIds.MethodDef) { moduleMethod = this.GetMethodDefAtRow(rowId); } else if (tokenKind == TokenTypeIds.MemberRef) { moduleMethod = this.GetModuleMemberReferenceAtRow(owningObject, rowId) as IModuleMethodReference; } else { // MDError... return null; } if (moduleMethod == null) { // MDError... return null; } // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(methodSpecRow.Instantiation); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); // TODO: Check if this is really field signature there. MethodSpecSignatureConverter methodSpecSigConv = new MethodSpecSignatureConverter(this, owningObject, memoryReader); methodSpecReference = new GenericMethodInstanceReference( this, methodSpecRowId | TokenTypeIds.MethodSpec, moduleMethod, methodSpecSigConv.GenericTypeArguments ); this.ModuleMethodSpecHashtable.Add(ownerId, methodSpecRowId, methodSpecReference); } } } return methodSpecReference; }
internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration) { object reference; Microsoft.Cci.IMethodReference methodRef; NamedTypeSymbol container = methodSymbol.ContainingType; System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) || !methodSymbol.Equals(methodSymbol.OriginalDefinition)); if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol)) { System.Diagnostics.Debug.Assert(!needDeclaration); return methodSymbol; } else if (!needDeclaration) { bool methodIsGeneric = methodSymbol.IsGeneric; bool typeIsGeneric = IsGenericType(container); if (methodIsGeneric || typeIsGeneric) { if (genericInstanceMap.TryGetValue(methodSymbol, out reference)) { return (Microsoft.Cci.IMethodReference)reference; } if (methodIsGeneric) { if (typeIsGeneric) { // Specialized and generic instance at the same time. throw new NotImplementedException(); } else { methodRef = new GenericMethodInstanceReference(methodSymbol); } } else { System.Diagnostics.Debug.Assert(typeIsGeneric); methodRef = new SpecializedMethodReference(methodSymbol); } genericInstanceMap.Add(methodSymbol, methodRef); return methodRef; } } return methodSymbol; }
public override void TraverseChildren(IMethodCall methodCall) { var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod; var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod); if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString")) { base.TraverseChildren(methodCall); return; } bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_"); bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_"); if (isEventAdd || isEventRemove) { base.TraverseChildren(methodCall); return; } if (!methodCall.IsVirtualCall) { base.TraverseChildren(methodCall); return; } var containingType = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType); List <ITypeReference> subTypesOfContainingType; if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType)) { base.TraverseChildren(methodCall); return; } Contract.Assert(0 < subTypesOfContainingType.Count); Contract.Assert(!methodCall.IsStaticCall); Contract.Assert(!resolvedMethod.IsConstructor); var overrides = FindOverrides(containingType, resolvedMethod); bool same = true; foreach (var o in overrides) { IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod; if (resolvedOverride != resolvedMethod) { same = false; } } if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same)) { base.TraverseChildren(methodCall); return; } Contract.Assume(1 <= overrides.Count); var getType = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemObject, CallingConvention.HasThis, this.sink.host.PlatformType.SystemType, this.sink.host.NameTable.GetNameFor("GetType"), 0); var op_Type_Equality = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemType, CallingConvention.Default, this.sink.host.PlatformType.SystemBoolean, this.sink.host.NameTable.GetNameFor("op_Equality"), 0, this.sink.host.PlatformType.SystemType, this.sink.host.PlatformType.SystemType); // Depending on whether the method is a void method or not // Turn into expression: // (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ... // Or turn into statements: // if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ... var turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void; IStatement elseStatement = null; IExpression elseValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = methodCall.MethodToCall, ThisArgument = methodCall.ThisArgument, Type = methodCall.Type, }; if (turnIntoStatements) { elseStatement = new ExpressionStatement() { Expression = elseValue, } } ; Conditional ifConditional = null; ConditionalStatement ifStatement = null; foreach (var typeMethodPair in overrides) { var t = typeMethodPair.Item1; var m = typeMethodPair.Item2; if (m.IsGeneric) { var baseMethod = m.ResolvedMethod; m = new GenericMethodInstanceReference() { CallingConvention = baseMethod.CallingConvention, ContainingType = baseMethod.ContainingTypeDefinition, GenericArguments = new List <ITypeReference>(IteratorHelper.GetConversionEnumerable <IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)), GenericMethod = baseMethod, InternFactory = this.sink.host.InternFactory, Name = baseMethod.Name, Parameters = baseMethod.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(baseMethod.Parameters), Type = baseMethod.Type, }; } var cond = new MethodCall() { Arguments = new List <IExpression>() { new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = false, MethodToCall = getType, ThisArgument = methodCall.ThisArgument, }, new TypeOf() { TypeToGet = t, }, }, IsStaticCall = true, IsVirtualCall = false, MethodToCall = op_Type_Equality, Type = this.sink.host.PlatformType.SystemBoolean, }; Expression thenValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = m, ThisArgument = methodCall.ThisArgument, Type = m.Type, }; thenValue = new Conversion() { Type = m.Type, TypeAfterConversion = methodCall.Type, ValueToConvert = thenValue, }; if (turnIntoStatements) { ifStatement = new ConditionalStatement() { Condition = cond, FalseBranch = elseStatement, TrueBranch = new ExpressionStatement() { Expression = thenValue, }, }; elseStatement = ifStatement; } else { ifConditional = new Conditional() { Condition = cond, ResultIfFalse = elseValue, ResultIfTrue = thenValue, }; elseValue = ifConditional; } } if (turnIntoStatements) { Contract.Assume(ifStatement != null); this.StmtTraverser.Traverse(ifStatement); } else { Contract.Assume(ifConditional != null); base.Traverse(ifConditional); } return; }