示例#1
0
        public override string ToString()
        {
            if (_cachedToString != null)
            {
                return(_cachedToString);
            }

            StringBuilder sb = new StringBuilder();

            if (!_genericTypeDefinition.IsNull())
            {
                sb.Append(_genericTypeDefinition.LowLevelToString());
            }
            else if (!RuntimeTypeHandle.IsNull())
            {
                sb.Append(RuntimeTypeHandle.LowLevelToString());
            }

            if (!Instantiation.IsNull)
            {
                for (int i = 0; i < Instantiation.Length; i++)
                {
                    sb.Append(i == 0 ? "[" : ", ");
                    sb.Append(Instantiation[i].ToString());
                }
                if (Instantiation.Length > 0)
                {
                    sb.Append("]");
                }
            }

            _cachedToString = sb.ToString();

            return(_cachedToString);
        }
示例#2
0
        public bool IsCanonicallyEquivalent(RuntimeTypeHandle other)
        {
            if (_defType != null)
            {
                TypeDesc typeToFindAsCanon   = _defType.ConvertToCanonForm(_canonKind);
                TypeDesc otherTypeAsTypeDesc = _defType.Context.ResolveRuntimeTypeHandle(other);
                TypeDesc otherTypeAsCanon    = otherTypeAsTypeDesc.ConvertToCanonForm(_canonKind);
                return(typeToFindAsCanon == otherTypeAsCanon);
            }

            if (!_genericDefinition.IsNull())
            {
                if (RuntimeAugments.IsGenericType(other))
                {
                    RuntimeTypeHandle   otherGenericDefinition;
                    RuntimeTypeHandle[] otherGenericArgs;
                    otherGenericDefinition = RuntimeAugments.GetGenericInstantiation(other, out otherGenericArgs);

                    return(_genericDefinition.Equals(otherGenericDefinition) && TypeLoaderEnvironment.Instance.CanInstantiationsShareCode(_genericArgs, otherGenericArgs, _canonKind));
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(_typeToFind.Equals(other));
            }
        }
示例#3
0
        private static __ComObject CreateComObjectInternal(RuntimeTypeHandle classType, IntPtr pComItf)
        {
            Debug.Assert(!classType.IsNull());

            if (classType.Equals(McgModule.s_DependencyReductionTypeRemovedTypeHandle))
            {
                // We should filter out the strongly typed RCW in TryGetClassInfoFromName step
#if !RHTESTCL
                Environment.FailFast(McgTypeHelpers.GetDiagnosticMessageForMissingType(classType));
#else
                Environment.FailFast("We should never see strongly typed RCW discarded here");
#endif
            }

            //Note that this doesn't run the constructor in RH but probably do in your reflection based implementation.
            //If this were a real RCW, you would actually 'new' the RCW which is wrong. Fortunately in CoreCLR we don't have
            //this scenario so we are OK, but we should figure out a way to fix this by having a runtime API.
            object newClass = InteropExtensions.RuntimeNewObject(classType);

            Debug.Assert(newClass is __ComObject);

            __ComObject newObj = InteropExtensions.UncheckedCast <__ComObject>(newClass);

            IntPtr pfnCtor = AddrOfIntrinsics.AddrOf <AddrOfIntrinsics.AddrOfAttachingCtor>(__ComObject.AttachingCtor);
            CalliIntrinsics.Call <int>(pfnCtor, newObj, pComItf, classType);

            return(newObj);
        }
示例#4
0
        private static RuntimeTypeHandle GetRuntimeTypeHandleIfAny(RuntimeTypeInfo elementType, bool multiDim, int rank)
        {
            Debug.Assert(multiDim || rank == 1);

            RuntimeTypeHandle elementTypeHandle = elementType.InternalTypeHandleIfAvailable;

            if (elementTypeHandle.IsNull())
            {
                return(default(RuntimeTypeHandle));
            }

            RuntimeTypeHandle typeHandle;

            if (!multiDim)
            {
                if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetArrayTypeForElementType(elementTypeHandle, out typeHandle))
                {
                    return(default(RuntimeTypeHandle));
                }
            }
            else
            {
                if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetMultiDimArrayTypeForElementType(elementTypeHandle, rank, out typeHandle))
                {
                    return(default(RuntimeTypeHandle));
                }
            }

            return(typeHandle);
        }
示例#5
0
 /// <summary>
 ///  Setter for RuntimeTypeHandle. Seperate from normal property as all uses should be done with great care.
 ///  Must not be set with partially constructed type handles
 /// </summary>
 public void SetRuntimeTypeHandleUnsafe(RuntimeTypeHandle runtimeTypeHandle)
 {
     Debug.Assert(!runtimeTypeHandle.IsNull());
     Debug.Assert(_runtimeTypeHandle.IsNull() || runtimeTypeHandle.Equals(_runtimeTypeHandle));
     Debug.Assert(runtimeTypeHandle.GetHashCode() == GetHashCode());
     _runtimeTypeHandle = runtimeTypeHandle;
 }
示例#6
0
        private void GetTypeNameHelper(out string name, out string nsName, out string assemblyName)
        {
            TypeReferenceHandle typeRefHandle;
            QTypeDefinition     qTypeDefinition;
            MetadataReader      reader;

            RuntimeTypeHandle genericDefinitionHandle = GetTypeDefinition().GetRuntimeTypeHandle();

            Debug.Assert(!genericDefinitionHandle.IsNull());

            string enclosingDummy;

            // Try to get the name from metadata
            if (TypeLoaderEnvironment.Instance.TryGetMetadataForNamedType(genericDefinitionHandle, out qTypeDefinition))
            {
                TypeDefinitionHandle typeDefHandle = qTypeDefinition.NativeFormatHandle;
                typeDefHandle.GetFullName(qTypeDefinition.NativeFormatReader, out name, out enclosingDummy, out nsName);
                assemblyName = typeDefHandle.GetContainingModuleName(qTypeDefinition.NativeFormatReader);
            }
            // Try to get the name from diagnostic metadata
            else if (TypeLoaderEnvironment.TryGetTypeReferenceForNamedType(genericDefinitionHandle, out reader, out typeRefHandle))
            {
                typeRefHandle.GetFullName(reader, out name, out enclosingDummy, out nsName);
                assemblyName = typeRefHandle.GetContainingModuleName(reader);
            }
            else
            {
                name         = genericDefinitionHandle.LowLevelToStringRawEETypeAddress();
                nsName       = "";
                assemblyName = "?";
            }
        }
