示例#1
0
        public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
        {
            TypeDesc canonicalizedTypeOfTargetMethod = OwningType.ConvertToCanonForm(kind);

            if (canonicalizedTypeOfTargetMethod == OwningType)
            {
                return(this);
            }

            return(Context.GetMethodForInstantiatedType(GetTypicalMethodDefinition(), (InstantiatedType)canonicalizedTypeOfTargetMethod));
        }
示例#2
0
        public override MethodDesc GetTypicalMethodDefinition()
        {
            TypeDesc owningTypeDefinition = OwningType.GetTypeDefinition();

            // If this method is on a type that is its own type definition, this it is the type method
            if (owningTypeDefinition == OwningType)
            {
                return(this);
            }

            // Otherwise, find its equivalent on the type definition of the owning type
            return(Context.ResolveRuntimeMethod(UnboxingStub, (DefType)owningTypeDefinition, _nameAndSignature, IntPtr.Zero, false));
        }
        public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
        {
            if (!OwningType.HasInstantiation)
            {
                return(this);
            }

            DefType canonicalizedTypeOfTargetMethod = (DefType)OwningType.ConvertToCanonForm(kind);

            if (canonicalizedTypeOfTargetMethod == OwningType)
            {
                return(this);
            }

            return(Context.ResolveRuntimeMethod(this.UnboxingStub, canonicalizedTypeOfTargetMethod, this.NameAndSignature, IntPtr.Zero, false));
        }
        /// <summary>
        /// True if either the containing type instantiation or any of this method's generic arguments
        /// are canonical
        /// </summary>
        public override bool IsCanonicalMethod(CanonicalFormKind policy)
        {
            if (OwningType.HasInstantiation && OwningType.IsCanonicalSubtype(policy))
            {
                return(true);
            }

            foreach (TypeDesc type in Instantiation)
            {
                if (type.IsCanonicalSubtype(policy))
                {
                    return(true);
                }
            }

            return(false);
        }
 public override string ToString()
 {
     return(OwningType.ToString() + "." + Name);
 }
