Browse Source

ILReader: support comparison between StackType.Ref and StackType.I

Update Unsafe.il tests to .NET 5.0 version.
pull/2218/head
Daniel Grunwald 5 years ago
parent
commit
6e8c1b3117
  1. 41
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs
  2. 82
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il
  3. 5
      ICSharpCode.Decompiler/IL/ILReader.cs

41
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs

@ -211,6 +211,11 @@ namespace System.Runtime.CompilerServices @@ -211,6 +211,11 @@ namespace System.Runtime.CompilerServices
return Unsafe.AsPointer(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SkipInit<T>(out T value)
{
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static int SizeOf<T>()
{
@ -321,12 +326,24 @@ namespace System.Runtime.CompilerServices @@ -321,12 +326,24 @@ namespace System.Runtime.CompilerServices
return ref Unsafe.Add(ref source, elementOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Add<T>(ref T source, UIntPtr elementOffset)
{
return ref Unsafe.Add(ref source, elementOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
{
return ref Unsafe.AddByteOffset(ref source, byteOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AddByteOffset<T>(ref T source, UIntPtr byteOffset)
{
return ref Unsafe.AddByteOffset(ref source, byteOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Subtract<T>(ref T source, int elementOffset)
{
@ -345,12 +362,24 @@ namespace System.Runtime.CompilerServices @@ -345,12 +362,24 @@ namespace System.Runtime.CompilerServices
return ref Unsafe.Subtract(ref source, elementOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Subtract<T>(ref T source, UIntPtr elementOffset)
{
return ref Unsafe.Subtract(ref source, elementOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
{
return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T SubtractByteOffset<T>(ref T source, UIntPtr byteOffset)
{
return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr ByteOffset<T>(ref T origin, ref T target)
{
@ -374,5 +403,17 @@ namespace System.Runtime.CompilerServices @@ -374,5 +403,17 @@ namespace System.Runtime.CompilerServices
{
return (ref left) < (ref right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static bool IsNullRef<T>(ref T source)
{
return Unsafe.AsPointer(ref source) == null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe static ref T NullRef<T>()
{
return ref *(T*)null;
}
}
}

82
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il

@ -77,21 +77,21 @@ @@ -77,21 +77,21 @@
.method public hidebysig static !!T ReadUnaligned<T>(void* source) cil managed aggressiveinlining
{
.maxstack 1
ldarg.0
ldarg.0
unaligned. 0x1
ldobj !!T
ret
} // end of method Unsafe::ReadUnaligned
.method public hidebysig static !!T ReadUnaligned<T>(uint8& source) cil managed aggressiveinlining
{
.maxstack 1
ldarg.0
ldarg.0
unaligned. 0x1
ldobj !!T
ret
} // end of method Unsafe::ReadUnaligned
.method public hidebysig static void Write<T>(void* destination,
!!T 'value') cil managed aggressiveinlining
{
@ -118,7 +118,7 @@ @@ -118,7 +118,7 @@
{
.maxstack 2
ldarg.0
ldarg.1
ldarg.1
unaligned. 0x01
stobj !!T
ret
@ -154,6 +154,12 @@ @@ -154,6 +154,12 @@
ret
} // end of method Unsafe::AsPointer
.method public hidebysig static void SkipInit<T> ([out] !!T& 'value') cil managed aggressiveinlining
{
.maxstack 0
ret
} // end of method Unsafe::SkipInit
.method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining
{
.maxstack 1
@ -255,7 +261,7 @@ @@ -255,7 +261,7 @@
.method public hidebysig static !!T& AsRef<T>(void* source) cil managed aggressiveinlining
{
// For .NET Core the roundtrip via a local is no longer needed see:
// https://github.com/dotnet/coreclr/issues/13341
// https://github.com/dotnet/runtime/issues/8730
// and
// https://github.com/dotnet/coreclr/pull/11218
#ifdef netcoreapp
@ -336,6 +342,17 @@ @@ -336,6 +342,17 @@
ret
} // end of method Unsafe::Add
.method public hidebysig static !!T& Add<T>(!!T& source, native uint elementOffset) cil managed aggressiveinlining
{
.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
{
.maxstack 2
@ -345,6 +362,15 @@ @@ -345,6 +362,15 @@
ret
} // end of method Unsafe::AddByteOffset
.method public hidebysig static !!T& AddByteOffset<T>(!!T& source, native uint byteOffset) cil managed aggressiveinlining
{
.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
{
.maxstack 3
@ -380,6 +406,17 @@ @@ -380,6 +406,17 @@
ret
} // end of method Unsafe::Subtract
.method public hidebysig static !!T& Subtract<T>(!!T& source, native uint elementOffset) cil managed aggressiveinlining
{
.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
{
.maxstack 2
@ -389,6 +426,15 @@ @@ -389,6 +426,15 @@
ret
} // end of method Unsafe::SubtractByteOffset
.method public hidebysig static !!T& SubtractByteOffset<T>(!!T& source, native uint byteOffset) cil managed aggressiveinlining
{
.maxstack 2
ldarg.0
ldarg.1
sub
ret
} // end of method Unsafe::SubtractByteOffset
.method public hidebysig static native int ByteOffset<T>(!!T& origin, !!T& target) cil managed aggressiveinlining
{
.maxstack 2
@ -404,7 +450,7 @@ @@ -404,7 +450,7 @@
ldarg.0
ldarg.1
ceq
ret
ret
} // end of method Unsafe::AreSame
.method public hidebysig static bool IsAddressGreaterThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining
@ -413,7 +459,7 @@ @@ -413,7 +459,7 @@
ldarg.0
ldarg.1
cgt.un
ret
ret
} // end of method Unsafe::IsAddressGreaterThan
.method public hidebysig static bool IsAddressLessThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining
@ -422,9 +468,27 @@ @@ -422,9 +468,27 @@
ldarg.0
ldarg.1
clt.un
ret
ret
} // end of method Unsafe::IsAddressLessThan
.method public hidebysig static bool IsNullRef<T>(!!T& source) cil managed aggressiveinlining
{
.maxstack 2
ldarg.0
ldc.i4.0
conv.u
ceq
ret
} // end of method Unsafe::IsNullRef
.method public hidebysig static !!T& NullRef<T>() cil managed aggressiveinlining
{
.maxstack 1
ldc.i4.0
conv.u
ret
} // end of method Unsafe::NullRef
} // end of class System.Runtime.CompilerServices.Unsafe
#ifdef netcoreapp

5
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1613,9 +1613,10 @@ namespace ICSharpCode.Decompiler.IL @@ -1613,9 +1613,10 @@ namespace ICSharpCode.Decompiler.IL
var right = Pop();
var left = Pop();
if (left.ResultType == StackType.O && right.ResultType.IsIntegerType())
if ((left.ResultType == StackType.O || left.ResultType == StackType.Ref) && right.ResultType.IsIntegerType())
{
// C++/CLI sometimes compares object references with integers.
// Also happens with Ref==I in Unsafe.IsNullRef().
if (right.ResultType == StackType.I4)
{
// ensure we compare at least native integer size
@ -1623,7 +1624,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1623,7 +1624,7 @@ namespace ICSharpCode.Decompiler.IL
}
left = new Conv(left, right.ResultType.ToPrimitiveType(), false, Sign.None);
}
else if (right.ResultType == StackType.O && left.ResultType.IsIntegerType())
else if ((right.ResultType == StackType.O || right.ResultType == StackType.Ref) && left.ResultType.IsIntegerType())
{
if (left.ResultType == StackType.I4)
{

Loading…
Cancel
Save