示例#7
0
 internal HandleBasedGenericMethodLookup(RuntimeTypeHandle declaringType, MethodNameAndSignature nameAndSignature, RuntimeTypeHandle[] genericMethodArgumentHandles) : base(null)
 {
     Debug.Assert(!declaringType.IsNull() && nameAndSignature != null && genericMethodArgumentHandles != null);
     _declaringType                = declaringType;
     _nameAndSignature             = nameAndSignature;
     _genericMethodArgumentHandles = genericMethodArgumentHandles;
 }
示例#8
0
        internal static RuntimePointerTypeInfo GetPointerTypeInfo(RuntimeTypeInfo elementType, RuntimeTypeHandle precomputedTypeHandle)
        {
            RuntimeTypeHandle      typeHandle = precomputedTypeHandle.IsNull() ? GetRuntimeTypeHandleIfAny(elementType) : precomputedTypeHandle;
            RuntimePointerTypeInfo type       = PointerTypeTable.Table.GetOrAdd(new UnificationKey(elementType, typeHandle));

            type.EstablishDebugName();
            return(type);
        }
示例#9
0
        internal static RuntimeConstructedGenericTypeInfo GetRuntimeConstructedGenericTypeInfo(RuntimeTypeInfo genericTypeDefinition, RuntimeTypeInfo[] genericTypeArguments, RuntimeTypeHandle precomputedTypeHandle)
        {
            RuntimeTypeHandle typeHandle = precomputedTypeHandle.IsNull() ? GetRuntimeTypeHandleIfAny(genericTypeDefinition, genericTypeArguments) : precomputedTypeHandle;
            UnificationKey    key        = new UnificationKey(genericTypeDefinition, genericTypeArguments, typeHandle);
            RuntimeConstructedGenericTypeInfo typeInfo = ConstructedGenericTypeTable.Table.GetOrAdd(key);

            typeInfo.EstablishDebugName();
            return(typeInfo);
        }
示例#10
0
        public sealed override bool IsAssignableFrom(Type c)
        {
            if (c == null)
            {
                return(false);
            }

            if (object.ReferenceEquals(c, this))
            {
                return(true);
            }

            c = c.UnderlyingSystemType;

            Type            typeInfo   = c;
            RuntimeTypeInfo toTypeInfo = this;

            if (typeInfo == null || !typeInfo.IsRuntimeImplemented())
            {
                return(false);  // Desktop compat: If typeInfo is null, or implemented by a different Reflection implementation, return "false."
            }
            RuntimeTypeInfo fromTypeInfo = typeInfo.CastToRuntimeTypeInfo();

            if (toTypeInfo.Equals(fromTypeInfo))
            {
                return(true);
            }

            RuntimeTypeHandle toTypeHandle   = toTypeInfo.InternalTypeHandleIfAvailable;
            RuntimeTypeHandle fromTypeHandle = fromTypeInfo.InternalTypeHandleIfAvailable;
            bool haveTypeHandles             = !(toTypeHandle.IsNull() || fromTypeHandle.IsNull());

            if (haveTypeHandles)
            {
                // If both types have type handles, let MRT handle this. It's not dependent on metadata.
                if (ReflectionCoreExecution.ExecutionEnvironment.IsAssignableFrom(toTypeHandle, fromTypeHandle))
                {
                    return(true);
                }

                // Runtime IsAssignableFrom does not handle casts from generic type definitions: always returns false. For those, we fall through to the
                // managed implementation. For everyone else, return "false".
                //
                // Runtime IsAssignableFrom does not handle pointer -> UIntPtr cast.
                if (!(fromTypeInfo.IsGenericTypeDefinition || fromTypeInfo.IsPointer))
                {
                    return(false);
                }
            }

            // If we got here, the types are open, or reduced away, or otherwise lacking in type handles. Perform the IsAssignability check in managed code.
            return(Assignability.IsAssignableFrom(this, typeInfo));
        }
示例#11
0
        /// <summary>
        /// Return the RuntimeTypeHandle for the named type described in metadata. This is used to implement the Create and Invoke
        /// apis for types.
        ///
        /// Preconditions:
        ///    metadataReader + typeDefHandle  - a valid metadata reader + typeDefinitionHandle where "metadataReader" is one
        ///                                      of the metadata readers returned by ExecutionEnvironment.MetadataReaders.
        ///
        /// Note: Although this method has a "bool" return value like the other mapping table accessors, the Project N pay-for-play design
        /// guarantees that any type enabled for metadata also has a RuntimeTypeHandle underneath.
        /// </summary>
        /// <param name="metadataReader">Metadata reader for module containing the type</param>
        /// <param name="typeDefHandle">TypeDef handle for the type to look up</param>
        /// <param name="runtimeTypeHandle">Runtime type handle (EEType) for the given type</param>
        public unsafe bool TryGetNamedTypeForMetadata(QTypeDefinition qTypeDefinition, out RuntimeTypeHandle runtimeTypeHandle)
        {
            runtimeTypeHandle = default(RuntimeTypeHandle);
            NamedTypeLookupResult result = _metadataToRuntimeTypeHandleHashtable.GetOrCreateValue(qTypeDefinition);

            if (result.VersionNumber <= _namedTypeLookupLiveVersion)
            {
                runtimeTypeHandle = result.RuntimeTypeHandle;
            }

            return(!runtimeTypeHandle.IsNull());
        }
