diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
index 89eedc1638a72..7f95b9bd401fc 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
@@ -16,6 +16,21 @@ namespace System.Runtime.CompilerServices
///
public static unsafe class Unsafe
{
+ ///
+ /// Determines the byte offset from origin to target from the given references.
+ ///
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static IntPtr ByteOffset(ref readonly T origin, ref readonly T target)
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg .1
+ // ldarg .0
+ // sub
+ // ret
+ }
+
///
/// Returns a pointer to the given by-ref parameter.
///
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
index b7a1863d3727d..ae2b81bfa418d 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
@@ -73,7 +73,6 @@ public static unsafe object RhNewArray(MethodTable* pEEType, int length)
}
}
- [RuntimeExport("RhBox")]
public static unsafe object RhBox(MethodTable* pEEType, ref byte data)
{
// A null can be passed for boxing of a null ref.
@@ -207,7 +206,6 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, MethodTable* pUnb
//
// Unbox helpers with RyuJIT conventions
//
- [RuntimeExport("RhUnbox2")]
public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj)
{
if ((obj == null) || !UnboxAnyTypeCompare(obj.GetMethodTable(), pUnboxToEEType))
@@ -218,7 +216,6 @@ public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj)
return ref obj.GetRawData();
}
- [RuntimeExport("RhUnboxNullable")]
public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEEType, object obj)
{
if (obj != null && obj.GetMethodTable() != pUnboxToEEType->NullableType)
@@ -228,7 +225,6 @@ public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEE
RhUnbox(obj, ref data, pUnboxToEEType);
}
- [RuntimeExport("RhUnboxTypeTest")]
public static unsafe void RhUnboxTypeTest(MethodTable* pType, MethodTable* pBoxType)
{
Debug.Assert(pType->IsValueType);
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
index 20427987539c3..8425f31f16cc1 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
@@ -63,7 +63,6 @@ internal enum AssignmentVariation
// IsInstanceOf test used for unusual cases (naked type parameters, variant generic types)
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
// this test must deal with all kinds of type tests
- [RuntimeExport("RhTypeCast_IsInstanceOfAny")]
public static unsafe object? IsInstanceOfAny(MethodTable* pTargetType, object? obj)
{
if (obj != null)
@@ -94,7 +93,6 @@ internal enum AssignmentVariation
return IsInstanceOfAny_NoCacheLookup(pTargetType, obj);
}
- [RuntimeExport("RhTypeCast_IsInstanceOfInterface")]
public static unsafe object? IsInstanceOfInterface(MethodTable* pTargetType, object? obj)
{
Debug.Assert(pTargetType->IsInterface);
@@ -184,7 +182,6 @@ internal enum AssignmentVariation
return obj;
}
- [RuntimeExport("RhTypeCast_IsInstanceOfClass")]
public static unsafe object? IsInstanceOfClass(MethodTable* pTargetType, object? obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "IsInstanceOfClass called with parameterized MethodTable");
@@ -248,7 +245,6 @@ internal enum AssignmentVariation
return obj;
}
- [RuntimeExport("RhTypeCast_IsInstanceOfException")]
public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object? obj)
{
// Based on IsInstanceOfClass
@@ -279,7 +275,6 @@ public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object
// ChkCast test used for unusual cases (naked type parameters, variant generic types)
// Unlike the ChkCastInterface and ChkCastClass functions,
// this test must deal with all kinds of type tests
- [RuntimeExport("RhTypeCast_CheckCastAny")]
public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj)
{
CastResult result;
@@ -307,7 +302,6 @@ public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj)
return objRet;
}
- [RuntimeExport("RhTypeCast_CheckCastInterface")]
public static unsafe object CheckCastInterface(MethodTable* pTargetType, object obj)
{
Debug.Assert(pTargetType->IsInterface);
@@ -393,7 +387,6 @@ private static unsafe object CheckCastInterface_Helper(MethodTable* pTargetType,
return ThrowInvalidCastException(pTargetType);
}
- [RuntimeExport("RhTypeCast_CheckCastClass")]
public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClass called with parameterized MethodTable");
@@ -411,7 +404,6 @@ public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj)
// Optimized helper for classes. Assumes that the trivial cases
// has been taken care of by the inlined check
- [RuntimeExport("RhTypeCast_CheckCastClassSpecial")]
private static unsafe object CheckCastClassSpecial(MethodTable* pTargetType, object obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClassSpecial called with parameterized MethodTable");
@@ -761,8 +753,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array)
//
// Array stelem/ldelema helpers with RyuJIT conventions
//
-
- [RuntimeExport("RhpLdelemaRef")]
public static unsafe ref object? LdelemaRef(object?[] array, nint index, MethodTable* elementType)
{
Debug.Assert(array is null || array.GetMethodTable()->IsArray, "first argument must be an array");
@@ -794,7 +784,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array)
return ref element;
}
- [RuntimeExport("RhpStelemRef")]
public static unsafe void StelemRef(object?[] array, nint index, object? obj)
{
// This is supported only on arrays
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
index 363a544f8c74d..6fb23a261f333 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
@@ -216,7 +216,7 @@ public static unsafe void StoreValueTypeField(IntPtr address, object fieldValue,
public static unsafe object LoadValueTypeField(IntPtr address, RuntimeTypeHandle fieldType)
{
- return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address);
+ return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address);
}
public static unsafe object LoadPointerTypeField(IntPtr address, RuntimeTypeHandle fieldType)
@@ -236,7 +236,7 @@ public static unsafe void StoreValueTypeField(object obj, int fieldOffset, objec
public static unsafe object LoadValueTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType)
{
ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize));
- return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref address);
+ return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref address);
}
public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType)
@@ -244,7 +244,7 @@ public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, Ru
ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize));
if (fieldType.ToMethodTable()->IsFunctionPointer)
- return RuntimeImports.RhBox(MethodTable.Of(), ref address);
+ return RuntimeExports.RhBox(MethodTable.Of(), ref address);
return ReflectionPointer.Box((void*)Unsafe.As(ref address), Type.GetTypeFromHandle(fieldType));
}
@@ -285,7 +285,7 @@ public static object LoadValueTypeFieldValueFromValueType(TypedReference typedRe
Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType);
Debug.Assert(fieldTypeHandle.ToMethodTable()->IsValueType);
- return RuntimeImports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset));
+ return RuntimeExports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset));
}
[CLSCompliant(false)]
@@ -391,7 +391,7 @@ public static bool IsInterface(RuntimeTypeHandle type)
public static unsafe object Box(RuntimeTypeHandle type, IntPtr address)
{
- return RuntimeImports.RhBox(type.ToMethodTable(), ref *(byte*)address);
+ return RuntimeExports.RhBox(type.ToMethodTable(), ref *(byte*)address);
}
//==============================================================================================
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
index dc30aaecd1f06..09439509355e8 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
@@ -330,7 +330,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex
for (int i = 0; i < length; i++)
{
object? value = Unsafe.Add(ref refSourceArray, sourceIndex - i);
- if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null)
+ if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null)
throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement);
Unsafe.Add(ref refDestinationArray, destinationIndex - i) = value;
}
@@ -340,7 +340,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex
for (int i = 0; i < length; i++)
{
object? value = Unsafe.Add(ref refSourceArray, sourceIndex + i);
- if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null)
+ if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null)
throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement);
Unsafe.Add(ref refDestinationArray, destinationIndex + i) = value;
}
@@ -370,7 +370,7 @@ private static unsafe void CopyImplValueTypeArrayToReferenceArray(Array sourceAr
ref object refDestinationArray = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(destinationArray));
for (int i = 0; i < length; i++)
{
- object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pElement);
+ object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pElement);
Unsafe.Add(ref refDestinationArray, destinationIndex + i) = boxedValue;
pElement += sourceElementSize;
}
@@ -457,7 +457,7 @@ private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArr
pDestinationElement -= cbElementSize;
}
- object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pSourceElement);
+ object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pSourceElement);
if (boxedElements != null)
boxedElements[i] = boxedValue;
else
@@ -768,7 +768,7 @@ internal unsafe nint GetFlattenedIndex(ReadOnlySpan indices)
MethodTable* pElementEEType = ElementMethodTable;
if (pElementEEType->IsValueType)
{
- return RuntimeImports.RhBox(pElementEEType, ref element);
+ return RuntimeExports.RhBox(pElementEEType, ref element);
}
else
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
index b6fc499829d17..61a2d5367c7cb 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
@@ -133,7 +133,7 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje
if (dstElementType == srcElementType)
{
// Rebox the value if the EETypeElementTypes match
- dstObject = RuntimeImports.RhBox(dstEEType, ref srcObject.GetRawData());
+ dstObject = RuntimeExports.RhBox(dstEEType, ref srcObject.GetRawData());
}
else
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
index 45bc2f9e19978..d7837bdc649e1 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
@@ -783,7 +783,7 @@ private unsafe void CopyBackToArray(ref object? src, object?[] dest)
}
else
{
- obj = RuntimeImports.RhBox(
+ obj = RuntimeExports.RhBox(
(transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type,
ref obj.GetRawData());
}
@@ -818,7 +818,7 @@ private unsafe void CopyBackToSpan(Span