Skip to content

Commit 87d0b45

Browse files
committed
Revert "Minor code tweaks" to fix .NET Native error
This reverts commit f286447 to work around a .NET Native compiler bug causing a crash. See more details in CommunityToolkit/WindowsCommunityToolkit#3573 (comment).
1 parent 2665e8e commit 87d0b45

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

Microsoft.Toolkit/Diagnostics/Guard.Comparable.Generic.cs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
112112
// so that only the right one will actually be translated into native code.
113113
if (sizeof(T) == 1)
114114
{
115-
if (*(byte*)&value == *(byte*)&target)
115+
byte valueByte = Unsafe.As<T, byte>(ref value);
116+
byte targetByte = Unsafe.As<T, byte>(ref target);
117+
118+
if (valueByte == targetByte)
116119
{
117120
return;
118121
}
@@ -121,7 +124,10 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
121124
}
122125
else if (sizeof(T) == 2)
123126
{
124-
if (*(ushort*)&value == *(ushort*)&target)
127+
ushort valueUShort = Unsafe.As<T, ushort>(ref value);
128+
ushort targetUShort = Unsafe.As<T, ushort>(ref target);
129+
130+
if (valueUShort == targetUShort)
125131
{
126132
return;
127133
}
@@ -130,7 +136,10 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
130136
}
131137
else if (sizeof(T) == 4)
132138
{
133-
if (*(uint*)&value == *(uint*)&target)
139+
uint valueUInt = Unsafe.As<T, uint>(ref value);
140+
uint targetUInt = Unsafe.As<T, uint>(ref target);
141+
142+
if (valueUInt == targetUInt)
134143
{
135144
return;
136145
}
@@ -139,7 +148,10 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
139148
}
140149
else if (sizeof(T) == 8)
141150
{
142-
if (Bit64Compare(*(ulong*)&value, *(ulong*)&target))
151+
ulong valueULong = Unsafe.As<T, ulong>(ref value);
152+
ulong targetULong = Unsafe.As<T, ulong>(ref target);
153+
154+
if (Bit64Compare(ref valueULong, ref targetULong))
143155
{
144156
return;
145157
}
@@ -148,20 +160,26 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
148160
}
149161
else if (sizeof(T) == 16)
150162
{
151-
ulong* p0 = (ulong*)&value;
152-
ulong* p1 = (ulong*)&target;
163+
ulong valueULong0 = Unsafe.As<T, ulong>(ref value);
164+
ulong targetULong0 = Unsafe.As<T, ulong>(ref target);
153165

154-
if (Bit64Compare(p0[0], p1[0]) && Bit64Compare(p0[1], p1[1]))
166+
if (Bit64Compare(ref valueULong0, ref targetULong0))
155167
{
156-
return;
168+
ulong valueULong1 = Unsafe.Add(ref Unsafe.As<T, ulong>(ref value), 1);
169+
ulong targetULong1 = Unsafe.Add(ref Unsafe.As<T, ulong>(ref target), 1);
170+
171+
if (Bit64Compare(ref valueULong1, ref targetULong1))
172+
{
173+
return;
174+
}
157175
}
158176

159177
ThrowHelper.ThrowArgumentExceptionForBitwiseEqualTo(value, target, name);
160178
}
161179
else
162180
{
163-
Span<byte> valueBytes = new Span<byte>(&value, sizeof(T));
164-
Span<byte> targetBytes = new Span<byte>(&target, sizeof(T));
181+
Span<byte> valueBytes = new Span<byte>(Unsafe.AsPointer(ref value), sizeof(T));
182+
Span<byte> targetBytes = new Span<byte>(Unsafe.AsPointer(ref target), sizeof(T));
165183

166184
if (valueBytes.SequenceEqual(targetBytes))
167185
{
@@ -175,15 +193,16 @@ public static unsafe void IsBitwiseEqualTo<T>(T value, T target, string name)
175193
// Compares 64 bits of data from two given memory locations for bitwise equality
176194
[Pure]
177195
[MethodImpl(MethodImplOptions.AggressiveInlining)]
178-
private static unsafe bool Bit64Compare(ulong left, ulong right)
196+
private static unsafe bool Bit64Compare(ref ulong left, ref ulong right)
179197
{
180198
// Handles 32 bit case, because using ulong is inefficient
181-
if (sizeof(nint) == 4)
199+
if (sizeof(IntPtr) == 4)
182200
{
183-
uint* p0 = (uint*)&left;
184-
uint* p1 = (uint*)&right;
201+
ref int r0 = ref Unsafe.As<ulong, int>(ref left);
202+
ref int r1 = ref Unsafe.As<ulong, int>(ref right);
185203

186-
return p0[0] == p1[0] && p0[1] == p1[1];
204+
return r0 == r1 &&
205+
Unsafe.Add(ref r0, 1) == Unsafe.Add(ref r1, 1);
187206
}
188207

189208
return left == right;

0 commit comments

Comments
 (0)