From 5c4fda60d6129c925169fd9fe2596e486fc0ebcf Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 13:50:32 -0800 Subject: [PATCH 01/12] Convert RuntimeMethodHandle.GetDeclaringType() to managed and QCall. --- .../src/System/RuntimeHandles.cs | 30 ++++++++--- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 50 +++++++++++-------- src/coreclr/vm/runtimehandles.h | 3 +- 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index bacbdcb2e92159..ecb70072c6cc78 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -30,7 +30,8 @@ internal RuntimeType GetTypeChecked() => /// /// An IntPtr handle to a RuntimeType to create a object from. /// A new object that corresponds to the value parameter. - public static RuntimeTypeHandle FromIntPtr(IntPtr value) => new RuntimeTypeHandle(GetTypeFromHandle(value)); + public static RuntimeTypeHandle FromIntPtr(IntPtr value) => + new RuntimeTypeHandle(value == IntPtr.Zero ? null : GetRuntimeTypeFromHandle(value)); [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetTypeFromHandleSlow")] private static partial void GetTypeFromHandleSlow( @@ -48,13 +49,8 @@ private static RuntimeType GetTypeFromHandleSlow(IntPtr handle) [MethodImpl(MethodImplOptions.InternalCall)] private static extern RuntimeType? GetTypeFromHandleIfExists(IntPtr handle); - private static RuntimeType? GetTypeFromHandle(IntPtr handle) + internal static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle) { - if (handle == IntPtr.Zero) - { - return null; - } - return GetTypeFromHandleIfExists(handle) ?? GetTypeFromHandleSlow(handle); } @@ -928,7 +924,25 @@ internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNam } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method); + private static extern unsafe MethodTable* GetMethodTable(RuntimeMethodHandleInternal method); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetHandleForArray")] + private static unsafe partial IntPtr GetHandleForArray(MethodTable* pMT); + + internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method) + { + Debug.Assert(!method.IsNullHandle()); + MethodTable* pMT = GetMethodTable(method); + if (pMT->IsArray) + { + IntPtr handle = GetHandleForArray(pMT); + return RuntimeTypeHandle.GetRuntimeTypeFromHandle(handle); + } + else + { + return RuntimeTypeHandle.GetRuntimeType(pMT); + } + } internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method) { diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index c9649c31e9e168..1c39a8a256836c 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -152,7 +152,7 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("ReboxToNullable", RuntimeMethodHandle::ReboxToNullable) FCFuncElement("GetImplAttributes", RuntimeMethodHandle::GetImplAttributes) FCFuncElement("GetAttributes", RuntimeMethodHandle::GetAttributes) - FCFuncElement("GetDeclaringType", RuntimeMethodHandle::GetDeclaringType) + FCFuncElement("GetMethodTable", RuntimeMethodHandle::GetMethodTable) FCFuncElement("GetSlot", RuntimeMethodHandle::GetSlot) FCFuncElement("GetMethodDef", RuntimeMethodHandle::GetMethodDef) FCFuncElement("GetUtf8NameInternal", RuntimeMethodHandle::GetUtf8Name) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 5aca38c2208c31..95b1f7348abbc0 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -144,6 +144,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_ConstructInstantiation) DllImportEntry(RuntimeMethodHandle_GetFunctionPointer) DllImportEntry(RuntimeMethodHandle_GetIsCollectible) + DllImportEntry(RuntimeMethodHandle_GetHandleForArray) DllImportEntry(RuntimeMethodHandle_GetMethodInstantiation) DllImportEntry(RuntimeMethodHandle_GetTypicalMethodDefinition) DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 1712c0a34c2897..9f3784871f81f1 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1462,7 +1462,7 @@ extern "C" void * QCALLTYPE RuntimeMethodHandle_GetFunctionPointer(MethodDesc * return funcPtr; } -extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMethod) +extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc* pMethod) { QCALL_CONTRACT; @@ -1477,6 +1477,27 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMet return isCollectible; } +extern "C" TADDR QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT) +{ + QCALL_CONTRACT; + _ASSERTE(pMT != NULL); + _ASSERTE(pMT->IsArray()); + + TypeHandle declType; + + BEGIN_QCALL; + + // Load the TypeDesc for the array type. Note the returned type is approximate, i.e. + // if shared between reference array types then we will get object[] back. + DWORD rank = pMT->GetRank(); + TypeHandle elemType = pMT->GetArrayElementTypeHandle(); + declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank); + + END_QCALL; + + return declType.AsTAddr(); +} + FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc* pMethod) { CONTRACTL @@ -1522,31 +1543,16 @@ FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMet } FCIMPLEND - -FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) { - CONTRACTL { +FCIMPL1(MethodTable*, RuntimeMethodHandle::GetMethodTable, MethodDesc *pMethod) +{ + CONTRACTL + { FCALL_CHECK; - PRECONDITION(CheckPointer(pMethod)); + PRECONDITION(pMethod != NULL); } CONTRACTL_END; - if (!pMethod) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - MethodTable *pMT = pMethod->GetMethodTable(); - TypeHandle declType(pMT); - if (pMT->IsArray()) - { - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - // Load the TypeDesc for the array type. Note the returned type is approximate, i.e. - // if shared between reference array types then we will get object[] back. - DWORD rank = pMT->GetRank(); - TypeHandle elemType = pMT->GetArrayElementTypeHandle(); - declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank); - HELPER_METHOD_FRAME_END(); - } - RETURN_CLASS_OBJECT(declType, NULL); + return pMethod->GetMethodTable(); } FCIMPLEND diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index a56f585d1ae3bd..dd29dc1fed47c8 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -234,7 +234,7 @@ class RuntimeMethodHandle static FCDECL1(INT32, GetAttributes, MethodDesc *pMethod); static FCDECL1(INT32, GetImplAttributes, ReflectMethodObject *pMethodUNSAFE); - static FCDECL1(ReflectClassBaseObject*, GetDeclaringType, MethodDesc *pMethod); + static FCDECL1(MethodTable*, GetMethodTable, MethodDesc *pMethod); static FCDECL1(INT32, GetSlot, MethodDesc *pMethod); static FCDECL1(INT32, GetMethodDef, ReflectMethodObject *pMethodUNSAFE); static FCDECL1(LPCUTF8, GetUtf8Name, MethodDesc *pMethod); @@ -282,6 +282,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodInstantiation(MethodDesc extern "C" void QCALLTYPE RuntimeMethodHandle_ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString); extern "C" void* QCALLTYPE RuntimeMethodHandle_GetFunctionPointer(MethodDesc * pMethod); extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMethod); +extern "C" TADDR QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT); extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); From ca2b7de954c59251b028a74f179a9aadf58c1034 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 14:20:08 -0800 Subject: [PATCH 02/12] Convert RuntimeTypeHandle.GetElementType() to managed. Correct nullability in signature and usage. --- .../Reflection/RuntimeCustomAttributeData.cs | 2 +- .../src/System/RuntimeHandles.cs | 15 ++++++++++++- .../src/System/RuntimeType.CoreCLR.cs | 2 +- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/runtimehandles.cpp | 21 +++++++------------ src/coreclr/vm/runtimehandles.h | 2 +- .../System/Reflection/MethodInvokerCommon.cs | 2 +- .../src/System/RuntimeType.cs | 4 ++-- 8 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs index 2ac866f246fce9..8a34a6996d14fe 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs @@ -1085,7 +1085,7 @@ public CustomAttributeType(RuntimeType parameterType) if (encodedType == CustomAttributeEncoding.Array) { - parameterType = (RuntimeType)parameterType.GetElementType(); + parameterType = (RuntimeType)parameterType.GetElementType()!; encodedArrayType = RuntimeCustomAttributeData.TypeToCustomAttributeEncoding(parameterType); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index ecb70072c6cc78..365bd8cbbe2cb1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -382,7 +382,20 @@ public ModuleHandle GetModuleHandle() internal static extern TypeAttributes GetAttributes(RuntimeType type); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType GetElementType(RuntimeType type); + private static extern IntPtr GetElementTypeHandleFromHandle(IntPtr handle); + + internal static RuntimeType? GetElementType(RuntimeType type) + { + IntPtr handle = GetElementTypeHandleFromHandle(type.GetUnderlyingNativeHandle()); + if (handle == IntPtr.Zero) + { + return null; + } + + RuntimeType result = GetRuntimeTypeFromHandle(handle); + GC.KeepAlive(type); + return result; + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool CompareCanonicalHandles(RuntimeType left, RuntimeType right); diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index fd387c16022ac4..f9a0430cab304d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -1038,7 +1038,7 @@ private RuntimeType[] PopulateInterfaces(Filter filter) if (ReflectedType.IsSZArray) { - RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType(); + RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType()!; if (!arrayType.IsPointer) { diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 1c39a8a256836c..0213637a9b1f4f 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -88,7 +88,7 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod) FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists) FCFuncElement("GetModuleIfExists", RuntimeTypeHandle::GetModuleIfExists) - FCFuncElement("GetElementType", RuntimeTypeHandle::GetElementType) + FCFuncElement("GetElementTypeHandleFromHandle", RuntimeTypeHandle::GetElementTypeHandleFromHandle) FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank) FCFuncElement("GetToken", RuntimeTypeHandle::GetToken) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 9f3784871f81f1..c5a6667b12413b 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -341,36 +341,31 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnS END_QCALL; } -FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); +FCIMPL1(TADDR, RuntimeTypeHandle::GetElementTypeHandleFromHandle, EnregisteredTypeHandle th) +{ + FCALL_CONTRACT; - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); + _ASSERTE(th != NULL); - TypeHandle typeHandle = refType->GetType(); + TypeHandle typeHandle = TypeHandle::FromPtr(th); TypeHandle typeReturn; if (!typeHandle.IsTypeDesc()) { if (!typeHandle.AsMethodTable()->IsArray()) - return NULL; + return (TADDR)NULL; typeReturn = typeHandle.GetArrayElementTypeHandle(); } else { if (typeHandle.IsGenericVariable()) - return NULL; + return (TADDR)NULL; typeReturn = typeHandle.AsTypeDesc()->GetTypeParam(); } - RETURN_CLASS_OBJECT(typeReturn, refType); + return typeReturn.AsTAddr(); } FCIMPLEND diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index dd29dc1fed47c8..b54eec8cafc39a 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -144,7 +144,7 @@ class RuntimeTypeHandle static FCDECL1(PtrArray*, GetInterfaces, ReflectClassBaseObject *pType); - static FCDECL1(ReflectClassBaseObject*, GetElementType, ReflectClassBaseObject* pType); + static FCDECL1(TADDR, GetElementTypeHandleFromHandle, EnregisteredTypeHandle th); static FCDECL1(INT32, GetNumVirtuals, ReflectClassBaseObject *pType); static FCDECL2(MethodDesc*, GetMethodAt, PTR_ReflectClassBaseObject pType, INT32 slot); static FCDECL3(FC_BOOL_RET, GetFields, ReflectClassBaseObject *pType, INT32 **result, INT32 *pCount); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs index d54640f8449d79..3e8bdb5778970b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvokerCommon.cs @@ -41,7 +41,7 @@ internal static void Initialize( RuntimeType type = argumentTypes[i]; if (RuntimeTypeHandle.IsByRef(type)) { - type = (RuntimeType)type.GetElementType(); + type = (RuntimeType)type.GetElementType()!; invokerFlags[i] |= InvokerArgFlags.IsValueType_ByRef_Or_Pointer; needsByRefStrategy = true; if (type.IsNullableOfT) diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 4aaa59c52c6287..331aa945cb036a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -93,7 +93,7 @@ public override MemberInfo[] GetDefaultMembers() return members ?? Array.Empty(); } - public override Type GetElementType() => RuntimeTypeHandle.GetElementType(this); + public override Type? GetElementType() => RuntimeTypeHandle.GetElementType(this); public override string? GetEnumName(object value) { @@ -757,7 +757,7 @@ internal static bool TryGetByRefElementType(RuntimeType type, [NotNullWhen(true) CorElementType corElemType = type.GetCorElementType(); if (corElemType == CorElementType.ELEMENT_TYPE_BYREF) { - elementType = RuntimeTypeHandle.GetElementType(type); + elementType = RuntimeTypeHandle.GetElementType(type)!; return true; } From 8ce122cb2fe78961cc1525529cc070705797ae8d Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 16:33:18 -0800 Subject: [PATCH 03/12] Convert RuntimeTypeHandle.GetDeclaringType to managed and QCalls. --- .../src/System/RuntimeHandles.cs | 35 ++++- .../src/System/RuntimeType.CoreCLR.cs | 2 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 2 + src/coreclr/vm/runtimehandles.cpp | 145 +++++++----------- src/coreclr/vm/runtimehandles.h | 4 +- 6 files changed, 95 insertions(+), 94 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 365bd8cbbe2cb1..3c39935e0262f3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -575,7 +575,40 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) internal static extern bool CanCastTo(RuntimeType type, RuntimeType target); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType GetDeclaringType(RuntimeType type); + private static extern RuntimeType GetDeclaringType(RuntimeType type, int a); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")] + private static partial IntPtr GetDeclaringTypeHandleForGenericVariable(IntPtr typeHandle); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandle")] + private static partial IntPtr GetDeclaringTypeHandle(IntPtr typeHandle); + + internal static unsafe RuntimeType? GetDeclaringType(RuntimeType type) + { + IntPtr retTypeHandle = IntPtr.Zero; + TypeHandle typeHandle = type.GetNativeTypeHandle(); + if (typeHandle.IsTypeDesc) + { + CorElementType elementType = (CorElementType)typeHandle.GetCorElementType(); + if (elementType is CorElementType.ELEMENT_TYPE_VAR or CorElementType.ELEMENT_TYPE_MVAR) + { + retTypeHandle = GetDeclaringTypeHandleForGenericVariable(type.GetUnderlyingNativeHandle()); + } + } + else + { + retTypeHandle = GetDeclaringTypeHandle(type.GetUnderlyingNativeHandle()); + } + + if (retTypeHandle == IntPtr.Zero) + { + return null; + } + + RuntimeType result = GetRuntimeTypeFromHandle(retTypeHandle); + GC.KeepAlive(type); + return result; + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type); diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index f9a0430cab304d..df93e83efd008f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -1597,7 +1597,7 @@ internal TypeCode TypeCode if (m_enclosingType == null) { // Use void as a marker of null enclosing type - RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType()); + RuntimeType? enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType()); Debug.Assert(enclosingType != typeof(void)); m_enclosingType = enclosingType ?? (RuntimeType)typeof(void); } diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 0213637a9b1f4f..917399bce6e5a1 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -83,7 +83,6 @@ FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetDeclaringMethod", RuntimeTypeHandle::GetDeclaringMethod) - FCFuncElement("GetDeclaringType", RuntimeTypeHandle::GetDeclaringType) FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod) FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod) FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 95b1f7348abbc0..3975c8d3b4a74a 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -127,6 +127,8 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals) DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented) DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation) + DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable) + DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandle) DllImportEntry(RuntimeTypeHandle_IsVisible) DllImportEntry(RuntimeTypeHandle_ConstructName) DllImportEntry(RuntimeTypeHandle_GetInstantiation) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index c5a6667b12413b..0e07491dab57e8 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1002,117 +1002,84 @@ FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClas } FCIMPLEND -FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; +extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle) +{ + QCALL_CONTRACT; TypeHandle retTypeHandle; - BOOL fThrowException = FALSE; - LPCWSTR argName = W("Arg_InvalidHandle"); - RuntimeExceptionKind reKind = kArgumentNullException; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - TypeHandle typeHandle = refType->GetType(); - - MethodTable* pMT = NULL; - mdTypeDef tkTypeDef = mdTokenNil; - - if (typeHandle.IsTypeDesc()) { - - if (typeHandle.IsGenericVariable()) { - TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable(); - mdToken defToken = pGenericVariable->GetTypeOrMethodDef(); - - // Try the fast way first (if the declaring type has been loaded already). - if (TypeFromToken(defToken) == mdtMethodDef) - { - MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken); - if (retMethod != NULL) - retTypeHandle = retMethod->GetMethodTable(); - } - else - { - retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken); - } + BEGIN_QCALL; - if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded()) - goto Exit; + TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle); + _ASSERTE(typeHandle.IsGenericVariable()); - // OK, need to go the slow way and load the type first. - HELPER_METHOD_FRAME_BEGIN_RET_1(refType); - { - if (TypeFromToken(defToken) == mdtMethodDef) - { - retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable(); - } - else - { - retTypeHandle = pGenericVariable->LoadOwnerType(); - } - retTypeHandle.CheckRestore(); - } - HELPER_METHOD_FRAME_END(); - goto Exit; - } + TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable(); + mdToken defToken = pGenericVariable->GetTypeOrMethodDef(); - retTypeHandle = TypeHandle(); - goto Exit; + // Try the fast way first (if the declaring type has been loaded already). + if (TypeFromToken(defToken) == mdtMethodDef) + { + MethodDesc* retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken); + if (retMethod != NULL) + retTypeHandle = retMethod->GetMethodTable(); } - - pMT = typeHandle.GetMethodTable(); - - if (pMT == NULL) + else { - fThrowException = TRUE; - goto Exit; + retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken); } - if(!pMT->GetClass()->IsNested()) + // Check if we need to go the slow way and load the type first. + if (retTypeHandle.IsNull() || !retTypeHandle.IsFullyLoaded()) { - retTypeHandle = TypeHandle(); - goto Exit; + if (TypeFromToken(defToken) == mdtMethodDef) + { + retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable(); + } + else + { + retTypeHandle = pGenericVariable->LoadOwnerType(); + } + retTypeHandle.CheckRestore(); } - tkTypeDef = pMT->GetCl(); + END_QCALL; - if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef))) - { - fThrowException = TRUE; - reKind = kBadImageFormatException; - argName = NULL; - goto Exit; - } + return retTypeHandle.AsTAddr(); +} - // Try the fast way first (if the declaring type has been loaded already). - retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef); - if (retTypeHandle.IsNull()) +extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle) +{ + QCALL_CONTRACT; + + TypeHandle retTypeHandle; + + BEGIN_QCALL; + + TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle); + _ASSERTE(!typeHandle.IsTypeDesc()); + + MethodTable* pMT = typeHandle.GetMethodTable(); + if (pMT->GetClass()->IsNested()) { - // OK, need to go the slow way and load the type first. - HELPER_METHOD_FRAME_BEGIN_RET_1(refType); + mdTypeDef tkTypeDef = pMT->GetCl(); + if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef))) + COMPlusThrow(kBadImageFormatException); + + // Try the fast way first (if the declaring type has been loaded already). + retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef); + if (retTypeHandle.IsNull()) { + // OK, need to go the slow way and load the type first. retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef, - ClassLoader::ThrowIfNotFound, - ClassLoader::PermitUninstDefOrRef); + ClassLoader::ThrowIfNotFound, + ClassLoader::PermitUninstDefOrRef); } - HELPER_METHOD_FRAME_END(); } -Exit: - if (fThrowException) - { - FCThrowRes(reKind, argName); - } + END_QCALL; - RETURN_CLASS_OBJECT(retTypeHandle, refType); - } -FCIMPLEND + return retTypeHandle.AsTAddr(); +} FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) { CONTRACTL { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index b54eec8cafc39a..fbfb1e6003a88b 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -122,8 +122,6 @@ class RuntimeTypeHandle static FCDECL1(ReflectMethodObject*, GetDeclaringMethod, ReflectClassBaseObject *pType); - static FCDECL1(ReflectClassBaseObject*, GetDeclaringType, ReflectClassBaseObject* pType); - static FCDECL1(Object *, GetArgumentTypesFromFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); @@ -192,6 +190,8 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnS extern "C" INT32 QCALLTYPE RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals(QCall::TypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_VerifyInterfaceIsImplemented(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pIFaceHandle); extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementation(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pOwner, MethodDesc * pMD); +extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); +extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QCall::TypeHandle pTypeHandle, QCall::AssemblyHandle pAssembly); class RuntimeMethodHandle From b7044cb55b550c9c396bdf9022c3603c726a3e86 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 16:35:58 -0800 Subject: [PATCH 04/12] Remove GetRuntimeTypeHelper. --- src/coreclr/vm/runtimehandles.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 0e07491dab57e8..609e11837e1521 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -157,27 +157,6 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetTypeFromHandleSlow( END_QCALL; } -// static -NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive) -{ - FC_INNER_PROLOG_NO_ME_SETUP(); - if (typeHandle.AsPtr() == NULL) - return NULL; - - OBJECTREF refType = typeHandle.GetManagedClassObjectIfExists(); - if (refType != NULL) - return (ReflectClassBaseObject*)OBJECTREFToObject(refType); - - HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive); - refType = typeHandle.GetManagedClassObject(); - HELPER_METHOD_FRAME_END(); - - FC_INNER_EPILOG(); - return (ReflectClassBaseObject*)OBJECTREFToObject(refType); -} - -#define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive)) - FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandleIfExists, EnregisteredTypeHandle th) { FCALL_CONTRACT; From 173e6c91c224f6185e069fe85e5c63a438b94a23 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 17:29:01 -0800 Subject: [PATCH 05/12] Fix mono build. --- src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index ccf63a22a79169..348125a734fb26 100644 --- a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -2106,7 +2106,7 @@ public override bool ContainsGenericParameters } if (HasElementType) - return GetElementType().ContainsGenericParameters; + return GetElementType()!.ContainsGenericParameters; if (IsFunctionPointer) { From da287a30a9cdb7a8c3979f793f49c07356e70742 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 19 Nov 2024 17:39:42 -0800 Subject: [PATCH 06/12] Fix nullable signasture in mono. --- .../System.Private.CoreLib/src/System/RuntimeTypeHandle.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/mono/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index 549beda1262736..84f7b025c3296b 100644 --- a/src/mono/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/mono/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -265,11 +265,11 @@ internal static RuntimeModule GetModule(RuntimeType type) return res!; } - internal static RuntimeType GetElementType(RuntimeType type) + internal static RuntimeType? GetElementType(RuntimeType type) { RuntimeType? res = null; GetElementType(new QCallTypeHandle(ref type), ObjectHandleOnStack.Create(ref res)); - return res!; + return res; } internal static IntPtr GetMonoClass(RuntimeType type) From 79dc5f961648cdd10f9bb0faba99feb4c73a2d3d Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 20 Nov 2024 20:12:12 -0800 Subject: [PATCH 07/12] Remove testing FCall. --- .../System.Private.CoreLib/src/System/RuntimeHandles.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 3c39935e0262f3..4a1703ca405e2c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -574,9 +574,6 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool CanCastTo(RuntimeType type, RuntimeType target); - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern RuntimeType GetDeclaringType(RuntimeType type, int a); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")] private static partial IntPtr GetDeclaringTypeHandleForGenericVariable(IntPtr typeHandle); From a691a5852047acfe371e4f7b3741b64b6bc28a88 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 22 Nov 2024 11:27:59 -0800 Subject: [PATCH 08/12] Feedback --- .../src/System/RuntimeHandles.cs | 16 ++++----------- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/runtimehandles.cpp | 20 +++++++++---------- src/coreclr/vm/runtimehandles.h | 8 ++++---- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 4a1703ca405e2c..1cf11e9cc84bf0 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -49,7 +49,7 @@ private static RuntimeType GetTypeFromHandleSlow(IntPtr handle) [MethodImpl(MethodImplOptions.InternalCall)] private static extern RuntimeType? GetTypeFromHandleIfExists(IntPtr handle); - internal static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle) + private static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle) { return GetTypeFromHandleIfExists(handle) ?? GetTypeFromHandleSlow(handle); } @@ -382,11 +382,11 @@ public ModuleHandle GetModuleHandle() internal static extern TypeAttributes GetAttributes(RuntimeType type); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern IntPtr GetElementTypeHandleFromHandle(IntPtr handle); + private static extern IntPtr GetElementTypeHandle(IntPtr handle); internal static RuntimeType? GetElementType(RuntimeType type) { - IntPtr handle = GetElementTypeHandleFromHandle(type.GetUnderlyingNativeHandle()); + IntPtr handle = GetElementTypeHandle(type.GetUnderlyingNativeHandle()); if (handle == IntPtr.Zero) { return null; @@ -976,15 +976,7 @@ internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal { Debug.Assert(!method.IsNullHandle()); MethodTable* pMT = GetMethodTable(method); - if (pMT->IsArray) - { - IntPtr handle = GetHandleForArray(pMT); - return RuntimeTypeHandle.GetRuntimeTypeFromHandle(handle); - } - else - { - return RuntimeTypeHandle.GetRuntimeType(pMT); - } + return RuntimeTypeHandle.GetRuntimeType(pMT); } internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method) diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 917399bce6e5a1..01da76ad011fd7 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -87,7 +87,7 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod) FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists) FCFuncElement("GetModuleIfExists", RuntimeTypeHandle::GetModuleIfExists) - FCFuncElement("GetElementTypeHandleFromHandle", RuntimeTypeHandle::GetElementTypeHandleFromHandle) + FCFuncElement("GetElementTypeHandle", RuntimeTypeHandle::GetElementTypeHandle) FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank) FCFuncElement("GetToken", RuntimeTypeHandle::GetToken) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 609e11837e1521..46d5e76372c50a 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -320,7 +320,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnS END_QCALL; } -FCIMPL1(TADDR, RuntimeTypeHandle::GetElementTypeHandleFromHandle, EnregisteredTypeHandle th) +FCIMPL1(EnregisteredTypeHandle, RuntimeTypeHandle::GetElementTypeHandle, EnregisteredTypeHandle th) { FCALL_CONTRACT; @@ -332,19 +332,19 @@ FCIMPL1(TADDR, RuntimeTypeHandle::GetElementTypeHandleFromHandle, EnregisteredTy if (!typeHandle.IsTypeDesc()) { if (!typeHandle.AsMethodTable()->IsArray()) - return (TADDR)NULL; + return NULL; typeReturn = typeHandle.GetArrayElementTypeHandle(); } else { if (typeHandle.IsGenericVariable()) - return (TADDR)NULL; + return NULL; typeReturn = typeHandle.AsTypeDesc()->GetTypeParam(); } - return typeReturn.AsTAddr(); + return (EnregisteredTypeHandle)typeReturn.AsTAddr(); } FCIMPLEND @@ -981,7 +981,7 @@ FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClas } FCIMPLEND -extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle) +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle) { QCALL_CONTRACT; @@ -1023,10 +1023,10 @@ extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVar END_QCALL; - return retTypeHandle.AsTAddr(); + return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } -extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle) +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle) { QCALL_CONTRACT; @@ -1057,7 +1057,7 @@ extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(Enregistered END_QCALL; - return retTypeHandle.AsTAddr(); + return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) { @@ -1418,7 +1418,7 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc* pMeth return isCollectible; } -extern "C" TADDR QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT) +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT) { QCALL_CONTRACT; _ASSERTE(pMT != NULL); @@ -1436,7 +1436,7 @@ extern "C" TADDR QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pM END_QCALL; - return declType.AsTAddr(); + return (EnregisteredTypeHandle)declType.AsTAddr(); } FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc* pMethod) diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index fbfb1e6003a88b..daed363a1dfcdb 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -142,7 +142,7 @@ class RuntimeTypeHandle static FCDECL1(PtrArray*, GetInterfaces, ReflectClassBaseObject *pType); - static FCDECL1(TADDR, GetElementTypeHandleFromHandle, EnregisteredTypeHandle th); + static FCDECL1(EnregisteredTypeHandle, GetElementTypeHandle, EnregisteredTypeHandle th); static FCDECL1(INT32, GetNumVirtuals, ReflectClassBaseObject *pType); static FCDECL2(MethodDesc*, GetMethodAt, PTR_ReflectClassBaseObject pType, INT32 slot); static FCDECL3(FC_BOOL_RET, GetFields, ReflectClassBaseObject *pType, INT32 **result, INT32 *pCount); @@ -190,8 +190,8 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnS extern "C" INT32 QCALLTYPE RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals(QCall::TypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_VerifyInterfaceIsImplemented(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pIFaceHandle); extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementation(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pOwner, MethodDesc * pMD); -extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); -extern "C" TADDR QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle); +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QCall::TypeHandle pTypeHandle, QCall::AssemblyHandle pAssembly); class RuntimeMethodHandle @@ -282,7 +282,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodInstantiation(MethodDesc extern "C" void QCALLTYPE RuntimeMethodHandle_ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString); extern "C" void* QCALLTYPE RuntimeMethodHandle_GetFunctionPointer(MethodDesc * pMethod); extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMethod); -extern "C" TADDR QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT); +extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT); extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); From c5235a64cf7a8e9448a6fe02df30c7c79607cbdd Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 22 Nov 2024 11:37:12 -0800 Subject: [PATCH 09/12] Remove unused RuntimeMethodHandle_GetHandleForArray. --- .../src/System/RuntimeHandles.cs | 3 --- src/coreclr/vm/qcallentrypoints.cpp | 1 - src/coreclr/vm/runtimehandles.cpp | 21 ------------------- src/coreclr/vm/runtimehandles.h | 1 - 4 files changed, 26 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 1cf11e9cc84bf0..fc8bfc589fabce 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -969,9 +969,6 @@ internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNam [MethodImpl(MethodImplOptions.InternalCall)] private static extern unsafe MethodTable* GetMethodTable(RuntimeMethodHandleInternal method); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetHandleForArray")] - private static unsafe partial IntPtr GetHandleForArray(MethodTable* pMT); - internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method) { Debug.Assert(!method.IsNullHandle()); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 3975c8d3b4a74a..7ac45ddbe41690 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -146,7 +146,6 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_ConstructInstantiation) DllImportEntry(RuntimeMethodHandle_GetFunctionPointer) DllImportEntry(RuntimeMethodHandle_GetIsCollectible) - DllImportEntry(RuntimeMethodHandle_GetHandleForArray) DllImportEntry(RuntimeMethodHandle_GetMethodInstantiation) DllImportEntry(RuntimeMethodHandle_GetTypicalMethodDefinition) DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 46d5e76372c50a..04b311c21a2cd8 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1418,27 +1418,6 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc* pMeth return isCollectible; } -extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT) -{ - QCALL_CONTRACT; - _ASSERTE(pMT != NULL); - _ASSERTE(pMT->IsArray()); - - TypeHandle declType; - - BEGIN_QCALL; - - // Load the TypeDesc for the array type. Note the returned type is approximate, i.e. - // if shared between reference array types then we will get object[] back. - DWORD rank = pMT->GetRank(); - TypeHandle elemType = pMT->GetArrayElementTypeHandle(); - declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank); - - END_QCALL; - - return (EnregisteredTypeHandle)declType.AsTAddr(); -} - FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc* pMethod) { CONTRACTL diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index daed363a1dfcdb..5cd70210e7aa83 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -282,7 +282,6 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodInstantiation(MethodDesc extern "C" void QCALLTYPE RuntimeMethodHandle_ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString); extern "C" void* QCALLTYPE RuntimeMethodHandle_GetFunctionPointer(MethodDesc * pMethod); extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMethod); -extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeMethodHandle_GetHandleForArray(MethodTable* pMT); extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); From ff5aa8a013b5961d2ce3697737a296749cd4a098 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 22 Nov 2024 13:55:34 -0800 Subject: [PATCH 10/12] Feedback --- .../src/System/RuntimeHandles.cs | 22 +++++++++---------- .../src/System/RuntimeType.CoreCLR.cs | 4 ++-- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/qcallentrypoints.cpp | 2 +- src/coreclr/vm/runtimehandles.cpp | 4 ++-- src/coreclr/vm/runtimehandles.h | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index fc8bfc589fabce..9ccb8ff3a7ac8f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -22,7 +22,7 @@ internal RuntimeTypeHandle GetNativeHandle() => new RuntimeTypeHandle(m_type ?? throw new ArgumentNullException(null, SR.Arg_InvalidHandle)); // Returns type for interop with EE. The type is guaranteed to be non-null. - internal RuntimeType GetTypeChecked() => + internal RuntimeType GetRuntimeTypeChecked() => m_type ?? throw new ArgumentNullException(null, SR.Arg_InvalidHandle); /// @@ -33,31 +33,31 @@ internal RuntimeType GetTypeChecked() => public static RuntimeTypeHandle FromIntPtr(IntPtr value) => new RuntimeTypeHandle(value == IntPtr.Zero ? null : GetRuntimeTypeFromHandle(value)); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetTypeFromHandleSlow")] - private static partial void GetTypeFromHandleSlow( + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow")] + private static partial void GetRuntimeTypeFromHandleSlow( IntPtr handle, ObjectHandleOnStack typeObject); [MethodImpl(MethodImplOptions.NoInlining)] - private static RuntimeType GetTypeFromHandleSlow(IntPtr handle) + private static RuntimeType GetRuntimeTypeFromHandleSlow(IntPtr handle) { RuntimeType? typeObject = null; - GetTypeFromHandleSlow(handle, ObjectHandleOnStack.Create(ref typeObject)); + GetRuntimeTypeFromHandleSlow(handle, ObjectHandleOnStack.Create(ref typeObject)); return typeObject!; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern RuntimeType? GetTypeFromHandleIfExists(IntPtr handle); + private static extern RuntimeType? GetRuntimeTypeFromHandleIfExists(IntPtr handle); private static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle) { - return GetTypeFromHandleIfExists(handle) ?? GetTypeFromHandleSlow(handle); + return GetRuntimeTypeFromHandleIfExists(handle) ?? GetRuntimeTypeFromHandleSlow(handle); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static unsafe RuntimeType GetRuntimeType(MethodTable* pMT) { - return pMT->AuxiliaryData->ExposedClassObject ?? GetTypeFromHandleSlow((IntPtr)pMT); + return pMT->AuxiliaryData->ExposedClassObject ?? GetRuntimeTypeFromHandleSlow((IntPtr)pMT); } /// @@ -715,7 +715,7 @@ internal RuntimeType MakePointer() internal int GetGenericVariableIndex() { - RuntimeType type = GetTypeChecked(); + RuntimeType type = GetRuntimeTypeChecked(); if (!IsGenericVariable(type)) throw new InvalidOperationException(SR.Arg_NotGenericParameter); @@ -728,7 +728,7 @@ internal int GetGenericVariableIndex() internal bool ContainsGenericVariables() { - return ContainsGenericVariables(GetTypeChecked()); + return ContainsGenericVariables(GetRuntimeTypeChecked()); } [MethodImpl(MethodImplOptions.InternalCall)] @@ -796,7 +796,7 @@ internal RuntimeMethodHandleInternal(IntPtr value) m_handle = value; } - internal IntPtr m_handle; + private IntPtr m_handle; } internal sealed class RuntimeMethodInfoStub : IRuntimeMethodInfo diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index df93e83efd008f..b73f8263782e90 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -2055,8 +2055,8 @@ internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType Type genericArgument = genericArguments[i]; Type genericParameter = genericParameters[i]; - if (!RuntimeTypeHandle.SatisfiesConstraints(genericParameter.TypeHandle.GetTypeChecked(), - typeContext, methodContext, genericArgument.TypeHandle.GetTypeChecked())) + if (!RuntimeTypeHandle.SatisfiesConstraints(genericParameter.TypeHandle.GetRuntimeTypeChecked(), + typeContext, methodContext, genericArgument.TypeHandle.GetRuntimeTypeChecked())) { throw new ArgumentException( SR.Format(SR.Argument_GenConstraintViolation, i.ToString(), genericArgument, definition, genericParameter), e); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 01da76ad011fd7..406ea61a5dcc55 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -105,7 +105,7 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("IsUnmanagedFunctionPointer", RuntimeTypeHandle::IsUnmanagedFunctionPointer) FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles) FCFuncElement("IsEquivalentTo", RuntimeTypeHandle::IsEquivalentTo) - FCFuncElement("GetTypeFromHandleIfExists", RuntimeTypeHandle::GetTypeFromHandleIfExists) + FCFuncElement("GetRuntimeTypeFromHandleIfExists", RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists) FCFuncEnd() FCFuncStart(gMetaDataImport) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 7ac45ddbe41690..0dcb57eb9607b2 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -138,7 +138,7 @@ static const Entry s_QCall[] = #ifdef FEATURE_COMINTEROP DllImportEntry(RuntimeTypeHandle_AllocateComObject) #endif // FEATURE_COMINTEROP - DllImportEntry(RuntimeTypeHandle_GetTypeFromHandleSlow) + DllImportEntry(RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow) DllImportEntry(RuntimeTypeHandle_CreateInstanceForAnotherGenericParameter) DllImportEntry(RuntimeTypeHandle_AllocateTypeAssociatedMemory) DllImportEntry(RuntimeTypeHandle_RegisterCollectibleTypeDependency) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 04b311c21a2cd8..0c3420f9724769 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -138,7 +138,7 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_IsCAVisibleFromDecoratedType( return bResult; } -extern "C" void QCALLTYPE RuntimeTypeHandle_GetTypeFromHandleSlow( +extern "C" void QCALLTYPE RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow( EnregisteredTypeHandle typeHandleRaw, QCall::ObjectHandleOnStack result) { @@ -157,7 +157,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetTypeFromHandleSlow( END_QCALL; } -FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandleIfExists, EnregisteredTypeHandle th) +FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists, EnregisteredTypeHandle th) { FCALL_CONTRACT; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 5cd70210e7aa83..ddd6554d23babf 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -109,7 +109,7 @@ class RuntimeTypeHandle ReflectClassBaseObject *pRuntimeTypeDONOTUSEDIRECTLY; // Static method on RuntimeTypeHandle - static FCDECL1(ReflectClassBaseObject*, GetTypeFromHandleIfExists, EnregisteredTypeHandle th); + static FCDECL1(ReflectClassBaseObject*, GetRuntimeTypeFromHandleIfExists, EnregisteredTypeHandle th); static FCDECL2(FC_BOOL_RET, IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE); @@ -155,7 +155,7 @@ class RuntimeTypeHandle static void ValidateTypeAbleToBeInstantiated(TypeHandle typeHandle, bool fGetUninitializedObject); }; -extern "C" void QCALLTYPE RuntimeTypeHandle_GetTypeFromHandleSlow(void* typeHandleRaw, QCall::ObjectHandleOnStack result); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow(void* typeHandleRaw, QCall::ObjectHandleOnStack result); extern "C" void QCALLTYPE RuntimeTypeHandle_CreateInstanceForAnotherGenericParameter(QCall::TypeHandle pTypeHandle, TypeHandle *pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack pInstantiatedObject); extern "C" void* QCALLTYPE RuntimeTypeHandle_AllocateTypeAssociatedMemory(QCall::TypeHandle type, uint32_t size); From defcaeb025cc8403918e5517c4e282fa52b63569 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 25 Nov 2024 09:10:35 -0800 Subject: [PATCH 11/12] Reuse function. --- src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 9ccb8ff3a7ac8f..17e034811d79c1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -19,7 +19,7 @@ public unsafe partial struct RuntimeTypeHandle : IEquatable, { // Returns handle for interop with EE. The handle is guaranteed to be non-null. internal RuntimeTypeHandle GetNativeHandle() => - new RuntimeTypeHandle(m_type ?? throw new ArgumentNullException(null, SR.Arg_InvalidHandle)); + new RuntimeTypeHandle(GetRuntimeTypeChecked()); // Returns type for interop with EE. The type is guaranteed to be non-null. internal RuntimeType GetRuntimeTypeChecked() => From cab3575ed8a46580e406e031a91e8965c27008f4 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 25 Nov 2024 10:45:15 -0800 Subject: [PATCH 12/12] Root RuntimeAssembly and RuntimeType constructor. --- src/coreclr/vm/corelib.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 518bb532f7d99f..05f76b569e3913 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -130,7 +130,9 @@ DEFINE_FIELD_U(m_fullname, AssemblyBaseObject, m_fullname) DEFINE_FIELD_U(m_syncRoot, AssemblyBaseObject, m_pSyncRoot) DEFINE_FIELD_U(m_assembly, AssemblyBaseObject, m_pAssembly) DEFINE_CLASS(ASSEMBLY, Reflection, RuntimeAssembly) - +#ifdef FOR_ILLINK +DEFINE_METHOD(ASSEMBLY, CTOR, .ctor, IM_RetVoid) +#endif // FOR_ILLINK DEFINE_CLASS(ASYNCCALLBACK, System, AsyncCallback) DEFINE_CLASS(ATTRIBUTE, System, Attribute) @@ -152,6 +154,9 @@ DEFINE_METHOD(CLASS, GET_METHODS, GetMethods, DEFINE_METHOD(CLASS, INVOKE_MEMBER, InvokeMember, IM_Str_BindingFlags_Binder_Obj_ArrObj_ArrParameterModifier_CultureInfo_ArrStr_RetObj) DEFINE_METHOD(CLASS, GET_METHOD_BASE, GetMethodBase, SM_RuntimeType_RuntimeMethodHandleInternal_RetMethodBase) DEFINE_METHOD(CLASS, GET_FIELD_INFO, GetFieldInfo, SM_RuntimeType_IRuntimeFieldInfo_RetFieldInfo) +#ifdef FOR_ILLINK +DEFINE_METHOD(CLASS, CTOR, .ctor, IM_RetVoid) +#endif // FOR_ILLINK #ifdef FEATURE_COMINTEROP DEFINE_METHOD(CLASS, FORWARD_CALL_TO_INVOKE, ForwardCallToInvokeMember, IM_Str_BindingFlags_Obj_ArrObj_ArrBool_ArrInt_ArrType_Type_RetObj)