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);