summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAhson Khan <ahkha@microsoft.com>2018-02-02 19:30:25 -0800
committerGitHub <noreply@github.com>2018-02-02 19:30:25 -0800
commit4456cc99ba0fbe3c02be3a9f54c34282caeb7218 (patch)
treeba670df7ce6a071a406a296e3a534bad35dd2276 /src
parent94ab205d5545699a49cc54d72e9d3d07a454f10a (diff)
downloadcoreclr-4456cc99ba0fbe3c02be3a9f54c34282caeb7218.tar.gz
coreclr-4456cc99ba0fbe3c02be3a9f54c34282caeb7218.tar.bz2
coreclr-4456cc99ba0fbe3c02be3a9f54c34282caeb7218.zip
Changing Span/Memory to return default on null instead of throwing. (#16186)
* Additional changes based on feedback (bounds checks) * Adding remaining bounds checks
Diffstat (limited to 'src')
-rw-r--r--src/mscorlib/shared/System/Memory.cs20
-rw-r--r--src/mscorlib/shared/System/ReadOnlyMemory.cs20
-rw-r--r--src/mscorlib/shared/System/ReadOnlySpan.Fast.cs16
-rw-r--r--src/mscorlib/shared/System/ReadOnlySpan.cs14
-rw-r--r--src/mscorlib/shared/System/Span.Fast.cs16
-rw-r--r--src/mscorlib/shared/System/Span.NonGeneric.cs55
-rw-r--r--src/mscorlib/shared/System/Span.cs14
7 files changed, 98 insertions, 57 deletions
diff --git a/src/mscorlib/shared/System/Memory.cs b/src/mscorlib/shared/System/Memory.cs
index 4df630f764..8fc5b04ee4 100644
--- a/src/mscorlib/shared/System/Memory.cs
+++ b/src/mscorlib/shared/System/Memory.cs
@@ -40,14 +40,16 @@ namespace System
/// Creates a new memory over the entirety of the target array.
/// </summary>
/// <param name="array">The target array.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory(T[] array)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ this = default;
+ return; // returns default
+ }
if (default(T) == null && array.GetType() != typeof(T[]))
ThrowHelper.ThrowArrayTypeMismatchException();
@@ -63,8 +65,7 @@ namespace System
/// <param name="array">The target array.</param>
/// <param name="start">The index at which to begin the memory.</param>
/// <param name="length">The number of items in the memory.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
@@ -73,7 +74,12 @@ namespace System
public Memory(T[] array, int start, int length)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+ this = default;
+ return; // returns default
+ }
if (default(T) == null && array.GetType() != typeof(T[]))
ThrowHelper.ThrowArrayTypeMismatchException();
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
@@ -106,7 +112,7 @@ namespace System
/// <summary>
/// Defines an implicit conversion of an array to a <see cref="Memory{T}"/>
/// </summary>
- public static implicit operator Memory<T>(T[] array) => (array != null) ? new Memory<T>(array) : default;
+ public static implicit operator Memory<T>(T[] array) => new Memory<T>(array);
/// <summary>
/// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="Memory{T}"/>
diff --git a/src/mscorlib/shared/System/ReadOnlyMemory.cs b/src/mscorlib/shared/System/ReadOnlyMemory.cs
index 5a8a6fcc21..166a204edb 100644
--- a/src/mscorlib/shared/System/ReadOnlyMemory.cs
+++ b/src/mscorlib/shared/System/ReadOnlyMemory.cs
@@ -38,14 +38,16 @@ namespace System
/// Creates a new memory over the entirety of the target array.
/// </summary>
/// <param name="array">The target array.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory(T[] array)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ this = default;
+ return; // returns default
+ }
_object = array;
_index = 0;
@@ -59,8 +61,7 @@ namespace System
/// <param name="array">The target array.</param>
/// <param name="start">The index at which to begin the memory.</param>
/// <param name="length">The number of items in the memory.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
@@ -69,7 +70,12 @@ namespace System
public ReadOnlyMemory(T[] array, int start, int length)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+ this = default;
+ return; // returns default
+ }
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
ThrowHelper.ThrowArgumentOutOfRangeException();
@@ -97,7 +103,7 @@ namespace System
/// <summary>
/// Defines an implicit conversion of an array to a <see cref="ReadOnlyMemory{T}"/>
/// </summary>
- public static implicit operator ReadOnlyMemory<T>(T[] array) => (array != null) ? new ReadOnlyMemory<T>(array) : default;
+ public static implicit operator ReadOnlyMemory<T>(T[] array) => new ReadOnlyMemory<T>(array);
/// <summary>
/// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="ReadOnlyMemory{T}"/>
diff --git a/src/mscorlib/shared/System/ReadOnlySpan.Fast.cs b/src/mscorlib/shared/System/ReadOnlySpan.Fast.cs
index 5c627cc166..2a30b2a927 100644
--- a/src/mscorlib/shared/System/ReadOnlySpan.Fast.cs
+++ b/src/mscorlib/shared/System/ReadOnlySpan.Fast.cs
@@ -39,13 +39,16 @@ namespace System
/// Creates a new read-only span over the entirety of the target array.
/// </summary>
/// <param name="array">The target array.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// reference (Nothing in Visual Basic).</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan(T[] array)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ this = default;
+ return; // returns default
+ }
_pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData()));
_length = array.Length;
@@ -58,7 +61,7 @@ namespace System
/// <param name="array">The target array.</param>
/// <param name="start">The index at which to begin the read-only span.</param>
/// <param name="length">The number of items in the read-only span.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// reference (Nothing in Visual Basic).</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
@@ -67,7 +70,12 @@ namespace System
public ReadOnlySpan(T[] array, int start, int length)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+ this = default;
+ return; // returns default
+ }
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
ThrowHelper.ThrowArgumentOutOfRangeException();
diff --git a/src/mscorlib/shared/System/ReadOnlySpan.cs b/src/mscorlib/shared/System/ReadOnlySpan.cs
index f0f022605e..4d747605ad 100644
--- a/src/mscorlib/shared/System/ReadOnlySpan.cs
+++ b/src/mscorlib/shared/System/ReadOnlySpan.cs
@@ -29,11 +29,11 @@ namespace System
#if !FEATURE_PORTABLE_SPAN
[NonVersionable]
#endif // !FEATURE_PORTABLE_SPAN
- get
- {
- return _length;
- }
- }
+ get
+ {
+ return _length;
+ }
+ }
/// <summary>
/// Returns true if Length is 0.
@@ -83,13 +83,13 @@ namespace System
/// <summary>
/// Defines an implicit conversion of an array to a <see cref="ReadOnlySpan{T}"/>
/// </summary>
- public static implicit operator ReadOnlySpan<T>(T[] array) => array != null ? new ReadOnlySpan<T>(array) : default;
+ public static implicit operator ReadOnlySpan<T>(T[] array) => new ReadOnlySpan<T>(array);
/// <summary>
/// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="ReadOnlySpan{T}"/>
/// </summary>
public static implicit operator ReadOnlySpan<T>(ArraySegment<T> arraySegment)
- => arraySegment.Array != null ? new ReadOnlySpan<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count) : default;
+ => new ReadOnlySpan<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
/// <summary>
/// Returns a 0-length read-only span whose base is the null pointer.
diff --git a/src/mscorlib/shared/System/Span.Fast.cs b/src/mscorlib/shared/System/Span.Fast.cs
index 1382e3d214..e0d4ec3227 100644
--- a/src/mscorlib/shared/System/Span.Fast.cs
+++ b/src/mscorlib/shared/System/Span.Fast.cs
@@ -39,14 +39,17 @@ namespace System
/// Creates a new span over the entirety of the target array.
/// </summary>
/// <param name="array">The target array.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// reference (Nothing in Visual Basic).</exception>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span(T[] array)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ this = default;
+ return; // returns default
+ }
if (default(T) == null && array.GetType() != typeof(T[]))
ThrowHelper.ThrowArrayTypeMismatchException();
@@ -61,7 +64,7 @@ namespace System
/// <param name="array">The target array.</param>
/// <param name="start">The index at which to begin the span.</param>
/// <param name="length">The number of items in the span.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
/// reference (Nothing in Visual Basic).</exception>
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
/// <exception cref="System.ArgumentOutOfRangeException">
@@ -71,7 +74,12 @@ namespace System
public Span(T[] array, int start, int length)
{
if (array == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+ this = default;
+ return; // returns default
+ }
if (default(T) == null && array.GetType() != typeof(T[]))
ThrowHelper.ThrowArrayTypeMismatchException();
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
diff --git a/src/mscorlib/shared/System/Span.NonGeneric.cs b/src/mscorlib/shared/System/Span.NonGeneric.cs
index 9ce6acdff6..679e639c58 100644
--- a/src/mscorlib/shared/System/Span.NonGeneric.cs
+++ b/src/mscorlib/shared/System/Span.NonGeneric.cs
@@ -24,25 +24,29 @@ namespace System
{
/// <summary>Creates a new <see cref="ReadOnlyMemory{char}"/> over the portion of the target string.</summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ return default;
return new ReadOnlyMemory<char>(text, 0, text.Length);
}
/// <summary>Creates a new <see cref="ReadOnlyMemory{char}"/> over the portion of the target string.</summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;text.Length).
/// </exception>
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text, int start)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ {
+ if (start != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
+ return default;
+ }
if ((uint)start > (uint)text.Length)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
@@ -52,14 +56,18 @@ namespace System
/// <summary>Creates a new <see cref="ReadOnlyMemory{char}"/> over the portion of the target string.</summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
/// </exception>
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text, int start, int length)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
+ return default;
+ }
if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
@@ -135,13 +143,13 @@ namespace System
/// Creates a new readonly span over the portion of the target string.
/// </summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
/// reference (Nothing in Visual Basic).</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<char> AsReadOnlySpan(this string text)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ return default;
return new ReadOnlySpan<char>(ref text.GetRawStringData(), text.Length);
}
@@ -150,9 +158,7 @@ namespace System
/// Creates a new readonly span over the portion of the target string.
/// </summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).
- /// </exception>
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;text.Length).
/// </exception>
@@ -160,7 +166,11 @@ namespace System
public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ {
+ if (start != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
+ return default;
+ }
if ((uint)start > (uint)text.Length)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
@@ -172,9 +182,7 @@ namespace System
/// Creates a new readonly span over the portion of the target string.
/// </summary>
/// <param name="text">The target string.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).
- /// </exception>
+ /// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
/// </exception>
@@ -182,21 +190,26 @@ namespace System
public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start, int length)
{
if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
+ return default;
+ }
if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetRawStringData(), start), length);
}
-
+
internal static unsafe void ClearWithoutReferences(ref byte b, nuint byteLength)
{
if (byteLength == 0)
return;
-
+
#if CORECLR && (AMD64 || ARM64)
- if (byteLength > 4096) goto PInvoke;
+ if (byteLength > 4096)
+ goto PInvoke;
Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength);
return;
#else
@@ -503,8 +516,8 @@ namespace System
return;
#endif
-
- PInvoke:
+
+ PInvoke:
RuntimeImports.RhZeroMemory(ref b, byteLength);
}
diff --git a/src/mscorlib/shared/System/Span.cs b/src/mscorlib/shared/System/Span.cs
index f5918110dd..106c0f7d5d 100644
--- a/src/mscorlib/shared/System/Span.cs
+++ b/src/mscorlib/shared/System/Span.cs
@@ -29,11 +29,11 @@ namespace System
#if !FEATURE_PORTABLE_SPAN
[NonVersionable]
#endif // !FEATURE_PORTABLE_SPAN
- get
- {
- return _length;
- }
- }
+ get
+ {
+ return _length;
+ }
+ }
/// <summary>
/// Returns true if Length is 0.
@@ -84,13 +84,13 @@ namespace System
/// <summary>
/// Defines an implicit conversion of an array to a <see cref="Span{T}"/>
/// </summary>
- public static implicit operator Span<T>(T[] array) => array != null ? new Span<T>(array) : default;
+ public static implicit operator Span<T>(T[] array) => new Span<T>(array);
/// <summary>
/// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="Span{T}"/>
/// </summary>
public static implicit operator Span<T>(ArraySegment<T> arraySegment)
- => arraySegment.Array != null ? new Span<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count) : default;
+ => new Span<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
/// <summary>
/// Returns an empty <see cref="Span{T}"/>