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 7db11a82041778..4b0967e372bbcb 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 @@ -120,6 +120,32 @@ public static unsafe Array NewMultiDimArray(RuntimeTypeHandle typeHandleForArray return Array.NewMultiDimArray(typeHandleForArrayType.ToMethodTable(), pImmutableLengths, lengths.Length); } + public static unsafe void SetArrayValue(Array array, int[] indices, object value) + { + MethodTable* elementMT = array.ElementMethodTable; + + if (elementMT->IsPointer || elementMT->IsFunctionPointer) + { + Debug.Assert(value.GetMethodTable()->ValueTypeSize == IntPtr.Size); + elementMT = value.GetMethodTable(); + } + + if (elementMT->IsValueType) + { + Debug.Assert(value.GetMethodTable()->IsValueType && elementMT->ValueTypeSize == value.GetMethodTable()->ValueTypeSize); + nint flattenedIndex = array.GetFlattenedIndex(indices); + ref byte element = ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(array), (nuint)flattenedIndex * array.ElementSize); + RuntimeImports.RhUnbox(value, ref element, elementMT); + } + else + { + RuntimeImports.RhCheckArrayStore(array, value); + nint flattenedIndex = array.GetFlattenedIndex(indices); + ref object element = ref Unsafe.Add(ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(array)), flattenedIndex); + element = value; + } + } + public static IntPtr GetAllocateObjectHelperForType(RuntimeTypeHandle type) { return RuntimeImports.RhGetRuntimeHelperForType(type.ToMethodTable(), RuntimeHelperKind.AllocateObject); 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 58378b92a9c5f0..faa4d51e935325 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 @@ -727,7 +727,7 @@ private unsafe nint GetFlattenedIndex(int rawIndex) return rawIndex; } - private unsafe nint GetFlattenedIndex(ReadOnlySpan indices) + internal unsafe nint GetFlattenedIndex(ReadOnlySpan indices) { // Checked by the caller Debug.Assert(indices.Length == Rank); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs index ab9fd61a3587ea..1f2f374b2436ec 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs @@ -213,7 +213,7 @@ internal sealed override IEnumerable SyntheticMethods for (int i = 0; i < rank; i++) indices[i] = (int)(args[i]); object value = args[rank]; - array.SetValue(value, indices); + RuntimeAugments.SetArrayValue(array, indices, value); return null; } );