diff options
3 files changed, 140 insertions, 0 deletions
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 f1d96ad9e4..c8a5758f4e 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 @@ -248,6 +248,28 @@ ret } // end of method Unsafe::Add + .method public hidebysig static !!T& Add<T>(!!T& source, native int elementOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + sizeof !!T + mul + add + ret + } // end of method Unsafe::Add + + .method public hidebysig static !!T& AddByteOffset<T>(!!T& source, native int byteOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.0 + ldarg.1 + add + ret + } // end of method Unsafe::AddByteOffset + .method public hidebysig static !!T& Subtract<T>(!!T& source, int32 elementOffset) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) @@ -261,6 +283,28 @@ ret } // end of method Unsafe::Subtract + .method public hidebysig static !!T& Subtract<T>(!!T& source, native int elementOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + sizeof !!T + mul + sub + ret + } // end of method Unsafe::Subtract + + .method public hidebysig static !!T& SubtractByteOffset<T>(!!T& source, native int byteOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.0 + ldarg.1 + sub + ret + } // end of method Unsafe::SubtractByteOffset + .method public hidebysig static bool AreSame<T>(!!T& left, !!T& right) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) 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 7f98bc9a46..a2dd77301b 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 @@ -90,6 +90,24 @@ <param name="elementOffset">The offset to add.</param> <returns>A new reference that reflects the addition of offset to pointer.</returns> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.IntPtr)"> + <summary> + Adds an element offset to the given reference. + </summary> + <typeparam name="T">The type of reference.</typeparam> + <param name="source">The reference to add the offset to.</param> + <param name="elementOffset">The offset to add.</param> + <returns>A new reference that reflects the addition of offset to pointer.</returns> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.AddByteOffset``1(``0@,System.IntPtr)"> + <summary> + Adds a byte offset to the given reference. + </summary> + <typeparam name="T">The type of reference.</typeparam> + <param name="source">The reference to add the offset to.</param> + <param name="byteOffset">The offset to add.</param> + <returns>A new reference that reflects the addition of byte offset to pointer.</returns> + </member> <member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.Int32)"> <summary> Subtracts an element offset from the given reference. @@ -99,6 +117,24 @@ <param name="elementOffset">The offset to subtract.</param> <returns>A new reference that reflects the subraction of offset from pointer.</returns> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.IntPtr)"> + <summary> + Subtracts an element offset from the given reference. + </summary> + <typeparam name="T">The type of reference.</typeparam> + <param name="source">The reference to subtract the offset from.</param> + <param name="elementOffset">The offset to subtract.</param> + <returns>A new reference that reflects the subraction of offset from pointer.</returns> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.SubtractByteOffset``1(``0@,System.IntPtr)"> + <summary> + Subtracts a byte offset from the given reference. + </summary> + <typeparam name="T">The type of reference.</typeparam> + <param name="source">The reference to subtract the offset from.</param> + <param name="bytesOffset">The offset to subtract.</param> + <returns>A new reference that reflects the subraction of byte offset from pointer.</returns> + </member> <member name="M:System.Runtime.CompilerServices.Unsafe.AreSame``1(``0@,``0@)"> <summary> Determines whether the specified references point to the same location. diff --git a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index ab8067c1d0..2a90b63525 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -432,6 +432,36 @@ namespace System.Runtime.CompilerServices } [Fact] + public static void RefAddIntPtr() + { + int[] a = new int[] { 0x123, 0x234, 0x345, 0x456 }; + + ref int r1 = ref Unsafe.Add(ref a[0], (IntPtr)1); + Assert.Equal(0x234, r1); + + ref int r2 = ref Unsafe.Add(ref r1, (IntPtr)2); + Assert.Equal(0x456, r2); + + ref int r3 = ref Unsafe.Add(ref r2, (IntPtr)-3); + Assert.Equal(0x123, r3); + } + + [Fact] + public static void RefAddByteOffset() + { + byte[] a = new byte[] { 0x12, 0x34, 0x56, 0x78 }; + + ref int r1 = ref Unsafe.AddByteOffset(ref a[0], (IntPtr)1); + Assert.Equal(0x34, r1); + + ref int r2 = ref Unsafe.AddByteOffset(ref r1, (IntPtr)2); + Assert.Equal(0x78, r2); + + ref int r3 = ref Unsafe.AddByteOffset(ref r2, (IntPtr) - 3); + Assert.Equal(0x12, r3); + } + + [Fact] public static void RefSubtract() { string[] a = new string[] { "abc", "def", "ghi", "jkl" }; @@ -447,6 +477,36 @@ namespace System.Runtime.CompilerServices } [Fact] + public static void RefSubtractIntPtr() + { + string[] a = new string[] { "abc", "def", "ghi", "jkl" }; + + ref string r1 = ref Unsafe.Subtract(ref a[0], (IntPtr)-2); + Assert.Equal("ghi", r1); + + ref string r2 = ref Unsafe.Subtract(ref r1, (IntPtr)-1); + Assert.Equal("jkl", r2); + + ref string r3 = ref Unsafe.Subtract(ref r2, (IntPtr)3); + Assert.Equal("abc", r3); + } + + [Fact] + public static void RefSubtractByteOffset() + { + byte[] a = new byte[] { 0x12, 0x34, 0x56, 0x78 }; + + ref int r1 = ref Unsafe.SubtractByteOffset(ref a[0], (IntPtr)-1); + Assert.Equal(0x34, r1); + + ref int r2 = ref Unsafe.SubtractByteOffset(ref r1, (IntPtr)-2); + Assert.Equal(0x78, r2); + + ref int r3 = ref Unsafe.SubtractByteOffset(ref r2, (IntPtr)3); + Assert.Equal(0x12, r3); + } + + [Fact] public static void RefAreSame() { long[] a = new long[2]; |