Example #1
0
        public Type GetConstructedGenericTypeForHandle(RuntimeTypeHandle typeHandle)
        {
            RuntimeTypeHandle genericTypeDefinitionHandle;
            RuntimeTypeHandle[] genericTypeArgumentHandles;
            genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(typeHandle, out genericTypeArgumentHandles);

            // Reflection blocked constructed generic types simply pretend to not be generic
            // This is reasonable, as the behavior of reflection blocked types is supposed
            // to be that they expose the minimal information about a type that is necessary
            // for users of Object.GetType to move from that type to a type that isn't
            // reflection blocked. By not revealing that reflection blocked types are generic
            // we are making it appear as if implementation detail types exposed to user code
            // are all non-generic, which is theoretically possible, and by doing so
            // we avoid (in all known circumstances) the very complicated case of representing
            // the interfaces, base types, and generic parameter types of reflection blocked
            // generic type definitions.
            if (ExecutionEnvironment.IsReflectionBlocked(genericTypeDefinitionHandle))
            {
                return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition: false);
            }

            RuntimeTypeInfo genericTypeDefinition = genericTypeDefinitionHandle.GetTypeForRuntimeTypeHandle();
            int count = genericTypeArgumentHandles.Length;
            RuntimeTypeInfo[] genericTypeArguments = new RuntimeTypeInfo[count];
            for (int i = 0; i < count; i++)
            {
                genericTypeArguments[i] = genericTypeArgumentHandles[i].GetTypeForRuntimeTypeHandle();
            }
            return genericTypeDefinition.GetConstructedGenericType(genericTypeArguments, typeHandle);
        }
Example #2
0
        private RuntimeTypeHandle GetOpenTypeDefinition(RuntimeTypeHandle typeHandle, out RuntimeTypeHandle[] typeArgumentsHandles)
        {
            if (RuntimeAugments.IsGenericType(typeHandle))
            {
                return(RuntimeAugments.GetGenericInstantiation(typeHandle, out typeArgumentsHandles));
            }

            typeArgumentsHandles = null;
            return(typeHandle);
        }
Example #3
0
        public CanonicallyEquivalentEntryLocator(RuntimeTypeHandle typeToFind, CanonicalFormKind kind)
        {
            if (RuntimeAugments.IsGenericType(typeToFind))
            {
                _genericDefinition = RuntimeAugments.GetGenericInstantiation(typeToFind, out _genericArgs);
            }
            else
            {
                _genericArgs       = null;
                _genericDefinition = default(RuntimeTypeHandle);
            }

            _typeToFind = typeToFind;
            _canonKind  = kind;
            _defType    = null;
        }
Example #4
0
            internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType)
            {
                //
                // Entries read from the hashtable are loaded as DefTypes, and compared to the input.
                // This lookup is slower than the lookups using RuntimeTypeHandles, but can handle cases where we don't have
                // RuntimeTypeHandle values for all of the components of the input DefType, but still need to look it up in case the type
                // statically exists and has an existing RuntimeTypeHandle value.
                //
                TypeSystemContext context = _typeToLookup.Context;

                RuntimeTypeHandle[] parsedArgsHandles;
                RuntimeTypeHandle   parsedTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(tentativeType, out parsedArgsHandles);

                DefType       parsedTypeDefinition = (DefType)context.ResolveRuntimeTypeHandle(parsedTypeDefinitionHandle);
                Instantiation parsedArgs           = context.ResolveRuntimeTypeHandles(parsedArgsHandles);
                DefType       parsedGenericType    = context.ResolveGenericInstantiation(parsedTypeDefinition, parsedArgs);

                return(parsedGenericType == _typeToLookup);
            }