示例#6
0
 /// <summary>
 /// Compute HashCode. Should only be overriden by a MethodDesc that represents an instantiated method.
 /// </summary>
 protected virtual int ComputeHashCode()
 {
     return(TypeHashingAlgorithms.ComputeMethodHashCode(OwningType.GetHashCode(), TypeHashingAlgorithms.ComputeNameHashCode(Name)));
 }
        private static void HandleCall(ref DependencyList list, NodeFactory factory, MethodIL methodIL, MethodDesc methodCalled, ref Tracker tracker)
        {
            switch (methodCalled.Name)
            {
            // Enum.GetValues(Type) needs array of that type
            case "GetValues" when methodCalled.OwningType == factory.TypeSystemContext.GetWellKnownType(WellKnownType.Enum):
            {
                TypeDesc type = tracker.GetLastType();
                if (type != null && type.IsEnum && !type.IsGenericDefinition /* generic enums! */)
                {
                    // Type could be something weird like MyEnum<object, __Canon> - normalize it
                    type = type.NormalizeInstantiation();

                    list = list ?? new DependencyList();
                    list.Add(factory.ConstructedTypeSymbol(type.MakeArrayType()), "Enum.GetValues");
                }
            }
            break;

            // Type.GetType(string...) needs the type with the given name
            case "GetType" when methodCalled.OwningType.IsSystemType() && methodCalled.Signature.Length > 0:
            {
                string name = tracker.GetLastString();
                if (name != null &&
                    methodIL.OwningMethod.OwningType is MetadataType mdType &&
                    ResolveType(name, mdType.Module, out TypeDesc type, out ModuleDesc referenceModule) &&
                    !factory.MetadataManager.IsReflectionBlocked(type))
                {
                    const string reason = "Type.GetType";
                    list = list ?? new DependencyList();
                    list.Add(factory.MaximallyConstructableType(type), reason);

                    // Also add module metadata in case this reference was through a type forward
                    if (factory.MetadataManager.CanGenerateMetadata(referenceModule.GetGlobalModuleType()))
                    {
                        list.Add(factory.ModuleMetadata(referenceModule), reason);
                    }

                    // Opportunistically remember the type so that it flows to Type.GetMethod if needed.
                    tracker.TrackType(type);
                }
            }
            break;

            // Type.GetMethod(string...)
            case "GetMethod" when methodCalled.OwningType.IsSystemType():
            {
                string   name = tracker.GetLastString();
                TypeDesc type = tracker.GetLastType();
                if (name != null &&
                    type != null &&
                    !factory.MetadataManager.IsReflectionBlocked(type))
                {
                    if (type.IsGenericDefinition)
                    {
                        Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: false);
                        if (inst.IsNull)
                        {
                            break;
                        }
                        type = ((MetadataType)type).MakeInstantiatedType(inst);
                        list = list ?? new DependencyList();
                        list.Add(factory.MaximallyConstructableType(type), "Type.GetMethod");
                    }
                    else
                    {
                        // Type could be something weird like SomeType<object, __Canon> - normalize it
                        type = type.NormalizeInstantiation();
                    }

                    MethodDesc reflectedMethod = type.GetMethod(name, null);
                    if (reflectedMethod != null &&
                        !factory.MetadataManager.IsReflectionBlocked(reflectedMethod))
                    {
                        if (reflectedMethod.HasInstantiation)
                        {
                            // Don't want to accidentally get Foo<__Canon>.Bar<object>()
                            if (reflectedMethod.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
                            {
                                break;
                            }

                            Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(reflectedMethod.Instantiation, allowCanon: false);
                            if (inst.IsNull)
                            {
                                break;
                            }
                            reflectedMethod = reflectedMethod.MakeInstantiatedMethod(inst);
                        }

                        const string reason = "Type.GetMethod";
                        list = list ?? new DependencyList();
                        if (reflectedMethod.IsVirtual)
                        {
                            RootVirtualMethodForReflection(ref list, factory, reflectedMethod, reason);
                        }

                        if (!reflectedMethod.IsAbstract)
                        {
                            list.Add(factory.CanonicalEntrypoint(reflectedMethod), reason);
                            if (reflectedMethod.HasInstantiation &&
                                reflectedMethod != reflectedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific))
                            {
                                list.Add(factory.MethodGenericDictionary(reflectedMethod), reason);
                            }
                        }
                    }
                }
            }
            break;

            case "SizeOf" when IsMarshalSizeOf(methodCalled):
            {
                TypeDesc type = tracker.GetLastType();
                if (IsTypeEligibleForMarshalSizeOfTracking(type))
                {
                    list = list ?? new DependencyList();

                    list.Add(factory.StructMarshallingData((DefType)type), "Marshal.SizeOf");
                }
            }
            break;
            }
        }
示例#8
0
 protected override int ComputeHashCode()
 {
     return(TypeHashingAlgorithms.ComputeMethodHashCode(OwningType.GetHashCode(), Instantiation.ComputeGenericInstanceHashCode(TypeHashingAlgorithms.ComputeNameHashCode(Name))));
 }
 public override bool IsCanonicalMethod(CanonicalFormKind policy)
 {
     return(OwningType.HasInstantiation && OwningType.IsCanonicalSubtype(policy));
 }
 protected virtual bool ComputeIsNonSharableMethod()
 {
     return(!OwningType.IsCanonicalSubtype(CanonicalFormKind.Any) &&
            OwningType == (OwningType.ConvertToCanonForm(CanonicalFormKind.Specific) as DefType));
 }
