From: Ahson Khan Date: Tue, 14 Nov 2017 15:31:48 +0000 (-0800) Subject: Add object null checks in Memory APIs to support default (#14816) X-Git-Tag: accepted/tizen/base/20180629.140029~575 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fffa91039bcf96c774d7244e68387740225ee8eb;p=platform%2Fupstream%2Fcoreclr.git Add object null checks in Memory APIs to support default (#14816) * Add object null checks in Memory APIs to support default * Changing Empty property to return default value. * Update use of object null checks * Addressing PR feedback. * Removing typeof char check. * Fix typo --- diff --git a/src/mscorlib/shared/System/Memory.cs b/src/mscorlib/shared/System/Memory.cs index d83bd58..e66a61e 100644 --- a/src/mscorlib/shared/System/Memory.cs +++ b/src/mscorlib/shared/System/Memory.cs @@ -20,7 +20,7 @@ namespace System // The highest order bit of _index is used to discern whether _object is an array/string or an owned memory // if (_index >> 31) == 1, object _object is an OwnedMemory - // else, object _object is a T[] or a string. It can only be a string if the Memory was created by + // else, object _object is a T[] or a string. It can only be a string if the Memory was created by // using unsafe / marshaling code to reinterpret a ReadOnlyMemory wrapped around a string as // a Memory. private readonly object _object; @@ -122,7 +122,7 @@ namespace System /// /// Returns an empty /// - public static Memory Empty { get; } = Array.Empty(); + public static Memory Empty => default; /// /// The number of items in the memory. @@ -187,15 +187,19 @@ namespace System { // This is dangerous, returning a writable span for a string that should be immutable. // However, we need to handle the case where a ReadOnlyMemory was created from a string - // and then cast to a Memory. Such a cast can only be done with unsafe or marshaling code, + // and then cast to a Memory. Such a cast can only be done with unsafe or marshaling code, // in which case that's the dangerous operation performed by the dev, and we're just following // suit here to make it work as best as possible. return new Span(ref Unsafe.As(ref s.GetRawStringData()), s.Length).Slice(_index, _length); } - else + else if (_object != null) { return new Span((T[])_object, _index, _length); } + else + { + return default; + } } } @@ -224,7 +228,7 @@ namespace System public unsafe MemoryHandle Retain(bool pin = false) { - MemoryHandle memoryHandle; + MemoryHandle memoryHandle = default; if (pin) { if (_index < 0) @@ -243,9 +247,8 @@ namespace System void* pointer = Unsafe.Add(Unsafe.AsPointer(ref s.GetRawStringData()), _index); memoryHandle = new MemoryHandle(null, pointer, handle); } - else + else if (_object is T[] array) { - var array = (T[])_object; var handle = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer = Unsafe.Add(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index); memoryHandle = new MemoryHandle(null, pointer, handle); @@ -258,10 +261,6 @@ namespace System ((OwnedMemory)_object).Retain(); memoryHandle = new MemoryHandle((OwnedMemory)_object); } - else - { - memoryHandle = new MemoryHandle(null); - } } return memoryHandle; } @@ -280,14 +279,10 @@ namespace System return true; } } - else + else if (_object is T[] arr) { - T[] arr = _object as T[]; - if (typeof(T) != typeof(char) || arr != null) - { - arraySegment = new ArraySegment(arr, _index, _length); - return true; - } + arraySegment = new ArraySegment(arr, _index, _length); + return true; } arraySegment = default(ArraySegment); @@ -333,7 +328,7 @@ namespace System [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - return CombineHashCodes(_object.GetHashCode(), _index.GetHashCode(), _length.GetHashCode()); + return _object != null ? CombineHashCodes(_object.GetHashCode(), _index.GetHashCode(), _length.GetHashCode()) : 0; } private static int CombineHashCodes(int left, int right) diff --git a/src/mscorlib/shared/System/ReadOnlyMemory.cs b/src/mscorlib/shared/System/ReadOnlyMemory.cs index 1b163dd..d68f622 100644 --- a/src/mscorlib/shared/System/ReadOnlyMemory.cs +++ b/src/mscorlib/shared/System/ReadOnlyMemory.cs @@ -75,7 +75,7 @@ namespace System _length = length; } - /// Creates a new memory over the existing object, start, and length. No validation is performed. + /// Creates a new memory over the existing object, start, and length. No validation is performed. /// The target object. /// The index at which to begin the memory. /// The number of items in the memory. @@ -104,7 +104,7 @@ namespace System /// /// Returns an empty /// - public static ReadOnlyMemory Empty { get; } = Array.Empty(); + public static ReadOnlyMemory Empty => default; /// /// The number of items in the memory. @@ -169,10 +169,14 @@ namespace System { return new ReadOnlySpan(ref Unsafe.As(ref s.GetRawStringData()), s.Length).Slice(_index, _length); } - else + else if (_object != null) { return new ReadOnlySpan((T[])_object, _index, _length); } + else + { + return default; + } } } @@ -206,7 +210,7 @@ namespace System /// public unsafe MemoryHandle Retain(bool pin = false) { - MemoryHandle memoryHandle; + MemoryHandle memoryHandle = default; if (pin) { if (_index < 0) @@ -220,9 +224,8 @@ namespace System void* pointer = Unsafe.Add(Unsafe.AsPointer(ref s.GetRawStringData()), _index); memoryHandle = new MemoryHandle(null, pointer, handle); } - else + else if (_object is T[] array) { - var array = (T[])_object; var handle = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer = Unsafe.Add(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index); memoryHandle = new MemoryHandle(null, pointer, handle); @@ -235,10 +238,6 @@ namespace System ((OwnedMemory)_object).Retain(); memoryHandle = new MemoryHandle((OwnedMemory)_object); } - else - { - memoryHandle = new MemoryHandle(null); - } } return memoryHandle; } @@ -258,14 +257,10 @@ namespace System return true; } } - else + else if (_object is T[] arr) { - T[] arr = _object as T[]; - if (typeof(T) != typeof(char) || arr != null) - { - arraySegment = new ArraySegment(arr, _index, _length); - return true; - } + arraySegment = new ArraySegment(arr, _index, _length); + return true; } arraySegment = default; @@ -313,7 +308,7 @@ namespace System [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { - return CombineHashCodes(_object.GetHashCode(), _index.GetHashCode(), _length.GetHashCode()); + return _object != null ? CombineHashCodes(_object.GetHashCode(), _index.GetHashCode(), _length.GetHashCode()) : 0; } private static int CombineHashCodes(int left, int right)