示例#12
0
        internal static RuntimeTypeHandle FindTypeSupportDynamic(Func <RuntimeTypeHandle, bool> predicate)
        {
            for (int i = 0; i < s_moduleCount; i++)
            {
                RuntimeTypeHandle info = s_modules[i].FindTypeSupportDynamic(predicate);

                if (!info.IsNull())
                {
                    return(info);
                }
            }

            return(default(RuntimeTypeHandle));
        }
示例#13
0
        /// <summary>
        /// Given a GUID, retrieve the corresponding type(s)
        /// </summary>
        internal static IEnumerable <RuntimeTypeHandle> GetTypesFromGuid(ref Guid guid)
        {
            List <RuntimeTypeHandle> rets = new List <RuntimeTypeHandle>(s_moduleCount);

            for (int i = 0; i < s_moduleCount; ++i)
            {
                RuntimeTypeHandle ret = s_modules[i].GetTypeFromGuid(ref guid);

                if (!ret.IsNull())
                {
                    rets.Add(ret);
                }
            }

            return(rets);
        }
示例#14
0
        private static void ValidateElementType(RuntimeTypeInfo elementType, RuntimeTypeHandle typeHandle, bool multiDim, int rank)
        {
            Debug.Assert(multiDim || rank == 1);

            if (elementType.IsByRef || elementType.IsByRefLike)
            {
                throw new TypeLoadException(SR.Format(SR.ArgumentException_InvalidArrayElementType, elementType));
            }

            // We only permit creating parameterized types if the pay-for-play policy specifically allows them *or* if the result
            // type would be an open type.
            if (typeHandle.IsNull() && !elementType.ContainsGenericParameters && !(elementType is RuntimeCLSIDTypeInfo))
            {
                throw ReflectionCoreExecution.ExecutionDomain.CreateMissingArrayTypeException(elementType, multiDim, rank);
            }
        }
示例#15
0
        private static RuntimeTypeHandle GetRuntimeTypeHandleIfAny(RuntimeTypeInfo elementType)
        {
            RuntimeTypeHandle elementTypeHandle = elementType.InternalTypeHandleIfAvailable;

            if (elementTypeHandle.IsNull())
            {
                return(default(RuntimeTypeHandle));
            }

            RuntimeTypeHandle typeHandle;

            if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetPointerTypeForTargetType(elementTypeHandle, out typeHandle))
            {
                return(default(RuntimeTypeHandle));
            }

            return(typeHandle);
        }
示例#16
0
        private static RuntimeArrayTypeInfo WithVerifiedTypeHandle(this RuntimeArrayTypeInfo arrayType, RuntimeTypeInfo elementType)
        {
            // We only permit creating parameterized types if the pay-for-play policy specifically allows them *or* if the result
            // type would be an open type.
            RuntimeTypeHandle typeHandle = arrayType.InternalTypeHandleIfAvailable;

            if (IsTypeConstructionEagerlyValidated &&
                typeHandle.IsNull() && !elementType.ContainsGenericParameters
#if FEATURE_COMINTEROP
                && !(elementType is RuntimeCLSIDTypeInfo)
#endif
                )
            {
                throw ReflectionCoreExecution.ExecutionDomain.CreateMissingArrayTypeException(elementType, isMultiDim: false, 1);
            }

            return(arrayType);
        }
示例#17
0
        /// <summary>
        /// Return the RuntimeTypeHandle for the named type described in metadata. This is used to implement the Create and Invoke
        /// apis for types.
        ///
        /// Preconditions:
        ///    metadataReader + typeDefHandle  - a valid metadata reader + typeDefinitionHandle where "metadataReader" is one
        ///                                      of the metadata readers returned by ExecutionEnvironment.MetadataReaders.
        ///
        /// Note: Although this method has a "bool" return value like the other mapping table accessors, the Project N pay-for-play design
        /// guarantees that any type enabled for metadata also has a RuntimeTypeHandle underneath.
        /// </summary>
        /// <param name="metadataReader">Metadata reader for module containing the type</param>
        /// <param name="typeDefHandle">TypeDef handle for the type to look up</param>
        /// <param name="runtimeTypeHandle">Runtime type handle (EEType) for the given type</param>
        public unsafe bool TryGetNamedTypeForMetadata(MetadataReader metadataReader, TypeDefinitionHandle typeDefHandle, out RuntimeTypeHandle runtimeTypeHandle)
        {
            NamedTypeMetadataDescription description = new NamedTypeMetadataDescription()
            {
                MetadataReader = metadataReader,
                TypeDefinition = typeDefHandle
            };

            runtimeTypeHandle = default(RuntimeTypeHandle);
            NamedTypeLookupResult result = _metadataToRuntimeTypeHandleHashtable.GetOrCreateValue(description);

            if (result.VersionNumber <= _namedTypeLookupLiveVersion)
            {
                runtimeTypeHandle = result.RuntimeTypeHandle;
            }

            return(!runtimeTypeHandle.IsNull());
        }
示例#18
0
        internal static NativeFormatRuntimeNamedTypeInfo GetRuntimeNamedTypeInfo(MetadataReader metadataReader, TypeDefinitionHandle typeDefHandle, RuntimeTypeHandle precomputedTypeHandle)
        {
            RuntimeTypeHandle typeHandle = precomputedTypeHandle;

            if (typeHandle.IsNull())
            {
                if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetNamedTypeForMetadata(new QTypeDefinition(metadataReader, typeDefHandle), out typeHandle))
                {
                    typeHandle = default(RuntimeTypeHandle);
                }
            }
            UnificationKey key = new UnificationKey(metadataReader, typeDefHandle, typeHandle);

            NativeFormatRuntimeNamedTypeInfo type = NamedTypeTable.Table.GetOrAdd(key);

            type.EstablishDebugName();
            return(type);
        }
