diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index ff087f04e4b0e..1c0ab43914723 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2788,7 +2788,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_Internal_Runtime_MethodTable_Of: case NI_System_Activator_AllocatorOf: case NI_System_Activator_DefaultConstructorOf: - case NI_System_EETypePtr_EETypePtrOf: betterToExpand = true; break; @@ -2981,7 +2980,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_Internal_Runtime_MethodTable_Of: case NI_System_Activator_AllocatorOf: case NI_System_Activator_DefaultConstructorOf: - case NI_System_EETypePtr_EETypePtrOf: { assert(IsTargetAbi(CORINFO_NATIVEAOT_ABI)); // Only NativeAOT supports it. CORINFO_RESOLVED_TOKEN resolvedToken; @@ -8830,13 +8828,6 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = NI_System_Enum_HasFlag; } } - else if (strcmp(className, "EETypePtr") == 0) - { - if (strcmp(methodName, "EETypePtrOf") == 0) - { - result = NI_System_EETypePtr_EETypePtrOf; - } - } break; } diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 2e68fd501243c..9c4f44e8e2f0b 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -101,7 +101,6 @@ enum NamedIntrinsic : unsigned short NI_System_Activator_AllocatorOf, NI_System_Activator_DefaultConstructorOf, - NI_System_EETypePtr_EETypePtrOf, NI_Internal_Runtime_MethodTable_Of, diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs index ee9c669b6cb35..afb4c9a509f4f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs @@ -73,7 +73,7 @@ private static IntPtr RhpResolveInterfaceMethod(object pObject, IntPtr pCell) } [RuntimeExport("RhResolveDispatch")] - private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, ushort slot) + private static IntPtr RhResolveDispatch(object pObject, MethodTable* interfaceType, ushort slot) { DispatchCellInfo cellInfo = default; cellInfo.CellType = DispatchCellType.InterfaceAndSlot; @@ -84,18 +84,12 @@ private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, } [RuntimeExport("RhResolveDispatchOnType")] - private static IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr interfaceType, ushort slot, EETypePtr* pGenericContext) + private static IntPtr RhResolveDispatchOnType(MethodTable* pInstanceType, MethodTable* pInterfaceType, ushort slot, MethodTable** ppGenericContext) { - // Type of object we're dispatching on. - MethodTable* pInstanceType = instanceType.ToPointer(); - - // Type of interface - MethodTable* pInterfaceType = interfaceType.ToPointer(); - return DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType, pInterfaceType, slot, - (MethodTable**)pGenericContext); + ppGenericContext); } private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo) @@ -110,7 +104,7 @@ private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, MethodTable* pResolvingInstanceType = pInstanceType; IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType, - cellInfo.InterfaceType.ToPointer(), + cellInfo.InterfaceType, cellInfo.InterfaceSlot, ppGenericContext: null); if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable) @@ -119,7 +113,7 @@ private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, // This will either give us the appropriate result, or throw. var pfnGetInterfaceImplementation = (delegate*) pInstanceType->GetClasslibFunction(ClassLibFunctionId.IDynamicCastableGetInterfaceImplementation); - pTargetCode = pfnGetInterfaceImplementation(pObject, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot); + pTargetCode = pfnGetInterfaceImplementation(pObject, cellInfo.InterfaceType, cellInfo.InterfaceSlot); Diagnostics.Debug.Assert(pTargetCode != IntPtr.Zero); } return pTargetCode; diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/EETypePtr.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/EETypePtr.cs deleted file mode 100644 index 8dc8889325743..0000000000000 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/EETypePtr.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -/*============================================================ -** -** Class: EETypePtr -** -** -** Purpose: Pointer Type to a MethodTable in the runtime. -** -** -===========================================================*/ - -namespace System -{ - // This type does not implement GetHashCode but implements Equals -#pragma warning disable 0659 - - [StructLayout(LayoutKind.Sequential)] - public struct EETypePtr - { - private IntPtr _value; - - internal EETypePtr(IntPtr value) - { - _value = value; - } - - internal bool Equals(EETypePtr p) - { - return (_value == p._value); - } - - internal unsafe Internal.Runtime.MethodTable* ToPointer() - { - return (Internal.Runtime.MethodTable*)(void*)_value; - } - - [Intrinsic] - internal static EETypePtr EETypePtrOf() - { - throw new NotImplementedException(); - } - } -} diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index fac623a25cbaf..c29e68d1c050a 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -386,14 +386,14 @@ public static void ThrowClasslibDivideByZeroException(IntPtr address) } [RuntimeExport("RhExceptionHandling_FailedAllocation")] - public static void FailedAllocation(EETypePtr pEEType, bool fIsOverflow) + public static void FailedAllocation(MethodTable* pEEType, bool fIsOverflow) { ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory; // Throw the out of memory exception defined by the classlib, using the input MethodTable* // to find the correct classlib. - throw pEEType.ToPointer()->GetClasslibException(exID); + throw pEEType->GetClasslibException(exID); } #if !INPLACE_RUNTIME diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs index 1abbe8b16f795..806208187e92f 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs @@ -21,10 +21,10 @@ internal enum DispatchCellType VTableOffset = 0x2, } - internal struct DispatchCellInfo + internal unsafe struct DispatchCellInfo { public DispatchCellType CellType; - public EETypePtr InterfaceType; + public MethodTable* InterfaceType; public ushort InterfaceSlot; public byte HasCache; public uint MetadataToken; diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs index abeb0c09b46ab..8c83e3cc3c836 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -164,20 +164,19 @@ private static unsafe bool UnboxAnyTypeCompare(MethodTable* pEEType, MethodTable } [RuntimeExport("RhUnboxAny")] - public static unsafe void RhUnboxAny(object? o, ref byte data, EETypePtr pUnboxToEEType) + public static unsafe void RhUnboxAny(object? o, ref byte data, MethodTable* pUnboxToEEType) { - MethodTable* ptrUnboxToEEType = (MethodTable*)pUnboxToEEType.ToPointer(); - if (ptrUnboxToEEType->IsValueType) + if (pUnboxToEEType->IsValueType) { bool isValid = false; - if (ptrUnboxToEEType->IsNullable) + if (pUnboxToEEType->IsNullable) { - isValid = (o == null) || o.GetMethodTable() == ptrUnboxToEEType->NullableType; + isValid = (o == null) || o.GetMethodTable() == pUnboxToEEType->NullableType; } else { - isValid = (o != null) && UnboxAnyTypeCompare(o.GetMethodTable(), ptrUnboxToEEType); + isValid = (o != null) && UnboxAnyTypeCompare(o.GetMethodTable(), pUnboxToEEType); } if (!isValid) @@ -187,16 +186,16 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, EETypePtr pUnboxT ExceptionIDs exID = o == null ? ExceptionIDs.NullReference : ExceptionIDs.InvalidCast; - throw ptrUnboxToEEType->GetClasslibException(exID); + throw pUnboxToEEType->GetClasslibException(exID); } - RhUnbox(o, ref data, ptrUnboxToEEType); + RhUnbox(o, ref data, pUnboxToEEType); } else { - if (o != null && (TypeCast.IsInstanceOfAny(ptrUnboxToEEType, o) == null)) + if (o != null && (TypeCast.IsInstanceOfAny(pUnboxToEEType, o) == null)) { - throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast); + throw pUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast); } Unsafe.As(ref data) = o; diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeImports.cs index c166368800401..bcadcd799b20d 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeImports.cs @@ -33,7 +33,7 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewObject")] - internal static extern object RhNewObject(EETypePtr pEEType); + internal static extern unsafe object RhNewObject(MethodTable* pEEType); // Move memory which may be on the heap which may have object references in it. // In general, a memcpy on the heap is unsafe, but this is able to perform the diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs index db284d80cce0e..08b1e6b0d87bf 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs @@ -9,38 +9,38 @@ using System.Runtime; using System.Runtime.CompilerServices; +using Internal.Runtime; using Internal.Runtime.Augments; namespace Internal.IntrinsicSupport { internal static class ComparerHelpers { - private static bool ImplementsIComparable(RuntimeTypeHandle t) + private static unsafe bool ImplementsIComparable(RuntimeTypeHandle t) { - EETypePtr objectType = t.ToEETypePtr(); - EETypePtr icomparableType = typeof(IComparable<>).TypeHandle.ToEETypePtr(); - int interfaceCount = objectType.Interfaces.Count; + MethodTable* objectType = t.ToMethodTable(); + MethodTable* icomparableType = typeof(IComparable<>).TypeHandle.ToMethodTable(); + int interfaceCount = objectType->NumInterfaces; for (int i = 0; i < interfaceCount; i++) { - EETypePtr interfaceType = objectType.Interfaces[i]; + MethodTable* interfaceType = objectType->InterfaceMap[i]; - if (!interfaceType.IsGeneric) + if (!interfaceType->IsGeneric) continue; - if (interfaceType.GenericDefinition == icomparableType) + if (interfaceType->GenericDefinition == icomparableType) { - var instantiation = interfaceType.Instantiation; - if (instantiation.Length != 1) + if (interfaceType->GenericArity != 1) continue; - if (objectType.IsValueType) + if (objectType->IsValueType) { - if (instantiation[0] == objectType) + if (interfaceType->GenericArguments[0] == objectType) { return true; } } - else if (RuntimeImports.AreTypesAssignable(objectType, instantiation[0])) + else if (RuntimeImports.AreTypesAssignable(objectType, interfaceType->GenericArguments[0])) { return true; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs index b35bee1fca61d..94592af9c8784 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs @@ -12,32 +12,31 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; +using Internal.Runtime; using Internal.Runtime.Augments; namespace Internal.IntrinsicSupport { internal static class EqualityComparerHelpers { - private static bool ImplementsIEquatable(RuntimeTypeHandle t) + private static unsafe bool ImplementsIEquatable(RuntimeTypeHandle t) { - EETypePtr objectType = t.ToEETypePtr(); - EETypePtr iequatableType = typeof(IEquatable<>).TypeHandle.ToEETypePtr(); - int interfaceCount = objectType.Interfaces.Count; + MethodTable* objectType = t.ToMethodTable(); + MethodTable* iequatableType = typeof(IEquatable<>).TypeHandle.ToMethodTable(); + int interfaceCount = objectType->NumInterfaces; for (int i = 0; i < interfaceCount; i++) { - EETypePtr interfaceType = objectType.Interfaces[i]; + MethodTable* interfaceType = objectType->InterfaceMap[i]; - if (!interfaceType.IsGeneric) + if (!interfaceType->IsGeneric) continue; - if (interfaceType.GenericDefinition == iequatableType) + if (interfaceType->GenericDefinition == iequatableType) { - var instantiation = interfaceType.Instantiation; - - if (instantiation.Length != 1) + if (interfaceType->GenericArity != 1) continue; - if (instantiation[0] == objectType) + if (interfaceType->GenericArguments[0] == objectType) { return true; } @@ -47,9 +46,9 @@ private static bool ImplementsIEquatable(RuntimeTypeHandle t) return false; } - internal static bool IsEnum(RuntimeTypeHandle t) + internal static unsafe bool IsEnum(RuntimeTypeHandle t) { - return t.ToEETypePtr().IsEnum; + return t.ToMethodTable()->IsEnum; } // this function utilizes the template type loader to generate new diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs index cc42a78d9da2c..4aac720d01142 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs @@ -23,6 +23,8 @@ using System.Numerics; using System.Reflection; +using Internal.Runtime; + using EETypeElementType = Internal.Runtime.EETypeElementType; namespace Internal.Reflection.Augments @@ -39,24 +41,24 @@ public static void Initialize(ReflectionCoreCallbacks reflectionCoreCallbacks) s_reflectionCoreCallbacks = reflectionCoreCallbacks; } - internal static TypeCode GetRuntimeTypeCode(RuntimeType type) + internal static unsafe TypeCode GetRuntimeTypeCode(RuntimeType type) { Debug.Assert(type != null); - EETypePtr eeType = type.ToEETypePtrMayBeNull(); - if (eeType.IsNull) + MethodTable* eeType = type.ToMethodTableMayBeNull(); + if (eeType == null) { // Type exists in metadata only. Aside from the enums, there is no chance a type with a TypeCode would not have an MethodTable, // so if it's not an enum, return the default. if (!type.IsActualEnum) return TypeCode.Object; Type underlyingType = Enum.GetUnderlyingType(type); - eeType = underlyingType.TypeHandle.ToEETypePtr(); + eeType = underlyingType.TypeHandle.ToMethodTable(); } // Note: Type.GetTypeCode() is expected to return the underlying type's TypeCode for enums. EETypePtr.CorElementType does the same, // so this one switch handles both cases. - EETypeElementType rhType = eeType.ElementType; + EETypeElementType rhType = eeType->ElementType; switch (rhType) { case EETypeElementType.Boolean: return TypeCode.Boolean; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs index c99fd28a8e27c..d58c1a151bc8e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs @@ -33,7 +33,7 @@ namespace Internal.Runtime.Augments { - public static class RuntimeAugments + public static unsafe class RuntimeAugments { /// /// Callbacks used for metadata-based stack trace resolution. @@ -66,7 +66,7 @@ public static void InitializeStackTraceMetadataSupport(StackTraceMetadataCallbac // public static object RawNewObject(RuntimeTypeHandle typeHandle) { - return RuntimeImports.RhNewObject(typeHandle.ToEETypePtr()); + return RuntimeImports.RhNewObject(typeHandle.ToMethodTable()); } // @@ -75,8 +75,8 @@ public static object RawNewObject(RuntimeTypeHandle typeHandle) public static Array NewArray(RuntimeTypeHandle typeHandleForArrayType, int count) { // Don't make the easy mistake of passing in the element MethodTable rather than the "array of element" MethodTable. - Debug.Assert(typeHandleForArrayType.ToEETypePtr().IsSzArray); - return RuntimeImports.RhNewArray(typeHandleForArrayType.ToEETypePtr(), count); + Debug.Assert(typeHandleForArrayType.ToMethodTable()->IsSzArray); + return RuntimeImports.RhNewArray(typeHandleForArrayType.ToMethodTable(), count); } // @@ -107,8 +107,8 @@ public static unsafe Array NewMultiDimArray(RuntimeTypeHandle typeHandleForArray { // We just checked above that all lower bounds are zero. In that case, we should actually allocate // a new SzArray instead. - Type elementType = Type.GetTypeFromHandle(new RuntimeTypeHandle(typeHandleForArrayType.ToEETypePtr().ArrayElementType))!; - return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToEETypePtr(), lengths[0]); + Type elementType = Type.GetTypeFromHandle(new RuntimeTypeHandle(typeHandleForArrayType.ToMethodTable()->RelatedParameterType))!; + return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToMethodTable(), lengths[0]); } // Create a local copy of the lengths that cannot be modified by the caller @@ -116,12 +116,12 @@ public static unsafe Array NewMultiDimArray(RuntimeTypeHandle typeHandleForArray for (int i = 0; i < lengths.Length; i++) pImmutableLengths[i] = lengths[i]; - return Array.NewMultiDimArray(typeHandleForArrayType.ToEETypePtr(), pImmutableLengths, lengths.Length); + return Array.NewMultiDimArray(typeHandleForArrayType.ToMethodTable(), pImmutableLengths, lengths.Length); } public static IntPtr GetAllocateObjectHelperForType(RuntimeTypeHandle type) { - return RuntimeImports.RhGetRuntimeHelperForType(type.ToEETypePtr(), RuntimeHelperKind.AllocateObject); + return RuntimeImports.RhGetRuntimeHelperForType(type.ToMethodTable(), RuntimeHelperKind.AllocateObject); } public static IntPtr GetFallbackDefaultConstructor() @@ -134,7 +134,7 @@ public static IntPtr GetFallbackDefaultConstructor() // public static Delegate CreateDelegate(RuntimeTypeHandle typeHandleForDelegate, IntPtr ldftnResult, object thisObject, bool isStatic, bool isOpen) { - return Delegate.CreateDelegate(typeHandleForDelegate.ToEETypePtr(), ldftnResult, thisObject, isStatic: isStatic, isOpen: isOpen); + return Delegate.CreateDelegate(typeHandleForDelegate.ToMethodTable(), ldftnResult, thisObject, isStatic: isStatic, isOpen: isOpen); } // @@ -177,7 +177,7 @@ public static unsafe bool FindBlob(TypeManagerHandle typeManager, int blobId, In public static IntPtr GetPointerFromTypeHandle(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().RawValue; + return (IntPtr)typeHandle.ToMethodTable(); } public static unsafe TypeManagerHandle GetModuleFromTypeHandle(RuntimeTypeHandle typeHandle) @@ -185,14 +185,14 @@ public static unsafe TypeManagerHandle GetModuleFromTypeHandle(RuntimeTypeHandle return typeHandle.ToMethodTable()->TypeManager; } - public static RuntimeTypeHandle CreateRuntimeTypeHandle(IntPtr ldTokenResult) + public static unsafe RuntimeTypeHandle CreateRuntimeTypeHandle(IntPtr ldTokenResult) { - return new RuntimeTypeHandle(new EETypePtr(ldTokenResult)); + return new RuntimeTypeHandle((MethodTable*)ldTokenResult); } public static unsafe void StoreValueTypeField(IntPtr address, object fieldValue, RuntimeTypeHandle fieldType) { - RuntimeImports.RhUnbox(fieldValue, ref *(byte*)address, fieldType.ToEETypePtr()); + RuntimeImports.RhUnbox(fieldValue, ref *(byte*)address, fieldType.ToMethodTable()); } public static unsafe ref byte GetRawData(object obj) @@ -202,7 +202,7 @@ public static unsafe ref byte GetRawData(object obj) public static unsafe object LoadValueTypeField(IntPtr address, RuntimeTypeHandle fieldType) { - return RuntimeImports.RhBox(fieldType.ToEETypePtr(), ref *(byte*)address); + return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address); } public static unsafe object LoadPointerTypeField(IntPtr address, RuntimeTypeHandle fieldType) @@ -212,19 +212,19 @@ public static unsafe object LoadPointerTypeField(IntPtr address, RuntimeTypeHand public static unsafe void StoreValueTypeField(ref byte address, object fieldValue, RuntimeTypeHandle fieldType) { - RuntimeImports.RhUnbox(fieldValue, ref address, fieldType.ToEETypePtr()); + RuntimeImports.RhUnbox(fieldValue, ref address, fieldType.ToMethodTable()); } public static unsafe void StoreValueTypeField(object obj, int fieldOffset, object fieldValue, RuntimeTypeHandle fieldType) { ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize)); - RuntimeImports.RhUnbox(fieldValue, ref address, fieldType.ToEETypePtr()); + RuntimeImports.RhUnbox(fieldValue, ref address, fieldType.ToMethodTable()); } public static unsafe object LoadValueTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType) { ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize)); - return RuntimeImports.RhBox(fieldType.ToEETypePtr(), ref address); + return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref address); } public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType) @@ -258,24 +258,24 @@ public static object LoadReferenceTypeField(object obj, int fieldOffset) [CLSCompliant(false)] public static void StoreValueTypeFieldValueIntoValueType(TypedReference typedReference, int fieldOffset, object fieldValue, RuntimeTypeHandle fieldTypeHandle) { - Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToEETypePtr().IsValueType); + Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); - RuntimeImports.RhUnbox(fieldValue, ref Unsafe.Add(ref typedReference.Value, fieldOffset), fieldTypeHandle.ToEETypePtr()); + RuntimeImports.RhUnbox(fieldValue, ref Unsafe.Add(ref typedReference.Value, fieldOffset), fieldTypeHandle.ToMethodTable()); } [CLSCompliant(false)] public static object LoadValueTypeFieldValueFromValueType(TypedReference typedReference, int fieldOffset, RuntimeTypeHandle fieldTypeHandle) { - Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToEETypePtr().IsValueType); - Debug.Assert(fieldTypeHandle.ToEETypePtr().IsValueType); + Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); + Debug.Assert(fieldTypeHandle.ToMethodTable()->IsValueType); - return RuntimeImports.RhBox(fieldTypeHandle.ToEETypePtr(), ref Unsafe.Add(ref typedReference.Value, fieldOffset)); + return RuntimeImports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset)); } [CLSCompliant(false)] public static void StoreReferenceTypeFieldValueIntoValueType(TypedReference typedReference, int fieldOffset, object fieldValue) { - Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToEETypePtr().IsValueType); + Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); Unsafe.As(ref Unsafe.Add(ref typedReference.Value, fieldOffset)) = fieldValue; } @@ -283,7 +283,7 @@ public static void StoreReferenceTypeFieldValueIntoValueType(TypedReference type [CLSCompliant(false)] public static object LoadReferenceTypeFieldValueFromValueType(TypedReference typedReference, int fieldOffset) { - Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToEETypePtr().IsValueType); + Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); return Unsafe.As(ref Unsafe.Add(ref typedReference.Value, fieldOffset)); } @@ -291,8 +291,8 @@ public static object LoadReferenceTypeFieldValueFromValueType(TypedReference typ [CLSCompliant(false)] public static unsafe object LoadPointerTypeFieldValueFromValueType(TypedReference typedReference, int fieldOffset, RuntimeTypeHandle fieldTypeHandle) { - Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToEETypePtr().IsValueType); - Debug.Assert(fieldTypeHandle.ToEETypePtr().IsPointer); + Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType); + Debug.Assert(fieldTypeHandle.ToMethodTable()->IsPointer); IntPtr ptrValue = Unsafe.As(ref Unsafe.Add(ref typedReference.Value, fieldOffset)); return ReflectionPointer.Box((void*)ptrValue, Type.GetTypeFromHandle(fieldTypeHandle)); @@ -309,7 +309,7 @@ public static int GetHighestStaticThreadStaticIndex(TypeManagerHandle typeManage return length / IntPtr.Size; } - public static unsafe int ObjectHeaderSize => sizeof(EETypePtr); + public static unsafe int ObjectHeaderSize => sizeof(ObjHeader); public static unsafe void EnsureClassConstructorRun(IntPtr staticClassConstructionContext) { @@ -319,9 +319,9 @@ public static unsafe void EnsureClassConstructorRun(IntPtr staticClassConstructi public static Type GetEnumUnderlyingType(RuntimeTypeHandle enumTypeHandle) { - Debug.Assert(enumTypeHandle.ToEETypePtr().IsEnum); + Debug.Assert(enumTypeHandle.ToMethodTable()->IsEnum); - EETypeElementType elementType = enumTypeHandle.ToEETypePtr().ElementType; + EETypeElementType elementType = enumTypeHandle.ToMethodTable()->ElementType; switch (elementType) { case EETypeElementType.Boolean: @@ -351,7 +351,7 @@ public static Type GetEnumUnderlyingType(RuntimeTypeHandle enumTypeHandle) public static RuntimeTypeHandle GetRelatedParameterTypeHandle(RuntimeTypeHandle parameterTypeHandle) { - EETypePtr elementType = parameterTypeHandle.ToEETypePtr().ArrayElementType; + MethodTable* elementType = parameterTypeHandle.ToMethodTable()->RelatedParameterType; return new RuntimeTypeHandle(elementType); } @@ -363,17 +363,17 @@ public static unsafe int GetArrayRankOrMinusOneForSzArray(RuntimeTypeHandle arra public static bool IsValueType(RuntimeTypeHandle type) { - return type.ToEETypePtr().IsValueType; + return type.ToMethodTable()->IsValueType; } public static bool IsInterface(RuntimeTypeHandle type) { - return type.ToEETypePtr().IsInterface; + return type.ToMethodTable()->IsInterface; } public static unsafe object Box(RuntimeTypeHandle type, IntPtr address) { - return RuntimeImports.RhBox(type.ToEETypePtr(), ref *(byte*)address); + return RuntimeImports.RhBox(type.ToMethodTable(), ref *(byte*)address); } // Used to mutate the first parameter in a closed static delegate. Note that this does no synchronization of any kind; @@ -404,8 +404,8 @@ public static RuntimeTypeHandle ProjectionTypeForArrays // public static bool IsAssignableFrom(RuntimeTypeHandle dstType, RuntimeTypeHandle srcType) { - EETypePtr dstEEType = dstType.ToEETypePtr(); - EETypePtr srcEEType = srcType.ToEETypePtr(); + MethodTable* dstEEType = dstType.ToMethodTable(); + MethodTable* srcEEType = srcType.ToMethodTable(); return RuntimeImports.AreTypesAssignable(srcEEType, dstEEType); } @@ -418,44 +418,39 @@ public static bool IsAssignableFrom(RuntimeTypeHandle dstType, RuntimeTypeHandle // public static bool TryGetBaseType(RuntimeTypeHandle typeHandle, out RuntimeTypeHandle baseTypeHandle) { - EETypePtr eeType = typeHandle.ToEETypePtr(); - if (eeType.IsGenericTypeDefinition || eeType.IsPointer || eeType.IsByRef || eeType.IsFunctionPointer) + MethodTable* eeType = typeHandle.ToMethodTable(); + if (eeType->IsGenericTypeDefinition || eeType->IsPointer || eeType->IsByRef || eeType->IsFunctionPointer) { baseTypeHandle = default(RuntimeTypeHandle); return false; } - baseTypeHandle = new RuntimeTypeHandle(eeType.BaseType); + baseTypeHandle = new RuntimeTypeHandle(eeType->BaseType); return true; } public static int GetGCDescSize(RuntimeTypeHandle typeHandle) { - return RuntimeImports.RhGetGCDescSize(typeHandle.ToEETypePtr()); + return RuntimeImports.RhGetGCDescSize(typeHandle.ToMethodTable()); } public static int GetInterfaceCount(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().Interfaces.Count; + return typeHandle.ToMethodTable()->NumInterfaces; } public static RuntimeTypeHandle GetInterface(RuntimeTypeHandle typeHandle, int index) { - return new RuntimeTypeHandle(typeHandle.ToEETypePtr().Interfaces[index]); + return new RuntimeTypeHandle(typeHandle.ToMethodTable()->InterfaceMap[index]); } public static IntPtr NewInterfaceDispatchCell(RuntimeTypeHandle interfaceTypeHandle, int slotNumber) { - IntPtr cell = RuntimeImports.RhNewInterfaceDispatchCell(interfaceTypeHandle.ToEETypePtr(), slotNumber); + IntPtr cell = RuntimeImports.RhNewInterfaceDispatchCell(interfaceTypeHandle.ToMethodTable(), slotNumber); if (cell == IntPtr.Zero) throw new OutOfMemoryException(); return cell; } - public static int GetValueTypeSize(RuntimeTypeHandle typeHandle) - { - return (int)typeHandle.ToEETypePtr().ValueTypeSize; - } - [Intrinsic] public static RuntimeTypeHandle GetCanonType(CanonTypeKind kind) { @@ -465,65 +460,65 @@ public static RuntimeTypeHandle GetCanonType(CanonTypeKind kind) public static RuntimeTypeHandle GetGenericDefinition(RuntimeTypeHandle typeHandle) { - EETypePtr eeType = typeHandle.ToEETypePtr(); - Debug.Assert(eeType.IsGeneric); - return new RuntimeTypeHandle(eeType.GenericDefinition); + MethodTable* eeType = typeHandle.ToMethodTable(); + Debug.Assert(eeType->IsGeneric); + return new RuntimeTypeHandle(eeType->GenericDefinition); } public static RuntimeTypeHandle GetGenericArgument(RuntimeTypeHandle typeHandle, int argumentIndex) { - EETypePtr eeType = typeHandle.ToEETypePtr(); - Debug.Assert(eeType.IsGeneric); - return new RuntimeTypeHandle(eeType.Instantiation[argumentIndex]); + MethodTable* eeType = typeHandle.ToMethodTable(); + Debug.Assert(eeType->IsGeneric); + return new RuntimeTypeHandle(eeType->GenericArguments[argumentIndex]); } public static RuntimeTypeHandle GetGenericInstantiation(RuntimeTypeHandle typeHandle, out RuntimeTypeHandle[] genericTypeArgumentHandles) { - EETypePtr eeType = typeHandle.ToEETypePtr(); + MethodTable* eeType = typeHandle.ToMethodTable(); - Debug.Assert(eeType.IsGeneric); + Debug.Assert(eeType->IsGeneric); - var instantiation = eeType.Instantiation; - genericTypeArgumentHandles = new RuntimeTypeHandle[instantiation.Length]; - for (int i = 0; i < instantiation.Length; i++) + MethodTableList instantiation = eeType->GenericArguments; + genericTypeArgumentHandles = new RuntimeTypeHandle[eeType->GenericArity]; + for (int i = 0; i < genericTypeArgumentHandles.Length; i++) { genericTypeArgumentHandles[i] = new RuntimeTypeHandle(instantiation[i]); } - return new RuntimeTypeHandle(eeType.GenericDefinition); + return new RuntimeTypeHandle(eeType->GenericDefinition); } public static bool IsGenericType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsGeneric; + return typeHandle.ToMethodTable()->IsGeneric; } public static bool IsArrayType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsArray; + return typeHandle.ToMethodTable()->IsArray; } - public static bool IsByRefLike(RuntimeTypeHandle typeHandle) => typeHandle.ToEETypePtr().IsByRefLike; + public static bool IsByRefLike(RuntimeTypeHandle typeHandle) => typeHandle.ToMethodTable()->IsByRefLike; public static bool IsDynamicType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsDynamicType; + return typeHandle.ToMethodTable()->IsDynamicType; } public static bool HasCctor(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().HasCctor; + return typeHandle.ToMethodTable()->HasCctor; } public static IntPtr ResolveDispatchOnType(RuntimeTypeHandle instanceType, RuntimeTypeHandle interfaceType, int slot) { - return RuntimeImports.RhResolveDispatchOnType(instanceType.ToEETypePtr(), interfaceType.ToEETypePtr(), checked((ushort)slot)); + return RuntimeImports.RhResolveDispatchOnType(instanceType.ToMethodTable(), interfaceType.ToMethodTable(), checked((ushort)slot)); } public static unsafe IntPtr ResolveStaticDispatchOnType(RuntimeTypeHandle instanceType, RuntimeTypeHandle interfaceType, int slot, out RuntimeTypeHandle genericContext) { - EETypePtr genericContextPtr = default; - IntPtr result = RuntimeImports.RhResolveDispatchOnType(instanceType.ToEETypePtr(), interfaceType.ToEETypePtr(), checked((ushort)slot), &genericContextPtr); + MethodTable* genericContextPtr = default; + IntPtr result = RuntimeImports.RhResolveDispatchOnType(instanceType.ToMethodTable(), interfaceType.ToMethodTable(), checked((ushort)slot), &genericContextPtr); if (result != IntPtr.Zero) genericContext = new RuntimeTypeHandle(genericContextPtr); else @@ -533,17 +528,17 @@ public static unsafe IntPtr ResolveStaticDispatchOnType(RuntimeTypeHandle instan public static IntPtr ResolveDispatch(object instance, RuntimeTypeHandle interfaceType, int slot) { - return RuntimeImports.RhResolveDispatch(instance, interfaceType.ToEETypePtr(), checked((ushort)slot)); + return RuntimeImports.RhResolveDispatch(instance, interfaceType.ToMethodTable(), checked((ushort)slot)); } public static bool IsUnmanagedPointerType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsPointer; + return typeHandle.ToMethodTable()->IsPointer; } public static bool IsFunctionPointerType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsFunctionPointer; + return typeHandle.ToMethodTable()->IsFunctionPointer; } public static unsafe RuntimeTypeHandle GetFunctionPointerReturnType(RuntimeTypeHandle typeHandle) @@ -585,12 +580,12 @@ public static unsafe bool IsUnmanagedFunctionPointerType(RuntimeTypeHandle typeH public static bool IsByRefType(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsByRef; + return typeHandle.ToMethodTable()->IsByRef; } public static bool IsGenericTypeDefinition(RuntimeTypeHandle typeHandle) { - return typeHandle.ToEETypePtr().IsGenericTypeDefinition; + return typeHandle.ToMethodTable()->IsGenericTypeDefinition; } // @@ -598,43 +593,43 @@ public static bool IsGenericTypeDefinition(RuntimeTypeHandle typeHandle) // public static bool CanPrimitiveWiden(RuntimeTypeHandle srcType, RuntimeTypeHandle dstType) { - EETypePtr srcEEType = srcType.ToEETypePtr(); - EETypePtr dstEEType = dstType.ToEETypePtr(); + MethodTable* srcEEType = srcType.ToMethodTable(); + MethodTable* dstEEType = dstType.ToMethodTable(); - if (srcEEType.IsGenericTypeDefinition || dstEEType.IsGenericTypeDefinition) + if (srcEEType->IsGenericTypeDefinition || dstEEType->IsGenericTypeDefinition) return false; - if (srcEEType.IsPointer || dstEEType.IsPointer) + if (srcEEType->IsPointer || dstEEType->IsPointer) return false; - if (srcEEType.IsFunctionPointer || dstEEType.IsFunctionPointer) + if (srcEEType->IsFunctionPointer || dstEEType->IsFunctionPointer) return false; - if (srcEEType.IsByRef || dstEEType.IsByRef) + if (srcEEType->IsByRef || dstEEType->IsByRef) return false; - if (!srcEEType.IsPrimitive) + if (!srcEEType->IsPrimitive) return false; - if (!dstEEType.IsPrimitive) + if (!dstEEType->IsPrimitive) return false; - if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstEEType.CorElementType)) + if (!new EETypePtr(srcEEType).CorElementTypeInfo.CanWidenTo(new EETypePtr(dstEEType).CorElementType)) return false; return true; } public static object CheckArgument(object srcObject, RuntimeTypeHandle dstType, BinderBundle? binderBundle) { - return InvokeUtils.CheckArgument(srcObject, dstType.ToEETypePtr(), InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle); + return InvokeUtils.CheckArgument(srcObject, dstType.ToMethodTable(), InvokeUtils.CheckArgumentSemantics.DynamicInvoke, binderBundle); } // FieldInfo.SetValueDirect() has a completely different set of rules on how to coerce the argument from // the other Reflection api. public static object CheckArgumentForDirectFieldAccess(object srcObject, RuntimeTypeHandle dstType) { - return InvokeUtils.CheckArgument(srcObject, dstType.ToEETypePtr(), InvokeUtils.CheckArgumentSemantics.SetFieldDirect, binderBundle: null); + return InvokeUtils.CheckArgument(srcObject, dstType.ToMethodTable(), InvokeUtils.CheckArgumentSemantics.SetFieldDirect, binderBundle: null); } public static bool IsAssignable(object srcObject, RuntimeTypeHandle dstType) { - EETypePtr srcEEType = srcObject.GetEETypePtr(); - return RuntimeImports.AreTypesAssignable(srcEEType, dstType.ToEETypePtr()); + MethodTable* srcEEType = srcObject.GetMethodTable(); + return RuntimeImports.AreTypesAssignable(srcEEType, dstType.ToMethodTable()); } //============================================================================================== @@ -642,12 +637,12 @@ public static bool IsAssignable(object srcObject, RuntimeTypeHandle dstType) //============================================================================================== public static bool IsNullable(RuntimeTypeHandle declaringTypeHandle) { - return declaringTypeHandle.ToEETypePtr().IsNullable; + return declaringTypeHandle.ToMethodTable()->IsNullable; } public static RuntimeTypeHandle GetNullableType(RuntimeTypeHandle nullableType) { - EETypePtr theT = nullableType.ToEETypePtr().NullableType; + MethodTable* theT = nullableType.ToMethodTable()->NullableType; return new RuntimeTypeHandle(theT); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ArrayHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ArrayHelpers.cs index 31d845248548c..c086019f5041c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ArrayHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ArrayHelpers.cs @@ -18,17 +18,16 @@ internal static class ArrayHelpers /// Helper for array allocations via `newobj` IL instruction. Dimensions are passed in as block of integers. /// The content of the dimensions block may be modified by the helper. /// - public static unsafe Array NewObjArray(IntPtr pEEType, int nDimensions, int* pDimensions) + public static unsafe Array NewObjArray(MethodTable* pEEType, int nDimensions, int* pDimensions) { - EETypePtr eeType = new EETypePtr(pEEType); - Debug.Assert(eeType.IsArray && !eeType.IsSzArray); + Debug.Assert(pEEType->IsArray && !pEEType->IsSzArray); Debug.Assert(nDimensions > 0); // Rank 1 arrays are handled below. - Debug.Assert(eeType.ArrayRank > 1); + Debug.Assert(pEEType->ArrayRank > 1); // Multidimensional arrays have two ctors, one with and one without lower bounds - int rank = eeType.ArrayRank; + int rank = pEEType->ArrayRank; Debug.Assert(rank == nDimensions || 2 * rank == nDimensions); if (rank < nDimensions) @@ -42,7 +41,7 @@ public static unsafe Array NewObjArray(IntPtr pEEType, int nDimensions, int* pDi } } - return Array.NewMultiDimArray(eeType, pDimensions, rank); + return Array.NewMultiDimArray(pEEType, pDimensions, rank); } /// @@ -51,27 +50,26 @@ public static unsafe Array NewObjArray(IntPtr pEEType, int nDimensions, int* pDi /// [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "The compiler ensures that if we have a TypeHandle of a Rank-1 MdArray, we also generated the SzArray.")] - public static unsafe Array NewObjArrayRare(IntPtr pEEType, int nDimensions, int* pDimensions) + public static unsafe Array NewObjArrayRare(MethodTable* pEEType, int nDimensions, int* pDimensions) { - EETypePtr eeType = new EETypePtr(pEEType); - Debug.Assert(eeType.IsArray); + Debug.Assert(pEEType->IsArray); Debug.Assert(nDimensions > 0); - Debug.Assert(eeType.ArrayRank == 1); + Debug.Assert(pEEType->ArrayRank == 1); - if (eeType.IsSzArray) + if (pEEType->IsSzArray) { - Array ret = RuntimeImports.RhNewArray(eeType, pDimensions[0]); + Array ret = RuntimeImports.RhNewArray(pEEType, pDimensions[0]); if (nDimensions > 1) { // Jagged arrays have constructor for each possible depth - EETypePtr elementType = eeType.ArrayElementType; - Debug.Assert(elementType.IsSzArray); + MethodTable* elementType = pEEType->RelatedParameterType; + Debug.Assert(elementType->IsSzArray); Array[] arrayOfArrays = (Array[])ret; for (int i = 0; i < arrayOfArrays.Length; i++) - arrayOfArrays[i] = NewObjArrayRare(elementType.RawValue, nDimensions - 1, pDimensions + 1); + arrayOfArrays[i] = NewObjArrayRare(elementType, nDimensions - 1, pDimensions + 1); } return ret; @@ -92,8 +90,8 @@ public static unsafe Array NewObjArrayRare(IntPtr pEEType, int nDimensions, int* // Multidimensional array of rank 1 with 0 lower bounds gets actually allocated // as an SzArray. SzArray is castable to MdArray rank 1. - Type elementType = Type.GetTypeFromHandle(new RuntimeTypeHandle(eeType.ArrayElementType))!; - return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToEETypePtr(), pDimensions[0]); + Type elementType = Type.GetTypeFromHandle(new RuntimeTypeHandle(pEEType->RelatedParameterType))!; + return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToMethodTable(), pDimensions[0]); } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index f6c921ad22d65..9f597e151d550 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -488,10 +488,10 @@ public static object ConvertNativeComInterfaceToManaged(IntPtr pUnk) [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "This API will be called from compiler generated code only.")] - internal static int AsAnyGetNativeSize(object o) + internal static unsafe int AsAnyGetNativeSize(object o) { // Array, string and StringBuilder are not implemented. - if (o.GetEETypePtr().IsArray || + if (o.GetMethodTable()->IsArray || o is string || o is StringBuilder) { @@ -504,10 +504,10 @@ o is string || [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "This API will be called from compiler generated code only.")] - internal static void AsAnyMarshalManagedToNative(object o, IntPtr address) + internal static unsafe void AsAnyMarshalManagedToNative(object o, IntPtr address) { // Array, string and StringBuilder are not implemented. - if (o.GetEETypePtr().IsArray || + if (o.GetMethodTable()->IsArray || o is string || o is StringBuilder) { @@ -517,10 +517,10 @@ o is string || Marshal.StructureToPtr(o, address, fDeleteOld: false); } - internal static void AsAnyMarshalNativeToManaged(IntPtr address, object o) + internal static unsafe void AsAnyMarshalNativeToManaged(IntPtr address, object o) { // Array, string and StringBuilder are not implemented. - if (o.GetEETypePtr().IsArray || + if (o.GetMethodTable()->IsArray || o is string || o is StringBuilder) { @@ -532,10 +532,10 @@ o is string || [UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode", Justification = "This API will be called from compiler generated code only.")] - internal static void AsAnyCleanupNative(IntPtr address, object o) + internal static unsafe void AsAnyCleanupNative(IntPtr address, object o) { // Array, string and StringBuilder are not implemented. - if (o.GetEETypePtr().IsArray || + if (o.GetMethodTable()->IsArray || o is string || o is StringBuilder) { @@ -591,7 +591,7 @@ public static unsafe object InitializeCustomMarshaller(RuntimeTypeHandle pParame throw new ApplicationException(); } - if (!RuntimeImports.AreTypesAssignable(pMarshallerType.ToEETypePtr(), EETypePtr.EETypePtrOf())) + if (!RuntimeImports.AreTypesAssignable(pMarshallerType.ToMethodTable(), MethodTable.Of())) { throw new ApplicationException(); } @@ -602,7 +602,7 @@ public static unsafe object InitializeCustomMarshaller(RuntimeTypeHandle pParame throw new ApplicationException(); } - if (!RuntimeImports.AreTypesAssignable(marshaller.GetEETypePtr(), EETypePtr.EETypePtrOf())) + if (!RuntimeImports.AreTypesAssignable(marshaller.GetMethodTable(), MethodTable.Of())) { throw new ApplicationException(); } @@ -615,7 +615,7 @@ internal unsafe struct ModuleFixupCell { public IntPtr Handle; public IntPtr ModuleName; - public EETypePtr CallingAssemblyType; + public MethodTable* CallingAssemblyType; public uint DllImportSearchPathAndCookie; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LdTokenHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LdTokenHelpers.cs index 88f98794c5db5..4ac17b83b5b00 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LdTokenHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LdTokenHelpers.cs @@ -12,9 +12,9 @@ namespace Internal.Runtime.CompilerHelpers /// internal static class LdTokenHelpers { - private static RuntimeTypeHandle GetRuntimeTypeHandle(IntPtr pEEType) + private static unsafe RuntimeTypeHandle GetRuntimeTypeHandle(MethodTable* pEEType) { - return new RuntimeTypeHandle(new EETypePtr(pEEType)); + return new RuntimeTypeHandle(pEEType); } private static unsafe RuntimeMethodHandle GetRuntimeMethodHandle(IntPtr pHandleSignature) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/OpenMethodResolver.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/OpenMethodResolver.cs index d3f21f5b6da98..1d4f979ced854 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/OpenMethodResolver.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/OpenMethodResolver.cs @@ -19,10 +19,10 @@ namespace Internal.Runtime.CompilerServices // so that repeated allocation of the same resolver will not leak. // 3) Use the ResolveMethod function to do the virtual lookup. This function takes advantage of // a lockless cache so the resolution is very fast for repeated lookups. - public struct OpenMethodResolver : IEquatable + public unsafe struct OpenMethodResolver : IEquatable { // Lazy initialized to point to the type loader method when the first `GVMResolve` resolver is created - private static unsafe delegate* s_lazyGvmLookupForSlot; + private static delegate* s_lazyGvmLookupForSlot; public const short DispatchResolve = 0; public const short GVMResolve = 1; @@ -34,23 +34,23 @@ public struct OpenMethodResolver : IEquatable private readonly int _handle; private readonly IntPtr _methodHandleOrSlotOrCodePointer; private readonly IntPtr _nonVirtualOpenInvokeCodePointer; - private readonly EETypePtr _declaringType; + private readonly MethodTable* _declaringType; public OpenMethodResolver(RuntimeTypeHandle declaringTypeOfSlot, int slot, GCHandle readerGCHandle, int handle) { _resolveType = DispatchResolve; - _declaringType = declaringTypeOfSlot.ToEETypePtr(); + _declaringType = declaringTypeOfSlot.ToMethodTable(); _methodHandleOrSlotOrCodePointer = new IntPtr(slot); _handle = handle; _readerGCHandle = readerGCHandle; _nonVirtualOpenInvokeCodePointer = IntPtr.Zero; } - public unsafe OpenMethodResolver(RuntimeTypeHandle declaringTypeOfSlot, RuntimeMethodHandle gvmSlot, GCHandle readerGCHandle, int handle) + public OpenMethodResolver(RuntimeTypeHandle declaringTypeOfSlot, RuntimeMethodHandle gvmSlot, GCHandle readerGCHandle, int handle) { _resolveType = GVMResolve; _methodHandleOrSlotOrCodePointer = *(IntPtr*)&gvmSlot; - _declaringType = declaringTypeOfSlot.ToEETypePtr(); + _declaringType = declaringTypeOfSlot.ToMethodTable(); _handle = handle; _readerGCHandle = readerGCHandle; _nonVirtualOpenInvokeCodePointer = IntPtr.Zero; @@ -63,7 +63,7 @@ public OpenMethodResolver(RuntimeTypeHandle declaringType, IntPtr codePointer, G { _resolveType = OpenNonVirtualResolve; _nonVirtualOpenInvokeCodePointer = _methodHandleOrSlotOrCodePointer = codePointer; - _declaringType = declaringType.ToEETypePtr(); + _declaringType = declaringType.ToMethodTable(); _handle = handle; _readerGCHandle = readerGCHandle; } @@ -72,7 +72,7 @@ public OpenMethodResolver(RuntimeTypeHandle declaringType, IntPtr codePointer, G { _resolveType = resolveType; _methodHandleOrSlotOrCodePointer = codePointer; - _declaringType = declaringType.ToEETypePtr(); + _declaringType = declaringType.ToMethodTable(); _handle = handle; _readerGCHandle = readerGCHandle; if (resolveType == OpenNonVirtualResolve) @@ -99,7 +99,7 @@ public RuntimeTypeHandle DeclaringType } } - public unsafe RuntimeMethodHandle GVMMethodHandle + public RuntimeMethodHandle GVMMethodHandle { get { @@ -148,7 +148,7 @@ public int Handle } } - private unsafe IntPtr ResolveMethod(object thisObject) + private IntPtr ResolveMethod(object thisObject) { if (_resolveType == DispatchResolve) { @@ -164,12 +164,12 @@ private unsafe IntPtr ResolveMethod(object thisObject) } } - internal static unsafe IntPtr ResolveMethodWorker(IntPtr resolver, object thisObject) + internal static IntPtr ResolveMethodWorker(IntPtr resolver, object thisObject) { return ((OpenMethodResolver*)resolver)->ResolveMethod(thisObject); } - public static unsafe IntPtr ResolveMethod(IntPtr resolver, object thisObject) + public static IntPtr ResolveMethod(IntPtr resolver, object thisObject) { IntPtr nonVirtualOpenInvokeCodePointer = ((OpenMethodResolver*)resolver)->_nonVirtualOpenInvokeCodePointer; if (nonVirtualOpenInvokeCodePointer != IntPtr.Zero) @@ -178,14 +178,14 @@ public static unsafe IntPtr ResolveMethod(IntPtr resolver, object thisObject) return TypeLoaderExports.OpenInstanceMethodLookup(resolver, thisObject); } - public static unsafe IntPtr ResolveMethod(IntPtr resolverPtr, RuntimeTypeHandle thisType) + public static IntPtr ResolveMethod(IntPtr resolverPtr, RuntimeTypeHandle thisType) { OpenMethodResolver* resolver = ((OpenMethodResolver*)resolverPtr); IntPtr nonVirtualOpenInvokeCodePointer = resolver->_nonVirtualOpenInvokeCodePointer; if (nonVirtualOpenInvokeCodePointer != IntPtr.Zero) return nonVirtualOpenInvokeCodePointer; - return RuntimeImports.RhResolveDispatchOnType(thisType.ToEETypePtr(), resolver->_declaringType, (ushort)resolver->_methodHandleOrSlotOrCodePointer); + return RuntimeImports.RhResolveDispatchOnType(thisType.ToMethodTable(), resolver->_declaringType, (ushort)resolver->_methodHandleOrSlotOrCodePointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -214,7 +214,7 @@ private static int CalcHashCode(int hashCode1, int hashCode2, int hashCode3, int public override int GetHashCode() { - return CalcHashCode(_resolveType, _handle, _methodHandleOrSlotOrCodePointer.GetHashCode(), _declaringType.IsNull ? 0 : _declaringType.GetHashCode()); + return CalcHashCode(_resolveType, _handle, _methodHandleOrSlotOrCodePointer.GetHashCode(), _declaringType == null ? 0 : (int)_declaringType->HashCode); } public bool Equals(OpenMethodResolver other) @@ -228,7 +228,7 @@ public bool Equals(OpenMethodResolver other) if (other._methodHandleOrSlotOrCodePointer != _methodHandleOrSlotOrCodePointer) return false; - return other._declaringType.Equals(_declaringType); + return other._declaringType == _declaringType; } public override bool Equals(object? obj) @@ -243,7 +243,7 @@ public override bool Equals(object? obj) private static LowLevelDictionary s_internedResolverHash = new LowLevelDictionary(); - public unsafe IntPtr ToIntPtr() + public IntPtr ToIntPtr() { lock (s_internedResolverHash) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs index 6be052ef4c045..54878128ff982 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs @@ -28,7 +28,7 @@ internal static IntPtr IDynamicCastableGetInterfaceImplementation(IDynamicInterf { ThrowInvalidOperationException(implType); } - IntPtr result = RuntimeImports.RhResolveDispatchOnType(new EETypePtr(implType), new EETypePtr(interfaceType), slot); + IntPtr result = RuntimeImports.RhResolveDispatchOnType(implType, interfaceType, slot); if (result == IntPtr.Zero) { IDynamicCastableGetInterfaceImplementationFailure(instance, interfaceType, implType); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs index 2c58b4c1aa228..235a5fad23dd0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/ThreadStatics.cs @@ -137,7 +137,7 @@ private static unsafe object AllocateThreadStaticStorageForType(TypeManagerHandl gcDesc = Internal.Runtime.Augments.RuntimeAugments.TypeLoaderCallbacks.GetThreadStaticGCDescForDynamicType(typeManager, typeTlsIndex); } - return RuntimeImports.RhNewObject(new EETypePtr(gcDesc)); + return RuntimeImports.RhNewObject((MethodTable*)gcDesc); } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs index bb98e9b9c8ec3..c15fd13580e1b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs @@ -15,6 +15,7 @@ using System.Runtime.Remoting; using Internal.Reflection.Augments; +using Internal.Runtime; using Internal.Runtime.CompilerServices; namespace System @@ -52,7 +53,7 @@ public static partial class Activator { // Grab a pointer to the optimized allocator for the type and call it. IntPtr allocator = AllocatorOf(); - t = RawCalliHelper.Call(allocator, EETypePtr.EETypePtrOf().RawValue); + t = RawCalliHelper.Call(allocator, (nint)MethodTable.Of()); RawCalliHelper.Call(defaultConstructor, t); // Debugger goo so that stepping in works. Only affects debug info generation. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs index cefa694e4081d..84d6fea959a16 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs @@ -79,7 +79,7 @@ private static unsafe Array InternalCreate(RuntimeType elementType, int rank, in if (rank == 1) { - return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToEETypePtr(), pLengths[0]); + return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToMethodTable(), pLengths[0]); } else { @@ -90,7 +90,7 @@ private static unsafe Array InternalCreate(RuntimeType elementType, int rank, in for (int i = 0; i < rank; i++) pImmutableLengths[i] = pLengths[i]; - return NewMultiDimArray(arrayType.TypeHandle.ToEETypePtr(), pImmutableLengths, rank); + return NewMultiDimArray(arrayType.TypeHandle.ToMethodTable(), pImmutableLengths, rank); } } @@ -113,13 +113,13 @@ private static unsafe Array InternalCreateFromArrayType(RuntimeType arrayType, i } } - EETypePtr eeType = arrayType.TypeHandle.ToEETypePtr(); + MethodTable* eeType = arrayType.TypeHandle.ToMethodTable(); if (rank == 1) { // Multidimensional array of rank 1 with 0 lower bounds gets actually allocated // as an SzArray. SzArray is castable to MdArray rank 1. - if (!eeType.IsSzArray) - eeType = arrayType.GetElementType().MakeArrayType().TypeHandle.ToEETypePtr(); + if (!eeType->IsSzArray) + eeType = arrayType.GetElementType().MakeArrayType().TypeHandle.ToMethodTable(); return RuntimeImports.RhNewArray(eeType, pLengths[0]); } @@ -136,8 +136,8 @@ private static unsafe Array InternalCreateFromArrayType(RuntimeType arrayType, i public unsafe void Initialize() { - EETypePtr pElementEEType = ElementEEType; - if (!pElementEEType.IsValueType) + MethodTable* pElementEEType = ElementMethodTable; + if (!pElementEEType->IsValueType) return; IntPtr constructorEntryPoint = RuntimeAugments.TypeLoaderCallbacks.TryGetDefaultConstructorForType(new RuntimeTypeHandle(pElementEEType)); @@ -205,12 +205,12 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de if ((uint)(destinationIndex + length) > destinationArray.NativeLength) throw new ArgumentException(SR.Arg_LongerThanDestArray, nameof(destinationArray)); - EETypePtr sourceElementEEType = sourceArray.ElementEEType; - EETypePtr destinationElementEEType = destinationArray.ElementEEType; + MethodTable* sourceElementEEType = sourceArray.ElementMethodTable; + MethodTable* destinationElementEEType = destinationArray.ElementMethodTable; - if (!destinationElementEEType.IsValueType && !destinationElementEEType.IsPointer && !destinationElementEEType.IsFunctionPointer) + if (!destinationElementEEType->IsValueType && !destinationElementEEType->IsPointer && !destinationElementEEType->IsFunctionPointer) { - if (!sourceElementEEType.IsValueType && !sourceElementEEType.IsPointer && !sourceElementEEType.IsFunctionPointer) + if (!sourceElementEEType->IsValueType && !sourceElementEEType->IsPointer && !sourceElementEEType->IsFunctionPointer) { CopyImplGcRefArray(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable); } @@ -227,7 +227,7 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de { if (sourceElementEEType == destinationElementEEType) { - if (sourceElementEEType.ContainsGCPointers) + if (sourceElementEEType->ContainsGCPointers) { CopyImplValueTypeArrayWithInnerGcRefs(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable); } @@ -236,7 +236,7 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de CopyImplValueTypeArrayNoInnerGcRefs(sourceArray, sourceIndex, destinationArray, destinationIndex, length); } } - else if ((sourceElementEEType.IsPointer || sourceElementEEType.IsFunctionPointer) && (destinationElementEEType.IsPointer || destinationElementEEType.IsFunctionPointer)) + else if ((sourceElementEEType->IsPointer || sourceElementEEType->IsFunctionPointer) && (destinationElementEEType->IsPointer || destinationElementEEType->IsFunctionPointer)) { // CLR compat note: CLR only allows Array.Copy between pointee types that would be assignable // to using array covariance rules (so int*[] can be copied to uint*[], but not to float*[]). @@ -248,9 +248,9 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de { CopyImplReferenceArrayToValueTypeArray(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable); } - else if (sourceElementEEType.IsPrimitive && destinationElementEEType.IsPrimitive) + else if (sourceElementEEType->IsPrimitive && destinationElementEEType->IsPrimitive) { - if (RuntimeImports.AreTypesAssignable(sourceArray.GetEETypePtr(), destinationArray.GetEETypePtr())) + if (RuntimeImports.AreTypesAssignable(sourceArray.GetMethodTable(), destinationArray.GetMethodTable())) { // If we're okay casting between these two, we're also okay blitting the values over CopyImplValueTypeArrayNoInnerGcRefs(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @@ -269,9 +269,9 @@ private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array de } } - private static bool IsSourceElementABaseClassOrInterfaceOfDestinationValueType(EETypePtr sourceElementEEType, EETypePtr destinationElementEEType) + private static unsafe bool IsSourceElementABaseClassOrInterfaceOfDestinationValueType(MethodTable* sourceElementEEType, MethodTable* destinationElementEEType) { - if (sourceElementEEType.IsValueType || sourceElementEEType.IsPointer || sourceElementEEType.IsFunctionPointer) + if (sourceElementEEType->IsValueType || sourceElementEEType->IsPointer || sourceElementEEType->IsFunctionPointer) return false; // It may look like we're passing the arguments to AreTypesAssignable in the wrong order but we're not. The source array is an interface or Object array, the destination @@ -289,11 +289,11 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex { // For mismatched array types, the desktop Array.Copy has a policy that determines whether to throw an ArrayTypeMismatch without any attempt to copy // or to throw an InvalidCastException in the middle of a copy. This code replicates that policy. - EETypePtr sourceElementEEType = sourceArray.ElementEEType; - EETypePtr destinationElementEEType = destinationArray.ElementEEType; + MethodTable* sourceElementEEType = sourceArray.ElementMethodTable; + MethodTable* destinationElementEEType = destinationArray.ElementMethodTable; - Debug.Assert(!sourceElementEEType.IsValueType && !sourceElementEEType.IsPointer && !sourceElementEEType.IsFunctionPointer); - Debug.Assert(!destinationElementEEType.IsValueType && !destinationElementEEType.IsPointer && !destinationElementEEType.IsFunctionPointer); + Debug.Assert(!sourceElementEEType->IsValueType && !sourceElementEEType->IsPointer && !sourceElementEEType->IsFunctionPointer); + Debug.Assert(!destinationElementEEType->IsValueType && !destinationElementEEType->IsPointer && !destinationElementEEType->IsFunctionPointer); bool attemptCopy = RuntimeImports.AreTypesAssignable(sourceElementEEType, destinationElementEEType); bool mustCastCheckEachElement = !attemptCopy; @@ -309,8 +309,8 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex // If either array is an interface array, we allow the attempt to copy even if the other element type does not statically implement the interface. // We don't have an "IsInterface" property in EETypePtr so we instead check for a null BaseType. The only the other MethodTable with a null BaseType is // System.Object but if that were the case, we would already have passed one of the AreTypesAssignable checks above. - attemptCopy = attemptCopy || sourceElementEEType.BaseType.IsNull; - attemptCopy = attemptCopy || destinationElementEEType.BaseType.IsNull; + attemptCopy = attemptCopy || sourceElementEEType->BaseType == null; + attemptCopy = attemptCopy || destinationElementEEType->BaseType == null; if (!attemptCopy) throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); @@ -348,16 +348,16 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex // private static unsafe void CopyImplValueTypeArrayToReferenceArray(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { - Debug.Assert(sourceArray.ElementEEType.IsValueType); - Debug.Assert(!destinationArray.ElementEEType.IsValueType && !destinationArray.ElementEEType.IsPointer && !destinationArray.ElementEEType.IsFunctionPointer); + Debug.Assert(sourceArray.ElementMethodTable->IsValueType); + Debug.Assert(!destinationArray.ElementMethodTable->IsValueType && !destinationArray.ElementMethodTable->IsPointer && !destinationArray.ElementMethodTable->IsFunctionPointer); // Caller has already validated this. - Debug.Assert(RuntimeImports.AreTypesAssignable(sourceArray.ElementEEType, destinationArray.ElementEEType)); + Debug.Assert(RuntimeImports.AreTypesAssignable(sourceArray.ElementMethodTable, destinationArray.ElementMethodTable)); if (reliable) throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_ConstrainedCopy); - EETypePtr sourceElementEEType = sourceArray.ElementEEType; + MethodTable* sourceElementEEType = sourceArray.ElementMethodTable; nuint sourceElementSize = sourceArray.ElementSize; fixed (byte* pSourceArray = &MemoryMarshal.GetArrayDataReference(sourceArray)) @@ -378,15 +378,15 @@ private static unsafe void CopyImplValueTypeArrayToReferenceArray(Array sourceAr // private static unsafe void CopyImplReferenceArrayToValueTypeArray(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { - Debug.Assert(!sourceArray.ElementEEType.IsValueType && !sourceArray.ElementEEType.IsPointer && !sourceArray.ElementEEType.IsFunctionPointer); - Debug.Assert(destinationArray.ElementEEType.IsValueType); + Debug.Assert(!sourceArray.ElementMethodTable->IsValueType && !sourceArray.ElementMethodTable->IsPointer && !sourceArray.ElementMethodTable->IsFunctionPointer); + Debug.Assert(destinationArray.ElementMethodTable->IsValueType); if (reliable) throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); - EETypePtr destinationElementEEType = destinationArray.ElementEEType; + MethodTable* destinationElementEEType = destinationArray.ElementMethodTable; nuint destinationElementSize = destinationArray.ElementSize; - bool isNullable = destinationElementEEType.IsNullable; + bool isNullable = destinationElementEEType->IsNullable; fixed (byte* pDestinationArray = &MemoryMarshal.GetArrayDataReference(destinationArray)) { @@ -403,7 +403,7 @@ private static unsafe void CopyImplReferenceArrayToValueTypeArray(Array sourceAr } else { - EETypePtr eeType = boxedValue.GetEETypePtr(); + MethodTable* eeType = boxedValue.GetMethodTable(); if (!(RuntimeImports.AreTypesAssignable(eeType, destinationElementEEType))) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); } @@ -420,10 +420,10 @@ private static unsafe void CopyImplReferenceArrayToValueTypeArray(Array sourceAr // private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { - Debug.Assert(sourceArray.GetEETypePtr() == destinationArray.GetEETypePtr()); - Debug.Assert(sourceArray.ElementEEType.IsValueType); + Debug.Assert(sourceArray.GetMethodTable() == destinationArray.GetMethodTable()); + Debug.Assert(sourceArray.ElementMethodTable->IsValueType); - EETypePtr sourceElementEEType = sourceArray.GetEETypePtr().ArrayElementType; + MethodTable* sourceElementEEType = sourceArray.GetMethodTable()->RelatedParameterType; bool reverseCopy = ((object)sourceArray == (object)destinationArray) && (sourceIndex < destinationIndex); // Copy scenario: ValueType-array to value-type array with embedded gc-refs. @@ -487,10 +487,10 @@ private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArr // private static unsafe void CopyImplValueTypeArrayNoInnerGcRefs(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length) { - Debug.Assert((sourceArray.ElementEEType.IsValueType && !sourceArray.ElementEEType.ContainsGCPointers) || - sourceArray.ElementEEType.IsPointer || sourceArray.ElementEEType.IsFunctionPointer); - Debug.Assert((destinationArray.ElementEEType.IsValueType && !destinationArray.ElementEEType.ContainsGCPointers) || - destinationArray.ElementEEType.IsPointer || destinationArray.ElementEEType.IsFunctionPointer); + Debug.Assert((sourceArray.ElementMethodTable->IsValueType && !sourceArray.ElementMethodTable->ContainsGCPointers) || + sourceArray.ElementMethodTable->IsPointer || sourceArray.ElementMethodTable->IsFunctionPointer); + Debug.Assert((destinationArray.ElementMethodTable->IsValueType && !destinationArray.ElementMethodTable->ContainsGCPointers) || + destinationArray.ElementMethodTable->IsPointer || destinationArray.ElementMethodTable->IsFunctionPointer); // Copy scenario: ValueType-array to value-type array with no embedded gc-refs. nuint elementSize = sourceArray.ElementSize; @@ -506,18 +506,18 @@ ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(sourceArray), ( // private static unsafe void CopyImplPrimitiveTypeWithWidening(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { - EETypePtr sourceElementEEType = sourceArray.ElementEEType; - EETypePtr destinationElementEEType = destinationArray.ElementEEType; + MethodTable* sourceElementEEType = sourceArray.ElementMethodTable; + MethodTable* destinationElementEEType = destinationArray.ElementMethodTable; - Debug.Assert(sourceElementEEType.IsPrimitive && destinationElementEEType.IsPrimitive); // Caller has already validated this. + Debug.Assert(sourceElementEEType->IsPrimitive && destinationElementEEType->IsPrimitive); // Caller has already validated this. - EETypeElementType sourceElementType = sourceElementEEType.ElementType; - EETypeElementType destElementType = destinationElementEEType.ElementType; + EETypeElementType sourceElementType = sourceElementEEType->ElementType; + EETypeElementType destElementType = destinationElementEEType->ElementType; nuint srcElementSize = sourceArray.ElementSize; nuint destElementSize = destinationArray.ElementSize; - if ((sourceElementEEType.IsEnum || destinationElementEEType.IsEnum) && sourceElementType != destElementType) + if ((sourceElementEEType->IsEnum || destinationElementEEType->IsEnum) && sourceElementType != destElementType) throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); if (reliable) @@ -847,19 +847,19 @@ public int GetLength(int dimension) return length; } - public int Rank + public unsafe int Rank { get { - return this.GetEETypePtr().ArrayRank; + return this.GetMethodTable()->ArrayRank; } } // Allocate new multidimensional array of given dimensions. Assumes that pLengths is immutable. - internal static unsafe Array NewMultiDimArray(EETypePtr eeType, int* pLengths, int rank) + internal static unsafe Array NewMultiDimArray(MethodTable* eeType, int* pLengths, int rank) { - Debug.Assert(eeType.IsArray && !eeType.IsSzArray); - Debug.Assert(rank == eeType.ArrayRank); + Debug.Assert(eeType->IsArray && !eeType->IsSzArray); + Debug.Assert(rank == eeType->ArrayRank); // Code below assumes 0 lower bounds. MdArray of rank 1 with zero lower bounds should never be allocated. // The runtime always allocates an SzArray for those: @@ -981,23 +981,23 @@ private unsafe nint GetFlattenedIndex(ReadOnlySpan indices) } } - internal object? InternalGetValue(nint flattenedIndex) + internal unsafe object? InternalGetValue(nint flattenedIndex) { Debug.Assert((nuint)flattenedIndex < NativeLength); - if (ElementEEType.IsPointer || ElementEEType.IsFunctionPointer) + if (ElementMethodTable->IsPointer || ElementMethodTable->IsFunctionPointer) throw new NotSupportedException(SR.NotSupported_Type); ref byte element = ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(this), (nuint)flattenedIndex * ElementSize); - EETypePtr pElementEEType = ElementEEType; - if (pElementEEType.IsValueType) + MethodTable* pElementEEType = ElementMethodTable; + if (pElementEEType->IsValueType) { return RuntimeImports.RhBox(pElementEEType, ref element); } else { - Debug.Assert(!pElementEEType.IsPointer && !pElementEEType.IsFunctionPointer); + Debug.Assert(!pElementEEType->IsPointer && !pElementEEType->IsFunctionPointer); return Unsafe.As(ref element); } } @@ -1008,19 +1008,19 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex) ref byte element = ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(this), (nuint)flattenedIndex * ElementSize); - EETypePtr pElementEEType = ElementEEType; - if (pElementEEType.IsValueType) + MethodTable* pElementEEType = ElementMethodTable; + if (pElementEEType->IsValueType) { // Unlike most callers of InvokeUtils.ChangeType(), Array.SetValue() does *not* permit conversion from a primitive to an Enum. - if (value != null && !(value.GetEETypePtr() == pElementEEType) && pElementEEType.IsEnum) + if (value != null && !(value.GetMethodTable() == pElementEEType) && pElementEEType->IsEnum) throw new InvalidCastException(SR.Format(SR.Arg_ObjObjEx, value.GetType(), Type.GetTypeFromHandle(new RuntimeTypeHandle(pElementEEType)))); value = InvokeUtils.CheckArgument(value, pElementEEType, InvokeUtils.CheckArgumentSemantics.ArraySet, binderBundle: null); - Debug.Assert(value == null || RuntimeImports.AreTypesAssignable(value.GetEETypePtr(), pElementEEType)); + Debug.Assert(value == null || RuntimeImports.AreTypesAssignable(value.GetMethodTable(), pElementEEType)); RuntimeImports.RhUnbox(value, ref element, pElementEEType); } - else if (pElementEEType.IsPointer || pElementEEType.IsFunctionPointer) + else if (pElementEEType->IsPointer || pElementEEType->IsFunctionPointer) { throw new NotSupportedException(SR.NotSupported_Type); } @@ -1038,22 +1038,16 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex) } } - internal EETypePtr ElementEEType - { - get - { - return this.GetEETypePtr().ArrayElementType; - } - } + internal unsafe MethodTable* ElementMethodTable => this.GetMethodTable()->RelatedParameterType; - internal CorElementType GetCorElementTypeOfElementType() + internal unsafe CorElementType GetCorElementTypeOfElementType() { - return ElementEEType.CorElementType; + return new EETypePtr(ElementMethodTable).CorElementType; } - internal bool IsValueOfElementType(object o) + internal unsafe bool IsValueOfElementType(object o) { - return ElementEEType.Equals(o.GetEETypePtr()); + return ElementMethodTable == o.GetMethodTable(); } // diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs index a427896ac230c..3aee8254f0fee 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs @@ -11,6 +11,7 @@ using System.Text; using Internal.Reflection.Augments; +using Internal.Runtime; using Internal.Runtime.Augments; using Internal.Runtime.CompilerServices; @@ -112,7 +113,7 @@ internal unsafe IntPtr GetFunctionPointer(out RuntimeTypeHandle typeOfFirstParam else { if (m_firstParameter != null) - typeOfFirstParameterIfInstanceDelegate = new RuntimeTypeHandle(m_firstParameter.GetEETypePtr()); + typeOfFirstParameterIfInstanceDelegate = new RuntimeTypeHandle(m_firstParameter.GetMethodTable()); // TODO! Implementation issue for generic invokes here ... we need another IntPtr for uniqueness. @@ -348,20 +349,20 @@ internal bool IsOpenStatic } } - internal static bool InternalEqualTypes(object a, object b) + internal static unsafe bool InternalEqualTypes(object a, object b) { - return a.GetEETypePtr() == b.GetEETypePtr(); + return a.GetMethodTable() == b.GetMethodTable(); } // Returns a new delegate of the specified type whose implementation is provided by the // provided delegate. - internal static Delegate CreateObjectArrayDelegate(Type t, Func handler) + internal static unsafe Delegate CreateObjectArrayDelegate(Type t, Func handler) { RuntimeTypeHandle typeHandle = t.TypeHandle; - EETypePtr delegateEEType = typeHandle.ToEETypePtr(); - Debug.Assert(!delegateEEType.IsNull); - Debug.Assert(delegateEEType.IsCanonical); + MethodTable* delegateEEType = typeHandle.ToMethodTable(); + Debug.Assert(delegateEEType != null); + Debug.Assert(delegateEEType->IsCanonical); Delegate del = (Delegate)(RuntimeImports.RhNewObject(delegateEEType)); @@ -383,9 +384,9 @@ internal static Delegate CreateObjectArrayDelegate(Type t, Func + internal unsafe struct EETypePtr { private MethodTable* _value; @@ -39,308 +35,6 @@ internal EETypePtr(MethodTable* value) _value = value; } - internal MethodTable* ToPointer() - { - return _value; - } - - public override bool Equals(object? obj) - { - if (obj is EETypePtr) - { - return this == (EETypePtr)obj; - } - return false; - } - - public bool Equals(EETypePtr p) - { - return this == p; - } - - public static bool operator ==(EETypePtr value1, EETypePtr value2) - { - return value1._value == value2._value; - } - - public static bool operator !=(EETypePtr value1, EETypePtr value2) - { - return !(value1 == value2); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return (int)_value->HashCode; - } - - // Caution: You cannot safely compare RawValue's as RH does NOT unify EETypes. Use the == or Equals() methods exposed by EETypePtr itself. - internal IntPtr RawValue - { - get - { - return (IntPtr)_value; - } - } - - internal bool IsNull - { - get - { - return _value == null; - } - } - - internal bool IsArray - { - get - { - return _value->IsArray; - } - } - - internal bool IsSzArray - { - get - { - return _value->IsSzArray; - } - } - - internal bool IsPointer - { - get - { - return _value->IsPointer; - } - } - - internal bool IsFunctionPointer - { - get - { - return _value->IsFunctionPointer; - } - } - - internal bool IsByRef - { - get - { - return _value->IsByRef; - } - } - - internal bool IsValueType - { - get - { - return _value->IsValueType; - } - } - - internal bool IsString - { - get - { - return _value->IsString; - } - } - - // Warning! UNLIKE the similarly named Reflection api, this method also returns "true" for Enums. - internal bool IsPrimitive - { - get - { - return _value->IsPrimitive; - } - } - - internal bool IsEnum - { - get - { - return _value->IsEnum; - } - } - - // Gets a value indicating whether this is a generic type definition (an uninstantiated generic type). - internal bool IsGenericTypeDefinition - { - get - { - return _value->IsGenericTypeDefinition; - } - } - - // Gets a value indicating whether this is an instantiated generic type. - internal bool IsGeneric - { - get - { - return _value->IsGeneric; - } - } - - internal GenericArgumentCollection Instantiation - { - get - { - return new GenericArgumentCollection(_value->GenericArity, _value->GenericArguments); - } - } - - internal EETypePtr GenericDefinition - { - get - { - return new EETypePtr(_value->GenericDefinition); - } - } - - /// - /// Gets a value indicating whether this is an class, a struct, an enum, or an interface, - /// that is not generic type definition - /// - internal bool IsCanonical - { - get - { - return _value->IsCanonical; - } - } - - /// - /// Gets a value indicating whether this is a class, a struct, an enum, or an interface. - /// - internal bool IsDefType - { - get - { - return _value->IsDefType; - } - } - - internal bool IsDynamicType - { - get - { - return _value->IsDynamicType; - } - } - - internal bool IsInterface - { - get - { - return _value->IsInterface; - } - } - - internal bool IsByRefLike - { - get - { - return _value->IsByRefLike; - } - } - - internal bool IsNullable - { - get - { - return _value->IsNullable; - } - } - - internal bool HasCctor - { - get - { - return _value->HasCctor; - } - } - - internal bool IsTrackedReferenceWithFinalizer - { - get - { - return _value->IsTrackedReferenceWithFinalizer; - } - } - - internal EETypePtr NullableType - { - get - { - return new EETypePtr(_value->NullableType); - } - } - - internal EETypePtr ArrayElementType - { - get - { - return new EETypePtr(_value->RelatedParameterType); - } - } - - internal int ArrayRank - { - get - { - return _value->ArrayRank; - } - } - - internal InterfaceCollection Interfaces - { - get - { - return new InterfaceCollection(_value); - } - } - - internal EETypePtr BaseType - { - get - { - if (IsArray) - return EETypePtr.EETypePtrOf(); - - if (IsPointer || IsByRef || IsFunctionPointer) - return new EETypePtr(default(IntPtr)); - - EETypePtr baseEEType = new EETypePtr(_value->NonArrayBaseType); - return baseEEType; - } - } - - internal IntPtr DispatchMap - { - get - { - return (IntPtr)_value->DispatchMap; - } - } - - // Instance contains pointers to managed objects. - internal bool ContainsGCPointers - { - get - { - return _value->ContainsGCPointers; - } - } - - internal uint ValueTypeSize - { - get - { - return _value->ValueTypeSize; - } - } - internal CorElementType CorElementType { get @@ -389,7 +83,7 @@ internal CorElementType CorElementType } } - internal EETypeElementType ElementType + private EETypeElementType ElementType { get { @@ -404,70 +98,5 @@ internal RuntimeImports.RhCorElementTypeInfo CorElementTypeInfo return RuntimeImports.GetRhCorElementTypeInfo(CorElementType); } } - - [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static EETypePtr EETypePtrOf() - { - // Compilers are required to provide a low level implementation of this method. - throw new NotImplementedException(); - } - - public struct InterfaceCollection - { - private MethodTable* _value; - - internal InterfaceCollection(MethodTable* value) - { - _value = value; - } - - public int Count - { - get - { - return _value->NumInterfaces; - } - } - - public EETypePtr this[int index] - { - get - { - Debug.Assert((uint)index < _value->NumInterfaces); - - return new EETypePtr(_value->InterfaceMap[index]); - } - } - } - - public struct GenericArgumentCollection - { - private MethodTableList _arguments; - private uint _argumentCount; - - internal GenericArgumentCollection(uint argumentCount, MethodTableList arguments) - { - _argumentCount = argumentCount; - _arguments = arguments; - } - - public int Length - { - get - { - return (int)_argumentCount; - } - } - - public EETypePtr this[int index] - { - get - { - Debug.Assert((uint)index < _argumentCount); - return new EETypePtr(_arguments[index]); - } - } - } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs index 50eca49d0a023..baf2e424546e4 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs @@ -10,6 +10,7 @@ using System.Runtime.InteropServices; using Internal.Reflection.Augments; +using Internal.Runtime; using Internal.Runtime.Augments; using Internal.Runtime.CompilerServices; @@ -21,12 +22,12 @@ namespace System public abstract partial class Enum : ValueType, IComparable, IFormattable, IConvertible { #pragma warning disable IDE0060 - internal static EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true) + internal static unsafe EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true) { Debug.Assert(enumType != null); Debug.Assert(enumType.IsEnum); - return enumType.TypeHandle.ToEETypePtr().ElementType switch + return enumType.TypeHandle.ToMethodTable()->ElementType switch { EETypeElementType.SByte or EETypeElementType.Byte => GetEnumInfo(enumType), EETypeElementType.Int16 or EETypeElementType.UInt16 => GetEnumInfo(enumType), @@ -61,20 +62,20 @@ internal static EnumInfo GetEnumInfo(RuntimeType enumType, b } #pragma warning restore - private static object InternalBoxEnum(Type enumType, long value) + private static unsafe object InternalBoxEnum(Type enumType, long value) { - return ToObject(enumType.TypeHandle.ToEETypePtr(), value); + return ToObject(enumType.TypeHandle.ToMethodTable(), value); } - private static CorElementType InternalGetCorElementType(RuntimeType rt) + private static unsafe CorElementType InternalGetCorElementType(RuntimeType rt) { Debug.Assert(rt.IsActualEnum); - return rt.TypeHandle.ToEETypePtr().CorElementType; + return new EETypePtr(rt.TypeHandle.ToMethodTable()).CorElementType; } - private CorElementType InternalGetCorElementType() + private unsafe CorElementType InternalGetCorElementType() { - return this.GetEETypePtr().CorElementType; + return new EETypePtr(this.GetMethodTable()).CorElementType; } // @@ -86,16 +87,16 @@ private CorElementType InternalGetCorElementType() // // The return value is "bool" if "value" is not an enum or an "integer type" as defined by the BCL Enum apis. // - internal static bool TryGetUnboxedValueOfEnumOrInteger(object value, out ulong result) + internal static unsafe bool TryGetUnboxedValueOfEnumOrInteger(object value, out ulong result) { - EETypePtr eeType = value.GetEETypePtr(); + MethodTable* eeType = value.GetMethodTable(); // For now, this check is required to flush out pointers. - if (!eeType.IsDefType) + if (!eeType->IsDefType) { result = 0; return false; } - EETypeElementType elementType = eeType.ElementType; + EETypeElementType elementType = eeType->ElementType; ref byte pValue = ref value.GetRawData(); @@ -152,12 +153,12 @@ internal static Type InternalGetUnderlyingType(RuntimeType enumType) } [Conditional("BIGENDIAN")] - private static unsafe void AdjustForEndianness(ref byte* pValue, EETypePtr enumEEType) + private static unsafe void AdjustForEndianness(ref byte* pValue, MethodTable* enumEEType) { // On Debug builds, include the big-endian code to help deter bitrot (the "Conditional("BIGENDIAN")" will prevent it from executing on little-endian). // On Release builds, exclude code to deter IL bloat and toolchain work. #if BIGENDIAN || DEBUG - EETypeElementType elementType = enumEEType.ElementType; + EETypeElementType elementType = enumEEType->ElementType; switch (elementType) { case EETypeElementType.SByte: @@ -187,9 +188,9 @@ private static unsafe void AdjustForEndianness(ref byte* pValue, EETypePtr enumE #region ToObject - internal static unsafe object ToObject(EETypePtr enumEEType, long value) + internal static unsafe object ToObject(MethodTable* enumEEType, long value) { - Debug.Assert(enumEEType.IsEnum); + Debug.Assert(enumEEType->IsEnum); byte* pValue = (byte*)&value; AdjustForEndianness(ref pValue, enumEEType); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs index 538fb9b7e246e..bc61b34c3b302 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs @@ -6,9 +6,11 @@ using System.Runtime; using System.Runtime.CompilerServices; +using MethodTable = Internal.Runtime.MethodTable; + namespace System { - internal static class InvokeUtils + internal static unsafe class InvokeUtils { // // Various reflection scenarios (Array.SetValue(), reflection Invoke, delegate DynamicInvoke and FieldInfo.Set()) perform @@ -37,22 +39,22 @@ internal enum CheckArgumentSemantics SetFieldDirect, // Throws ArgumentException - other than that, like DynamicInvoke except that enums and integers cannot be intermingled, and null cannot substitute for default(valuetype). } - internal static object? CheckArgument(object? srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle? binderBundle) + internal static object? CheckArgument(object? srcObject, MethodTable* dstEEType, CheckArgumentSemantics semantics, BinderBundle? binderBundle) { // Methods with ByRefLike types in signatures should be filtered out earlier - Debug.Assert(!dstEEType.IsByRefLike); + Debug.Assert(!dstEEType->IsByRefLike); if (srcObject == null) { // null -> default(T) - if (dstEEType.IsPointer) + if (dstEEType->IsPointer) { return default(IntPtr); } - else if (dstEEType.IsValueType && !dstEEType.IsNullable) + else if (dstEEType->IsValueType && !dstEEType->IsNullable) { if (semantics == CheckArgumentSemantics.SetFieldDirect) - throw CreateChangeTypeException(typeof(object).TypeHandle.ToEETypePtr(), dstEEType, semantics); + throw CreateChangeTypeException(MethodTable.Of(), dstEEType, semantics); return Runtime.RuntimeImports.RhNewObject(dstEEType); } else @@ -62,11 +64,11 @@ internal enum CheckArgumentSemantics } else { - EETypePtr srcEEType = srcObject.GetEETypePtr(); + MethodTable* srcEEType = srcObject.GetMethodTable(); - if (srcEEType.RawValue == dstEEType.RawValue || + if (srcEEType == dstEEType || RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) || - (dstEEType.IsInterface && srcObject is Runtime.InteropServices.IDynamicInterfaceCastable castable + (dstEEType->IsInterface && srcObject is Runtime.InteropServices.IDynamicInterfaceCastable castable && castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false))) { return srcObject; @@ -76,7 +78,7 @@ internal enum CheckArgumentSemantics } } - internal static object? CheckArgumentConversions(object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle? binderBundle) + internal static object? CheckArgumentConversions(object srcObject, MethodTable* dstEEType, CheckArgumentSemantics semantics, BinderBundle? binderBundle) { object? dstObject; Exception exception = ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(srcObject, dstEEType, semantics, out dstObject); @@ -96,17 +98,17 @@ internal enum CheckArgumentSemantics } // Special coersion rules for primitives, enums and pointer. - private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, out object? dstObject) + private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(object srcObject, MethodTable* dstEEType, CheckArgumentSemantics semantics, out object? dstObject) { - EETypePtr srcEEType = srcObject.GetEETypePtr(); + MethodTable* srcEEType = srcObject.GetMethodTable(); - if (semantics == CheckArgumentSemantics.SetFieldDirect && (srcEEType.IsEnum || dstEEType.IsEnum)) + if (semantics == CheckArgumentSemantics.SetFieldDirect && (srcEEType->IsEnum || dstEEType->IsEnum)) { dstObject = null; return CreateChangeTypeException(srcEEType, dstEEType, semantics); } - if (dstEEType.IsPointer || dstEEType.IsFunctionPointer) + if (dstEEType->IsPointer || dstEEType->IsFunctionPointer) { Exception exception = ConvertPointerIfPossible(srcObject, dstEEType, semantics, out object dstPtr); if (exception != null) @@ -118,14 +120,14 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje return null; } - if (!(srcEEType.IsPrimitive && dstEEType.IsPrimitive)) + if (!(srcEEType->IsPrimitive && dstEEType->IsPrimitive)) { dstObject = null; return CreateChangeTypeException(srcEEType, dstEEType, semantics); } - CorElementType dstCorElementType = dstEEType.CorElementType; - if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType)) + CorElementType dstCorElementType = new EETypePtr(dstEEType).CorElementType; + if (!new EETypePtr(srcEEType).CorElementTypeInfo.CanWidenTo(dstCorElementType)) { dstObject = null; return CreateChangeTypeArgumentException(srcEEType, dstEEType); @@ -139,51 +141,51 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje case CorElementType.ELEMENT_TYPE_CHAR: char charValue = Convert.ToChar(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, charValue) : charValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, charValue) : charValue; break; case CorElementType.ELEMENT_TYPE_I1: sbyte sbyteValue = Convert.ToSByte(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, sbyteValue) : sbyteValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, sbyteValue) : sbyteValue; break; case CorElementType.ELEMENT_TYPE_I2: short shortValue = Convert.ToInt16(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, shortValue) : shortValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, shortValue) : shortValue; break; case CorElementType.ELEMENT_TYPE_I4: int intValue = Convert.ToInt32(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, intValue) : intValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, intValue) : intValue; break; case CorElementType.ELEMENT_TYPE_I8: long longValue = Convert.ToInt64(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, longValue) : longValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, longValue) : longValue; break; case CorElementType.ELEMENT_TYPE_U1: byte byteValue = Convert.ToByte(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, byteValue) : byteValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, byteValue) : byteValue; break; case CorElementType.ELEMENT_TYPE_U2: ushort ushortValue = Convert.ToUInt16(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, ushortValue) : ushortValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, ushortValue) : ushortValue; break; case CorElementType.ELEMENT_TYPE_U4: uint uintValue = Convert.ToUInt32(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, uintValue) : uintValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, uintValue) : uintValue; break; case CorElementType.ELEMENT_TYPE_U8: ulong ulongValue = Convert.ToUInt64(srcObject); - dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, (long)ulongValue) : ulongValue; + dstObject = dstEEType->IsEnum ? Enum.ToObject(dstEEType, (long)ulongValue) : ulongValue; break; case CorElementType.ELEMENT_TYPE_R4: - if (srcEEType.CorElementType == CorElementType.ELEMENT_TYPE_CHAR) + if (new EETypePtr(srcEEType).CorElementType == CorElementType.ELEMENT_TYPE_CHAR) { dstObject = (float)(char)srcObject; } @@ -194,7 +196,7 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje break; case CorElementType.ELEMENT_TYPE_R8: - if (srcEEType.CorElementType == CorElementType.ELEMENT_TYPE_CHAR) + if (new EETypePtr(srcEEType).CorElementType == CorElementType.ELEMENT_TYPE_CHAR) { dstObject = (double)(char)srcObject; } @@ -210,11 +212,11 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje return CreateChangeTypeException(srcEEType, dstEEType, semantics); } - Debug.Assert(dstObject.GetEETypePtr() == dstEEType); + Debug.Assert(dstObject.GetMethodTable() == dstEEType); return null; } - private static Exception ConvertPointerIfPossible(object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, out object dstPtr) + private static Exception ConvertPointerIfPossible(object srcObject, MethodTable* dstEEType, CheckArgumentSemantics semantics, out object dstPtr) { if (srcObject is IntPtr or UIntPtr) { @@ -224,7 +226,7 @@ private static Exception ConvertPointerIfPossible(object srcObject, EETypePtr ds if (srcObject is Pointer srcPointer) { - if (dstEEType == typeof(void*).TypeHandle.ToEETypePtr() || RuntimeImports.AreTypesAssignable(pSourceType: srcPointer.GetPointerType().TypeHandle.ToEETypePtr(), pTargetType: dstEEType)) + if (dstEEType == typeof(void*).TypeHandle.ToMethodTable() || RuntimeImports.AreTypesAssignable(pSourceType: srcPointer.GetPointerType().TypeHandle.ToMethodTable(), pTargetType: dstEEType)) { dstPtr = srcPointer.GetPointerValue(); return null; @@ -232,10 +234,10 @@ private static Exception ConvertPointerIfPossible(object srcObject, EETypePtr ds } dstPtr = null; - return CreateChangeTypeException(srcObject.GetEETypePtr(), dstEEType, semantics); + return CreateChangeTypeException(srcObject.GetMethodTable(), dstEEType, semantics); } - private static Exception CreateChangeTypeException(EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics) + private static Exception CreateChangeTypeException(MethodTable* srcEEType, MethodTable* dstEEType, CheckArgumentSemantics semantics) { switch (semantics) { @@ -250,10 +252,10 @@ private static Exception CreateChangeTypeException(EETypePtr srcEEType, EETypePt } } - internal static ArgumentException CreateChangeTypeArgumentException(EETypePtr srcEEType, EETypePtr dstEEType, bool destinationIsByRef = false) + internal static ArgumentException CreateChangeTypeArgumentException(MethodTable* srcEEType, MethodTable* dstEEType, bool destinationIsByRef = false) => CreateChangeTypeArgumentException(srcEEType, Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType)), destinationIsByRef); - internal static ArgumentException CreateChangeTypeArgumentException(EETypePtr srcEEType, Type dstType, bool destinationIsByRef = false) + internal static ArgumentException CreateChangeTypeArgumentException(MethodTable* srcEEType, Type dstType, bool destinationIsByRef = false) { object? destinationTypeName = dstType; if (destinationIsByRef) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs index 057db98ff670a..98d2565a07ee2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -138,10 +138,10 @@ public sealed override int GetHashCode() return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1); } - private MulticastDelegate NewMulticastDelegate(Delegate[] invocationList, int invocationCount, bool thisIsMultiCastAlready = false) + private unsafe MulticastDelegate NewMulticastDelegate(Delegate[] invocationList, int invocationCount, bool thisIsMultiCastAlready = false) { // First, allocate a new multicast delegate just like this one, i.e. same type as the this object - MulticastDelegate result = (MulticastDelegate)RuntimeImports.RhNewObject(this.GetEETypePtr()); + MulticastDelegate result = (MulticastDelegate)RuntimeImports.RhNewObject(this.GetMethodTable()); // Performance optimization - if this already points to a true multicast delegate, // copy _methodPtr and _methodPtrAux fields rather than calling into the EE to get them diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Object.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Object.NativeAot.cs index 1d68cad28ab30..727fbc9fbfdd2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Object.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Object.NativeAot.cs @@ -26,11 +26,11 @@ public Type GetType() } [Intrinsic] - protected internal object MemberwiseClone() + protected internal unsafe object MemberwiseClone() { - object clone = this.GetEETypePtr().IsArray ? - RuntimeImports.RhNewArray(this.GetEETypePtr(), Unsafe.As(this).Length) : - RuntimeImports.RhNewObject(this.GetEETypePtr()); + object clone = this.GetMethodTable()->IsArray ? + RuntimeImports.RhNewArray(this.GetMethodTable(), Unsafe.As(this).Length) : + RuntimeImports.RhNewObject(this.GetMethodTable()); // copy contents of "this" to the clone @@ -38,7 +38,7 @@ protected internal object MemberwiseClone() ref byte src = ref this.GetRawData(); ref byte dst = ref clone.GetRawData(); - if (this.GetEETypePtr().ContainsGCPointers) + if (this.GetMethodTable()->ContainsGCPointers) Buffer.BulkMoveWithWriteBarrier(ref dst, ref src, byteCount); else Buffer.Memmove(ref dst, ref src, byteCount); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs index 4f2e51afe59da..012e410885b8e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs @@ -7,10 +7,12 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Internal.Runtime; + namespace System.Reflection { // caches information required for efficient argument validation and type coercion for reflection Invoke. - public class DynamicInvokeInfo + public unsafe class DynamicInvokeInfo { // Public state public MethodBase Method { get; } @@ -22,7 +24,7 @@ public class DynamicInvokeInfo // private readonly bool _isValueTypeInstanceMethod; private readonly bool _needsCopyBack; private readonly Transform _returnTransform; - private readonly EETypePtr _returnType; + private readonly MethodTable* _returnType; private readonly ArgumentInfo[] _arguments; // We use negative argument count to signal unsupported invoke signatures @@ -40,19 +42,19 @@ private enum Transform AllocateReturnBox = 0x0020, } - private readonly struct ArgumentInfo + private readonly unsafe struct ArgumentInfo { - internal ArgumentInfo(Transform transform, EETypePtr type) + internal ArgumentInfo(Transform transform, MethodTable* type) { Transform = transform; Type = type; } internal Transform Transform { get; } - internal EETypePtr Type { get; } + internal MethodTable* Type { get; } } - public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) + public unsafe DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) { Method = method; InvokeThunk = invokeThunk; @@ -83,26 +85,26 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) // This can return a null MethodTable for reference types. // The compiler makes sure it returns a non-null MT for everything else. - EETypePtr eeArgumentType = argumentType.ToEETypePtrMayBeNull(); + MethodTable* eeArgumentType = argumentType.ToMethodTableMayBeNull(); if (argumentType.IsValueType) { - Debug.Assert(eeArgumentType.IsValueType); + Debug.Assert(eeArgumentType->IsValueType); - if (eeArgumentType.IsByRefLike) + if (eeArgumentType->IsByRefLike) _argumentCount = ArgumentCount_NotSupported_ByRefLike; - if (eeArgumentType.IsNullable) + if (eeArgumentType->IsNullable) transform |= Transform.Nullable; } else if (argumentType.IsPointer) { - Debug.Assert(eeArgumentType.IsPointer); + Debug.Assert(eeArgumentType->IsPointer); transform |= Transform.Pointer; } else if (argumentType.IsFunctionPointer) { - Debug.Assert(eeArgumentType.IsFunctionPointer); + Debug.Assert(eeArgumentType->IsFunctionPointer); transform |= Transform.FunctionPointer; } @@ -128,20 +130,20 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) } Debug.Assert(!returnType.IsByRef); - EETypePtr eeReturnType = returnType.ToEETypePtrMayBeNull(); + MethodTable* eeReturnType = returnType.ToMethodTableMayBeNull(); if (returnType.IsValueType) { - Debug.Assert(eeReturnType.IsValueType); + Debug.Assert(eeReturnType->IsValueType); if (returnType != typeof(void)) { - if (eeReturnType.IsByRefLike) + if (eeReturnType->IsByRefLike) _argumentCount = ArgumentCount_NotSupported_ByRefLike; if ((transform & Transform.ByRef) == 0) transform |= Transform.AllocateReturnBox; - if (eeReturnType.IsNullable) + if (eeReturnType->IsNullable) transform |= Transform.Nullable; } else @@ -152,7 +154,7 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) } else if (returnType.IsPointer) { - Debug.Assert(eeReturnType.IsPointer); + Debug.Assert(eeReturnType->IsPointer); transform |= Transform.Pointer; if ((transform & Transform.ByRef) == 0) @@ -160,7 +162,7 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) } else if (returnType.IsFunctionPointer) { - Debug.Assert(eeReturnType.IsFunctionPointer); + Debug.Assert(eeReturnType->IsFunctionPointer); transform |= Transform.FunctionPointer; if ((transform & Transform.ByRef) == 0) @@ -217,7 +219,7 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) { returnObject = RuntimeImports.RhNewObject( (_returnTransform & (Transform.Pointer | Transform.FunctionPointer)) != 0 ? - EETypePtr.EETypePtrOf() : _returnType); + MethodTable.Of() : _returnType); ret = ref returnObject.GetRawData(); } @@ -285,7 +287,7 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) { returnObject = RuntimeImports.RhNewObject( (_returnTransform & (Transform.Pointer | Transform.FunctionPointer)) != 0 ? - EETypePtr.EETypePtrOf() : _returnType); + MethodTable.Of() : _returnType); ret = ref returnObject.GetRawData(); } @@ -351,7 +353,7 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk) { returnObject = RuntimeImports.RhNewObject( (_returnTransform & (Transform.Pointer | Transform.FunctionPointer)) != 0 ? - EETypePtr.EETypePtrOf() : _returnType); + MethodTable.Of() : _returnType); ret = ref returnObject.GetRawData(); } @@ -587,17 +589,17 @@ private unsafe ref byte InvokeDirectWithFewArguments( { // In case if the parameter is nullable Enum type the ParameterInfo.DefaultValue returns a raw value which // needs to be parsed to the Enum type, for more info: https://github.com/dotnet/runtime/issues/12924 - EETypePtr nullableType = argumentInfo.Type.NullableType; - if (nullableType.IsEnum) + MethodTable* nullableType = argumentInfo.Type->NullableType; + if (nullableType->IsEnum) { - defaultValue = Enum.ToObject(Type.GetTypeFromMethodTable(nullableType.ToPointer()), defaultValue); + defaultValue = Enum.ToObject(Type.GetTypeFromMethodTable(nullableType), defaultValue); } } return defaultValue; } - private void ThrowForNeverValidNonNullArgument(EETypePtr srcEEType, int index) + private void ThrowForNeverValidNonNullArgument(MethodTable* srcEEType, int index) { Debug.Assert(index != 0 || _isStatic); throw InvokeUtils.CreateChangeTypeArgumentException(srcEEType, Method.GetParametersAsSpan()[index - (_isStatic ? 0 : 1)].ParameterType, destinationIsByRef: false); @@ -622,7 +624,7 @@ private unsafe void CheckArguments( if ((argumentInfo.Transform & Transform.Reference) == 0) arg = RuntimeImports.RhNewObject( (argumentInfo.Transform & (Transform.Pointer | Transform.FunctionPointer)) != 0 ? - EETypePtr.EETypePtrOf() : argumentInfo.Type); + MethodTable.Of() : argumentInfo.Type); } else { @@ -639,20 +641,20 @@ private unsafe void CheckArguments( goto Again; // Redo the argument handling to deal with null } - EETypePtr srcEEType = arg.GetEETypePtr(); - EETypePtr dstEEType = argumentInfo.Type; + MethodTable* srcEEType = arg.GetMethodTable(); + MethodTable* dstEEType = argumentInfo.Type; - if (srcEEType.RawValue != dstEEType.RawValue) + if (srcEEType != dstEEType) { // Destination type can be null if we don't have a MethodTable for this type. This means one cannot // possibly pass a valid non-null object instance here. - if (dstEEType.IsNull) + if (dstEEType == null) { ThrowForNeverValidNonNullArgument(srcEEType, i); } if (!(RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) || - (dstEEType.IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable + (dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable && castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false)))) { // ByRefs have to be exact match @@ -712,24 +714,24 @@ private unsafe void CheckArguments( if ((argumentInfo.Transform & Transform.Reference) == 0) arg = RuntimeImports.RhNewObject( (argumentInfo.Transform & (Transform.Pointer | Transform.FunctionPointer)) != 0 ? - EETypePtr.EETypePtrOf() : argumentInfo.Type); + MethodTable.Of() : argumentInfo.Type); } else { - EETypePtr srcEEType = arg.GetEETypePtr(); - EETypePtr dstEEType = argumentInfo.Type; + MethodTable* srcEEType = arg.GetMethodTable(); + MethodTable* dstEEType = argumentInfo.Type; - if (srcEEType.RawValue != dstEEType.RawValue) + if (srcEEType != dstEEType) { // Destination type can be null if we don't have a MethodTable for this type. This means one cannot // possibly pass a valid non-null object instance here. - if (dstEEType.IsNull) + if (dstEEType == null) { ThrowForNeverValidNonNullArgument(srcEEType, i); } if (!(RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) || - (dstEEType.IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable + (dstEEType->IsInterface && arg is System.Runtime.InteropServices.IDynamicInterfaceCastable castable && castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false)))) { // ByRefs have to be exact match @@ -789,14 +791,14 @@ private unsafe void CopyBackToArray(ref object? src, object?[] dest) { if ((transform & Transform.Pointer) != 0) { - Type type = Type.GetTypeFromMethodTable(argumentInfo.Type.ToPointer()); + Type type = Type.GetTypeFromMethodTable(argumentInfo.Type); Debug.Assert(type.IsPointer); obj = Pointer.Box((void*)Unsafe.As(ref obj.GetRawData()), type); } else { obj = RuntimeImports.RhBox( - (transform & Transform.FunctionPointer) != 0 ? EETypePtr.EETypePtrOf() : argumentInfo.Type, + (transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type, ref obj.GetRawData()); } } @@ -824,14 +826,14 @@ private unsafe void CopyBackToSpan(Span src, Span dest) { if ((transform & Transform.Pointer) != 0) { - Type type = Type.GetTypeFromMethodTable(argumentInfo.Type.ToPointer()); + Type type = Type.GetTypeFromMethodTable(argumentInfo.Type); Debug.Assert(type.IsPointer); obj = Pointer.Box((void*)Unsafe.As(ref obj.GetRawData()), type); } else { obj = RuntimeImports.RhBox( - (transform & Transform.FunctionPointer) != 0 ? EETypePtr.EETypePtrOf() : argumentInfo.Type, + (transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type, ref obj.GetRawData()); } } @@ -854,14 +856,14 @@ private unsafe object ReturnTransform(ref byte byref, bool wrapInTargetInvocatio object obj; if ((_returnTransform & Transform.Pointer) != 0) { - Type type = Type.GetTypeFromMethodTable(_returnType.ToPointer()); + Type type = Type.GetTypeFromMethodTable(_returnType); Debug.Assert(type.IsPointer); obj = Pointer.Box((void*)Unsafe.As(ref byref), type); } else if ((_returnTransform & Transform.FunctionPointer) != 0) { - Debug.Assert(Type.GetTypeFromMethodTable(_returnType.ToPointer()).IsFunctionPointer); - obj = RuntimeImports.RhBox(EETypePtr.EETypePtrOf(), ref byref); + Debug.Assert(Type.GetTypeFromMethodTable(_returnType).IsFunctionPointer); + obj = RuntimeImports.RhBox(MethodTable.Of(), ref byref); } else if ((_returnTransform & Transform.Reference) != 0) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs index 3342337435419..262ddb9857b75 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs @@ -59,19 +59,19 @@ public static void RunModuleConstructor(ModuleHandle module) } [return: NotNullIfNotNull(nameof(obj))] - public static object? GetObjectValue(object? obj) + public static unsafe object? GetObjectValue(object? obj) { if (obj == null) return null; - EETypePtr eeType = obj.GetEETypePtr(); - if ((!eeType.IsValueType) || eeType.IsPrimitive) + MethodTable* eeType = obj.GetMethodTable(); + if ((!eeType->IsValueType) || eeType->IsPrimitive) return obj; return obj.MemberwiseClone(); } - public static new bool Equals(object? o1, object? o2) + public static new unsafe bool Equals(object? o1, object? o2) { if (o1 == o2) return true; @@ -80,11 +80,11 @@ public static void RunModuleConstructor(ModuleHandle module) return false; // If it's not a value class, don't compare by value - if (!o1.GetEETypePtr().IsValueType) + if (!o1.GetMethodTable()->IsValueType) return false; // Make sure they are the same type. - if (o1.GetEETypePtr() != o2.GetEETypePtr()) + if (o1.GetMethodTable() != o2.GetMethodTable()) return false; return RuntimeImports.RhCompareObjectContentsAndPadding(o1, o2); @@ -182,17 +182,16 @@ public static unsafe bool TryEnsureSufficientExecutionStack() } [Intrinsic] - public static bool IsReferenceOrContainsReferences() + public static unsafe bool IsReferenceOrContainsReferences() { - var pEEType = EETypePtr.EETypePtrOf(); - return !pEEType.IsValueType || pEEType.ContainsGCPointers; + MethodTable* pEEType = MethodTable.Of(); + return !pEEType->IsValueType || pEEType->ContainsGCPointers; } [Intrinsic] - internal static bool IsReference() + internal static unsafe bool IsReference() { - var pEEType = EETypePtr.EETypePtrOf(); - return !pEEType.IsValueType; + return !MethodTable.Of()->IsValueType; } [Intrinsic] @@ -232,9 +231,6 @@ internal static unsafe ushort GetElementSize(this Array array) internal static unsafe ref MethodTable* GetMethodTableRef(this object obj) => ref obj.m_pEEType; - internal static unsafe EETypePtr GetEETypePtr(this object obj) - => new EETypePtr(obj.m_pEEType); - // Returns true iff the object has a component size; // i.e., is variable length like System.String or Array. [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -350,7 +346,7 @@ public static unsafe object GetUninitializedObject( throw ReflectionCoreExecution.ExecutionEnvironment.CreateMissingMetadataException(type); } // Paranoid check: not-meant-for-GC-heap types should be reliably identifiable by empty vtable. - Debug.Assert(!mt->ContainsGCPointers || RuntimeImports.RhGetGCDescSize(new EETypePtr(mt)) != 0); + Debug.Assert(!mt->ContainsGCPointers || RuntimeImports.RhGetGCDescSize(mt) != 0); if (mt->IsNullable) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs index 4d404018b0a07..4d156c039422a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs @@ -9,6 +9,8 @@ using System.Runtime.Versioning; using System.Threading; +using Internal.Runtime; + namespace System.Runtime.InteropServices { /// @@ -417,7 +419,7 @@ internal sealed unsafe class ManagedObjectWrapperHolder static ManagedObjectWrapperHolder() { delegate* unmanaged callback = &IsRootedCallback; - if (!RuntimeImports.RhRegisterRefCountedHandleCallback((nint)callback, EETypePtr.EETypePtrOf())) + if (!RuntimeImports.RhRegisterRefCountedHandleCallback((nint)callback, MethodTable.Of())) { throw new OutOfMemoryException(); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs index a371386010cee..2b03b2b92806d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs @@ -15,37 +15,30 @@ namespace System.Runtime.InteropServices /// /// Hooks for interop code to access internal functionality in System.Private.CoreLib.dll. /// - internal static class InteropExtensions + internal static unsafe class InteropExtensions { - internal static bool MightBeBlittable(this EETypePtr eeType) + internal static bool MightBeBlittable(this RuntimeTypeHandle handle) { // // This is used as the approximate implementation of MethodTable::IsBlittable(). It will err in the direction of declaring // things blittable since it is used for argument validation only. // - return !eeType.ContainsGCPointers; + return !handle.ToMethodTable()->ContainsGCPointers; } public static bool IsBlittable(this RuntimeTypeHandle handle) { - return handle.ToEETypePtr().MightBeBlittable(); - } - - public static bool IsBlittable(this object obj) - { - return obj.GetEETypePtr().MightBeBlittable(); + return handle.MightBeBlittable(); } public static bool IsGenericType(this RuntimeTypeHandle handle) { - EETypePtr eeType = handle.ToEETypePtr(); - return eeType.IsGeneric; + return handle.ToMethodTable()->IsGeneric; } public static bool IsGenericTypeDefinition(this RuntimeTypeHandle handle) { - EETypePtr eeType = handle.ToEETypePtr(); - return eeType.IsGenericTypeDefinition; + return handle.ToMethodTable()->IsGenericTypeDefinition; } // @@ -65,32 +58,32 @@ public static IntPtr GetRawFunctionPointerForOpenStaticDelegate(this Delegate de public static int GetValueTypeSize(this RuntimeTypeHandle handle) { - return (int)handle.ToEETypePtr().ValueTypeSize; + return (int)handle.ToMethodTable()->ValueTypeSize; } public static bool IsValueType(this RuntimeTypeHandle handle) { - return handle.ToEETypePtr().IsValueType; + return handle.ToMethodTable()->IsValueType; } public static bool IsEnum(this RuntimeTypeHandle handle) { - return handle.ToEETypePtr().IsEnum; + return handle.ToMethodTable()->IsEnum; } public static bool IsInterface(this RuntimeTypeHandle handle) { - return handle.ToEETypePtr().IsInterface; + return handle.ToMethodTable()->IsInterface; } public static bool AreTypesAssignable(RuntimeTypeHandle sourceType, RuntimeTypeHandle targetType) { - return RuntimeImports.AreTypesAssignable(sourceType.ToEETypePtr(), targetType.ToEETypePtr()); + return RuntimeImports.AreTypesAssignable(sourceType.ToMethodTable(), targetType.ToMethodTable()); } public static RuntimeTypeHandle GetTypeHandle(this object target) { - return new RuntimeTypeHandle(target.GetEETypePtr()); + return new RuntimeTypeHandle(target.GetMethodTable()); } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs index 80761d024050e..0f3c321d5cf36 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs @@ -49,9 +49,9 @@ public static IntPtr OffsetOf(Type t, string fieldName) return new IntPtr(RuntimeInteropData.GetStructFieldOffset(t.TypeHandle, fieldName)); } - private static void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses) + private static unsafe void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses) { - if (!allowValueClasses && structure.GetEETypePtr().IsValueType) + if (!allowValueClasses && structure.GetMethodTable()->IsValueType) { throw new ArgumentException(SR.Argument_StructMustNotBeValueClass, nameof(structure)); } @@ -204,9 +204,9 @@ public static void SetLastPInvokeError(int error) PInvokeMarshal.t_lastError = error; } - internal static bool IsPinnable(object o) + internal static unsafe bool IsPinnable(object o) { - return (o == null) || !o.GetEETypePtr().ContainsGCPointers; + return (o == null) || !o.GetMethodTable()->ContainsGCPointers; } [EditorBrowsable(EditorBrowsableState.Never)] @@ -269,7 +269,7 @@ private static unsafe T ReadValueSlow(object ptr, int ofs, delegate*IsArray || ptr is string || ptr is StringBuilder) { @@ -349,7 +349,7 @@ private static unsafe void WriteValueSlow(object ptr, int ofs, T val, delegat throw new AccessViolationException(); } - if (ptr.GetEETypePtr().IsArray || + if (ptr.GetMethodTable()->IsArray || ptr is string || ptr is StringBuilder) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ObjectiveCMarshal.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ObjectiveCMarshal.NativeAot.cs index 88bcba537f932..ccb969f172801 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ObjectiveCMarshal.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ObjectiveCMarshal.NativeAot.cs @@ -131,7 +131,7 @@ private static IntPtr CreateReferenceTrackingHandleInternal( throw new InvalidOperationException(SR.InvalidOperation_ObjectiveCMarshalNotInitialized); } - if (!obj.GetEETypePtr().IsTrackedReferenceWithFinalizer) + if (!obj.GetMethodTable()->IsTrackedReferenceWithFinalizer) { throw new InvalidOperationException(SR.InvalidOperation_ObjectiveCTypeNoFinalizer); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs index 25800445c62ba..2b011f0161466 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading; +using Internal.Runtime; using Internal.Runtime.Augments; using Internal.Runtime.CompilerHelpers; using Internal.Runtime.CompilerServices; @@ -46,13 +47,13 @@ public static int GetHRForException(Exception e) /// Return the stub to the pinvoke marshalling stub /// /// The delegate - public static IntPtr GetFunctionPointerForDelegate(Delegate del) + public static unsafe IntPtr GetFunctionPointerForDelegate(Delegate del) { if (del == null) return IntPtr.Zero; #pragma warning disable CA2208 // Instantiate argument exceptions correctly - if (del.GetEETypePtr().IsGeneric) + if (del.GetMethodTable()->IsGeneric) throw new ArgumentException(SR.Argument_NeedNonGenericType, "delegate"); #pragma warning restore CA2208 @@ -234,7 +235,7 @@ private static PInvokeDelegateThunk AllocateThunk(Delegate del) // NativeFunctionPointerWrapper derived class // #pragma warning disable CA2208 // Instantiate argument exceptions correctly - if (delegateType.ToEETypePtr().BaseType != EETypePtr.EETypePtrOf()) + if (delegateType.ToMethodTable()->BaseType != MethodTable.Of()) throw new ArgumentException(SR.Arg_MustBeDelegate, "t"); #pragma warning restore CA2208 diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 05f48424e5916..3b88cedcf3e1d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -386,9 +386,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) [RuntimeImport(RuntimeLibrary, "RhTypeCast_AreTypesAssignable")] internal static extern unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType); - internal static unsafe bool AreTypesAssignable(EETypePtr pSourceType, EETypePtr pTargetType) - => AreTypesAssignable(pSourceType.ToPointer(), pTargetType.ToPointer()); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_CheckArrayStore")] internal static extern void RhCheckArrayStore(object array, object? obj); @@ -397,9 +394,6 @@ internal static unsafe bool AreTypesAssignable(EETypePtr pSourceType, EETypePtr [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOfAny")] internal static extern unsafe object IsInstanceOf(MethodTable* pTargetType, object obj); - internal static unsafe object IsInstanceOf(EETypePtr pTargetType, object obj) - => IsInstanceOf(pTargetType.ToPointer(), obj); - // // calls to runtime for allocation // These calls are needed in types which cannot use "new" to allocate and need to do it manually @@ -414,36 +408,21 @@ internal static unsafe object IsInstanceOf(EETypePtr pTargetType, object obj) [RuntimeImport(RuntimeLibrary, "RhNewObject")] internal static extern unsafe object RhNewObject(MethodTable* pEEType); - internal static unsafe object RhNewObject(EETypePtr pEEType) - => RhNewObject(pEEType.ToPointer()); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewArray")] - private static extern unsafe Array RhNewArray(MethodTable* pEEType, int length); - - internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) - => RhNewArray(pEEType.ToPointer(), length); + internal static extern unsafe Array RhNewArray(MethodTable* pEEType, int length); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); - internal static unsafe string RhNewString(EETypePtr pEEType, int length) - => RhNewString(pEEType.ToPointer(), length); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhBox")] internal static extern unsafe object RhBox(MethodTable* pEEType, ref byte data); - internal static unsafe object RhBox(EETypePtr pEEType, ref byte data) - => RhBox(pEEType.ToPointer(), ref data); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhUnbox")] - private static extern unsafe void RhUnbox(object? obj, ref byte data, MethodTable* pUnboxToEEType); - - internal static unsafe void RhUnbox(object? obj, ref byte data, EETypePtr pUnboxToEEType) - => RhUnbox(obj, ref data, pUnboxToEEType.ToPointer()); + internal static extern unsafe void RhUnbox(object? obj, ref byte data, MethodTable* pUnboxToEEType); // Busy spin for the given number of iterations. [LibraryImport(RuntimeLibrary, EntryPoint = "RhSpinWait")] @@ -489,15 +468,15 @@ internal static unsafe int RhCompatibleReentrantWaitAny(bool alertable, int time [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhGetGCDescSize")] - internal static extern int RhGetGCDescSize(EETypePtr eeType); + internal static extern unsafe int RhGetGCDescSize(MethodTable* eeType); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewInterfaceDispatchCell")] - internal static extern unsafe IntPtr RhNewInterfaceDispatchCell(EETypePtr pEEType, int slotNumber); + internal static extern unsafe IntPtr RhNewInterfaceDispatchCell(MethodTable* pEEType, int slotNumber); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhResolveDispatch")] - internal static extern IntPtr RhResolveDispatch(object pObject, EETypePtr pInterfaceType, ushort slot); + internal static extern unsafe IntPtr RhResolveDispatch(object pObject, MethodTable* pInterfaceType, ushort slot); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhpResolveInterfaceMethod")] @@ -505,16 +484,16 @@ internal static unsafe int RhCompatibleReentrantWaitAny(bool alertable, int time [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhResolveDispatchOnType")] - internal static extern unsafe IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr interfaceType, ushort slot, EETypePtr* pGenericContext); + internal static extern unsafe IntPtr RhResolveDispatchOnType(MethodTable* instanceType, MethodTable* interfaceType, ushort slot, MethodTable** pGenericContext); - internal static unsafe IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr interfaceType, ushort slot) + internal static unsafe IntPtr RhResolveDispatchOnType(MethodTable* instanceType, MethodTable* interfaceType, ushort slot) { return RhResolveDispatchOnType(instanceType, interfaceType, slot, null); } [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhGetRuntimeHelperForType")] - internal static extern unsafe IntPtr RhGetRuntimeHelperForType(EETypePtr pEEType, RuntimeHelperKind kind); + internal static extern unsafe IntPtr RhGetRuntimeHelperForType(MethodTable* pEEType, RuntimeHelperKind kind); // // Support for GC and HandleTable callouts. @@ -538,11 +517,11 @@ internal enum GcRestrictedCalloutKind [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhRegisterRefCountedHandleCallback")] - internal static extern bool RhRegisterRefCountedHandleCallback(IntPtr pCalloutMethod, EETypePtr pTypeFilter); + internal static extern unsafe bool RhRegisterRefCountedHandleCallback(IntPtr pCalloutMethod, MethodTable* pTypeFilter); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhUnregisterRefCountedHandleCallback")] - internal static extern void RhUnregisterRefCountedHandleCallback(IntPtr pCalloutMethod, EETypePtr pTypeFilter); + internal static extern unsafe void RhUnregisterRefCountedHandleCallback(IntPtr pCalloutMethod, MethodTable* pTypeFilter); #if FEATURE_OBJCMARSHAL [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs index fb8db35f2d269..c5d13a97abd3f 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/TypeLoaderExports.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Threading; +using Internal.Runtime; using Internal.Runtime.Augments; namespace System.Runtime @@ -106,7 +107,7 @@ private static unsafe IntPtr GVMLookupForSlotSlow(object obj, RuntimeMethodHandl { Value v = CacheMiss((IntPtr)obj.GetMethodTable(), RuntimeMethodHandle.ToIntPtr(slot), (IntPtr context, IntPtr signature, object contextObject, ref IntPtr auxResult) - => RuntimeAugments.TypeLoaderCallbacks.ResolveGenericVirtualMethodTarget(new RuntimeTypeHandle(new EETypePtr(context)), *(RuntimeMethodHandle*)&signature)); + => RuntimeAugments.TypeLoaderCallbacks.ResolveGenericVirtualMethodTarget(new RuntimeTypeHandle((MethodTable*)context), *(RuntimeMethodHandle*)&signature)); return v._result; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs index e9fca05ca8012..bb9cd160986db 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs @@ -52,7 +52,7 @@ internal void Free() private static bool DoNotThrowForAssembly => AppContext.TryGetSwitch("Switch.System.Reflection.Disabled.DoNotThrowForAssembly", out bool doNotThrow) && doNotThrow; private static bool DoNotThrowForAttributes => AppContext.TryGetSwitch("Switch.System.Reflection.Disabled.DoNotThrowForAttributes", out bool doNotThrow) && doNotThrow; - internal EETypePtr ToEETypePtrMayBeNull() => new EETypePtr(_pUnderlyingEEType); + internal MethodTable* ToMethodTableMayBeNull() => _pUnderlyingEEType; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal RuntimeTypeInfo GetRuntimeTypeInfo() @@ -161,13 +161,13 @@ public override bool IsEnumDefined(object value) if (value is Enum) { - if (value.GetEETypePtr() != this.ToEETypePtrMayBeNull()) + if (value.GetMethodTable() != this.ToMethodTableMayBeNull()) throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, value.GetType(), this)); } else { Type underlyingType = Enum.InternalGetUnderlyingType(this); - if (!(underlyingType.TypeHandle.ToEETypePtr() == value.GetEETypePtr())) + if (!(underlyingType.TypeHandle.ToMethodTable() == value.GetMethodTable())) throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, value.GetType(), underlyingType)); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index cf48b0aedc754..06c61be08a8ff 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -21,9 +21,6 @@ public unsafe struct RuntimeTypeHandle : IEquatable, ISeriali internal unsafe RuntimeTypeHandle(MethodTable* pEEType) => _value = (IntPtr)pEEType; - internal RuntimeTypeHandle(EETypePtr pEEType) - => _value = pEEType.RawValue; - private RuntimeTypeHandle(IntPtr value) => _value = value; @@ -36,12 +33,12 @@ public override bool Equals(object? obj) return false; } - public override int GetHashCode() + public override unsafe int GetHashCode() { if (IsNull) return 0; - return this.ToEETypePtr().GetHashCode(); + return (int)this.ToMethodTable()->HashCode; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -100,12 +97,6 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) throw new PlatformNotSupportedException(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EETypePtr ToEETypePtr() - { - return new EETypePtr(_value); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal MethodTable* ToMethodTable() { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs index 5e9344ea29192..a8efc76018a30 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs @@ -5,6 +5,8 @@ using System.Runtime; using System.Runtime.CompilerServices; +using Internal.Runtime; + namespace System { // This class is marked EagerStaticClassConstruction because it's nice to have this @@ -16,12 +18,12 @@ public partial class String [Intrinsic] public static readonly string Empty = ""; - internal static string FastAllocateString(int length) + internal static unsafe string FastAllocateString(int length) { // We allocate one extra char as an interop convenience so that our strings are null- // terminated, however, we don't pass the extra +1 to the string allocation because the base // size of this object includes the _firstChar field. - string newStr = RuntimeImports.RhNewString(EETypePtr.EETypePtrOf(), length); + string newStr = RuntimeImports.RhNewString(MethodTable.Of(), length); Debug.Assert(newStr._stringLength == length); return newStr; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs index ad29037c586da..3b209cd489c44 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs @@ -7,6 +7,7 @@ using System.Runtime.InteropServices; using Internal.Reflection.Augments; +using Internal.Runtime; using Internal.Runtime.CompilerServices; namespace System @@ -47,20 +48,20 @@ internal static RuntimeTypeHandle RawTargetTypeToken(TypedReference value) return value._typeHandle; } - public static object ToObject(TypedReference value) + public static unsafe object ToObject(TypedReference value) { RuntimeTypeHandle typeHandle = value._typeHandle; if (typeHandle.IsNull) ThrowHelper.ThrowArgumentException_ArgumentNull_TypedRefType(); - EETypePtr eeType = typeHandle.ToEETypePtr(); - if (eeType.IsValueType) + MethodTable* eeType = typeHandle.ToMethodTable(); + if (eeType->IsValueType) { return RuntimeImports.RhBox(eeType, ref value.Value); } - else if (eeType.IsPointer || eeType.IsFunctionPointer) + else if (eeType->IsPointer || eeType->IsFunctionPointer) { - return RuntimeImports.RhBox(EETypePtr.EETypePtrOf(), ref value.Value); + return RuntimeImports.RhBox(MethodTable.Of(), ref value.Value); } else { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs index 4a3ad1e546c7b..e8340e4119151 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs @@ -49,7 +49,7 @@ internal virtual unsafe int __GetFieldHelper(int index, out MethodTable* mt) public override unsafe bool Equals([NotNullWhen(true)] object? obj) { - if (obj == null || obj.GetEETypePtr() != this.GetEETypePtr()) + if (obj == null || obj.GetMethodTable() != this.GetMethodTable()) return false; int numFields = __GetFieldHelper(GetNumFields, out _); @@ -60,10 +60,10 @@ public override unsafe bool Equals([NotNullWhen(true)] object? obj) if (numFields == UseFastHelper) { // Sanity check - if there are GC references, we should not be comparing bytes - Debug.Assert(!this.GetEETypePtr().ContainsGCPointers); + Debug.Assert(!this.GetMethodTable()->ContainsGCPointers); // Compare the memory - int valueTypeSize = (int)this.GetEETypePtr().ValueTypeSize; + int valueTypeSize = (int)this.GetMethodTable()->ValueTypeSize; return SpanHelpers.SequenceEqual(ref thisRawData, ref thatRawData, valueTypeSize); } else @@ -93,9 +93,9 @@ public override unsafe bool Equals([NotNullWhen(true)] object? obj) return true; } - public override int GetHashCode() + public override unsafe int GetHashCode() { - int hashCode = this.GetEETypePtr().GetHashCode(); + int hashCode = (int)this.GetMethodTable()->HashCode; hashCode ^= GetHashCodeImpl(); diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index 70d82828cd008..539418fc76c30 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -76,16 +76,10 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [RuntimeImport(RuntimeLibrary, "RhNewObject")] private static extern unsafe object RhNewObject(MethodTable* pEEType); - internal static unsafe object RhNewObject(EETypePtr pEEType) - => RhNewObject(pEEType.ToPointer()); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewArray")] private static extern unsafe Array RhNewArray(MethodTable* pEEType, int length); - internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) - => RhNewArray(pEEType.ToPointer(), length); - [DllImport(RuntimeLibrary)] internal static extern unsafe void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj index 1b61079464ee8..ec2e93c06ad04 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj +++ b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj @@ -160,9 +160,6 @@ Runtime.Base\src\System\Runtime\CompilerServices\IsByRefLikeAttribute.cs - - System\EETypePtr.cs - System\Runtime\ExceptionIDs.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index bd4595f45137c..7ae867370bdf4 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -1354,13 +1354,12 @@ private static bool IsActivatorAllocatorOf(MethodDesc method) private static bool IsEETypePtrOf(MethodDesc method) { - if (method.IsIntrinsic && (method.Name == "EETypePtrOf" || method.Name == "Of") && method.Instantiation.Length == 1) + if (method.IsIntrinsic && method.Name == "Of" && method.Instantiation.Length == 1) { MetadataType owningType = method.OwningType as MetadataType; if (owningType != null) { - return (owningType.Name == "EETypePtr" && owningType.Namespace == "System") - || (owningType.Name == "MethodTable" && owningType.Namespace == "Internal.Runtime"); + return owningType.Name == "MethodTable" && owningType.Namespace == "Internal.Runtime"; } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index b00f3f00a4737..e21640cbdbc24 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1824,7 +1824,6 @@ private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, switch (method.Name) { - case "EETypePtrOf": case "Of": ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, ref pResult.lookup); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_CLASS;