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 acaeb1669d14..ce31a59b5a1e 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 @@ -58,7 +58,7 @@ .class public abstract auto ansi sealed beforefieldinit System.Runtime.CompilerServices.Unsafe extends [System.Runtime]System.Object { - .method public hidebysig static !!T Read(void* source) cil managed aggressiveinlining + .method public hidebysig static !!T Read(void* source) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 1 @@ -157,6 +157,50 @@ ret } // end of method Unsafe::AsRef + .method public hidebysig static !!TTo& As(!!TFrom& source) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 1 + ldarg.0 + ret + } // end of method Unsafe::AsRef + + .method public hidebysig static !!T& Add(!!T& source, int32 elementOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + sizeof !!T + conv.i + mul + add + ret + } + + .method public hidebysig static !!T& Subtract(!!T& source, int32 elementOffset) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + sizeof !!T + conv.i + mul + sub + ret + } + + .method public hidebysig static bool AreSame(!!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 + ceq + ret + } + } // 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.ilproj b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj index aedb5ac29c89..1d015dec99ea 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.ilproj @@ -2,7 +2,7 @@ - 4.0.1.0 + 4.0.2.0 netstandard1.0 $(MSBuildThisFileDirectory)System.Runtime.CompilerServices.Unsafe.xml 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 3e0759fee3a5..4fdac0260f10 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 @@ -72,6 +72,42 @@ The location of the value to reference. A reference to a value of type T. + + + Reinterprets the given reference as a reference to a value of type U. + + The type of reference to reinterpret. + The desired type of the reference. + The reference to reinterpret. + A reference to a value of type TTo. + + + + Adds element offset to the given reference. + + The type of reference. + The reference to add the offset to. + The offset to add. + A new reference that reflects the addition of offset to pointer. + + + + Adds element offset to the given reference. + + The type of reference. + The reference to subtract the offset from. + The offset to subtract. + A new reference that reflects the addition of offset to pointer. + + + + Determines whether the specified references point to the same location. + + The first reference to compare. + The second reference to compare. + true if left and right point to the same location; otherwise false. + + 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 4f4f4af97987..ba9a380345c9 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -235,6 +235,75 @@ public static void DangerousAs() object o = new Object(); Assert.IsType(typeof(Object), Unsafe.As(o)); } + + // Active Issue: https://github.com/dotnet/coreclr/issues/6505 + // These tests require C# compiler with support for ref returns and locals +#if false + [Fact] + public unsafe static void AsRef() + { + byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 }; + fixed (byte * p = b) + { + ref int r = ref Unsafe.AsRef(p); + Assert.Equal(r, 0x42424242); + + r = 0x0EF00EF0; + Assert.Equal(b[0] | b[1] | b[2] | b[3], 0xFE); + } + } + + [Fact] + public static void RefAs() + { + byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 }; + + ref int r = ref Unsafe.As(ref b[0]); + Assert.Equal(r, 0x42424242); + + r = 0x0EF00EF0; + Assert.Equal(b[0] | b[1] | b[2] | b[3], 0xFE); + } + + [Fact] + public static void RefAdd() + { + int[] a = new int[] { 0x123, 0x234, 0x345, 0x456 }; + + ref int r1 = ref Unsafe.Add(ref a[0], 1); + Assert.Equal(r1, 0x234); + + ref int r2 = ref Unsafe.Add(ref r1, 2); + Assert.Equal(r2, 0x456); + + ref int r3 = ref Unsafe.Add(ref r2, -3); + Assert.Equal(r3, 0x123); + } + + [Fact] + public static void RefSubtract() + { + string[] a = new string[] { "abc", "def", "ghi", "jkl" }; + + ref string r1 = ref Unsafe.Subtract(ref a[0], -2); + Assert.Equal(r1, "ghi"); + + ref string r2 = ref Unsafe.Subtract(ref r1, -1); + Assert.Equal(r2, "jkl"); + + ref string r3 = ref Unsafe.Subtract(ref r2, 3); + Assert.Equal(r3, "abc"); + } + + [Fact] + public static void RefAreSame() + { + long[] a = new long[2]; + + Assert.True(Unsafe.AreSame(ref a[0], ref a[0])); + Assert.False(Unsafe.AreSame(ref a[0], ref a[1])); + } +#endif } [StructLayout(LayoutKind.Explicit)]