示例#19
0
        internal static RuntimeArrayTypeInfo GetArrayTypeInfo(RuntimeTypeInfo elementType, bool multiDim, int rank, RuntimeTypeHandle precomputedTypeHandle)
        {
            Debug.Assert(multiDim || rank == 1);

            RuntimeTypeHandle    typeHandle = precomputedTypeHandle.IsNull() ? GetRuntimeTypeHandleIfAny(elementType, multiDim, rank) : precomputedTypeHandle;
            UnificationKey       key        = new UnificationKey(elementType, typeHandle);
            RuntimeArrayTypeInfo type;

            if (!multiDim)
            {
                type = ArrayTypeTable.Table.GetOrAdd(key);
            }
            else
            {
                type = TypeTableForMultiDimArrayTypeTables.Table.GetOrAdd(rank).GetOrAdd(key);
            }
            type.EstablishDebugName();
            return(type);
        }
示例#20
0
文件: McgModule.cs 项目: tmds/corert
        /// <summary>
        /// Returns the requested interface pointer specified by itfType from the CCWActivationFactory
        /// object instance. Typically the requested interface is the
        /// System.Runtime.InteropServices.WindowsRuntime.IActivationFactory interface.
        /// </summary>
        public unsafe int GetCCWActivationFactory(HSTRING activatableClassId, RuntimeTypeHandle itfType, IntPtr *factoryOut)
        {
            try
            {
                string classId = McgMarshal.HStringToString(activatableClassId);

                if (classId == null)
                {
                    return(Interop.COM.E_INVALIDARG);
                }

                RuntimeTypeHandle factoryTypeHandle = default(RuntimeTypeHandle);

                if (m_ccwFactoriesNameMap != null)
                {
                    int slot = m_ccwFactoriesNameMap.FindString(classId);

                    if (slot >= 0)
                    {
                        factoryTypeHandle = m_ccwFactories[slot].FactoryType;
                    }
                }

                if (factoryTypeHandle.IsNull())
                {
                    return(Interop.COM.E_NOINTERFACE);
                }

                object factory = InteropExtensions.RuntimeNewObject(factoryTypeHandle);

                *factoryOut = McgMarshal.ObjectToComInterface(
                    factory,
                    itfType);
            }
            catch (Exception ex)
            {
                *factoryOut = default(IntPtr);
                return(McgMarshal.GetHRForExceptionWinRT(ex));
            }

            return(Interop.COM.S_OK);
        }
示例#21
0
        private static RuntimeTypeHandle GetRuntimeTypeHandleIfAny(RuntimeTypeInfo elementType, bool multiDim, int rank)
        {
            Debug.Assert(multiDim || rank == 1);

            RuntimeTypeHandle elementTypeHandle = elementType.InternalTypeHandleIfAvailable;

            if (elementTypeHandle.IsNull())
            {
                return(default(RuntimeTypeHandle));
            }

            // The check is here on purpose - one of the implementations of IsByRefLike contains a custom attribute
            // search and those are very expensive from size on disk footprint perspective. We purposefully
            // place this call in a path that won't be part of the executable image unless more advanced reflection services
            // are also needed ("pay for play"). We really don't want a typeof() to push the app into requiring the full reflection
            // stack to be compiled into the final executable.
            if (elementType.IsByRefLike)
            {
                throw new TypeLoadException(SR.Format(SR.ArgumentException_InvalidArrayElementType, elementType));
            }

            RuntimeTypeHandle typeHandle;

            if (!multiDim)
            {
                if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetArrayTypeForElementType(elementTypeHandle, out typeHandle))
                {
                    return(default(RuntimeTypeHandle));
                }
            }
            else
            {
                if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetMultiDimArrayTypeForElementType(elementTypeHandle, rank, out typeHandle))
                {
                    return(default(RuntimeTypeHandle));
                }
            }

            return(typeHandle);
        }
示例#22
0
        private static RuntimeTypeHandle GetRuntimeTypeHandleIfAny(RuntimeTypeInfo genericTypeDefinition, RuntimeTypeInfo[] genericTypeArguments)
        {
            RuntimeTypeHandle genericTypeDefinitionHandle = genericTypeDefinition.InternalTypeHandleIfAvailable;

            if (genericTypeDefinitionHandle.IsNull())
            {
                return(default(RuntimeTypeHandle));
            }

            if (ReflectionCoreExecution.ExecutionEnvironment.IsReflectionBlocked(genericTypeDefinitionHandle))
            {
                return(default(RuntimeTypeHandle));
            }

            int count = genericTypeArguments.Length;

            RuntimeTypeHandle[] genericTypeArgumentHandles = new RuntimeTypeHandle[count];
            for (int i = 0; i < count; i++)
            {
                RuntimeTypeHandle genericTypeArgumentHandle = genericTypeArguments[i].InternalTypeHandleIfAvailable;
                if (genericTypeArgumentHandle.IsNull())
                {
                    return(default(RuntimeTypeHandle));
                }
                genericTypeArgumentHandles[i] = genericTypeArgumentHandle;
            }

            RuntimeTypeHandle typeHandle;

            if (!ReflectionCoreExecution.ExecutionEnvironment.TryGetConstructedGenericTypeForComponents(genericTypeDefinitionHandle, genericTypeArgumentHandles, out typeHandle))
            {
                return(default(RuntimeTypeHandle));
            }

            return(typeHandle);
        }