示例#11
0
        public override string ToString()
        {
            string result = OwningType.ToString() + ".Method(" + NameAndSignature.Name + ")";

            return(result);
        }
        private static void HandleCall(ref DependencyList list, NodeFactory factory, MethodIL methodIL, MethodDesc methodCalled, ref Tracker tracker)
        {
            switch (methodCalled.Name)
            {
            // Enum.GetValues(Type) needs array of that type
            case "GetValues" when methodCalled.OwningType == factory.TypeSystemContext.GetWellKnownType(WellKnownType.Enum):
            {
                TypeDesc type = tracker.GetLastType();
                if (type != null && type.IsEnum && !type.IsGenericDefinition /* generic enums! */)
                {
                    list = list ?? new DependencyList();
                    list.Add(factory.ConstructedTypeSymbol(type.MakeArrayType()), "Enum.GetValues");
                }
            }
            break;

            // Type.GetType(string...) needs the type with the given name
            case "GetType" when methodCalled.OwningType.IsSystemType() && methodCalled.Signature.Length > 0:
            {
                string name = tracker.GetLastString();
                if (name != null &&
                    methodIL.OwningMethod.OwningType is MetadataType mdType &&
                    ResolveType(name, mdType.Module, out TypeDesc type, out ModuleDesc referenceModule) &&
                    !factory.MetadataManager.IsReflectionBlocked(type))
                {
                    const string reason = "Type.GetType";
                    list = list ?? new DependencyList();
                    list.Add(factory.MaximallyConstructableType(type), reason);

                    // Also add module metadata in case this reference was through a type forward
                    if (factory.MetadataManager.CanGenerateMetadata(referenceModule.GetGlobalModuleType()))
                    {
                        list.Add(factory.ModuleMetadata(referenceModule), reason);
                    }

                    // Opportunistically remember the type so that it flows to Type.GetMethod if needed.
                    tracker.TrackType(type);
                }
            }
            break;

            // Type.GetMethod(string...)
            case "GetMethod" when methodCalled.OwningType.IsSystemType():
            {
                string   name = tracker.GetLastString();
                TypeDesc type = tracker.GetLastType();
                if (name != null &&
                    type != null &&
                    !factory.MetadataManager.IsReflectionBlocked(type))
                {
                    if (type.IsGenericDefinition)
                    {
                        Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: false);
                        if (inst.IsNull)
                        {
                            break;
                        }
                        type = ((MetadataType)type).MakeInstantiatedType(inst);
                        list = list ?? new DependencyList();
                        list.Add(factory.MaximallyConstructableType(type), "Type.GetMethod");
                    }

                    MethodDesc reflectedMethod = type.GetMethod(name, null);
                    if (reflectedMethod != null &&
                        !factory.MetadataManager.IsReflectionBlocked(reflectedMethod))
                    {
                        if (reflectedMethod.HasInstantiation)
                        {
                            // Don't want to accidentally get Foo<__Canon>.Bar<object>()
                            if (reflectedMethod.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
                            {
                                break;
                            }

                            Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(reflectedMethod.Instantiation, allowCanon: false);
                            if (inst.IsNull)
                            {
                                break;
                            }
                            reflectedMethod = reflectedMethod.MakeInstantiatedMethod(inst);
                        }

                        const string reason = "Type.GetMethod";
                        list = list ?? new DependencyList();
                        if (reflectedMethod.IsVirtual)
                        {
                            RootVirtualMethodForReflection(ref list, factory, reflectedMethod, reason);
                        }

                        if (!reflectedMethod.IsAbstract)
                        {
                            list.Add(factory.CanonicalEntrypoint(reflectedMethod), reason);
                            if (reflectedMethod.HasInstantiation &&
                                reflectedMethod != reflectedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific))
                            {
                                list.Add(factory.MethodGenericDictionary(reflectedMethod), reason);
                            }
                        }
                    }
                }
            }
            break;

            case "SizeOf" when methodCalled.OwningType.IsSystemRuntimeInteropServicesMarshal() && !methodCalled.HasInstantiation &&
                methodCalled.Signature.Length == 1 && methodCalled.Signature[0].IsSystemType():
            {
                TypeDesc type = tracker.GetLastType();
                if (type != null && !type.IsGenericDefinition && !type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    list = list ?? new DependencyList();

                    MethodDesc marshalSizeOfGeneric = methodCalled.OwningType.GetKnownMethod(
                        "SizeOf", new MethodSignature(MethodSignatureFlags.Static, 1, methodCalled.Context.GetWellKnownType(WellKnownType.Int32), TypeDesc.EmptyTypes));
                    marshalSizeOfGeneric = marshalSizeOfGeneric.MakeInstantiatedMethod(type);

                    // InteropManager is looking for the following method bodies or dictionaries to decide marshalling info need.
                    // We should ideally model these as separate entities in the dependency graph and add those entities instead.
                    // Fixable after https://github.com/dotnet/corert/issues/6063 is fixed.
                    if (marshalSizeOfGeneric.GetCanonMethodTarget(CanonicalFormKind.Specific) != marshalSizeOfGeneric)
                    {
                        list.Add(factory.MethodGenericDictionary(marshalSizeOfGeneric), "Marshal.SizeOf");
                    }
                    else
                    {
                        list.Add(factory.MethodEntrypoint(marshalSizeOfGeneric), "Marshal.SizeOf");
                    }
                }
            }
            break;
            }
        }