diff --git a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs index 633b1544582d3..5aa5a6a0f0f69 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs @@ -138,8 +138,8 @@ public static unsafe void Copy(Array sourceArray, Array destinationArray, int le MethodTable* pMT = RuntimeHelpers.GetMethodTable(sourceArray); if (pMT == RuntimeHelpers.GetMethodTable(destinationArray) && !pMT->IsMultiDimensionalArray && - (uint)length <= (nuint)sourceArray.LongLength && - (uint)length <= (nuint)destinationArray.LongLength) + (uint)length <= sourceArray.NativeLength && + (uint)length <= destinationArray.NativeLength) { nuint byteCount = (uint)length * (nuint)pMT->ComponentSize; ref byte src = ref Unsafe.As(sourceArray).Data; @@ -169,8 +169,8 @@ public static unsafe void Copy(Array sourceArray, int sourceIndex, Array destina if (pMT == RuntimeHelpers.GetMethodTable(destinationArray) && !pMT->IsMultiDimensionalArray && length >= 0 && sourceIndex >= 0 && destinationIndex >= 0 && - (uint)(sourceIndex + length) <= (nuint)sourceArray.LongLength && - (uint)(destinationIndex + length) <= (nuint)destinationArray.LongLength) + (uint)(sourceIndex + length) <= sourceArray.NativeLength && + (uint)(destinationIndex + length) <= destinationArray.NativeLength) { nuint elementSize = (nuint)pMT->ComponentSize; nuint byteCount = (uint)length * elementSize; @@ -214,9 +214,9 @@ private static unsafe void Copy(Array sourceArray, int sourceIndex, Array destin throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_ArrayLB); destinationIndex -= dstLB; - if ((uint)(sourceIndex + length) > (nuint)sourceArray.LongLength) + if ((uint)(sourceIndex + length) > sourceArray.NativeLength) throw new ArgumentException(SR.Arg_LongerThanSrcArray, nameof(sourceArray)); - if ((uint)(destinationIndex + length) > (nuint)destinationArray.LongLength) + if ((uint)(destinationIndex + length) > destinationArray.NativeLength) throw new ArgumentException(SR.Arg_LongerThanDestArray, nameof(destinationArray)); if (sourceArray.GetType() == destinationArray.GetType() || IsSimpleCopy(sourceArray, destinationArray)) @@ -287,7 +287,7 @@ public static unsafe void Clear(Array array, int index, int length) int offset = index - lowerBound; - if (index < lowerBound || offset < 0 || length < 0 || (uint)(offset + length) > (nuint)array.LongLength) + if (index < lowerBound || offset < 0 || length < 0 || (uint)(offset + length) > array.NativeLength) ThrowHelper.ThrowIndexOutOfRangeException(); nuint elementSize = pMT->ComponentSize; @@ -340,7 +340,10 @@ private unsafe nint GetFlattenedIndex(ReadOnlySpan indices) public int Length => checked((int)Unsafe.As(this).Length); - public long LongLength => Unsafe.As(this).Length; + // This could return a length greater than int.MaxValue + internal nuint NativeLength => Unsafe.As(this).Length; + + public long LongLength => (long)NativeLength; public unsafe int Rank { diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.Enumerators.cs b/src/libraries/System.Private.CoreLib/src/System/Array.Enumerators.cs index da01cb5fe9e1a..04c972c0a3c45 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.Enumerators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.Enumerators.cs @@ -26,9 +26,9 @@ public object Clone() public bool MoveNext() { nint index = _index + 1; - if ((nuint)index >= (nuint)_array.LongLength) + if ((nuint)index >= _array.NativeLength) { - _index = (nint)_array.LongLength; + _index = (nint)_array.NativeLength; return false; } _index = index; @@ -42,7 +42,7 @@ public object? Current nint index = _index; Array array = _array; - if ((nuint)index >= (nuint)array.LongLength) + if ((nuint)index >= array.NativeLength) { if (index < 0) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index d81870abf782e..5d9f18e91c574 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -26,7 +26,7 @@ public static unsafe void BlockCopy(Array src, int srcOffset, Array dst, int dst if (dst == null) throw new ArgumentNullException(nameof(dst)); - nuint uSrcLen = (nuint)src.LongLength; + nuint uSrcLen = src.NativeLength; if (src.GetType() != typeof(byte[])) { if (!src.GetCorElementTypeOfElementType().IsPrimitiveType()) @@ -37,7 +37,7 @@ public static unsafe void BlockCopy(Array src, int srcOffset, Array dst, int dst nuint uDstLen = uSrcLen; if (src != dst) { - uDstLen = (nuint)dst.LongLength; + uDstLen = dst.NativeLength; if (dst.GetType() != typeof(byte[])) { if (!dst.GetCorElementTypeOfElementType().IsPrimitiveType()) @@ -73,7 +73,7 @@ public static int ByteLength(Array array) if (!array.GetCorElementTypeOfElementType().IsPrimitiveType()) throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array)); - nuint byteLength = (nuint)array.LongLength * (nuint)array.GetElementSize(); + nuint byteLength = array.NativeLength * (nuint)array.GetElementSize(); // This API is explosed both as Buffer.ByteLength and also used indirectly in argument // checks for Buffer.GetByte/SetByte. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs index 5c4c319d883ac..ae0c0f8f74a2f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs @@ -25,7 +25,7 @@ public ArrayWithOffset(object? array, int offset) throw new ArgumentException(SR.ArgumentException_NotIsomorphic); } - nuint nativeTotalSize = (nuint)arrayObj.LongLength * (nuint)arrayObj.GetElementSize(); + nuint nativeTotalSize = arrayObj.NativeLength * (nuint)arrayObj.GetElementSize(); if (nativeTotalSize > MaxSizeForInterop) { throw new ArgumentException(SR.Argument_StructArrayTooLarge); diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs index c56c972ad6157..8c49dc5f3eff9 100644 --- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs @@ -36,6 +36,12 @@ public int Length get => Length; } + // This could return a length greater than int.MaxValue + internal nuint NativeLength + { + get => (nuint)Unsafe.As(this).Count; + } + public long LongLength { get @@ -63,7 +69,7 @@ public static unsafe void Clear(Array array, int index, int length) int lowerBound = array.GetLowerBound(0); int elementSize = array.GetElementSize(); - nuint numComponents = (nuint)(nint)Unsafe.As(array).Count; + nuint numComponents = array.NativeLength; int offset = index - lowerBound;