Example #5
0
        private static bool ImplementsIComparable(RuntimeTypeHandle t)
        {
            int interfaceCount = RuntimeAugments.GetInterfaceCount(t);

            for (int i = 0; i < interfaceCount; i++)
            {
                RuntimeTypeHandle interfaceType = RuntimeAugments.GetInterface(t, i);

                if (!RuntimeAugments.IsGenericType(interfaceType))
                {
                    continue;
                }

                RuntimeTypeHandle   genericDefinition;
                RuntimeTypeHandle[] genericTypeArgs;
                genericDefinition = RuntimeAugments.GetGenericInstantiation(interfaceType,
                                                                            out genericTypeArgs);

                if (genericDefinition.Equals(typeof(IComparable <>).TypeHandle))
                {
                    if (genericTypeArgs.Length != 1)
                    {
                        continue;
                    }

                    if (RuntimeAugments.IsValueType(t))
                    {
                        if (genericTypeArgs[0].Equals(t))
                        {
                            return(true);
                        }
                    }
                    else if (RuntimeAugments.IsAssignableFrom(genericTypeArgs[0], t))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        private string GetTypeNameDebug(RuntimeTypeHandle rtth)
        {
            string result;

            if (RuntimeAugments.IsGenericType(rtth))
            {
                RuntimeTypeHandle[] typeArgumentsHandles;
                RuntimeTypeHandle   openTypeDef = RuntimeAugments.GetGenericInstantiation(rtth, out typeArgumentsHandles);;
                result = GetTypeNameDebug(openTypeDef) + "<";
                for (int i = 0; i < typeArgumentsHandles.Length; i++)
                {
                    result += (i == 0 ? "" : ",") + GetTypeNameDebug(typeArgumentsHandles[i]);
                }
                return(result + ">");
            }
            else
            {
                System.Reflection.Runtime.General.QTypeDefinition qTypeDefinition;

                // Check if we have metadata.
                if (Instance.TryGetMetadataForNamedType(rtth, out qTypeDefinition))
                {
                    return(qTypeDefinition.NativeFormatHandle.GetFullName(qTypeDefinition.NativeFormatReader));
                }
            }

            result = "EEType:0x";
            ulong num = (ulong)RuntimeAugments.GetPointerFromTypeHandle(rtth);

            int          shift     = IntPtr.Size * 8;
            const string HexDigits = "0123456789ABCDEF";

            while (shift > 0)
            {
                shift -= 4;
                int digit = (int)((num >> shift) & 0xF);
                result += HexDigits[digit];
            }
            return(result);
        }
        public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth)
        {
            TypeDesc returnedType;

            if (_runtimeTypeHandleResolutionCache.TryGetValue(rtth, out returnedType))
            {
                return(returnedType);
            }

            if (rtth.Equals(CanonType.RuntimeTypeHandle))
            {
                returnedType = CanonType;
            }
            else if (rtth.Equals(UniversalCanonType.RuntimeTypeHandle))
            {
                returnedType = UniversalCanonType;
            }
            else if (RuntimeAugments.IsGenericTypeDefinition(rtth))
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    unsafe
                    {
                        TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount];
                        for (int i = 0; i < genericParameters.Length; i++)
                        {
                            genericParameters[i] = GetSignatureVariable(i, false);
                        }

                        returnedType = new NoMetadataType(this, rtth, null, new Instantiation(genericParameters), rtth.GetHashCode());
                    }
                }
            }
            else if (RuntimeAugments.IsGenericType(rtth))
            {
                RuntimeTypeHandle   typeDefRuntimeTypeHandle;
                RuntimeTypeHandle[] genericArgRuntimeTypeHandles;
                typeDefRuntimeTypeHandle = RuntimeAugments.GetGenericInstantiation(rtth, out genericArgRuntimeTypeHandles);

                DefType       typeDef     = (DefType)ResolveRuntimeTypeHandle(typeDefRuntimeTypeHandle);
                Instantiation genericArgs = ResolveRuntimeTypeHandles(genericArgRuntimeTypeHandles);
                returnedType = ResolveGenericInstantiation(typeDef, genericArgs);
            }
            else if (RuntimeAugments.IsArrayType(rtth))
            {
                RuntimeTypeHandle elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          elementType       = ResolveRuntimeTypeHandle(elementTypeHandle);
                unsafe
                {
                    if (rtth.ToEETypePtr()->IsSzArray)
                    {
                        returnedType = GetArrayType(elementType);
                    }
                    else
                    {
                        returnedType = GetArrayType(elementType, rtth.ToEETypePtr()->ArrayRank);
                    }
                }
            }
            else if (RuntimeAugments.IsUnmanagedPointerType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetPointerType(targetType);
            }
            else if (RuntimeAugments.IsByRefType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetByRefType(targetType);
            }
            else
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    returnedType = new NoMetadataType(this, rtth, null, Instantiation.Empty, rtth.GetHashCode());
                }
            }

            // We either retrieved an existing DefType that is already registered with the runtime
            // or one that is not associated with an MethodTable yet. If it's not associated, associate it.
            if (returnedType.RuntimeTypeHandle.IsNull())
            {
                TypeBuilderState state = returnedType.GetTypeBuilderStateIfExist();
                bool             skipStoringRuntimeTypeHandle = false;

                // If we've already attempted to lookup and failed to retrieve this type handle, we
                // may have already decided to create a new one. In that case, do not attempt to abort
                // that creation process as it may have already begun the process of type creation
                if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle)
                {
                    skipStoringRuntimeTypeHandle = true;
                }

                if (!skipStoringRuntimeTypeHandle)
                {
                    returnedType.SetRuntimeTypeHandleUnsafe(rtth);
                }
            }

            _runtimeTypeHandleResolutionCache.Add(rtth, returnedType);

            return(returnedType.WithDebugName());
        }
 public bool TryGetConstructedGenericTypeComponents(RuntimeTypeHandle runtimeTypeHandle, out RuntimeTypeHandle genericTypeDefinitionHandle, out RuntimeTypeHandle[] genericTypeArgumentHandles)
 {
     genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles);
     return(true);
 }
