diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index ba42162dd03478..b10ec23495b98d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -175,8 +175,10 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd) mt = mt->ParentMethodTable; } +#if FEATURE_TYPEEQUIVALENCE // this helper is not supposed to be used with type-equivalent "to" type. Debug.Assert(!((MethodTable*)toTypeHnd)->HasTypeEquivalence); +#endif // FEATURE_TYPEEQUIVALENCE obj = null; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index c080e2339be75b..3bb984f14e7d69 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -751,7 +751,9 @@ internal unsafe struct MethodTable private const uint enum_flag_ContainsGCPointers = 0x01000000; private const uint enum_flag_ContainsGenericVariables = 0x20000000; private const uint enum_flag_HasComponentSize = 0x80000000; +#if FEATURE_TYPEEQUIVALENCE private const uint enum_flag_HasTypeEquivalence = 0x02000000; +#endif // FEATURE_TYPEEQUIVALENCE private const uint enum_flag_HasFinalizer = 0x00100000; private const uint enum_flag_Category_Mask = 0x000F0000; private const uint enum_flag_Category_ValueType = 0x00040000; diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index b8da46a4bcdc14..236078b88c5679 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -436,11 +436,35 @@ public ModuleHandle GetModuleHandle() [MethodImpl(MethodImplOptions.InternalCall)] internal static extern int GetToken(RuntimeType type); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetMethodAt")] + private static unsafe partial IntPtr GetMethodAt(MethodTable* pMT, int slot); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern Type[] GetArgumentTypesFromFunctionPointer(RuntimeType type); + internal static RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot) + { + TypeHandle typeHandle = type.GetNativeTypeHandle(); + if (typeHandle.IsTypeDesc) + { + throw new ArgumentException(SR.Arg_InvalidHandle); + } + + if (slot < 0) + { + throw new ArgumentException(SR.Arg_ArgumentOutOfRangeException); + } + + return new RuntimeMethodHandleInternal(GetMethodAt(typeHandle.AsMethodTable(), slot)); + } + + internal static Type[] GetArgumentTypesFromFunctionPointer(RuntimeType type) + { + Debug.Assert(type.IsFunctionPointer); + Type[]? argTypes = null; + GetArgumentTypesFromFunctionPointer(new QCallTypeHandle(ref type), ObjectHandleOnStack.Create(ref argTypes)); + return argTypes!; + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetArgumentTypesFromFunctionPointer")] + private static partial void GetArgumentTypesFromFunctionPointer(QCallTypeHandle type, ObjectHandleOnStack argTypes); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsUnmanagedFunctionPointer(RuntimeType type); @@ -796,8 +820,11 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) } #if FEATURE_TYPEEQUIVALENCE - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool IsEquivalentTo(RuntimeType rtType1, RuntimeType rtType2); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_IsEquivalentTo")] + private static partial Interop.BOOL IsEquivalentTo(QCallTypeHandle rtType1, QCallTypeHandle rtType2); + + internal static bool IsEquivalentTo(RuntimeType rtType1, RuntimeType rtType2) + => IsEquivalentTo(new QCallTypeHandle(ref rtType1), new QCallTypeHandle(ref rtType2)) == Interop.BOOL.TRUE; #endif // FEATURE_TYPEEQUIVALENCE } @@ -1213,7 +1240,17 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m internal static extern bool IsConstructor(RuntimeMethodHandleInternal method); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern LoaderAllocator GetLoaderAllocator(RuntimeMethodHandleInternal method); + private static extern LoaderAllocator GetLoaderAllocatorInternal(RuntimeMethodHandleInternal method); + + internal static LoaderAllocator GetLoaderAllocator(RuntimeMethodHandleInternal method) + { + if (method.IsNullHandle()) + { + throw new ArgumentNullException(SR.Arg_InvalidHandle); + } + + return GetLoaderAllocatorInternal(method); + } } // This type is used to remove the expense of having a managed reference object that is dynamically @@ -1519,7 +1556,17 @@ internal static void SetValueDirect(RtFieldInfo field, RuntimeType fieldType, Ty internal static extern bool AcquiresContextFromThis(RuntimeFieldHandleInternal field); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern LoaderAllocator GetLoaderAllocator(RuntimeFieldHandleInternal method); + private static extern LoaderAllocator GetLoaderAllocatorInternal(RuntimeFieldHandleInternal field); + + internal static LoaderAllocator GetLoaderAllocator(RuntimeFieldHandleInternal field) + { + if (field.IsNullHandle()) + { + throw new ArgumentNullException(SR.Arg_InvalidHandle); + } + + return GetLoaderAllocatorInternal(field); + } // ISerializable interface [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] @@ -1883,7 +1930,16 @@ internal Type[] GetCustomModifiers(int parameterIndex, bool required) => GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern int GetParameterOffset(int parameterIndex); + private static extern unsafe int GetParameterOffsetInternal(void* sig, int csig, int parameterIndex); + + internal int GetParameterOffset(int parameterIndex) + { + int offsetMaybe = GetParameterOffsetInternal(m_sig, m_csig, parameterIndex); + // If the result is negative, it is an error code. + if (offsetMaybe < 0) + Marshal.ThrowExceptionForHR(offsetMaybe, new IntPtr(-1)); + return offsetMaybe; + } [MethodImpl(MethodImplOptions.InternalCall)] internal extern int GetTypeParameterOffset(int offset, int index); diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index bf637ffcdf1214..39529e099b0845 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -3,7 +3,6 @@ true true true - true true @@ -16,6 +15,7 @@ true true true + true true diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index afe644af3535b2..78efad1f4d7c7f 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -154,6 +154,10 @@ if(FEATURE_COMWRAPPERS) add_compile_definitions(FEATURE_COMWRAPPERS) endif(FEATURE_COMWRAPPERS) +if(FEATURE_TYPEEQUIVALENCE) + add_compile_definitions(FEATURE_TYPEEQUIVALENCE) +endif(FEATURE_TYPEEQUIVALENCE) + if(FEATURE_OBJCMARSHAL) add_compile_definitions(FEATURE_OBJCMARSHAL) endif() @@ -180,9 +184,6 @@ if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARG add_compile_definitions(FEATURE_ON_STACK_REPLACEMENT) endif (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64) add_compile_definitions(FEATURE_PGO) -if (CLR_CMAKE_TARGET_WIN32) - add_definitions(-DFEATURE_TYPEEQUIVALENCE) -endif(CLR_CMAKE_TARGET_WIN32) if (CLR_CMAKE_TARGET_ARCH_AMD64) # Enable the AMD64 Unix struct passing JIT-EE interface for all AMD64 platforms, to enable altjit. add_definitions(-DUNIX_AMD64_ABI_ITF) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 85752b0d597959..4b6b8d1d145896 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -39,3 +39,7 @@ endif() if (CLR_CMAKE_TARGET_APPLE) set(FEATURE_OBJCMARSHAL 1) endif() + +if (CLR_CMAKE_TARGET_WIN32) + set(FEATURE_TYPEEQUIVALENCE 1) +endif(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/utilcode/check.cpp b/src/coreclr/utilcode/check.cpp index 2d584d895d2378..e9dfeaf3fd1515 100644 --- a/src/coreclr/utilcode/check.cpp +++ b/src/coreclr/utilcode/check.cpp @@ -121,7 +121,7 @@ void CHECK::Trigger(LPCSTR reason) pMessage->AppendASCII((m_message != (LPCSTR)1) ? m_message : ""); #if _DEBUG - pMessage->AppendASCII("FAILED: "); + pMessage->AppendASCII("\nFAILED: "); pMessage->AppendASCII(m_condition); #endif diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index d3e196cfe61bb8..5aff25d5caa72c 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -91,7 +91,6 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank) FCFuncElement("GetToken", RuntimeTypeHandle::GetToken) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) - FCFuncElement("GetMethodAt", RuntimeTypeHandle::GetMethodAt) FCFuncElement("GetFields", RuntimeTypeHandle::GetFields) FCFuncElement("GetInterfaces", RuntimeTypeHandle::GetInterfaces) FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes) @@ -101,10 +100,8 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable) FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables) FCFuncElement("SatisfiesConstraints", RuntimeTypeHandle::SatisfiesConstraints) - FCFuncElement("GetArgumentTypesFromFunctionPointer", RuntimeTypeHandle::GetArgumentTypesFromFunctionPointer) FCFuncElement("IsUnmanagedFunctionPointer", RuntimeTypeHandle::IsUnmanagedFunctionPointer) FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles) - FCFuncElement("IsEquivalentTo", RuntimeTypeHandle::IsEquivalentTo) FCFuncElement("GetRuntimeTypeFromHandleIfExists", RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists) FCFuncEnd() @@ -139,7 +136,7 @@ FCFuncEnd() FCFuncStart(gSignatureNative) FCFuncElement("GetSignature", SignatureNative::GetSignature) FCFuncElement("CompareSig", SignatureNative::CompareSig) - FCFuncElement("GetParameterOffset", SignatureNative::GetParameterOffset) + FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset) FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) FCFuncElement("GetCallingConventionFromFunctionPointerAtOffset", SignatureNative::GetCallingConventionFromFunctionPointerAtOffset) @@ -162,7 +159,7 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor) FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver) - FCFuncElement("GetLoaderAllocator", RuntimeMethodHandle::GetLoaderAllocator) + FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal) FCFuncEnd() FCFuncStart(gCOMFieldHandleNewFuncs) @@ -172,7 +169,7 @@ FCFuncStart(gCOMFieldHandleNewFuncs) FCFuncElement("GetToken", RuntimeFieldHandle::GetToken) FCFuncElement("GetStaticFieldForGenericType", RuntimeFieldHandle::GetStaticFieldForGenericType) FCFuncElement("AcquiresContextFromThis", RuntimeFieldHandle::AcquiresContextFromThis) - FCFuncElement("GetLoaderAllocator", RuntimeFieldHandle::GetLoaderAllocator) + FCFuncElement("GetLoaderAllocatorInternal", RuntimeFieldHandle::GetLoaderAllocatorInternal) FCFuncElement("IsFastPathSupported", RuntimeFieldHandle::IsFastPathSupported) FCFuncElement("GetInstanceFieldOffset", RuntimeFieldHandle::GetInstanceFieldOffset) FCFuncElement("GetStaticFieldAddress", RuntimeFieldHandle::GetStaticFieldAddress) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index d65f6a838b63b2..a60d16dfb22218 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -120,9 +120,11 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_MakeArray) DllImportEntry(RuntimeTypeHandle_IsCollectible) DllImportEntry(RuntimeTypeHandle_GetConstraints) + DllImportEntry(RuntimeTypeHandle_GetArgumentTypesFromFunctionPointer) DllImportEntry(RuntimeTypeHandle_GetAssemblySlow) DllImportEntry(RuntimeTypeHandle_GetModuleSlow) DllImportEntry(RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals) + DllImportEntry(RuntimeTypeHandle_GetMethodAt) DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented) DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation) DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable) @@ -137,6 +139,9 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_AllocateComObject) #endif // FEATURE_COMINTEROP DllImportEntry(RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow) +#ifdef FEATURE_TYPEEQUIVALENCE + DllImportEntry(RuntimeTypeHandle_IsEquivalentTo) +#endif // FEATURE_TYPEEQUIVALENCE DllImportEntry(RuntimeTypeHandle_CreateInstanceForAnotherGenericParameter) DllImportEntry(RuntimeTypeHandle_InternalAlloc) DllImportEntry(RuntimeTypeHandle_InternalAllocNoChecks) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 0c3420f9724769..932c69fa34eb5a 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -168,24 +168,22 @@ FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeTypeFromHandleIfEx } FCIMPLEND -FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE) +#ifdef FEATURE_TYPEEQUIVALENCE +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsEquivalentTo(QCall::TypeHandle rtType1, QCall::TypeHandle rtType2) { - FCALL_CONTRACT; - - REFLECTCLASSBASEREF rtType1 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType1UNSAFE); - REFLECTCLASSBASEREF rtType2 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType2UNSAFE); + QCALL_CONTRACT; BOOL areEquivalent = FALSE; - HELPER_METHOD_FRAME_BEGIN_RET_2(rtType1, rtType2); - if (rtType1 != NULL && rtType2 != NULL) - areEquivalent = rtType1->GetType().IsEquivalentTo(rtType2->GetType()); + BEGIN_QCALL; - HELPER_METHOD_FRAME_END(); + areEquivalent = rtType1.AsTypeHandle().IsEquivalentTo(rtType2.AsTypeHandle()); + + END_QCALL; - FC_RETURN_BOOL(areEquivalent); + return areEquivalent; } -FCIMPLEND +#endif // FEATURE_TYPEEQUIVALENCE FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) { CONTRACTL { @@ -271,25 +269,17 @@ FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc* pFi } FCIMPLEND -FCIMPL1(Object*, RuntimeFieldHandle::GetLoaderAllocator, FieldDesc* pField) +FCIMPL1(Object*, RuntimeFieldHandle::GetLoaderAllocatorInternal, FieldDesc* pField) { - CONTRACTL { + CONTRACTL + { FCALL_CHECK; + PRECONDITION(pField != NULL); } CONTRACTL_END; - OBJECTREF loaderAllocator = NULL; - - if (!pField) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator); - LoaderAllocator *pLoaderAllocator = pField->GetApproxEnclosingMethodTable()->GetLoaderAllocator(); - loaderAllocator = pLoaderAllocator->GetExposedObject(); - - HELPER_METHOD_FRAME_END(); - + OBJECTREF loaderAllocator = pLoaderAllocator->GetExposedObject(); return OBJECTREFToObject(loaderAllocator); } FCIMPLEND @@ -415,32 +405,19 @@ extern "C" INT32 QCALLTYPE RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals(QCa return numVirtuals; } -FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); +extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, INT32 slot) +{ + QCALL_CONTRACT; - TypeHandle typeHandle = refType->GetType(); + _ASSERTE(pMT != NULL); + _ASSERTE(slot >= 0); MethodDesc* pRetMethod = NULL; - if (typeHandle.IsGenericVariable()) - FCThrowRes(kArgumentException, W("Arg_InvalidHandle")); - - HELPER_METHOD_FRAME_BEGIN_RET_1(refType); + BEGIN_QCALL; - MethodTable *pMT = typeHandle.GetMethodTable(); INT32 numVirtuals = (INT32)pMT->GetNumVirtuals(); - - if (slot < 0) - COMPlusThrow(kArgumentException, W("Arg_ArgumentOutOfRangeException")); - else if (slot < numVirtuals) + if (slot < numVirtuals) { pRetMethod = pMT->GetMethodDescForSlot((DWORD)slot); } @@ -473,13 +450,11 @@ FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pT } } - HELPER_METHOD_FRAME_END(); + END_QCALL; return pRetMethod; } -FCIMPLEND - FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) { CONTRACTL { FCALL_CHECK; @@ -705,47 +680,46 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN } FCIMPLEND -FCIMPL1(Object *, RuntimeTypeHandle::GetArgumentTypesFromFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE) +extern "C" void QCALLTYPE RuntimeTypeHandle_GetArgumentTypesFromFunctionPointer(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack argTypes) { - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(pTypeUNSAFE)); - } - CONTRACTL_END; + QCALL_CONTRACT; + + BEGIN_QCALL; + + GCX_COOP(); struct { - PTRARRAYREF retVal; + PTRARRAYREF types; } gc; + gc.types = NULL; + GCPROTECT_BEGIN(gc); - gc.retVal = NULL; + FnPtrTypeDesc* fnPtr = pTypeHandle.AsTypeHandle().AsFnPtrType(); - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - TypeHandle typeHandle = refType->GetType(); - if (!typeHandle.IsFnPtrType()) - FCThrowRes(kArgumentException, W("Arg_InvalidHandle")); + // Allocate a System.Type[] for arguments and return types. + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); + TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); + DWORD cRetAndArgTypes = fnPtr->GetNumArgs() + 1; + gc.types = (PTRARRAYREF)AllocateSzArray(arrayHandle, cRetAndArgTypes); - FnPtrTypeDesc* fnPtr = typeHandle.AsFnPtrType(); + TypeHandle* retAndArgTypes = fnPtr->GetRetAndArgTypes(); + _ASSERTE(retAndArgTypes != NULL); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); + // Fill the array. + for (DWORD position = 0; position < cRetAndArgTypes; ++position) { - MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); - TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); - DWORD cArgs = fnPtr->GetNumArgs(); - gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cArgs + 1); - - for (DWORD position = 0; position <= cArgs; position++) - { - TypeHandle typeHandle = fnPtr->GetRetAndArgTypes()[position]; - OBJECTREF refType = typeHandle.GetManagedClassObject(); - gc.retVal->SetAt(position, refType); - } + TypeHandle typeHandle = retAndArgTypes[position]; + OBJECTREF refType = typeHandle.GetManagedClassObject(); + gc.types->SetAt(position, refType); } - HELPER_METHOD_FRAME_END(); - return OBJECTREFToObject(gc.retVal); + argTypes.Set(gc.types); + + GCPROTECT_END(); + + END_QCALL; } -FCIMPLEND FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); { @@ -1489,49 +1463,38 @@ FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) { } FCIMPLEND -FCIMPL2(INT32, SignatureNative::GetParameterOffset, SignatureNative* pSignatureUNSAFE, INT32 parameterIndex) +FCIMPL3(INT32, SignatureNative::GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex) { FCALL_CONTRACT; - struct - { - SIGNATURENATIVEREF pSig; - } gc; - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; + _ASSERTE(sig != NULL); + _ASSERTE(csig > 0); - INT32 offset = 0; + HRESULT hr; + SigPointer sp(sig, csig); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); + uint32_t callConv; + IfFailRet(sp.GetCallingConvInfo(&callConv)); + if ((callConv & IMAGE_CEE_CS_CALLCONV_MASK) != IMAGE_CEE_CS_CALLCONV_FIELD) { - SigPointer sp(gc.pSig->GetCorSig(), gc.pSig->GetCorSigSize()); - - uint32_t callConv = 0; - IfFailThrow(sp.GetCallingConvInfo(&callConv)); - - if ((callConv & IMAGE_CEE_CS_CALLCONV_MASK) != IMAGE_CEE_CS_CALLCONV_FIELD) + if (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) { - if (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) - { - IfFailThrow(sp.GetData(NULL)); - } - - uint32_t numArgs; - IfFailThrow(sp.GetData(&numArgs)); - _ASSERTE((uint32_t)parameterIndex <= numArgs); - - for (int i = 0; i < parameterIndex; i++) - IfFailThrow(sp.SkipExactlyOne()); - } - else - { - _ASSERTE(parameterIndex == 0); + IfFailRet(sp.GetData(NULL)); } - offset = (INT32)(sp.GetPtr() - gc.pSig->GetCorSig()); + uint32_t numArgs; + IfFailRet(sp.GetData(&numArgs)); + _ASSERTE((uint32_t)parameterIndex <= numArgs); + + for (INT32 i = 0; i < parameterIndex; i++) + IfFailRet(sp.SkipExactlyOne()); + } + else + { + _ASSERTE(parameterIndex == 0); } - HELPER_METHOD_FRAME_END(); + INT32 offset = (INT32)(sp.GetPtr() - sig); return offset; } FCIMPLEND @@ -2364,25 +2327,17 @@ FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod) } FCIMPLEND -FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod) +FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocatorInternal, MethodDesc *pMethod) { - CONTRACTL { + CONTRACTL + { FCALL_CHECK; + PRECONDITION(pMethod != NULL); } CONTRACTL_END; - OBJECTREF loaderAllocator = NULL; - - if (!pMethod) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator); - LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator(); - loaderAllocator = pLoaderAllocator->GetExposedObject(); - - HELPER_METHOD_FRAME_END(); - + OBJECTREF loaderAllocator = pLoaderAllocator->GetExposedObject(); return OBJECTREFToObject(loaderAllocator); } FCIMPLEND diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 3cd538c67781e6..30683f5c2a8e70 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -111,8 +111,6 @@ class RuntimeTypeHandle // Static method on RuntimeTypeHandle static FCDECL1(ReflectClassBaseObject*, GetRuntimeTypeFromHandleIfExists, EnregisteredTypeHandle th); - static FCDECL2(FC_BOOL_RET, IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE); - static FCDECL1(AssemblyBaseObject*, GetAssemblyIfExists, ReflectClassBaseObject *pType); static FCDECL1(ReflectModuleBaseObject*, GetModuleIfExists, ReflectClassBaseObject* pType); static FCDECL1(INT32, GetAttributes, ReflectClassBaseObject* pType); @@ -122,7 +120,6 @@ class RuntimeTypeHandle static FCDECL1(ReflectMethodObject*, GetDeclaringMethod, ReflectClassBaseObject *pType); - static FCDECL1(Object *, GetArgumentTypesFromFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); @@ -144,7 +141,6 @@ class RuntimeTypeHandle 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); static FCDECL1(MethodDesc *, GetFirstIntroducedMethod, ReflectClassBaseObject* pType); @@ -156,7 +152,9 @@ class RuntimeTypeHandle }; extern "C" void QCALLTYPE RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow(void* typeHandleRaw, QCall::ObjectHandleOnStack result); - +#ifdef FEATURE_TYPEEQUIVALENCE +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsEquivalentTo(QCall::TypeHandle rtType1, QCall::TypeHandle rtType2); +#endif // FEATURE_TYPEEQUIVALENCE extern "C" void QCALLTYPE RuntimeTypeHandle_CreateInstanceForAnotherGenericParameter(QCall::TypeHandle pTypeHandle, TypeHandle *pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack pInstantiatedObject); extern "C" void QCALLTYPE RuntimeTypeHandle_InternalAlloc(MethodTable* pMT, QCall::ObjectHandleOnStack allocated); extern "C" void QCALLTYPE RuntimeTypeHandle_InternalAllocNoChecks(MethodTable* pMT, QCall::ObjectHandleOnStack allocated); @@ -187,9 +185,11 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle p extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetConstraints(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypes); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetArgumentTypesFromFunctionPointer(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack argTypes); extern "C" void QCALLTYPE RuntimeTypeHandle_GetAssemblySlow(QCall::ObjectHandleOnStack type, QCall::ObjectHandleOnStack assembly); extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnStack type, QCall::ObjectHandleOnStack module); extern "C" INT32 QCALLTYPE RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals(QCall::TypeHandle pTypeHandle); +extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, INT32 slot); 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" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); @@ -232,7 +232,7 @@ class RuntimeMethodHandle static FCDECL1(FC_BOOL_RET, IsConstructor, MethodDesc *pMethod); - static FCDECL1(Object*, GetLoaderAllocator, MethodDesc *pMethod); + static FCDECL1(Object*, GetLoaderAllocatorInternal, MethodDesc *pMethod); }; extern "C" MethodDesc* QCALLTYPE MethodBase_GetCurrentMethod(QCall::StackCrawlMarkHandle stackMark); @@ -272,7 +272,7 @@ class RuntimeFieldHandle static FCDECL1(INT32, GetToken, FieldDesc* pField); static FCDECL2(FieldDesc*, GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringType); static FCDECL1(FC_BOOL_RET, AcquiresContextFromThis, FieldDesc *pField); - static FCDECL1(Object*, GetLoaderAllocator, FieldDesc *pField); + static FCDECL1(Object*, GetLoaderAllocatorInternal, FieldDesc *pField); }; extern "C" void QCALLTYPE RuntimeFieldHandle_GetValue(FieldDesc* fieldDesc, QCall::ObjectHandleOnStack instance, QCall::TypeHandle fieldType, QCall::TypeHandle declaringType, BOOL *pIsClassInitialized, QCall::ObjectHandleOnStack result); @@ -330,7 +330,7 @@ class SignatureNative : public Object static FCDECL2(FC_BOOL_RET, CompareSig, SignatureNative* pLhs, SignatureNative* pRhs); - static FCDECL2(INT32, GetParameterOffset, SignatureNative* pSig, INT32 parameterIndex); + static FCDECL3(INT32, GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex); static FCDECL3(INT32, GetTypeParameterOffset, SignatureNative* pSig, INT32 offset, INT32 index);