Example #1
0
        //
        // Return a type's transitive implemeted interface list using the runtime type system. If the underlying runtime type system does not support
        // this operation, return null and TypeInfo.ImplementedInterfaces will fall back to metadata. Note that returning null is not the same thing
        // as returning a 0-length enumerable.
        //
        public static IEnumerable <RuntimeTypeHandle> TryGetImplementedInterfaces(RuntimeTypeHandle typeHandle)
        {
            EETypePtr eeType = typeHandle.ToEETypePtr();

            RuntimeImports.RhEETypeClassification eeTypeClassification = RuntimeImports.RhGetEETypeClassification(eeType);
            if (eeTypeClassification == RuntimeImports.RhEETypeClassification.GenericTypeDefinition ||
                eeTypeClassification == RuntimeImports.RhEETypeClassification.UnmanagedPointer)
            {
                return(null);
            }

            uint numInterfaces = RuntimeImports.RhGetNumInterfaces(eeType);
            LowLevelList <RuntimeTypeHandle> implementedInterfaces = new LowLevelList <RuntimeTypeHandle>();

            for (uint i = 0; i < numInterfaces; i++)
            {
                EETypePtr         ifcEEType = RuntimeImports.RhGetInterface(eeType, i);
                RuntimeTypeHandle ifcrth    = new RuntimeTypeHandle(ifcEEType);
                if (Callbacks.IsReflectionBlocked(ifcrth))
                {
                    continue;
                }

                implementedInterfaces.Add(ifcrth);
            }
            return(implementedInterfaces.ToArray());
        }
Example #2
0
        // Returns a new delegate of the specified type whose implementation is provied by the
        // provided delegate.
        internal static Delegate CreateObjectArrayDelegate(Type t, Func <object[], object> handler)
        {
            EETypePtr delegateEEType;

            if (!t.TryGetEEType(out delegateEEType))
            {
                throw new InvalidOperationException();
            }

            RuntimeImports.RhEETypeClassification delegateEETypeClassification = RuntimeImports.RhGetEETypeClassification(delegateEEType);
            if (!(delegateEETypeClassification == RuntimeImports.RhEETypeClassification.Regular || delegateEETypeClassification == RuntimeImports.RhEETypeClassification.Generic))
            {
                throw new InvalidOperationException();
            }

            Delegate del = (Delegate)(RuntimeImports.RhNewObject(delegateEEType));

            IntPtr objArrayThunk = del.GetThunk(Delegate.ObjectArrayThunk);

            if (objArrayThunk == IntPtr.Zero)
            {
                throw new InvalidOperationException();
            }

            del.m_helperObject    = handler;
            del.m_functionPointer = objArrayThunk;
            del.m_firstParameter  = del;
            return(del);
        }
Example #3
0
        protected const int ObjectArrayThunk    = 7;                  // This may not exist

        //
        // If the thunk does not exist, the function will return IntPtr.Zero.
        protected virtual IntPtr GetThunk(int whichThunk)
        {
#if DEBUG
            // The GetThunk function should be overriden on all delegate types, except for universal
            // canonical delegates which use calling convention converter thunks to marshal arguments
            // for the delegate call. If we execute this version of GetThunk, we can at least assert
            // that the current delegate type is a generic type.
            Debug.Assert(RuntimeImports.RhGetEETypeClassification(this.EETypePtr) == RuntimeImports.RhEETypeClassification.Generic);
#endif
            return(TypeLoaderExports.GetDelegateThunk(this, whichThunk));
        }
