// // 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()); }
// 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); }
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)); }
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); } }
// // 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); }
// // 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); } } } }
public static bool IsGenericTypeDefinition(RuntimeTypeHandle typeHandle) { return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.GenericTypeDefinition); }
public static bool IsUnmanagedPointerType(RuntimeTypeHandle typeHandle) { return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.UnmanagedPointer); }
public static bool IsArrayType(RuntimeTypeHandle typeHandle) { return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.Array); }