diff options
author | Levi Broderick <levib@microsoft.com> | 2018-01-24 01:19:25 +0300 |
---|---|---|
committer | Levi Broderick <levib@microsoft.com> | 2018-01-24 11:16:44 +0300 |
commit | 83f35ef9a79b5cd1412aeaad8d2cb84e1bfe73c4 (patch) | |
tree | 1a2c74d55d3e86844cb1869c0bd0f826bb66f2d0 /src/System.Runtime.CompilerServices.Unsafe | |
parent | 2836df39b74713ce26dadbd9bd3448dffbf3bf30 (diff) |
Add Unsafe.IsAddressGreaterThan and IsAddressLessThan
Diffstat (limited to 'src/System.Runtime.CompilerServices.Unsafe')
4 files changed, 84 insertions, 0 deletions
diff --git a/src/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs b/src/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs index fe7fcc03c0..411b25efd2 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs @@ -30,6 +30,8 @@ namespace System.Runtime.CompilerServices public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { } public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { } public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } + public static bool IsAddressGreaterThan<T>(ref T left, ref T right) { throw null; } + public static bool IsAddressLessThan<T>(ref T left, ref T right) { throw null; } public unsafe static T Read<T>(void* source) { throw null; } public unsafe static T ReadUnaligned<T>(void* source) { throw null; } public static T ReadUnaligned<T>(ref byte source) { throw null; } diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index 07c61f177d..891f9ac201 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -419,6 +419,26 @@ ret } // end of method Unsafe::AreSame + .method public hidebysig static bool IsAddressGreaterThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.0 + ldarg.1 + cgt.un + ret + } // end of method Unsafe::IsAddressGreaterThan + + .method public hidebysig static bool IsAddressLessThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.0 + ldarg.1 + clt.un + ret + } // end of method Unsafe::IsAddressLessThan + } // end of class System.Runtime.CompilerServices.Unsafe .class private auto ansi sealed beforefieldinit System.Runtime.Versioning.NonVersionableAttribute diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml index 8c24ae6194..bb4911a411 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml @@ -201,6 +201,30 @@ <param name="right">The second reference to compare.</param> <returns><c>true</c> if <paramref name="left"/> and <paramref name="right"/> point to the same location; otherwise <c>false</c>.</returns> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressGreaterThan``1(``0@,``0@)"> + <summary> + Determines whether the memory address referenced by <paramref name="left"/> is greater than the memory address referenced by <paramref name="right"/>. + </summary> + <param name="left">The first reference to compare.</param> + <param name="right">The second reference to compare.</param> + <returns><c>true</c> if the memory address referenced by <paramref name="left"/> is greater than the memory address referenced by <paramref name="right"/>; otherwise <c>false</c>.</returns> + <remarks> + This check is conceptually similar to "(void*)(&left) > (void*)(&right)". Both parameters must reference the same object, array, or span; + or the objects being referenced must both be pinned; or both references must represent unmanaged pointers; otherwise the result is undefined. + </remarks> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressLessThan``1(``0@,``0@)"> + <summary> + Determines whether the memory address referenced by <paramref name="left"/> is less than the memory address referenced by <paramref name="right"/>. + </summary> + <param name="left">The first reference to compare.</param> + <param name="right">The second reference to compare.</param> + <returns><c>true</c> if the memory address referenced by <paramref name="left"/> is less than the memory address referenced by <paramref name="right"/>; otherwise <c>false</c>.</returns> + <remarks> + This check is conceptually similar to "(void*)(&left) < (void*)(&right)". Both parameters must reference the same object, array, or span; + or the objects being referenced must both be pinned; or both references must represent unmanaged pointers; otherwise the result is undefined. + </remarks> + </member> <member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Void*,System.Void*,System.UInt32)"> <summary> Copies bytes from the source address to the destination address. diff --git a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index fce1ae27d3..508358d907 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -609,6 +609,44 @@ namespace System.Runtime.CompilerServices } [Fact] + public static unsafe void RefIsAddressGreaterThan() + { + int[] a = new int[2]; + + Assert.False(Unsafe.IsAddressGreaterThan(ref a[0], ref a[0])); + Assert.False(Unsafe.IsAddressGreaterThan(ref a[0], ref a[1])); + Assert.True(Unsafe.IsAddressGreaterThan(ref a[1], ref a[0])); + Assert.False(Unsafe.IsAddressGreaterThan(ref a[1], ref a[1])); + + // The following tests ensure that we're using unsigned comparison logic + + Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(1)), ref Unsafe.AsRef<byte>((void*)(-1)))); + Assert.True(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(-1)), ref Unsafe.AsRef<byte>((void*)(1)))); + Assert.True(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)))); + Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)))); + Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>(null), ref Unsafe.AsRef<byte>(null))); + } + + [Fact] + public static unsafe void RefIsAddressLessThan() + { + int[] a = new int[2]; + + Assert.False(Unsafe.IsAddressLessThan(ref a[0], ref a[0])); + Assert.True(Unsafe.IsAddressLessThan(ref a[0], ref a[1])); + Assert.False(Unsafe.IsAddressLessThan(ref a[1], ref a[0])); + Assert.False(Unsafe.IsAddressLessThan(ref a[1], ref a[1])); + + // The following tests ensure that we're using unsigned comparison logic + + Assert.True(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(1)), ref Unsafe.AsRef<byte>((void*)(-1)))); + Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(-1)), ref Unsafe.AsRef<byte>((void*)(1)))); + Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)))); + Assert.True(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)))); + Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>(null), ref Unsafe.AsRef<byte>(null))); + } + + [Fact] public static unsafe void ReadUnaligned_ByRef_Int32() { byte[] unaligned = Int32Double.Unaligned(123456789, 3.42); |