Example #9
0
        // This method computes the method pointer and dictionary pointer for a GVM.
        // Inputs:
        //      - targetTypeHanlde: target type on which the GVM is implemented
        //      - nameAndSignature: name and signature of the GVM method
        //      - genericMethodArgumentHandles: GVM instantiation arguments
        // Outputs:
        //      - methodPointer: pointer to the GVM's implementation
        //      - dictionaryPointer: (if applicable) pointer to the dictionary to be used with the GVM call
        public bool TryGetGenericVirtualMethodPointer(RuntimeTypeHandle targetTypeHandle, MethodNameAndSignature nameAndSignature, RuntimeTypeHandle[] genericMethodArgumentHandles, out IntPtr methodPointer, out IntPtr dictionaryPointer)
        {
            methodPointer = dictionaryPointer = IntPtr.Zero;

            TypeSystemContext context = TypeSystemContextFactory.Create();

            DefType            targetType          = (DefType)context.ResolveRuntimeTypeHandle(targetTypeHandle);
            Instantiation      methodInstantiation = context.ResolveRuntimeTypeHandles(genericMethodArgumentHandles);
            InstantiatedMethod method = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, nameAndSignature, methodInstantiation, IntPtr.Zero, false);

            if (!method.CanShareNormalGenericCode())
            {
                // First see if we can find an exact method implementation for the GVM (avoid using USG implementations if we can,
                // because USG code is much slower).
                if (TryLookupExactMethodPointerForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out methodPointer))
                {
                    Debug.Assert(methodPointer != IntPtr.Zero);
                    TypeSystemContextFactory.Recycle(context);
                    return(true);
                }
            }

            // If we cannot find an exact method entry point, look for an equivalent template and compute the generic dictinoary
            TemplateLocator    templateLocator  = new TemplateLocator();
            NativeLayoutInfo   nativeLayoutInfo = new NativeLayoutInfo();
            InstantiatedMethod templateMethod   = templateLocator.TryGetGenericMethodTemplate(method, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token);

            if (templateMethod == null)
            {
                return(false);
            }

            methodPointer = templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal) ?
                            templateMethod.UsgFunctionPointer :
                            templateMethod.FunctionPointer;

            if (!TryLookupGenericMethodDictionaryForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out dictionaryPointer))
            {
                using (LockHolder.Hold(_typeLoaderLock))
                {
                    // Now that we hold the lock, we may find that existing types can now find
                    // their associated RuntimeTypeHandle. Flush the type builder states as a way
                    // to force the reresolution of RuntimeTypeHandles which couldn't be found before.
                    context.FlushTypeBuilderStates();

                    if (!TypeBuilder.TryBuildGenericMethod(method, out dictionaryPointer))
                    {
                        return(false);
                    }
                }
            }

            Debug.Assert(methodPointer != IntPtr.Zero && dictionaryPointer != IntPtr.Zero);

            if (templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal))
            {
                // Check if we need to wrap the method pointer into a calling convention converter thunk
                if (!TypeLoaderEnvironment.Instance.MethodSignatureHasVarsNeedingCallingConventionConverter(context, nameAndSignature.Signature))
                {
                    TypeSystemContextFactory.Recycle(context);
                    return(true);
                }

                RuntimeTypeHandle[] typeArgs = Array.Empty <RuntimeTypeHandle>();

                if (RuntimeAugments.IsGenericType(targetTypeHandle))
                {
                    RuntimeAugments.GetGenericInstantiation(targetTypeHandle, out typeArgs);
                }

                // Create a CallingConventionConverter to call the method correctly
                IntPtr thunkPtr = CallConverterThunk.MakeThunk(
                    CallConverterThunk.ThunkKind.StandardToGenericInstantiating,
                    methodPointer,
                    nameAndSignature.Signature,
                    dictionaryPointer,
                    typeArgs,
                    genericMethodArgumentHandles);

                Debug.Assert(thunkPtr != IntPtr.Zero);

                methodPointer = thunkPtr;
                // Set dictionaryPointer to null so we don't make a fat function pointer around the whole thing.
                dictionaryPointer = IntPtr.Zero;

                // TODO! add a new call converter thunk that will pass the instantiating arg through and use a fat function pointer.
                // should allow us to make fewer thunks.
            }

            TypeSystemContextFactory.Recycle(context);
            return(true);
        }
        internal static String ToDisplayStringIfAvailable(this Type type, List <int> genericParameterOffsets)
        {
            RuntimeTypeHandle runtimeTypeHandle = ReflectionCoreExecution.ExecutionDomain.GetTypeHandleIfAvailable(type);
            bool hasRuntimeTypeHandle           = !runtimeTypeHandle.Equals(default(RuntimeTypeHandle));

            if (type.HasElementType)
            {
                if (type.IsArray)
                {
                    // Multidim arrays. This is the one case where GetElementType() isn't pay-for-play safe so
                    // talk to the diagnostic mapping tables directly if possible or give up.
                    if (!hasRuntimeTypeHandle)
                    {
                        return(null);
                    }

                    int rank = type.GetArrayRank();
                    return(CreateArrayTypeStringIfAvailable(type.GetElementType(), rank));
                }
                else
                {
                    String s = type.GetElementType().ToDisplayStringIfAvailable(null);
                    if (s == null)
                    {
                        return(null);
                    }
                    return(s + (type.IsPointer ? "*" : "&"));
                }
            }
            else if (((hasRuntimeTypeHandle && RuntimeAugments.IsGenericType(runtimeTypeHandle)) || type.IsConstructedGenericType))
            {
                Type   genericTypeDefinition;
                Type[] genericTypeArguments;
                if (hasRuntimeTypeHandle)
                {
                    RuntimeTypeHandle   genericTypeDefinitionHandle;
                    RuntimeTypeHandle[] genericTypeArgumentHandles;

                    genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles);
                    genericTypeDefinition       = Type.GetTypeFromHandle(genericTypeDefinitionHandle);
                    genericTypeArguments        = new Type[genericTypeArgumentHandles.Length];
                    for (int i = 0; i < genericTypeArguments.Length; i++)
                    {
                        genericTypeArguments[i] = Type.GetTypeFromHandle(genericTypeArgumentHandles[i]);
                    }
                }
                else
                {
                    genericTypeDefinition = type.GetGenericTypeDefinition();
                    genericTypeArguments  = type.GenericTypeArguments;
                }

                return(CreateConstructedGenericTypeStringIfAvailable(genericTypeDefinition, genericTypeArguments));
            }
            else if (type.IsGenericParameter)
            {
                return(type.Name);
            }
            else if (hasRuntimeTypeHandle)
            {
                String s;
                if (!DiagnosticMappingTables.TryGetDiagnosticStringForNamedType(runtimeTypeHandle, out s, genericParameterOffsets))
                {
                    return(null);
                }

                return(s);
            }
            else
            {
                return(null);
            }
        }
        internal static string ToDisplayStringIfAvailable(this Type type, List <int> genericParameterOffsets)
        {
            RuntimeTypeHandle runtimeTypeHandle = ReflectionCoreExecution.ExecutionDomain.GetTypeHandleIfAvailable(type);
            bool hasRuntimeTypeHandle           = !runtimeTypeHandle.Equals(default(RuntimeTypeHandle));

            if (type.HasElementType)
            {
                if (type.IsArray)
                {
                    // Multidim arrays. This is the one case where GetElementType() isn't pay-for-play safe so
                    // talk to the diagnostic mapping tables directly if possible or give up.
                    if (!hasRuntimeTypeHandle)
                    {
                        return(null);
                    }

                    int rank = type.GetArrayRank();
                    return(CreateArrayTypeStringIfAvailable(type.GetElementType(), rank));
                }
                else
                {
                    string s = type.GetElementType().ToDisplayStringIfAvailable(null);
                    if (s == null)
                    {
                        return(null);
                    }
                    return(s + (type.IsPointer ? "*" : "&"));
                }
            }
            else if (((hasRuntimeTypeHandle && RuntimeAugments.IsGenericType(runtimeTypeHandle)) || type.IsConstructedGenericType))
            {
                Type   genericTypeDefinition;
                Type[] genericTypeArguments;
                if (hasRuntimeTypeHandle)
                {
                    RuntimeTypeHandle   genericTypeDefinitionHandle;
                    RuntimeTypeHandle[] genericTypeArgumentHandles;

                    genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles);
                    genericTypeDefinition       = Type.GetTypeFromHandle(genericTypeDefinitionHandle);
                    genericTypeArguments        = new Type[genericTypeArgumentHandles.Length];
                    for (int i = 0; i < genericTypeArguments.Length; i++)
                    {
                        genericTypeArguments[i] = Type.GetTypeFromHandle(genericTypeArgumentHandles[i]);
                    }
                }
                else
                {
                    genericTypeDefinition = type.GetGenericTypeDefinition();
                    genericTypeArguments  = type.GenericTypeArguments;
                }

                return(CreateConstructedGenericTypeStringIfAvailable(genericTypeDefinition, genericTypeArguments));
            }
            else if (type.IsGenericParameter)
            {
                return(type.Name);
            }
            else if (hasRuntimeTypeHandle)
            {
                string s;
                if (!DiagnosticMappingTables.TryGetDiagnosticStringForNamedType(runtimeTypeHandle, out s, genericParameterOffsets))
                {
                    return(null);
                }

                return(s);
            }
            else
            {
                // First, see if Type.Name is available. If Type.Name is available, then we can be reasonably confident that it is safe to call Type.FullName.
                // We'll still wrap the call in a try-catch as a failsafe.
                string s = type.InternalNameIfAvailable;
                if (s == null)
                {
                    return(null);
                }

                try
                {
                    s = type.FullName;
                }
                catch (MissingMetadataException)
                {
                }

                // Insert commas so that CreateConstructedGenericTypeStringIfAvailable can fill the blanks.
                // This is not strictly correct for types nested under generic types, but at this point we're doing
                // best effort within reason.
                if (type.IsGenericTypeDefinition)
                {
                    s += "[";
                    int genericArgCount = type.GetGenericArguments().Length;
                    while (genericArgCount-- > 0)
                    {
                        genericParameterOffsets.Add(s.Length);
                        if (genericArgCount > 0)
                        {
                            s = s + ",";
                        }
                    }
                    s += "]";
                }

                return(s);
            }
        }