示例#23
0
        private static RuntimeConstructedGenericTypeInfo WithVerifiedTypeHandle(this RuntimeConstructedGenericTypeInfo genericType, RuntimeTypeInfo[] genericTypeArguments)
        {
            // We only permit creating parameterized types if the pay-for-play policy specifically allows them *or* if the result
            // type would be an open type.
            RuntimeTypeHandle typeHandle = genericType.InternalTypeHandleIfAvailable;

            if (IsTypeConstructionEagerlyValidated && typeHandle.IsNull())
            {
                bool atLeastOneOpenType = false;
                foreach (RuntimeTypeInfo genericTypeArgument in genericTypeArguments)
                {
                    if (genericTypeArgument.ContainsGenericParameters)
                    {
                        atLeastOneOpenType = true;
                    }
                }
                if (!atLeastOneOpenType)
                {
                    throw ReflectionCoreExecution.ExecutionDomain.CreateMissingConstructedGenericTypeException(genericType.GetGenericTypeDefinition(), genericTypeArguments.CloneTypeArray());
                }
            }

            return(genericType);
        }
示例#24
0
        // Todo: This is looking up the hierarchy to DefType and ParameterizedType. It should really
        // call a virtual or an outside type to handle those parts
        internal bool RetrieveRuntimeTypeHandleIfPossible()
        {
            TypeDesc type = this;

            if (!type.RuntimeTypeHandle.IsNull())
            {
                return(true);
            }

            TypeBuilderState state = GetTypeBuilderStateIfExist();

            if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle)
            {
                return(false);
            }

            if (type is DefType)
            {
                DefType typeAsDefType = (DefType)type;

                TypeDesc          typeDefinition = typeAsDefType.GetTypeDefinition();
                RuntimeTypeHandle typeDefHandle  = typeDefinition.RuntimeTypeHandle;
                if (typeDefHandle.IsNull())
                {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
                    NativeFormat.NativeFormatType mdType = typeDefinition as NativeFormat.NativeFormatType;
                    if (mdType != null)
                    {
                        // Look up the runtime type handle in the module metadata
                        if (TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(new QTypeDefinition(mdType.MetadataReader, mdType.Handle), out typeDefHandle))
                        {
                            typeDefinition.SetRuntimeTypeHandleUnsafe(typeDefHandle);
                        }
                    }
#endif
#if ECMA_METADATA_SUPPORT
                    Ecma.EcmaType ecmaType = typeDefinition as Ecma.EcmaType;
                    if (ecmaType != null)
                    {
                        // Look up the runtime type handle in the module metadata
                        if (TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(new QTypeDefinition(ecmaType.MetadataReader, ecmaType.Handle), out typeDefHandle))
                        {
                            typeDefinition.SetRuntimeTypeHandleUnsafe(typeDefHandle);
                        }
                    }
#endif
                }

                if (!typeDefHandle.IsNull())
                {
                    Instantiation instantiation = typeAsDefType.Instantiation;

                    if ((instantiation.Length > 0) && !typeAsDefType.IsGenericDefinition)
                    {
                        // Generic type. First make sure we have type handles for the arguments, then check
                        // the instantiation.
                        bool argumentsRegistered = true;
                        bool arrayArgumentsFound = false;
                        for (int i = 0; i < instantiation.Length; i++)
                        {
                            if (!instantiation[i].RetrieveRuntimeTypeHandleIfPossible())
                            {
                                argumentsRegistered = false;
                                arrayArgumentsFound = arrayArgumentsFound || (instantiation[i] is ArrayType);
                            }
                        }

                        RuntimeTypeHandle rtth;

                        // If at least one of the arguments is not known to the runtime, we take a slower
                        // path to compare the current type we need a handle for to the list of generic
                        // types statically available, by loading them as DefTypes and doing a DefType comparaison
                        if ((argumentsRegistered && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.HandleBasedGenericTypeLookup(typeAsDefType), out rtth)) ||
                            (arrayArgumentsFound && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.DefTypeBasedGenericTypeLookup(typeAsDefType), out rtth)))
                        {
                            typeAsDefType.SetRuntimeTypeHandleUnsafe(rtth);
                            return(true);
                        }
                    }
                    else
                    {
                        // Nongeneric, or generic type def types are just the type handle of the type definition as found above
                        type.SetRuntimeTypeHandleUnsafe(typeDefHandle);
                        return(true);
                    }
                }
            }
            else if (type is ParameterizedType)
            {
                ParameterizedType typeAsParameterType = (ParameterizedType)type;

                if (typeAsParameterType.ParameterType.RetrieveRuntimeTypeHandleIfPossible())
                {
                    RuntimeTypeHandle rtth;
                    if ((type is ArrayType &&
                         (TypeLoaderEnvironment.Instance.TryGetArrayTypeForElementType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, type.IsMdArray, type.IsMdArray ? ((ArrayType)type).Rank : -1, out rtth) ||
                          TypeLoaderEnvironment.Instance.TryGetArrayTypeHandleForNonDynamicArrayTypeFromTemplateTable(type as ArrayType, out rtth)))
                        ||
                        (type is PointerType && TypeSystemContext.PointerTypesCache.TryGetValue(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth)))
                    {
                        typeAsParameterType.SetRuntimeTypeHandleUnsafe(rtth);
                        return(true);
                    }
                    else if (type is ByRefType)
                    {
                        // Byref types don't have any associated type handles, so return success at this point
                        // since we were able to resolve the typehandle of the element type
                        return(true);
                    }
                }
            }
            else if (type is SignatureVariable)
            {
                // SignatureVariables do not have RuntimeTypeHandles
            }
            else
            {
                Debug.Assert(false);
            }

            // Make a note on the type build state that we have attempted to retrieve RuntimeTypeHandle but there is not one
            GetOrCreateTypeBuilderState().AttemptedAndFailedToRetrieveTypeHandle = true;

            return(false);
        }
        private bool FindMatchingInterfaceSlot(NativeFormatModuleInfo module, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle instanceTypeHandle, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch, bool defaultMethods)
        {
            uint numTargetImplementations = entryParser.GetUnsigned();

#if GVM_RESOLUTION_TRACE
            Debug.WriteLine(" :: Declaring type = " + GetTypeNameDebug(declaringType));
            Debug.WriteLine(" :: Target type = " + GetTypeNameDebug(openTargetTypeHandle));
#endif

            for (uint j = 0; j < numTargetImplementations; j++)
            {
                uint nameAndSigToken = entryParser.GetUnsigned();

                MethodNameAndSignature targetMethodNameAndSignature = null;
                RuntimeTypeHandle      targetTypeHandle             = default;
                bool isDefaultInterfaceMethodImplementation;

                if (nameAndSigToken != SpecialGVMInterfaceEntry.Diamond && nameAndSigToken != SpecialGVMInterfaceEntry.Reabstraction)
                {
                    targetMethodNameAndSignature           = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, module.Handle, nameAndSigToken);
                    targetTypeHandle                       = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    isDefaultInterfaceMethodImplementation = RuntimeAugments.IsInterface(targetTypeHandle);
#if GVM_RESOLUTION_TRACE
                    Debug.WriteLine("    Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle));
#endif
                }
                else
                {
                    isDefaultInterfaceMethodImplementation = true;
                }

                uint numIfaceImpls = entryParser.GetUnsigned();

                for (uint k = 0; k < numIfaceImpls; k++)
                {
                    RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

#if GVM_RESOLUTION_TRACE
                    Debug.WriteLine("      -> Current implementing type = " + GetTypeNameDebug(implementingTypeHandle));
#endif

                    uint numIfaceSigs = entryParser.GetUnsigned();

                    if (!openTargetTypeHandle.Equals(implementingTypeHandle) ||
                        defaultMethods != isDefaultInterfaceMethodImplementation)
                    {
                        // Skip over signatures data
                        for (uint l = 0; l < numIfaceSigs; l++)
                        {
                            entryParser.GetUnsigned();
                        }

                        continue;
                    }

                    for (uint l = 0; l < numIfaceSigs; l++)
                    {
                        RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle);

                        NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, entryParser.GetUnsigned());

                        if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref ifaceSigParser, module.Handle, targetTypeInstantiation, null, out currentIfaceTypeHandle))
                        {
#if GVM_RESOLUTION_TRACE
                            Debug.WriteLine("         -> Current interface on type = " + GetTypeNameDebug(currentIfaceTypeHandle));
#endif
                            Debug.Assert(!currentIfaceTypeHandle.IsNull());

                            if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) ||
                                (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle)))
                            {
#if GVM_RESOLUTION_TRACE
                                Debug.WriteLine("    " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!");
#endif
                                if (targetMethodNameAndSignature == null)
                                {
                                    if (nameAndSigToken == SpecialGVMInterfaceEntry.Diamond)
                                    {
                                        throw new AmbiguousImplementationException();
                                    }
                                    else
                                    {
                                        Debug.Assert(nameAndSigToken == SpecialGVMInterfaceEntry.Reabstraction);
                                        throw new EntryPointNotFoundException();
                                    }
                                }

                                // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller
                                if (!RuntimeAugments.IsInterface(targetTypeHandle) || !RuntimeAugments.IsGenericTypeDefinition(targetTypeHandle))
                                {
                                    // Not a default interface method or default interface method on a non-generic type.
                                    // We have a usable type handle.
                                    declaringType = targetTypeHandle;
                                }
                                else if (RuntimeAugments.IsGenericType(currentIfaceTypeHandle) && RuntimeAugments.GetGenericDefinition(currentIfaceTypeHandle).Equals(targetTypeHandle))
                                {
                                    // Default interface method implemented on the same type that declared the slot.
                                    // Use the instantiation as-is from what we found.
                                    declaringType = currentIfaceTypeHandle;
                                }
                                else
                                {
                                    declaringType = default;

                                    // Default interface method implemented on a different generic interface.
                                    // We need to find a usable instantiation. There should be only one match because we
                                    // would be dealing with a diamond otherwise.
                                    int numInstanceInterfaces = RuntimeAugments.GetInterfaceCount(instanceTypeHandle);
                                    for (int instIntfIndex = 0; instIntfIndex < numInstanceInterfaces; instIntfIndex++)
                                    {
                                        RuntimeTypeHandle instIntf = RuntimeAugments.GetInterface(instanceTypeHandle, instIntfIndex);
                                        if (RuntimeAugments.IsGenericType(instIntf) &&
                                            RuntimeAugments.GetGenericDefinition(instIntf).Equals(targetTypeHandle))
                                        {
                                            // Got a potential interface. Check if the implementing interface is in the interface
                                            // list. We don't want IsAssignableFrom because we need an exact match.
                                            int numIntInterfaces = RuntimeAugments.GetInterfaceCount(instIntf);
                                            for (int intIntfIndex = 0; intIntfIndex < numIntInterfaces; intIntfIndex++)
                                            {
                                                if (RuntimeAugments.GetInterface(instIntf, intIntfIndex).Equals(currentIfaceTypeHandle))
                                                {
                                                    Debug.Assert(declaringType.IsNull());
                                                    declaringType = instIntf;
#if !DEBUG
                                                    break;
#endif
                                                }
                                            }
#if !DEBUG
                                            if (!declaringType.IsNull())
                                            {
                                                break;
                                            }
#endif
                                        }
                                    }

                                    Debug.Assert(!declaringType.IsNull());
                                }

                                methodNameAndSignature = targetMethodNameAndSignature;
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#26
0
        /// <summary>
        /// Returns the existing RCW or create a new RCW from the COM interface pointer
        /// NOTE: This does not do any unboxing at all.
        /// </summary>
        /// <param name="expectedContext">
        /// The current context of this thread. If it is passed and is not Default, we'll check whether the
        /// returned RCW from cache matches this expected context. If it is not a match (from a different
        /// context, and is not free threaded), we'll go ahead ignoring the cached entry, and create a new
        /// RCW instead - which will always end up in the current context
        /// We'll skip the check if current == ContextCookie.Default.
        /// </param>
        private static object ComInterfaceToComObjectInternal_NoCache(
            IntPtr pComItf,
            IntPtr pComIdentityIUnknown,
            RuntimeTypeHandle interfaceType,
            RuntimeTypeHandle classTypeInSignature,
            ContextCookie expectedContext,
            CreateComObjectFlags flags,
            out string className
            )
        {
            className = null;

            //
            // Lookup RCW in global RCW cache based on the identity IUnknown
            //
            __ComObject comObject = ComObjectCache.Lookup(pComIdentityIUnknown);

            if (comObject != null)
            {
                bool useThisComObject = true;

                if (!expectedContext.IsDefault)
                {
                    //
                    // Make sure the returned RCW matches the context we specify (if any)
                    //
                    if (!comObject.IsFreeThreaded &&
                        !comObject.ContextCookie.Equals(expectedContext))
                    {
                        //
                        // This is a mismatch.
                        // We only care about context for WinRT factory RCWs (which is the only place we are
                        // passing in the context right now).
                        // When we get back a WinRT factory RCW created in a different context. This means the
                        // factory is a singleton, and the returned IActivationFactory could be either one of
                        // the following:
                        // 1) A raw pointer, and it acts like a free threaded object
                        // 2) A proxy that is used across different contexts. It might maintain a list of contexts
                        // that it is marshaled to, and will fail to be called if it is not marshaled to this
                        // context yet.
                        //
                        // In this case, it is unsafe to use this RCW in this context and we should proceed
                        // to create a duplicated one instead. It might make sense to have a context-sensitive
                        // RCW cache but I don't think this case will be common enough to justify it
                        //
                        // @TODO: Check for DCOM proxy as well
                        useThisComObject = false;
                    }
                }

                if (useThisComObject)
                {
                    //
                    // We found one - AddRef and return
                    //
                    comObject.AddRef();
                    return(comObject);
                }
            }

            string winrtClassName = null;

            bool isSealed = false;

            if (!classTypeInSignature.IsNull())
            {
                isSealed = classTypeInSignature.IsSealed();
            }

            //
            // Only look at runtime class name if the class type in signature is not sealed
            // NOTE: In the case of System.Uri, we are not pass the class type, only the interface
            //
            if (!isSealed &&
                (flags & CreateComObjectFlags.SkipTypeResolutionAndUnboxing) == 0)
            {
                IntPtr pInspectable;

                bool needRelease = false;

                if (interfaceType.IsSupportIInspectable())
                {
                    //
                    // Use the interface pointer as IInspectable as we know it is indeed a WinRT interface that
                    // derives from IInspectable
                    //
                    pInspectable = pComItf;
                }
                else if ((flags & CreateComObjectFlags.IsWinRTObject) != 0)
                {
                    //
                    // Otherwise, if someone tells us that this is a WinRT object, but we don't have a
                    // IInspectable interface at hand, we'll QI for it
                    //
                    pInspectable = McgMarshal.ComQueryInterfaceNoThrow(pComItf, ref Interop.COM.IID_IInspectable);
                    needRelease  = true;
                }
                else
                {
                    pInspectable = default(IntPtr);
                }

                try
                {
                    if (pInspectable != default(IntPtr))
                    {
                        className      = McgComHelpers.GetRuntimeClassName(pInspectable);
                        winrtClassName = className;
                    }
                }
                finally
                {
                    if (needRelease && pInspectable != default(IntPtr))
                    {
                        McgMarshal.ComRelease(pInspectable);
                        pInspectable = default(IntPtr);
                    }
                }
            }

            //
            // 1. Prefer using the class returned from GetRuntimeClassName
            // 2. Otherwise use the class (if there) in the signature
            // 3. Out of options - create __ComObject
            //
            RuntimeTypeHandle classTypeToCreateRCW  = default(RuntimeTypeHandle);
            RuntimeTypeHandle interfaceTypeFromName = default(RuntimeTypeHandle);

            if (!String.IsNullOrEmpty(className))
            {
                if (!McgModuleManager.TryGetClassTypeFromName(className, out classTypeToCreateRCW))
                {
                    //
                    // If we can't find the class name in our map, try interface as well
                    // Such as IVector<Int32>
                    // This apparently won't work if we haven't seen the interface type in MCG
                    //
                    McgModuleManager.TryGetInterfaceTypeFromName(className, out interfaceTypeFromName);
                }
            }

            if (classTypeToCreateRCW.IsNull())
            {
                classTypeToCreateRCW = classTypeInSignature;
            }

            // Use identity IUnknown to create the new RCW
            // @TODO: Transfer the ownership of ref count to the RCW
            if (classTypeToCreateRCW.IsNull())
            {
                //
                // Create a weakly typed RCW because we have no information about this particular RCW
                // @TODO - what if this RCW is not seen by MCG but actually exists in WinMD and therefore we
                // are missing GCPressure and ComMarshallingType information for this object?
                //
                comObject = new __ComObject(pComIdentityIUnknown, default(RuntimeTypeHandle));
            }
            else
            {
                //
                // Create a strongly typed RCW based on RuntimeTypeHandle
                //
                comObject = CreateComObjectInternal(classTypeToCreateRCW, pComIdentityIUnknown);            // Use identity IUnknown to create the new RCW
            }

#if DEBUG
            //
            // Remember the runtime class name for debugging purpose
            // This way you can tell what the class name is, even when we failed to create a strongly typed
            // RCW for it
            //
            comObject.m_runtimeClassName = className;
#endif

            //
            // Make sure we QI for that interface
            //
            if (!interfaceType.IsNull())
            {
                comObject.QueryInterface_NoAddRef_Internal(interfaceType, /* cacheOnly= */ false, /* throwOnQueryInterfaceFailure= */ false);
            }

            return(comObject);
        }
示例#27
0
        /// <summary>
        /// Returns the existing RCW or create a new RCW from the COM interface pointer
        /// NOTE: This does unboxing unless CreateComObjectFlags.SkipTypeResolutionAndUnboxing is specified
        /// </summary>
        /// <param name="expectedContext">
        /// The current context of this thread. If it is passed and is not Default, we'll check whether the
        /// returned RCW from cache matches this expected context. If it is not a match (from a different
        /// context, and is not free threaded), we'll go ahead ignoring the cached entry, and create a new
        /// RCW instead - which will always end up in the current context
        /// We'll skip the check if current == ContextCookie.Default.
        /// </param>
        internal static object ComInterfaceToComObjectInternal(
            IntPtr pComItf,
            IntPtr pComIdentityIUnknown,
            RuntimeTypeHandle interfaceType,
            RuntimeTypeHandle classTypeInSignature,
            ContextCookie expectedContext,
            CreateComObjectFlags flags
            )
        {
            string className;
            object obj = ComInterfaceToComObjectInternal_NoCache(
                pComItf,
                pComIdentityIUnknown,
                interfaceType,
                classTypeInSignature,
                expectedContext,
                flags,
                out className
                );

            //
            // The assumption here is that if the classInfoInSignature is null and interfaceTypeInfo
            // is either IUnknow and IInspectable we need to try unboxing.
            //
            bool doUnboxingCheck =
                (flags & CreateComObjectFlags.SkipTypeResolutionAndUnboxing) == 0 &&
                obj != null &&
                classTypeInSignature.IsNull() &&
                (interfaceType.Equals(InternalTypes.IUnknown) ||
                 interfaceType.IsIInspectable());

            if (doUnboxingCheck)
            {
                //
                // Try unboxing
                // Even though this might just be a IUnknown * from the signature, we still attempt to unbox
                // if it implements IInspectable
                //
                // @TODO - We might need to optimize this by pre-checking the names to see if they
                // potentially represents a boxed type, but for now let's keep it simple and I also don't
                // want to replicate the knowledge here
                // @TODO2- We probably should skip the creating the COM object in the first place.
                //
                // NOTE: the RCW here could be a cached one (for a brief time if GC doesn't kick in. as there
                // is nothing to hold the RCW alive for IReference<T> RCWs), so this could save us a RCW
                // creation cost potentially. Desktop CLR doesn't do this. But we also paying for unnecessary
                // cache management cost, and it is difficult to say which way is better without proper
                // measuring
                //
                object unboxedObj = McgMarshal.UnboxIfBoxed(obj, className);
                if (unboxedObj != null)
                {
                    return(unboxedObj);
                }
            }

            //
            // In order for variance to work, we save the incoming interface pointer as specified in the
            // signature into the cache, so that we know this RCW does support this interface and variance
            // can take advantage of that later
            // NOTE: In some cases, native might pass a WinRT object as a 'compatible' interface, for example,
            // pass IVector<IFoo> as IVector<Object> because they are 'compatible', but QI for IVector<object>
            // won't succeed. In this case, we'll just believe it implements IVector<Object> as in the
            // signature while the underlying interface pointer is actually IVector<IFoo>
            //
            __ComObject comObject = obj as __ComObject;

            if (comObject != null)
            {
                McgMarshal.ComAddRef(pComItf);

                try
                {
                    comObject.InsertIntoCache(interfaceType, ContextCookie.Current, ref pComItf, true);
                }
                finally
                {
                    //
                    // Only release when a exception is thrown or we didn't 'swallow' the ref count by
                    // inserting it into the cache
                    //
                    McgMarshal.ComSafeRelease(pComItf);
                }
            }

            return(obj);
        }
示例#28
0
        private bool FindMatchingInterfaceSlot(NativeFormatModuleInfo module, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch)
        {
            uint numTargetImplementations = entryParser.GetUnsigned();

            for (uint j = 0; j < numTargetImplementations; j++)
            {
                uint nameAndSigToken = extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned());
                MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, module.Handle, nameAndSigToken);
                RuntimeTypeHandle      targetTypeHandle             = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

#if REFLECTION_EXECUTION_TRACE
                ReflectionExecutionLogger.WriteLine("    Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle));
#endif

                uint numIfaceImpls = entryParser.GetUnsigned();

                for (uint k = 0; k < numIfaceImpls; k++)
                {
                    RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    uint numIfaceSigs = entryParser.GetUnsigned();

                    if (!openTargetTypeHandle.Equals(implementingTypeHandle))
                    {
                        // Skip over signatures data
                        for (uint l = 0; l < numIfaceSigs; l++)
                        {
                            entryParser.GetUnsigned();
                        }

                        continue;
                    }

                    for (uint l = 0; l < numIfaceSigs; l++)
                    {
                        RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle);

                        NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetExternalNativeLayoutOffset(entryParser.GetUnsigned()));

                        if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref ifaceSigParser, module.Handle, targetTypeInstantiation, null, out currentIfaceTypeHandle))
                        {
                            Debug.Assert(!currentIfaceTypeHandle.IsNull());

                            if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) ||
                                (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle)))
                            {
#if REFLECTION_EXECUTION_TRACE
                                ReflectionExecutionLogger.WriteLine("    " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!");
#endif
                                // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller
                                declaringType          = targetTypeHandle;
                                methodNameAndSignature = targetMethodNameAndSignature;
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }