Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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.
 }
Ejemplo n.º 6
0
 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;
        }
Ejemplo n.º 8
0
            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;
            }