Example #4
0
            protected sealed override RuntimeType Factory(EETypePtr eeType)
            {
                RuntimeImports.RhEETypeClassification classification = RuntimeImports.RhGetEETypeClassification(eeType);
                switch (classification)
                {
                case RuntimeImports.RhEETypeClassification.Regular:
                    return(new RuntimeEENamedNonGenericType(eeType));

                case RuntimeImports.RhEETypeClassification.Array:
                    return(new RuntimeEEArrayType(eeType));

                case RuntimeImports.RhEETypeClassification.UnmanagedPointer:
                    return(new RuntimeEEPointerType(eeType));

                case RuntimeImports.RhEETypeClassification.GenericTypeDefinition:
                    return(new RuntimeEENamedGenericType(eeType));

                case RuntimeImports.RhEETypeClassification.Generic:
                    // 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 (RuntimeAugments.Callbacks.IsReflectionBlocked(new RuntimeTypeHandle(eeType)))
                    {
                        return(new RuntimeEENamedNonGenericType(eeType));
                    }

                    if (RuntimeImports.AreTypesAssignable(eeType, typeof(MDArrayRank2).TypeHandle.ToEETypePtr()))
                    {
                        return(new RuntimeEEArrayType(eeType, rank: 2));
                    }
                    if (RuntimeImports.AreTypesAssignable(eeType, typeof(MDArrayRank3).TypeHandle.ToEETypePtr()))
                    {
                        return(new RuntimeEEArrayType(eeType, rank: 3));
                    }
                    if (RuntimeImports.AreTypesAssignable(eeType, typeof(MDArrayRank4).TypeHandle.ToEETypePtr()))
                    {
                        return(new RuntimeEEArrayType(eeType, rank: 4));
                    }
                    return(new RuntimeEEConstructedGenericType(eeType));

                default:
                    throw new ArgumentException(SR.Arg_InvalidRuntimeTypeHandle);
                }
            }
Example #5
0
        //
        // Return a type's base type using the runtime type system. If the underlying runtime type system does not support
        // this operation, return false and TypeInfo.BaseType will fall back to metadata.
        //
        // Note that "default(RuntimeTypeHandle)" is a valid result that will map to a null result. (For example, System.Object has a "null" base type.)
        //
        public static bool TryGetBaseType(RuntimeTypeHandle typeHandle, out RuntimeTypeHandle baseTypeHandle)
        {
            EETypePtr eeType = typeHandle.ToEETypePtr();

            RuntimeImports.RhEETypeClassification eeTypeClassification = RuntimeImports.RhGetEETypeClassification(eeType);
            if (eeTypeClassification == RuntimeImports.RhEETypeClassification.GenericTypeDefinition ||
                eeTypeClassification == RuntimeImports.RhEETypeClassification.UnmanagedPointer)
            {
                baseTypeHandle = default(RuntimeTypeHandle);
                return(false);
            }
            baseTypeHandle = new RuntimeTypeHandle(eeType.BaseType);
            return(true);
        }
Example #6
0
        //
        // Note: This works on both Enum's and underlying integer values.
        //
        //
        // This returns the underlying enum values as "ulong" regardless of the actual underlying type. Signed integral
        // types get sign-extended into the 64-bit value, unsigned types get zero-extended.
        //
        // The return value is "bool" if "value" is not an enum or an "integer type" as defined by the BCL Enum apis.
        //
        private static bool TryGetUnboxedValueOfEnumOrInteger(Object value, out ulong result)
        {
            EETypePtr eeType = value.EETypePtr;

            // For now, this check is required to flush out pointers.
            RuntimeImports.RhEETypeClassification classification = RuntimeImports.RhGetEETypeClassification(eeType);
            if (classification != RuntimeImports.RhEETypeClassification.Regular)
            {
                result = 0;
                return(false);
            }
            RuntimeImports.RhCorElementType corElementType = eeType.CorElementType;
            unsafe
            {
                fixed(IntPtr *pEEType = &value.m_pEEType)
                {
                    IntPtr pValue = Object.GetAddrOfPinnedObjectFromEETypeField(pEEType);

                    switch (corElementType)
                    {
                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                        result = (*(bool *)pValue) ? 1UL : 0UL;
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                        result = (ulong)(long)(*(char *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                        result = (ulong)(long)(*(sbyte *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                        result = (ulong)(long)(*(byte *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                        result = (ulong)(long)(*(short *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                        result = (ulong)(long)(*(ushort *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                        result = (ulong)(long)(*(int *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                        result = (ulong)(long)(*(uint *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                        result = (ulong)(long)(*(long *)pValue);
                        return(true);

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                        result = (ulong)(long)(*(ulong *)pValue);
                        return(true);

                    default:
                        result = 0;
                        return(false);
                    }
                }
            }
        }
Example #7
0
 public static bool IsGenericTypeDefinition(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.GenericTypeDefinition);
 }
Example #8
0
 public static bool IsUnmanagedPointerType(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.UnmanagedPointer);
 }
Example #9
0
 public static bool IsArrayType(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.Array);
 }