diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index e3c10b4108..856000b842 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -76,6 +76,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index dd00235d24..4d2bb4285e 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -181,6 +181,12 @@ public void CheckedUnchecked([ValueSource("defaultOptions")] CompilerOptions csc Run(cscOptions: cscOptions); } + [Test] + public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions cscOptions) + { + Run(cscOptions: cscOptions); + } + [Test] public void PInvoke([ValueSource("defaultOptions")] CompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/TrickyTypes.cs b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/TrickyTypes.cs index 3f2b2b7172..83b609b2ff 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/TrickyTypes.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/TrickyTypes.cs @@ -25,6 +25,7 @@ class TrickyTypes static void Main() { InterestingConstants(); + TruncatedComp(); } static void Print(T val) @@ -46,5 +47,50 @@ static void InterestingConstants() Print(val2); Print(2147483648u); } + + static void TruncatedComp() + { + Console.WriteLine("TruncatedComp1(1):"); + TruncatedComp1(1); + + Console.WriteLine("TruncatedComp1(-1):"); + TruncatedComp1(-1); + + Console.WriteLine("TruncatedComp1(0x100000001):"); + TruncatedComp1(0x100000001); + + Console.WriteLine("TruncatedComp1(long.MinValue):"); + TruncatedComp1(long.MinValue); + + Console.WriteLine("TruncatedComp2(1):"); + TruncatedComp2(1, 1); + + Console.WriteLine("TruncatedComp2(-1):"); + TruncatedComp2(-1, -1); + + Console.WriteLine("TruncatedComp2(0x100000001):"); + TruncatedComp2(0x100000001, 1); + + Console.WriteLine("TruncatedComp2(long.MinValue):"); + TruncatedComp2(long.MinValue, int.MinValue); + } + + static void TruncatedComp1(long val) + { + Print((int)val == val); + Print(val == (int)val); + Print(val < (int)val); + Print((int)val >= val); + } + + static void TruncatedComp2(long val1, int val2) + { + Print(val1 == val2); + Print((int)val1 == val2); + Print(val1 < val2); + Print((int)val1 < val2); + Print(val1 <= val2); + Print((int)val1 <= val2); + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/UnsafeCode.cs b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/UnsafeCode.cs index bb98dc77e8..49d398c2ef 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/UnsafeCode.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/UnsafeCode.cs @@ -22,7 +22,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness { public class UnsafeCode { - struct SimpleStruct + private struct SimpleStruct { public int X; public double Y; @@ -34,58 +34,6 @@ static void Main() // (but for now, it's already valuable knowing whether the decompiled code can be re-compiled) } - public unsafe int* NullPointer - { - get { - return null; - } - } - - public unsafe int* PointerCast(long* p) - { - return (int*)p; - } - - public unsafe long ConvertDoubleToLong(double d) - { - return *(long*)(&d); - } - - public unsafe double ConvertLongToDouble(long d) - { - return *(double*)(&d); - } - - public unsafe int ConvertFloatToInt(float d) - { - return *(int*)(&d); - } - - public unsafe float ConvertIntToFloat(int d) - { - return *(float*)(&d); - } - - public unsafe void PassRefParameterAsPointer(ref int p) - { - fixed (int* ptr = &p) { - this.PassPointerAsRefParameter(ptr); - } - } - - public unsafe void PassPointerAsRefParameter(int* p) - { - this.PassRefParameterAsPointer(ref *p); - } - - public unsafe void AddressInMultiDimensionalArray(double[,] matrix) - { - fixed (double* ptr = &matrix[1, 2]) { - this.PointerReferenceExpression(ptr); - this.PointerReferenceExpression(ptr); - } - } - public unsafe int MultipleExitsOutOfFixedBlock(int[] arr) { fixed (int* ptr = &arr[0]) { @@ -101,42 +49,7 @@ public unsafe int MultipleExitsOutOfFixedBlock(int[] arr) Console.WriteLine("outside"); return 2; } - - public unsafe void FixedStringAccess(string text) - { - fixed (char* ptr = text) { - char* ptr2 = ptr; - while (*ptr2 != '\0') { - *ptr2 = 'A'; - ptr2++; - } - } - } - - public unsafe void PutDoubleIntoLongArray1(long[] array, int index, double val) - { - fixed (long* ptr = array) { - ((double*)ptr)[index] = val; - } - } - - public unsafe void PutDoubleIntoLongArray2(long[] array, int index, double val) - { - fixed (long* ptr = &array[index]) { - *(double*)ptr = val; - } - } - - public unsafe string PointerReferenceExpression(double* d) - { - return d->ToString(); - } - - public unsafe string PointerReferenceExpression2(long addr) - { - return ((int*)addr)->ToString(); - } - + public unsafe void FixMultipleStrings(string text) { fixed (char* ptr = text, userName = Environment.UserName, ptr2 = text) { @@ -146,66 +59,9 @@ public unsafe void FixMultipleStrings(string text) } } - public unsafe string StackAlloc(int count) - { - char* ptr = stackalloc char[count]; - char* ptr2 = stackalloc char[100]; - for (int i = 0; i < count; i++) { - ptr[i] = (char)i; - } - return this.PointerReferenceExpression((double*)ptr); - } - - public unsafe string StackAllocStruct(int count) - { - SimpleStruct* s = stackalloc SimpleStruct[checked(count * 2)]; - SimpleStruct* p = stackalloc SimpleStruct[10]; - return this.PointerReferenceExpression(&s->Y); - } - - public unsafe int* PointerArithmetic(int* p) - { - return p + 2; - } - public unsafe byte* PointerArithmetic2(long* p, int y, int x) { return (byte*)((short*)p + (y * x)); } - - public unsafe long* PointerArithmetic3(long* p) - { - return (long*)((byte*)p + 3); - } - - public unsafe long* PointerArithmetic4(void* p) - { - return (long*)((byte*)p + 3); - } - - public unsafe int PointerArithmetic5(void* p, byte* q, int i) - { - return (int)(q[i] + *(byte*)p); - } - - public unsafe int PointerSubtraction(long* p, long* q) - { - return (int)((long)(p - q)); - } - - public unsafe int PointerSubtraction2(long* p, short* q) - { - return (int)((long)((byte*)p - (byte*)q)); - } - - public unsafe int PointerSubtraction3(void* p, void* q) - { - return (int)((long)((byte*)p - (byte*)q)); - } - - unsafe ~UnsafeCode() - { - this.PassPointerAsRefParameter(this.NullPointer); - } } } \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/.gitignore b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/.gitignore new file mode 100644 index 0000000000..61d62080ad --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/.gitignore @@ -0,0 +1 @@ +/*.dll diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/.gitignore b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/.gitignore index a520eba402..bf449394f4 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/.gitignore +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/.gitignore @@ -1,3 +1,4 @@ /*.res /*.dll /*.exe +/*.pdb diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs new file mode 100644 index 0000000000..9f0ae3ab0e --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs @@ -0,0 +1,288 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public class UnsafeCode + { + public struct SimpleStruct + { + public int X; + public double Y; + } + + public struct StructWithFixedSizeMembers + { + public unsafe fixed int Integers[100]; + public int NormalMember; + public unsafe fixed double Doubles[200]; + + [Obsolete("another attribute")] + public unsafe fixed byte Old[1]; + } + + public unsafe int* NullPointer { + get { + return null; + } + } + + public unsafe int SizeOf() + { + return sizeof(SimpleStruct); + } + + private static void UseBool(bool b) + { + } + + public unsafe void PointerComparison(int* a, double* b) + { + UnsafeCode.UseBool(a == b); + UnsafeCode.UseBool(a != b); + UnsafeCode.UseBool(a < b); + UnsafeCode.UseBool(a > b); + UnsafeCode.UseBool(a <= b); + UnsafeCode.UseBool(a >= b); + } + + public unsafe void PointerComparisonWithNull(int* a) + { + UnsafeCode.UseBool(a == null); + UnsafeCode.UseBool(a != null); + } + + public unsafe int* PointerCast(long* p) + { + return (int*)p; + } + + public unsafe long ConvertDoubleToLong(double d) + { + return *(long*)(&d); + } + + public unsafe double ConvertLongToDouble(long d) + { + return *(double*)(&d); + } + + public unsafe int ConvertFloatToInt(float d) + { + return *(int*)(&d); + } + + public unsafe float ConvertIntToFloat(int d) + { + return *(float*)(&d); + } + + public unsafe int PointerCasts() + { + int result = 0; + *(float*)(&result) = 0.5f; + ((byte*)(&result))[3] = 3; + return result; + } + + public unsafe void PassRefParameterAsPointer(ref int p) + { + fixed (int* p2 = &p) { + this.PassPointerAsRefParameter(p2); + } + } + + public unsafe void PassPointerAsRefParameter(int* p) + { + this.PassRefParameterAsPointer(ref *p); + } + + public unsafe void AddressInMultiDimensionalArray(double[,] matrix) + { + fixed (double* d = &matrix[1, 2]) { + this.PointerReferenceExpression(d); + this.PointerReferenceExpression(d); + } + } + + public unsafe void FixedStringAccess(string text) + { + fixed (char* ptr = text) { + char* ptr2 = ptr; + while (*ptr2 == 'a') { + *ptr2 = 'A'; + ptr2++; + } + } + } + + public unsafe void PutDoubleIntoLongArray1(long[] array, int index, double val) + { + fixed (long* ptr = array) { + *(double*)(ptr + index) = val; + } + } + + public unsafe void PutDoubleIntoLongArray2(long[] array, int index, double val) + { + fixed (long* ptr = &array[index]) { + *(double*)ptr = val; + } + } + + public unsafe string PointerReferenceExpression(double* d) + { + return d->ToString(); + } + + public unsafe string PointerReferenceExpression2(long addr) + { + return ((int*)addr)->ToString(); + } + + public unsafe int* PointerArithmetic(int* p) + { + return p + 2; + } + + public unsafe long* PointerArithmetic2(long* p) + { + return 3 + p; + } + + public unsafe long* PointerArithmetic3(long* p) + { + return (long*)((byte*)p + 3); + } + + public unsafe long* PointerArithmetic4(void* p) + { + return (long*)((byte*)p + 3); + } + + public unsafe int PointerArithmetic5(void* p, byte* q, int i) + { + return q[i] + *(byte*)p; + } + + public unsafe int PointerArithmetic6(SimpleStruct* p, int i) + { + return p[i].X; + } + + public unsafe int* PointerArithmeticLong1(int* p, long offset) + { + return p + offset; + } + + public unsafe int* PointerArithmeticLong2(int* p, long offset) + { + return offset + p; + } + + public unsafe int* PointerArithmeticLong3(int* p, long offset) + { + return p - offset; + } + + public unsafe SimpleStruct* PointerArithmeticLong1s(SimpleStruct* p, long offset) + { + return p + offset; + } + + public unsafe SimpleStruct* PointerArithmeticLong2s(SimpleStruct* p, long offset) + { + return offset + p; + } + + public unsafe SimpleStruct* PointerArithmeticLong3s(SimpleStruct* p, long offset) + { + return p - offset; + } + + public unsafe int PointerSubtraction(long* p, long* q) + { + return (int)(p - q); + } + + public unsafe long PointerSubtractionLong(long* p, long* q) + { + return p - q; + } + + public unsafe int PointerSubtraction2(long* p, short* q) + { + return (int)((byte*)p - (byte*)q); + } + + public unsafe int PointerSubtraction3(void* p, void* q) + { + return (int)((byte*)p - (byte*)q); + } + + public unsafe long PointerSubtraction4(sbyte* p, sbyte* q) + { + return p - q; + } + + public unsafe long PointerSubtraction5(SimpleStruct* p, SimpleStruct* q) + { + return p - q; + } + + public unsafe double FixedMemberAccess(StructWithFixedSizeMembers* m, int i) + { + return (double)m->Integers[i] + m->Doubles[i]; + } + + public unsafe double* FixedMemberBasePointer(StructWithFixedSizeMembers* m) + { + return m->Doubles; + } + + public unsafe string UsePointer(double* ptr) + { + return ptr->ToString(); + } + + public unsafe string StackAlloc(int count) + { + char* ptr = stackalloc char[count]; + char* ptr2 = stackalloc char[100]; + for (int i = 0; i < count; i++) { + ptr[i] = (char)i; + ptr2[i] = '\0'; + } + return this.UsePointer((double*)ptr); + } + + public unsafe string StackAllocStruct(int count) + { + SimpleStruct* ptr = stackalloc SimpleStruct[checked(count * 2)]; + SimpleStruct* _ = stackalloc SimpleStruct[10]; + return this.UsePointer(&ptr->Y); + } + + unsafe ~UnsafeCode() + { + this.PassPointerAsRefParameter(this.NullPointer); + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il new file mode 100644 index 0000000000..337eb233f7 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il @@ -0,0 +1,1149 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly '5ph04scr' +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module '5ph04scr.dll' +// MVID: {979A8D45-AB93-4029-8820-2753F73AD209} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x01AF0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 X + .field public float64 Y + } // end of class SimpleStruct + + .class sequential ansi sealed nested public beforefieldinit StructWithFixedSizeMembers + extends [mscorlib]System.ValueType + { + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer0' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 400 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 FixedElementField + } // end of class 'e__FixedBuffer0' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer1' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1600 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public float64 FixedElementField + } // end of class 'e__FixedBuffer1' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer2' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 FixedElementField + } // end of class 'e__FixedBuffer2' + + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' Integers + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 59 53 79 73 74 65 6D 2E 49 6E 74 33 32 2C // ..YSystem.Int32, + 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 // mscorlib, Versi + 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 // on=4.0.0.0, Cult + 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 // ure=neutral, Pub + 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 // licKeyToken=b77a + 35 63 35 36 31 39 33 34 65 30 38 39 64 00 00 00 // 5c561934e089d... + 00 00 ) + .field public int32 NormalMember + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' Doubles + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 5A 53 79 73 74 65 6D 2E 44 6F 75 62 6C 65 // ..ZSystem.Double + 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 // , mscorlib, Vers + 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C // ion=4.0.0.0, Cul + 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 // ture=neutral, Pu + 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 // blicKeyToken=b77 + 61 35 63 35 36 31 39 33 34 65 30 38 39 C8 00 00 // a5c561934e089... + 00 00 00 ) + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer2' Old + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 58 53 79 73 74 65 6D 2E 42 79 74 65 2C 20 // ..XSystem.Byte, + 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F // mscorlib, Versio + 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 // n=4.0.0.0, Cultu + 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C // re=neutral, Publ + 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 // icKeyToken=b77a5 + 63 35 36 31 39 33 34 65 30 38 39 01 00 00 00 00 // c561934e089..... + 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 11 61 6E 6F 74 68 65 72 20 61 74 74 72 69 // ...another attri + 62 75 74 65 00 00 ) // bute.. + } // end of class StructWithFixedSizeMembers + + .method public hidebysig specialname instance int32* + get_NullPointer() cil managed + { + // Code size 8 (0x8) + .maxstack 1 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stloc.0 + IL_0004: br.s IL_0006 + + IL_0006: ldloc.0 + IL_0007: ret + } // end of method UnsafeCode::get_NullPointer + + .method public hidebysig instance int32 + SizeOf() cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::SizeOf + + .method private hidebysig static void UseBool(bool b) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method UnsafeCode::UseBool + + .method public hidebysig instance void + PointerComparison(int32* a, + float64* b) cil managed + { + // Code size 71 (0x47) + .maxstack 2 + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ceq + IL_0005: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000a: nop + IL_000b: ldarg.1 + IL_000c: ldarg.2 + IL_000d: ceq + IL_000f: ldc.i4.0 + IL_0010: ceq + IL_0012: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0017: nop + IL_0018: ldarg.1 + IL_0019: ldarg.2 + IL_001a: clt.un + IL_001c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0021: nop + IL_0022: ldarg.1 + IL_0023: ldarg.2 + IL_0024: cgt.un + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_002b: nop + IL_002c: ldarg.1 + IL_002d: ldarg.2 + IL_002e: cgt.un + IL_0030: ldc.i4.0 + IL_0031: ceq + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0038: nop + IL_0039: ldarg.1 + IL_003a: ldarg.2 + IL_003b: clt.un + IL_003d: ldc.i4.0 + IL_003e: ceq + IL_0040: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0045: nop + IL_0046: ret + } // end of method UnsafeCode::PointerComparison + + .method public hidebysig instance void + PointerComparisonWithNull(int32* a) cil managed + { + // Code size 27 (0x1b) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.0 + IL_0003: conv.u + IL_0004: ceq + IL_0006: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000b: nop + IL_000c: ldarg.1 + IL_000d: ldc.i4.0 + IL_000e: conv.u + IL_000f: ceq + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0019: nop + IL_001a: ret + } // end of method UnsafeCode::PointerComparisonWithNull + + .method public hidebysig instance int32* + PointerCast(int64* p) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method UnsafeCode::PointerCast + + .method public hidebysig instance int64 + ConvertDoubleToLong(float64 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.i8 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertDoubleToLong + + .method public hidebysig instance float64 + ConvertLongToDouble(int64 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (float64 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.r8 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertLongToDouble + + .method public hidebysig instance int32 + ConvertFloatToInt(float32 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.i4 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertFloatToInt + + .method public hidebysig instance float32 + ConvertIntToFloat(int32 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (float32 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.r4 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertIntToFloat + + .method public hidebysig instance int32 + PointerCasts() cil managed + { + // Code size 26 (0x1a) + .maxstack 2 + .locals init (int32 V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: ldloca.s V_0 + IL_0005: conv.u + IL_0006: ldc.r4 0.5 + IL_000b: stind.r4 + IL_000c: ldloca.s V_0 + IL_000e: conv.u + IL_000f: ldc.i4.3 + IL_0010: conv.i + IL_0011: add + IL_0012: ldc.i4.3 + IL_0013: stind.i1 + IL_0014: ldloc.0 + IL_0015: stloc.1 + IL_0016: br.s IL_0018 + + IL_0018: ldloc.1 + IL_0019: ret + } // end of method UnsafeCode::PointerCasts + + .method public hidebysig instance void + PassRefParameterAsPointer(int32& p) cil managed + { + // Code size 18 (0x12) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: nop + IL_0004: ldarg.0 + IL_0005: ldloc.0 + IL_0006: conv.i + IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000c: nop + IL_000d: nop + IL_000e: ldc.i4.0 + IL_000f: conv.u + IL_0010: stloc.0 + IL_0011: ret + } // end of method UnsafeCode::PassRefParameterAsPointer + + .method public hidebysig instance void + PassPointerAsRefParameter(int32* p) cil managed + { + // Code size 10 (0xa) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0008: nop + IL_0009: ret + } // end of method UnsafeCode::PassPointerAsRefParameter + + .method public hidebysig instance void + AddressInMultiDimensionalArray(float64[0...,0...] matrix) cil managed + { + // Code size 34 (0x22) + .maxstack 3 + .locals init (float64& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.1 + IL_0003: ldc.i4.2 + IL_0004: call instance float64& float64[0...,0...]::Address(int32, + int32) + IL_0009: stloc.0 + IL_000a: nop + IL_000b: ldarg.0 + IL_000c: ldloc.0 + IL_000d: conv.i + IL_000e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_0013: pop + IL_0014: ldarg.0 + IL_0015: ldloc.0 + IL_0016: conv.i + IL_0017: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_001c: pop + IL_001d: nop + IL_001e: ldc.i4.0 + IL_001f: conv.u + IL_0020: stloc.0 + IL_0021: ret + } // end of method UnsafeCode::AddressInMultiDimensionalArray + + .method public hidebysig instance void + FixedStringAccess(string text) cil managed + { + // Code size 45 (0x2d) + .maxstack 2 + .locals init (char* V_0, + char* V_1, + string pinned V_2, + bool V_3) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.2 + IL_0003: ldloc.2 + IL_0004: conv.i + IL_0005: dup + IL_0006: brfalse.s IL_000e + + IL_0008: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000d: add + IL_000e: stloc.0 + IL_000f: nop + IL_0010: ldloc.0 + IL_0011: stloc.1 + IL_0012: br.s IL_001f + + IL_0014: nop + IL_0015: ldloc.1 + IL_0016: ldc.i4.s 65 + IL_0018: stind.i2 + IL_0019: ldloc.1 + IL_001a: ldc.i4.2 + IL_001b: conv.i + IL_001c: add + IL_001d: stloc.1 + IL_001e: nop + IL_001f: ldloc.1 + IL_0020: ldind.u2 + IL_0021: ldc.i4.s 97 + IL_0023: ceq + IL_0025: stloc.3 + IL_0026: ldloc.3 + IL_0027: brtrue.s IL_0014 + + IL_0029: nop + IL_002a: ldnull + IL_002b: stloc.2 + IL_002c: ret + } // end of method UnsafeCode::FixedStringAccess + + .method public hidebysig instance void + PutDoubleIntoLongArray1(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 39 (0x27) + .maxstack 3 + .locals init (int64& pinned V_0, + int64[] V_1) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: dup + IL_0003: stloc.1 + IL_0004: brfalse.s IL_000b + + IL_0006: ldloc.1 + IL_0007: ldlen + IL_0008: conv.i4 + IL_0009: brtrue.s IL_0010 + + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: br.s IL_0018 + + IL_0010: ldloc.1 + IL_0011: ldc.i4.0 + IL_0012: ldelema [mscorlib]System.Int64 + IL_0017: stloc.0 + IL_0018: nop + IL_0019: ldloc.0 + IL_001a: conv.i + IL_001b: ldarg.2 + IL_001c: conv.i + IL_001d: ldc.i4.8 + IL_001e: mul + IL_001f: add + IL_0020: ldarg.3 + IL_0021: stind.r8 + IL_0022: nop + IL_0023: ldc.i4.0 + IL_0024: conv.u + IL_0025: stloc.0 + IL_0026: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray1 + + .method public hidebysig instance void + PutDoubleIntoLongArray2(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 19 (0x13) + .maxstack 2 + .locals init (int64& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldelema [mscorlib]System.Int64 + IL_0008: stloc.0 + IL_0009: nop + IL_000a: ldloc.0 + IL_000b: conv.i + IL_000c: ldarg.3 + IL_000d: stind.r8 + IL_000e: nop + IL_000f: ldc.i4.0 + IL_0010: conv.u + IL_0011: stloc.0 + IL_0012: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray2 + + .method public hidebysig instance string + PointerReferenceExpression(float64* d) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Double::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerReferenceExpression + + .method public hidebysig instance string + PointerReferenceExpression2(int64 addr) cil managed + { + // Code size 13 (0xd) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: conv.u + IL_0003: call instance string [mscorlib]System.Int32::ToString() + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerReferenceExpression2 + + .method public hidebysig instance int32* + PointerArithmetic(int32* p) cil managed + { + // Code size 10 (0xa) + .maxstack 2 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.8 + IL_0003: conv.i + IL_0004: add + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::PointerArithmetic + + .method public hidebysig instance int64* + PointerArithmetic2(int64* p) cil managed + { + // Code size 11 (0xb) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldc.i4.s 24 + IL_0003: conv.i + IL_0004: ldarg.1 + IL_0005: add + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method UnsafeCode::PointerArithmetic2 + + .method public hidebysig instance int64* + PointerArithmetic3(int64* p) cil managed + { + // Code size 10 (0xa) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.3 + IL_0003: conv.i + IL_0004: add + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::PointerArithmetic3 + + .method public hidebysig instance int64* + PointerArithmetic4(void* p) cil managed + { + // Code size 10 (0xa) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.3 + IL_0003: conv.i + IL_0004: add + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::PointerArithmetic4 + + .method public hidebysig instance int32 + PointerArithmetic5(void* p, + uint8* q, + int32 i) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldarg.3 + IL_0003: add + IL_0004: ldind.u1 + IL_0005: ldarg.1 + IL_0006: ldind.u1 + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmetic5 + + .method public hidebysig instance int32 + PointerArithmetic6(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int32 i) cil managed + { + // Code size 22 (0x16) + .maxstack 3 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: conv.i + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: mul + IL_000b: add + IL_000c: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: ldloc.0 + IL_0015: ret + } // end of method UnsafeCode::PointerArithmetic6 + + .method public hidebysig instance int32* + PointerArithmeticLong1(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldc.i4.4 + IL_0004: conv.i8 + IL_0005: mul + IL_0006: conv.i + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong1 + + .method public hidebysig instance int32* + PointerArithmeticLong2(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: ldarg.1 + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong2 + + .method public hidebysig instance int32* + PointerArithmeticLong3(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldc.i4.4 + IL_0004: conv.i8 + IL_0005: mul + IL_0006: conv.i + IL_0007: sub + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong3 + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong1s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: conv.i8 + IL_000a: mul + IL_000b: conv.i + IL_000c: add + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong1s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong2s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: ldarg.1 + IL_000c: add + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong2s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong3s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: conv.i8 + IL_000a: mul + IL_000b: conv.i + IL_000c: sub + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong3s + + .method public hidebysig instance int32 + PointerSubtraction(int64* p, + int64* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.8 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction + + .method public hidebysig instance int64 + PointerSubtractionLong(int64* p, + int64* q) cil managed + { + // Code size 12 (0xc) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.8 + IL_0005: div + IL_0006: conv.i8 + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtractionLong + + .method public hidebysig instance int32 + PointerSubtraction2(int64* p, + int16* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction2 + + .method public hidebysig instance int32 + PointerSubtraction3(void* p, + void* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction3 + + .method public hidebysig instance int64 + PointerSubtraction4(int8* p, + int8* q) cil managed + { + // Code size 12 (0xc) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtraction4 + + .method public hidebysig instance int64 + PointerSubtraction5(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* q) cil managed + { + // Code size 17 (0x11) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: div + IL_000b: conv.i8 + IL_000c: stloc.0 + IL_000d: br.s IL_000f + + IL_000f: ldloc.0 + IL_0010: ret + } // end of method UnsafeCode::PointerSubtraction5 + + .method public hidebysig instance float64 + FixedMemberAccess(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m, + int32 i) cil managed + { + // Code size 44 (0x2c) + .maxstack 4 + .locals init (float64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000c: conv.u + IL_000d: ldarg.2 + IL_000e: conv.i + IL_000f: ldc.i4.4 + IL_0010: mul + IL_0011: add + IL_0012: ldind.i4 + IL_0013: conv.r8 + IL_0014: ldarg.1 + IL_0015: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_001a: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1'::FixedElementField + IL_001f: conv.u + IL_0020: ldarg.2 + IL_0021: conv.i + IL_0022: ldc.i4.8 + IL_0023: mul + IL_0024: add + IL_0025: ldind.r8 + IL_0026: add + IL_0027: stloc.0 + IL_0028: br.s IL_002a + + IL_002a: ldloc.0 + IL_002b: ret + } // end of method UnsafeCode::FixedMemberAccess + + .method public hidebysig instance float64* + FixedMemberBasePointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 18 (0x12) + .maxstack 1 + .locals init (float64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0007: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1'::FixedElementField + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::FixedMemberBasePointer + + .method public hidebysig instance string + UsePointer(float64* ptr) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Double::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::UsePointer + + .method public hidebysig instance string + StackAlloc(int32 count) cil managed + { + // Code size 65 (0x41) + .maxstack 3 + .locals init (char* V_0, + char* V_1, + int32 V_2, + string V_3, + bool V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: conv.u + IL_0003: ldc.i4.2 + IL_0004: mul.ovf.un + IL_0005: localloc + IL_0007: stloc.0 + IL_0008: ldc.i4.s 100 + IL_000a: conv.u + IL_000b: ldc.i4.2 + IL_000c: mul.ovf.un + IL_000d: localloc + IL_000f: stloc.1 + IL_0010: ldc.i4.0 + IL_0011: stloc.2 + IL_0012: br.s IL_002b + + IL_0014: nop + IL_0015: ldloc.0 + IL_0016: ldloc.2 + IL_0017: conv.i + IL_0018: ldc.i4.2 + IL_0019: mul + IL_001a: add + IL_001b: ldloc.2 + IL_001c: conv.u2 + IL_001d: stind.i2 + IL_001e: ldloc.1 + IL_001f: ldloc.2 + IL_0020: conv.i + IL_0021: ldc.i4.2 + IL_0022: mul + IL_0023: add + IL_0024: ldc.i4.0 + IL_0025: stind.i2 + IL_0026: nop + IL_0027: ldloc.2 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.2 + IL_002b: ldloc.2 + IL_002c: ldarg.1 + IL_002d: clt + IL_002f: stloc.s V_4 + IL_0031: ldloc.s V_4 + IL_0033: brtrue.s IL_0014 + + IL_0035: ldarg.0 + IL_0036: ldloc.0 + IL_0037: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_003c: stloc.3 + IL_003d: br.s IL_003f + + IL_003f: ldloc.3 + IL_0040: ret + } // end of method UnsafeCode::StackAlloc + + .method public hidebysig instance string + StackAllocStruct(int32 count) cil managed + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_1, + string V_2) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.2 + IL_0003: mul.ovf + IL_0004: conv.u + IL_0005: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000b: mul.ovf.un + IL_000c: localloc + IL_000e: stloc.0 + IL_000f: ldc.i4.s 10 + IL_0011: conv.u + IL_0012: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0018: mul.ovf.un + IL_0019: localloc + IL_001b: stloc.1 + IL_001c: ldarg.0 + IL_001d: ldloc.0 + IL_001e: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0023: conv.u + IL_0024: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0029: stloc.2 + IL_002a: br.s IL_002c + + IL_002c: ldloc.2 + IL_002d: ret + } // end of method UnsafeCode::StackAllocStruct + + .method family hidebysig virtual instance void + Finalize() cil managed + { + // Code size 27 (0x1b) + .maxstack 2 + .try + { + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.0 + IL_0003: call instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + IL_0008: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000d: nop + IL_000e: nop + IL_000f: leave.s IL_0019 + + } // end .try + finally + { + IL_0011: ldarg.0 + IL_0012: call instance void [mscorlib]System.Object::Finalize() + IL_0017: nop + IL_0018: endfinally + } // end handler + IL_0019: nop + IL_001a: ret + } // end of method UnsafeCode::Finalize + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method UnsafeCode::.ctor + + .property instance int32* NullPointer() + { + .get instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + } // end of property UnsafeCode::NullPointer +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file ../../../TestCases/Pretty\UnsafeCode.res diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il new file mode 100644 index 0000000000..4d26c8d303 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il @@ -0,0 +1,904 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly zuwavv1x +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module zuwavv1x.dll +// MVID: {4CC9FC6C-21CA-408A-ABC9-544A07D1E512} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x01600000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 X + .field public float64 Y + } // end of class SimpleStruct + + .class sequential ansi sealed nested public beforefieldinit StructWithFixedSizeMembers + extends [mscorlib]System.ValueType + { + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer0' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 400 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 FixedElementField + } // end of class 'e__FixedBuffer0' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer1' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1600 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public float64 FixedElementField + } // end of class 'e__FixedBuffer1' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer2' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 FixedElementField + } // end of class 'e__FixedBuffer2' + + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' Integers + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 59 53 79 73 74 65 6D 2E 49 6E 74 33 32 2C // ..YSystem.Int32, + 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 // mscorlib, Versi + 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 // on=4.0.0.0, Cult + 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 // ure=neutral, Pub + 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 // licKeyToken=b77a + 35 63 35 36 31 39 33 34 65 30 38 39 64 00 00 00 // 5c561934e089d... + 00 00 ) + .field public int32 NormalMember + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' Doubles + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 5A 53 79 73 74 65 6D 2E 44 6F 75 62 6C 65 // ..ZSystem.Double + 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 // , mscorlib, Vers + 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C // ion=4.0.0.0, Cul + 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 // ture=neutral, Pu + 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 // blicKeyToken=b77 + 61 35 63 35 36 31 39 33 34 65 30 38 39 C8 00 00 // a5c561934e089... + 00 00 00 ) + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer2' Old + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 58 53 79 73 74 65 6D 2E 42 79 74 65 2C 20 // ..XSystem.Byte, + 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F // mscorlib, Versio + 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 // n=4.0.0.0, Cultu + 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C // re=neutral, Publ + 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 // icKeyToken=b77a5 + 63 35 36 31 39 33 34 65 30 38 39 01 00 00 00 00 // c561934e089..... + 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 11 61 6E 6F 74 68 65 72 20 61 74 74 72 69 // ...another attri + 62 75 74 65 00 00 ) // bute.. + } // end of class StructWithFixedSizeMembers + + .method public hidebysig specialname instance int32* + get_NullPointer() cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: conv.u + IL_0002: ret + } // end of method UnsafeCode::get_NullPointer + + .method public hidebysig instance int32 + SizeOf() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0006: ret + } // end of method UnsafeCode::SizeOf + + .method private hidebysig static void UseBool(bool b) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method UnsafeCode::UseBool + + .method public hidebysig instance void + PointerComparison(int32* a, + float64* b) cil managed + { + // Code size 64 (0x40) + .maxstack 2 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ceq + IL_0004: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0009: ldarg.1 + IL_000a: ldarg.2 + IL_000b: ceq + IL_000d: ldc.i4.0 + IL_000e: ceq + IL_0010: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0015: ldarg.1 + IL_0016: ldarg.2 + IL_0017: clt.un + IL_0019: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_001e: ldarg.1 + IL_001f: ldarg.2 + IL_0020: cgt.un + IL_0022: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0027: ldarg.1 + IL_0028: ldarg.2 + IL_0029: cgt.un + IL_002b: ldc.i4.0 + IL_002c: ceq + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0033: ldarg.1 + IL_0034: ldarg.2 + IL_0035: clt.un + IL_0037: ldc.i4.0 + IL_0038: ceq + IL_003a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_003f: ret + } // end of method UnsafeCode::PointerComparison + + .method public hidebysig instance void + PointerComparisonWithNull(int32* a) cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: ceq + IL_0005: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000a: ldarg.1 + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: ceq + IL_000f: ldc.i4.0 + IL_0010: ceq + IL_0012: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0017: ret + } // end of method UnsafeCode::PointerComparisonWithNull + + .method public hidebysig instance int32* + PointerCast(int64* p) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } // end of method UnsafeCode::PointerCast + + .method public hidebysig instance int64 + ConvertDoubleToLong(float64 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.i8 + IL_0004: ret + } // end of method UnsafeCode::ConvertDoubleToLong + + .method public hidebysig instance float64 + ConvertLongToDouble(int64 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.r8 + IL_0004: ret + } // end of method UnsafeCode::ConvertLongToDouble + + .method public hidebysig instance int32 + ConvertFloatToInt(float32 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.i4 + IL_0004: ret + } // end of method UnsafeCode::ConvertFloatToInt + + .method public hidebysig instance float32 + ConvertIntToFloat(int32 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.r4 + IL_0004: ret + } // end of method UnsafeCode::ConvertIntToFloat + + .method public hidebysig instance int32 + PointerCasts() cil managed + { + // Code size 21 (0x15) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: conv.u + IL_0005: ldc.r4 0.5 + IL_000a: stind.r4 + IL_000b: ldloca.s V_0 + IL_000d: conv.u + IL_000e: ldc.i4.3 + IL_000f: conv.i + IL_0010: add + IL_0011: ldc.i4.3 + IL_0012: stind.i1 + IL_0013: ldloc.0 + IL_0014: ret + } // end of method UnsafeCode::PointerCasts + + .method public hidebysig instance void + PassRefParameterAsPointer(int32& p) cil managed + { + // Code size 14 (0xe) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldloc.0 + IL_0004: conv.i + IL_0005: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000a: ldc.i4.0 + IL_000b: conv.u + IL_000c: stloc.0 + IL_000d: ret + } // end of method UnsafeCode::PassRefParameterAsPointer + + .method public hidebysig instance void + PassPointerAsRefParameter(int32* p) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0007: ret + } // end of method UnsafeCode::PassPointerAsRefParameter + + .method public hidebysig instance void + AddressInMultiDimensionalArray(float64[0...,0...] matrix) cil managed + { + // Code size 31 (0x1f) + .maxstack 3 + .locals init (float64& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.2 + IL_0003: call instance float64& float64[0...,0...]::Address(int32, + int32) + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: ldloc.0 + IL_000b: conv.i + IL_000c: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_0011: pop + IL_0012: ldarg.0 + IL_0013: ldloc.0 + IL_0014: conv.i + IL_0015: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_001a: pop + IL_001b: ldc.i4.0 + IL_001c: conv.u + IL_001d: stloc.0 + IL_001e: ret + } // end of method UnsafeCode::AddressInMultiDimensionalArray + + .method public hidebysig instance void + FixedStringAccess(string text) cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (char* V_0, + char* V_1, + string pinned V_2) + IL_0000: ldarg.1 + IL_0001: stloc.2 + IL_0002: ldloc.2 + IL_0003: conv.i + IL_0004: dup + IL_0005: brfalse.s IL_000d + + IL_0007: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000c: add + IL_000d: stloc.0 + IL_000e: ldloc.0 + IL_000f: stloc.1 + IL_0010: br.s IL_001b + + IL_0012: ldloc.1 + IL_0013: ldc.i4.s 65 + IL_0015: stind.i2 + IL_0016: ldloc.1 + IL_0017: ldc.i4.2 + IL_0018: conv.i + IL_0019: add + IL_001a: stloc.1 + IL_001b: ldloc.1 + IL_001c: ldind.u2 + IL_001d: ldc.i4.s 97 + IL_001f: beq.s IL_0012 + + IL_0021: ldnull + IL_0022: stloc.2 + IL_0023: ret + } // end of method UnsafeCode::FixedStringAccess + + .method public hidebysig instance void + PutDoubleIntoLongArray1(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 36 (0x24) + .maxstack 3 + .locals init (int64& pinned V_0, + int64[] V_1) + IL_0000: ldarg.1 + IL_0001: dup + IL_0002: stloc.1 + IL_0003: brfalse.s IL_000a + + IL_0005: ldloc.1 + IL_0006: ldlen + IL_0007: conv.i4 + IL_0008: brtrue.s IL_000f + + IL_000a: ldc.i4.0 + IL_000b: conv.u + IL_000c: stloc.0 + IL_000d: br.s IL_0017 + + IL_000f: ldloc.1 + IL_0010: ldc.i4.0 + IL_0011: ldelema [mscorlib]System.Int64 + IL_0016: stloc.0 + IL_0017: ldloc.0 + IL_0018: conv.i + IL_0019: ldarg.2 + IL_001a: conv.i + IL_001b: ldc.i4.8 + IL_001c: mul + IL_001d: add + IL_001e: ldarg.3 + IL_001f: stind.r8 + IL_0020: ldc.i4.0 + IL_0021: conv.u + IL_0022: stloc.0 + IL_0023: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray1 + + .method public hidebysig instance void + PutDoubleIntoLongArray2(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 16 (0x10) + .maxstack 2 + .locals init (int64& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldelema [mscorlib]System.Int64 + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: conv.i + IL_000a: ldarg.3 + IL_000b: stind.r8 + IL_000c: ldc.i4.0 + IL_000d: conv.u + IL_000e: stloc.0 + IL_000f: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray2 + + .method public hidebysig instance string + PointerReferenceExpression(float64* d) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Double::ToString() + IL_0006: ret + } // end of method UnsafeCode::PointerReferenceExpression + + .method public hidebysig instance string + PointerReferenceExpression2(int64 addr) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u + IL_0002: call instance string [mscorlib]System.Int32::ToString() + IL_0007: ret + } // end of method UnsafeCode::PointerReferenceExpression2 + + .method public hidebysig instance int32* + PointerArithmetic(int32* p) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.8 + IL_0002: conv.i + IL_0003: add + IL_0004: ret + } // end of method UnsafeCode::PointerArithmetic + + .method public hidebysig instance int64* + PointerArithmetic2(int64* p) cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldc.i4.s 24 + IL_0002: conv.i + IL_0003: ldarg.1 + IL_0004: add + IL_0005: ret + } // end of method UnsafeCode::PointerArithmetic2 + + .method public hidebysig instance int64* + PointerArithmetic3(int64* p) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.3 + IL_0002: conv.i + IL_0003: add + IL_0004: ret + } // end of method UnsafeCode::PointerArithmetic3 + + .method public hidebysig instance int64* + PointerArithmetic4(void* p) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.3 + IL_0002: conv.i + IL_0003: add + IL_0004: ret + } // end of method UnsafeCode::PointerArithmetic4 + + .method public hidebysig instance int32 + PointerArithmetic5(void* p, + uint8* q, + int32 i) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: ldarg.3 + IL_0002: add + IL_0003: ldind.u1 + IL_0004: ldarg.1 + IL_0005: ldind.u1 + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmetic5 + + .method public hidebysig instance int32 + PointerArithmetic6(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int32 i) cil managed + { + // Code size 17 (0x11) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: conv.i + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: mul + IL_000a: add + IL_000b: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0010: ret + } // end of method UnsafeCode::PointerArithmetic6 + + .method public hidebysig instance int32* + PointerArithmeticLong1(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong1 + + .method public hidebysig instance int32* + PointerArithmeticLong2(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: ldc.i4.4 + IL_0002: conv.i8 + IL_0003: mul + IL_0004: conv.i + IL_0005: ldarg.1 + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong2 + + .method public hidebysig instance int32* + PointerArithmeticLong3(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: sub + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong3 + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong1s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: add + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong1s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong2s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0007: conv.i8 + IL_0008: mul + IL_0009: conv.i + IL_000a: ldarg.1 + IL_000b: add + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong2s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong3s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: sub + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong3s + + .method public hidebysig instance int32 + PointerSubtraction(int64* p, + int64* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.8 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction + + .method public hidebysig instance int64 + PointerSubtractionLong(int64* p, + int64* q) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.8 + IL_0004: div + IL_0005: conv.i8 + IL_0006: ret + } // end of method UnsafeCode::PointerSubtractionLong + + .method public hidebysig instance int32 + PointerSubtraction2(int64* p, + int16* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction2 + + .method public hidebysig instance int32 + PointerSubtraction3(void* p, + void* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction3 + + .method public hidebysig instance int64 + PointerSubtraction4(int8* p, + int8* q) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: ret + } // end of method UnsafeCode::PointerSubtraction4 + + .method public hidebysig instance int64 + PointerSubtraction5(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* q) cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: div + IL_000a: conv.i8 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtraction5 + + .method public hidebysig instance float64 + FixedMemberAccess(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m, + int32 i) cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer0'::FixedElementField + IL_000b: conv.u + IL_000c: ldarg.2 + IL_000d: conv.i + IL_000e: ldc.i4.4 + IL_000f: mul + IL_0010: add + IL_0011: ldind.i4 + IL_0012: conv.r8 + IL_0013: ldarg.1 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0019: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1'::FixedElementField + IL_001e: conv.u + IL_001f: ldarg.2 + IL_0020: conv.i + IL_0021: ldc.i4.8 + IL_0022: mul + IL_0023: add + IL_0024: ldind.r8 + IL_0025: add + IL_0026: ret + } // end of method UnsafeCode::FixedMemberAccess + + .method public hidebysig instance float64* + FixedMemberBasePointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0006: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer1'::FixedElementField + IL_000b: conv.u + IL_000c: ret + } // end of method UnsafeCode::FixedMemberBasePointer + + .method public hidebysig instance string + UsePointer(float64* ptr) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Double::ToString() + IL_0006: ret + } // end of method UnsafeCode::UsePointer + + .method public hidebysig instance string + StackAlloc(int32 count) cil managed + { + // Code size 52 (0x34) + .maxstack 3 + .locals init (char* V_0, + char* V_1, + int32 V_2) + IL_0000: ldarg.1 + IL_0001: conv.u + IL_0002: ldc.i4.2 + IL_0003: mul.ovf.un + IL_0004: localloc + IL_0006: stloc.0 + IL_0007: ldc.i4.s 100 + IL_0009: conv.u + IL_000a: ldc.i4.2 + IL_000b: mul.ovf.un + IL_000c: localloc + IL_000e: stloc.1 + IL_000f: ldc.i4.0 + IL_0010: stloc.2 + IL_0011: br.s IL_0028 + + IL_0013: ldloc.0 + IL_0014: ldloc.2 + IL_0015: conv.i + IL_0016: ldc.i4.2 + IL_0017: mul + IL_0018: add + IL_0019: ldloc.2 + IL_001a: conv.u2 + IL_001b: stind.i2 + IL_001c: ldloc.1 + IL_001d: ldloc.2 + IL_001e: conv.i + IL_001f: ldc.i4.2 + IL_0020: mul + IL_0021: add + IL_0022: ldc.i4.0 + IL_0023: stind.i2 + IL_0024: ldloc.2 + IL_0025: ldc.i4.1 + IL_0026: add + IL_0027: stloc.2 + IL_0028: ldloc.2 + IL_0029: ldarg.1 + IL_002a: blt.s IL_0013 + + IL_002c: ldarg.0 + IL_002d: ldloc.0 + IL_002e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0033: ret + } // end of method UnsafeCode::StackAlloc + + .method public hidebysig instance string + StackAllocStruct(int32 count) cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: ldarg.1 + IL_0001: ldc.i4.2 + IL_0002: mul.ovf + IL_0003: conv.u + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: mul.ovf.un + IL_000b: localloc + IL_000d: stloc.0 + IL_000e: ldc.i4.s 10 + IL_0010: conv.u + IL_0011: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0017: mul.ovf.un + IL_0018: localloc + IL_001a: pop + IL_001b: ldarg.0 + IL_001c: ldloc.0 + IL_001d: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0022: conv.u + IL_0023: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0028: ret + } // end of method UnsafeCode::StackAllocStruct + + .method family hidebysig virtual instance void + Finalize() cil managed + { + // Code size 22 (0x16) + .maxstack 2 + .try + { + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: call instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000c: leave.s IL_0015 + + } // end .try + finally + { + IL_000e: ldarg.0 + IL_000f: call instance void [mscorlib]System.Object::Finalize() + IL_0014: endfinally + } // end handler + IL_0015: ret + } // end of method UnsafeCode::Finalize + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method UnsafeCode::.ctor + + .property instance int32* NullPointer() + { + .get instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + } // end of property UnsafeCode::NullPointer +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file ../../../TestCases/Pretty\UnsafeCode.opt.res diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il new file mode 100644 index 0000000000..eda65d772f --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il @@ -0,0 +1,910 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly UnsafeCode +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module UnsafeCode.dll +// MVID: {958D637E-F39D-447B-A248-B73AECEC847A} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x007C0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 X + .field public float64 Y + } // end of class SimpleStruct + + .class sequential ansi sealed nested public beforefieldinit StructWithFixedSizeMembers + extends [mscorlib]System.ValueType + { + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 400 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 FixedElementField + } // end of class 'e__FixedBuffer' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1600 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public float64 FixedElementField + } // end of class 'e__FixedBuffer' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 FixedElementField + } // end of class 'e__FixedBuffer' + + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Integers + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 59 53 79 73 74 65 6D 2E 49 6E 74 33 32 2C // ..YSystem.Int32, + 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 // mscorlib, Versi + 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 // on=4.0.0.0, Cult + 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 // ure=neutral, Pub + 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 // licKeyToken=b77a + 35 63 35 36 31 39 33 34 65 30 38 39 64 00 00 00 // 5c561934e089d... + 00 00 ) + .field public int32 NormalMember + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Doubles + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 5A 53 79 73 74 65 6D 2E 44 6F 75 62 6C 65 // ..ZSystem.Double + 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 // , mscorlib, Vers + 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C // ion=4.0.0.0, Cul + 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 // ture=neutral, Pu + 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 // blicKeyToken=b77 + 61 35 63 35 36 31 39 33 34 65 30 38 39 C8 00 00 // a5c561934e089... + 00 00 00 ) + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Old + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 58 53 79 73 74 65 6D 2E 42 79 74 65 2C 20 // ..XSystem.Byte, + 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F // mscorlib, Versio + 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 // n=4.0.0.0, Cultu + 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C // re=neutral, Publ + 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 // icKeyToken=b77a5 + 63 35 36 31 39 33 34 65 30 38 39 01 00 00 00 00 // c561934e089..... + 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 11 61 6E 6F 74 68 65 72 20 61 74 74 72 69 // ...another attri + 62 75 74 65 00 00 ) // bute.. + } // end of class StructWithFixedSizeMembers + + .method public hidebysig specialname instance int32* + get_NullPointer() cil managed + { + // Code size 3 (0x3) + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: conv.u + IL_0002: ret + } // end of method UnsafeCode::get_NullPointer + + .method public hidebysig instance int32 + SizeOf() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0006: ret + } // end of method UnsafeCode::SizeOf + + .method private hidebysig static void UseBool(bool b) cil managed + { + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method UnsafeCode::UseBool + + .method public hidebysig instance void + PointerComparison(int32* a, + float64* b) cil managed + { + // Code size 64 (0x40) + .maxstack 2 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ceq + IL_0004: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0009: ldarg.1 + IL_000a: ldarg.2 + IL_000b: ceq + IL_000d: ldc.i4.0 + IL_000e: ceq + IL_0010: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0015: ldarg.1 + IL_0016: ldarg.2 + IL_0017: clt.un + IL_0019: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_001e: ldarg.1 + IL_001f: ldarg.2 + IL_0020: cgt.un + IL_0022: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0027: ldarg.1 + IL_0028: ldarg.2 + IL_0029: cgt.un + IL_002b: ldc.i4.0 + IL_002c: ceq + IL_002e: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0033: ldarg.1 + IL_0034: ldarg.2 + IL_0035: clt.un + IL_0037: ldc.i4.0 + IL_0038: ceq + IL_003a: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_003f: ret + } // end of method UnsafeCode::PointerComparison + + .method public hidebysig instance void + PointerComparisonWithNull(int32* a) cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: ceq + IL_0005: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000a: ldarg.1 + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: ceq + IL_000f: ldc.i4.0 + IL_0010: ceq + IL_0012: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0017: ret + } // end of method UnsafeCode::PointerComparisonWithNull + + .method public hidebysig instance int32* + PointerCast(int64* p) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ret + } // end of method UnsafeCode::PointerCast + + .method public hidebysig instance int64 + ConvertDoubleToLong(float64 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.i8 + IL_0004: ret + } // end of method UnsafeCode::ConvertDoubleToLong + + .method public hidebysig instance float64 + ConvertLongToDouble(int64 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.r8 + IL_0004: ret + } // end of method UnsafeCode::ConvertLongToDouble + + .method public hidebysig instance int32 + ConvertFloatToInt(float32 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.i4 + IL_0004: ret + } // end of method UnsafeCode::ConvertFloatToInt + + .method public hidebysig instance float32 + ConvertIntToFloat(int32 d) cil managed + { + // Code size 5 (0x5) + .maxstack 8 + IL_0000: ldarga.s d + IL_0002: conv.u + IL_0003: ldind.r4 + IL_0004: ret + } // end of method UnsafeCode::ConvertIntToFloat + + .method public hidebysig instance int32 + PointerCasts() cil managed + { + // Code size 20 (0x14) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: conv.u + IL_0005: ldc.r4 0.5 + IL_000a: stind.r4 + IL_000b: ldloca.s V_0 + IL_000d: conv.u + IL_000e: ldc.i4.3 + IL_000f: add + IL_0010: ldc.i4.3 + IL_0011: stind.i1 + IL_0012: ldloc.0 + IL_0013: ret + } // end of method UnsafeCode::PointerCasts + + .method public hidebysig instance void + PassRefParameterAsPointer(int32& p) cil managed + { + // Code size 14 (0xe) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldloc.0 + IL_0004: conv.i + IL_0005: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000a: ldc.i4.0 + IL_000b: conv.u + IL_000c: stloc.0 + IL_000d: ret + } // end of method UnsafeCode::PassRefParameterAsPointer + + .method public hidebysig instance void + PassPointerAsRefParameter(int32* p) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0007: ret + } // end of method UnsafeCode::PassPointerAsRefParameter + + .method public hidebysig instance void + AddressInMultiDimensionalArray(float64[0...,0...] matrix) cil managed + { + // Code size 31 (0x1f) + .maxstack 3 + .locals init (float64& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.2 + IL_0003: call instance float64& float64[0...,0...]::Address(int32, + int32) + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: ldloc.0 + IL_000b: conv.i + IL_000c: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_0011: pop + IL_0012: ldarg.0 + IL_0013: ldloc.0 + IL_0014: conv.i + IL_0015: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_001a: pop + IL_001b: ldc.i4.0 + IL_001c: conv.u + IL_001d: stloc.0 + IL_001e: ret + } // end of method UnsafeCode::AddressInMultiDimensionalArray + + .method public hidebysig instance void + FixedStringAccess(string text) cil managed + { + // Code size 37 (0x25) + .maxstack 2 + .locals init (char* V_0, + string pinned V_1, + char* V_2) + IL_0000: ldarg.1 + IL_0001: stloc.1 + IL_0002: ldloc.1 + IL_0003: conv.i + IL_0004: stloc.0 + IL_0005: ldloc.0 + IL_0006: brfalse.s IL_0010 + + IL_0008: ldloc.0 + IL_0009: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000e: add + IL_000f: stloc.0 + IL_0010: ldloc.0 + IL_0011: stloc.2 + IL_0012: br.s IL_001c + + IL_0014: ldloc.2 + IL_0015: ldc.i4.s 65 + IL_0017: stind.i2 + IL_0018: ldloc.2 + IL_0019: ldc.i4.2 + IL_001a: add + IL_001b: stloc.2 + IL_001c: ldloc.2 + IL_001d: ldind.u2 + IL_001e: ldc.i4.s 97 + IL_0020: beq.s IL_0014 + + IL_0022: ldnull + IL_0023: stloc.1 + IL_0024: ret + } // end of method UnsafeCode::FixedStringAccess + + .method public hidebysig instance void + PutDoubleIntoLongArray1(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 36 (0x24) + .maxstack 3 + .locals init (int64& pinned V_0, + int64[] V_1) + IL_0000: ldarg.1 + IL_0001: dup + IL_0002: stloc.1 + IL_0003: brfalse.s IL_000a + + IL_0005: ldloc.1 + IL_0006: ldlen + IL_0007: conv.i4 + IL_0008: brtrue.s IL_000f + + IL_000a: ldc.i4.0 + IL_000b: conv.u + IL_000c: stloc.0 + IL_000d: br.s IL_0017 + + IL_000f: ldloc.1 + IL_0010: ldc.i4.0 + IL_0011: ldelema [mscorlib]System.Int64 + IL_0016: stloc.0 + IL_0017: ldloc.0 + IL_0018: conv.i + IL_0019: ldarg.2 + IL_001a: conv.i + IL_001b: ldc.i4.8 + IL_001c: mul + IL_001d: add + IL_001e: ldarg.3 + IL_001f: stind.r8 + IL_0020: ldc.i4.0 + IL_0021: conv.u + IL_0022: stloc.0 + IL_0023: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray1 + + .method public hidebysig instance void + PutDoubleIntoLongArray2(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 16 (0x10) + .maxstack 2 + .locals init (int64& pinned V_0) + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldelema [mscorlib]System.Int64 + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: conv.i + IL_000a: ldarg.3 + IL_000b: stind.r8 + IL_000c: ldc.i4.0 + IL_000d: conv.u + IL_000e: stloc.0 + IL_000f: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray2 + + .method public hidebysig instance string + PointerReferenceExpression(float64* d) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Double::ToString() + IL_0006: ret + } // end of method UnsafeCode::PointerReferenceExpression + + .method public hidebysig instance string + PointerReferenceExpression2(int64 addr) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: conv.u + IL_0002: call instance string [mscorlib]System.Int32::ToString() + IL_0007: ret + } // end of method UnsafeCode::PointerReferenceExpression2 + + .method public hidebysig instance int32* + PointerArithmetic(int32* p) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.2 + IL_0002: conv.i + IL_0003: ldc.i4.4 + IL_0004: mul + IL_0005: add + IL_0006: ret + } // end of method UnsafeCode::PointerArithmetic + + .method public hidebysig instance int64* + PointerArithmetic2(int64* p) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldc.i4.3 + IL_0001: conv.i + IL_0002: ldc.i4.8 + IL_0003: mul + IL_0004: ldarg.1 + IL_0005: add + IL_0006: ret + } // end of method UnsafeCode::PointerArithmetic2 + + .method public hidebysig instance int64* + PointerArithmetic3(int64* p) cil managed + { + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.3 + IL_0002: add + IL_0003: ret + } // end of method UnsafeCode::PointerArithmetic3 + + .method public hidebysig instance int64* + PointerArithmetic4(void* p) cil managed + { + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldc.i4.3 + IL_0002: add + IL_0003: ret + } // end of method UnsafeCode::PointerArithmetic4 + + .method public hidebysig instance int32 + PointerArithmetic5(void* p, + uint8* q, + int32 i) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: ldarg.3 + IL_0002: add + IL_0003: ldind.u1 + IL_0004: ldarg.1 + IL_0005: ldind.u1 + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmetic5 + + .method public hidebysig instance int32 + PointerArithmetic6(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int32 i) cil managed + { + // Code size 17 (0x11) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: conv.i + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: mul + IL_000a: add + IL_000b: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0010: ret + } // end of method UnsafeCode::PointerArithmetic6 + + .method public hidebysig instance int32* + PointerArithmeticLong1(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong1 + + .method public hidebysig instance int32* + PointerArithmeticLong2(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: ldc.i4.4 + IL_0002: conv.i8 + IL_0003: mul + IL_0004: conv.i + IL_0005: ldarg.1 + IL_0006: add + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong2 + + .method public hidebysig instance int32* + PointerArithmeticLong3(int32* p, + int64 offset) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: sub + IL_0007: ret + } // end of method UnsafeCode::PointerArithmeticLong3 + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong1s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: add + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong1s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong2s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.2 + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0007: conv.i8 + IL_0008: mul + IL_0009: conv.i + IL_000a: ldarg.1 + IL_000b: add + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong2s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong3s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: sub + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong3s + + .method public hidebysig instance int32 + PointerSubtraction(int64* p, + int64* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.8 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction + + .method public hidebysig instance int64 + PointerSubtractionLong(int64* p, + int64* q) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.8 + IL_0004: div + IL_0005: conv.i8 + IL_0006: ret + } // end of method UnsafeCode::PointerSubtractionLong + + .method public hidebysig instance int32 + PointerSubtraction2(int64* p, + int16* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction2 + + .method public hidebysig instance int32 + PointerSubtraction3(void* p, + void* q) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: conv.i4 + IL_0007: ret + } // end of method UnsafeCode::PointerSubtraction3 + + .method public hidebysig instance int64 + PointerSubtraction4(int8* p, + int8* q) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: ldc.i4.1 + IL_0004: div + IL_0005: conv.i8 + IL_0006: ret + } // end of method UnsafeCode::PointerSubtraction4 + + .method public hidebysig instance int64 + PointerSubtraction5(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* q) cil managed + { + // Code size 12 (0xc) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: sub + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: div + IL_000a: conv.i8 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtraction5 + + .method public hidebysig instance float64 + FixedMemberAccess(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m, + int32 i) cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000b: conv.u + IL_000c: ldarg.2 + IL_000d: conv.i + IL_000e: ldc.i4.4 + IL_000f: mul + IL_0010: add + IL_0011: ldind.i4 + IL_0012: conv.r8 + IL_0013: ldarg.1 + IL_0014: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0019: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_001e: conv.u + IL_001f: ldarg.2 + IL_0020: conv.i + IL_0021: ldc.i4.8 + IL_0022: mul + IL_0023: add + IL_0024: ldind.r8 + IL_0025: add + IL_0026: ret + } // end of method UnsafeCode::FixedMemberAccess + + .method public hidebysig instance float64* + FixedMemberBasePointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0006: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000b: conv.u + IL_000c: ret + } // end of method UnsafeCode::FixedMemberBasePointer + + .method public hidebysig instance string + UsePointer(float64* ptr) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: call instance string [mscorlib]System.Double::ToString() + IL_0006: ret + } // end of method UnsafeCode::UsePointer + + .method public hidebysig instance string + StackAlloc(int32 count) cil managed + { + // Code size 52 (0x34) + .maxstack 3 + .locals init (char* V_0, + char* V_1, + int32 V_2) + IL_0000: ldarg.1 + IL_0001: conv.u + IL_0002: ldc.i4.2 + IL_0003: mul.ovf.un + IL_0004: localloc + IL_0006: stloc.0 + IL_0007: ldc.i4.s 100 + IL_0009: conv.u + IL_000a: ldc.i4.2 + IL_000b: mul.ovf.un + IL_000c: localloc + IL_000e: stloc.1 + IL_000f: ldc.i4.0 + IL_0010: stloc.2 + IL_0011: br.s IL_0028 + + IL_0013: ldloc.0 + IL_0014: ldloc.2 + IL_0015: conv.i + IL_0016: ldc.i4.2 + IL_0017: mul + IL_0018: add + IL_0019: ldloc.2 + IL_001a: conv.u2 + IL_001b: stind.i2 + IL_001c: ldloc.1 + IL_001d: ldloc.2 + IL_001e: conv.i + IL_001f: ldc.i4.2 + IL_0020: mul + IL_0021: add + IL_0022: ldc.i4.0 + IL_0023: stind.i2 + IL_0024: ldloc.2 + IL_0025: ldc.i4.1 + IL_0026: add + IL_0027: stloc.2 + IL_0028: ldloc.2 + IL_0029: ldarg.1 + IL_002a: blt.s IL_0013 + + IL_002c: ldarg.0 + IL_002d: ldloc.0 + IL_002e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0033: ret + } // end of method UnsafeCode::StackAlloc + + .method public hidebysig instance string + StackAllocStruct(int32 count) cil managed + { + // Code size 41 (0x29) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: ldarg.1 + IL_0001: ldc.i4.2 + IL_0002: mul.ovf + IL_0003: conv.u + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: mul.ovf.un + IL_000b: localloc + IL_000d: stloc.0 + IL_000e: ldc.i4.s 10 + IL_0010: conv.u + IL_0011: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0017: mul.ovf.un + IL_0018: localloc + IL_001a: pop + IL_001b: ldarg.0 + IL_001c: ldloc.0 + IL_001d: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0022: conv.u + IL_0023: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0028: ret + } // end of method UnsafeCode::StackAllocStruct + + .method family hidebysig virtual instance void + Finalize() cil managed + { + .override [mscorlib]System.Object::Finalize + // Code size 22 (0x16) + .maxstack 2 + .try + { + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: call instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000c: leave.s IL_0015 + + } // end .try + finally + { + IL_000e: ldarg.0 + IL_000f: call instance void [mscorlib]System.Object::Finalize() + IL_0014: endfinally + } // end handler + IL_0015: ret + } // end of method UnsafeCode::Finalize + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method UnsafeCode::.ctor + + .property instance int32* NullPointer() + { + .get instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + } // end of property UnsafeCode::NullPointer +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il new file mode 100644 index 0000000000..f05799cea0 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il @@ -0,0 +1,1155 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly UnsafeCode +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module UnsafeCode.dll +// MVID: {A3E96E65-04A9-4270-81A4-F0FB3CB8D517} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x10000000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x01310000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + extends [mscorlib]System.Object +{ + .class sequential ansi sealed nested public beforefieldinit SimpleStruct + extends [mscorlib]System.ValueType + { + .field public int32 X + .field public float64 Y + } // end of class SimpleStruct + + .class sequential ansi sealed nested public beforefieldinit StructWithFixedSizeMembers + extends [mscorlib]System.ValueType + { + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 400 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 FixedElementField + } // end of class 'e__FixedBuffer' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1600 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public float64 FixedElementField + } // end of class 'e__FixedBuffer' + + .class sequential ansi sealed nested public beforefieldinit 'e__FixedBuffer' + extends [mscorlib]System.ValueType + { + .pack 0 + .size 1 + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.UnsafeValueTypeAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 FixedElementField + } // end of class 'e__FixedBuffer' + + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Integers + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 59 53 79 73 74 65 6D 2E 49 6E 74 33 32 2C // ..YSystem.Int32, + 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 // mscorlib, Versi + 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 // on=4.0.0.0, Cult + 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 // ure=neutral, Pub + 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 // licKeyToken=b77a + 35 63 35 36 31 39 33 34 65 30 38 39 64 00 00 00 // 5c561934e089d... + 00 00 ) + .field public int32 NormalMember + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Doubles + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 5A 53 79 73 74 65 6D 2E 44 6F 75 62 6C 65 // ..ZSystem.Double + 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 // , mscorlib, Vers + 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C // ion=4.0.0.0, Cul + 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 // ture=neutral, Pu + 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 // blicKeyToken=b77 + 61 35 63 35 36 31 39 33 34 65 30 38 39 C8 00 00 // a5c561934e089... + 00 00 00 ) + .field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' Old + .custom instance void [mscorlib]System.Runtime.CompilerServices.FixedBufferAttribute::.ctor(class [mscorlib]System.Type, + int32) = ( 01 00 58 53 79 73 74 65 6D 2E 42 79 74 65 2C 20 // ..XSystem.Byte, + 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F // mscorlib, Versio + 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 // n=4.0.0.0, Cultu + 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C // re=neutral, Publ + 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 // icKeyToken=b77a5 + 63 35 36 31 39 33 34 65 30 38 39 01 00 00 00 00 // c561934e089..... + 00 ) + .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string) = ( 01 00 11 61 6E 6F 74 68 65 72 20 61 74 74 72 69 // ...another attri + 62 75 74 65 00 00 ) // bute.. + } // end of class StructWithFixedSizeMembers + + .method public hidebysig specialname instance int32* + get_NullPointer() cil managed + { + // Code size 8 (0x8) + .maxstack 1 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stloc.0 + IL_0004: br.s IL_0006 + + IL_0006: ldloc.0 + IL_0007: ret + } // end of method UnsafeCode::get_NullPointer + + .method public hidebysig instance int32 + SizeOf() cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::SizeOf + + .method private hidebysig static void UseBool(bool b) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method UnsafeCode::UseBool + + .method public hidebysig instance void + PointerComparison(int32* a, + float64* b) cil managed + { + // Code size 71 (0x47) + .maxstack 2 + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ceq + IL_0005: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000a: nop + IL_000b: ldarg.1 + IL_000c: ldarg.2 + IL_000d: ceq + IL_000f: ldc.i4.0 + IL_0010: ceq + IL_0012: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0017: nop + IL_0018: ldarg.1 + IL_0019: ldarg.2 + IL_001a: clt.un + IL_001c: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0021: nop + IL_0022: ldarg.1 + IL_0023: ldarg.2 + IL_0024: cgt.un + IL_0026: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_002b: nop + IL_002c: ldarg.1 + IL_002d: ldarg.2 + IL_002e: cgt.un + IL_0030: ldc.i4.0 + IL_0031: ceq + IL_0033: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0038: nop + IL_0039: ldarg.1 + IL_003a: ldarg.2 + IL_003b: clt.un + IL_003d: ldc.i4.0 + IL_003e: ceq + IL_0040: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0045: nop + IL_0046: ret + } // end of method UnsafeCode::PointerComparison + + .method public hidebysig instance void + PointerComparisonWithNull(int32* a) cil managed + { + // Code size 27 (0x1b) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.0 + IL_0003: conv.u + IL_0004: ceq + IL_0006: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_000b: nop + IL_000c: ldarg.1 + IL_000d: ldc.i4.0 + IL_000e: conv.u + IL_000f: ceq + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: call void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UseBool(bool) + IL_0019: nop + IL_001a: ret + } // end of method UnsafeCode::PointerComparisonWithNull + + .method public hidebysig instance int32* + PointerCast(int64* p) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method UnsafeCode::PointerCast + + .method public hidebysig instance int64 + ConvertDoubleToLong(float64 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.i8 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertDoubleToLong + + .method public hidebysig instance float64 + ConvertLongToDouble(int64 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (float64 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.r8 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertLongToDouble + + .method public hidebysig instance int32 + ConvertFloatToInt(float32 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.i4 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertFloatToInt + + .method public hidebysig instance float32 + ConvertIntToFloat(int32 d) cil managed + { + // Code size 10 (0xa) + .maxstack 1 + .locals init (float32 V_0) + IL_0000: nop + IL_0001: ldarga.s d + IL_0003: conv.u + IL_0004: ldind.r4 + IL_0005: stloc.0 + IL_0006: br.s IL_0008 + + IL_0008: ldloc.0 + IL_0009: ret + } // end of method UnsafeCode::ConvertIntToFloat + + .method public hidebysig instance int32 + PointerCasts() cil managed + { + // Code size 25 (0x19) + .maxstack 2 + .locals init (int32 V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: ldloca.s V_0 + IL_0005: conv.u + IL_0006: ldc.r4 0.5 + IL_000b: stind.r4 + IL_000c: ldloca.s V_0 + IL_000e: conv.u + IL_000f: ldc.i4.3 + IL_0010: add + IL_0011: ldc.i4.3 + IL_0012: stind.i1 + IL_0013: ldloc.0 + IL_0014: stloc.1 + IL_0015: br.s IL_0017 + + IL_0017: ldloc.1 + IL_0018: ret + } // end of method UnsafeCode::PointerCasts + + .method public hidebysig instance void + PassRefParameterAsPointer(int32& p) cil managed + { + // Code size 18 (0x12) + .maxstack 2 + .locals init (int32& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: nop + IL_0004: ldarg.0 + IL_0005: ldloc.0 + IL_0006: conv.i + IL_0007: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000c: nop + IL_000d: nop + IL_000e: ldc.i4.0 + IL_000f: conv.u + IL_0010: stloc.0 + IL_0011: ret + } // end of method UnsafeCode::PassRefParameterAsPointer + + .method public hidebysig instance void + PassPointerAsRefParameter(int32* p) cil managed + { + // Code size 10 (0xa) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassRefParameterAsPointer(int32&) + IL_0008: nop + IL_0009: ret + } // end of method UnsafeCode::PassPointerAsRefParameter + + .method public hidebysig instance void + AddressInMultiDimensionalArray(float64[0...,0...] matrix) cil managed + { + // Code size 34 (0x22) + .maxstack 3 + .locals init (float64& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.1 + IL_0003: ldc.i4.2 + IL_0004: call instance float64& float64[0...,0...]::Address(int32, + int32) + IL_0009: stloc.0 + IL_000a: nop + IL_000b: ldarg.0 + IL_000c: ldloc.0 + IL_000d: conv.i + IL_000e: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_0013: pop + IL_0014: ldarg.0 + IL_0015: ldloc.0 + IL_0016: conv.i + IL_0017: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PointerReferenceExpression(float64*) + IL_001c: pop + IL_001d: nop + IL_001e: ldc.i4.0 + IL_001f: conv.u + IL_0020: stloc.0 + IL_0021: ret + } // end of method UnsafeCode::AddressInMultiDimensionalArray + + .method public hidebysig instance void + FixedStringAccess(string text) cil managed + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (char* V_0, + string pinned V_1, + char* V_2, + bool V_3) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.1 + IL_0003: ldloc.1 + IL_0004: conv.i + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: brfalse.s IL_0011 + + IL_0009: ldloc.0 + IL_000a: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_000f: add + IL_0010: stloc.0 + IL_0011: nop + IL_0012: ldloc.0 + IL_0013: stloc.2 + IL_0014: br.s IL_0020 + + IL_0016: nop + IL_0017: ldloc.2 + IL_0018: ldc.i4.s 65 + IL_001a: stind.i2 + IL_001b: ldloc.2 + IL_001c: ldc.i4.2 + IL_001d: add + IL_001e: stloc.2 + IL_001f: nop + IL_0020: ldloc.2 + IL_0021: ldind.u2 + IL_0022: ldc.i4.s 97 + IL_0024: ceq + IL_0026: stloc.3 + IL_0027: ldloc.3 + IL_0028: brtrue.s IL_0016 + + IL_002a: nop + IL_002b: ldnull + IL_002c: stloc.1 + IL_002d: ret + } // end of method UnsafeCode::FixedStringAccess + + .method public hidebysig instance void + PutDoubleIntoLongArray1(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 39 (0x27) + .maxstack 3 + .locals init (int64& pinned V_0, + int64[] V_1) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: dup + IL_0003: stloc.1 + IL_0004: brfalse.s IL_000b + + IL_0006: ldloc.1 + IL_0007: ldlen + IL_0008: conv.i4 + IL_0009: brtrue.s IL_0010 + + IL_000b: ldc.i4.0 + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: br.s IL_0018 + + IL_0010: ldloc.1 + IL_0011: ldc.i4.0 + IL_0012: ldelema [mscorlib]System.Int64 + IL_0017: stloc.0 + IL_0018: nop + IL_0019: ldloc.0 + IL_001a: conv.i + IL_001b: ldarg.2 + IL_001c: conv.i + IL_001d: ldc.i4.8 + IL_001e: mul + IL_001f: add + IL_0020: ldarg.3 + IL_0021: stind.r8 + IL_0022: nop + IL_0023: ldc.i4.0 + IL_0024: conv.u + IL_0025: stloc.0 + IL_0026: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray1 + + .method public hidebysig instance void + PutDoubleIntoLongArray2(int64[] 'array', + int32 index, + float64 val) cil managed + { + // Code size 19 (0x13) + .maxstack 2 + .locals init (int64& pinned V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldelema [mscorlib]System.Int64 + IL_0008: stloc.0 + IL_0009: nop + IL_000a: ldloc.0 + IL_000b: conv.i + IL_000c: ldarg.3 + IL_000d: stind.r8 + IL_000e: nop + IL_000f: ldc.i4.0 + IL_0010: conv.u + IL_0011: stloc.0 + IL_0012: ret + } // end of method UnsafeCode::PutDoubleIntoLongArray2 + + .method public hidebysig instance string + PointerReferenceExpression(float64* d) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Double::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerReferenceExpression + + .method public hidebysig instance string + PointerReferenceExpression2(int64 addr) cil managed + { + // Code size 13 (0xd) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: conv.u + IL_0003: call instance string [mscorlib]System.Int32::ToString() + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerReferenceExpression2 + + .method public hidebysig instance int32* + PointerArithmetic(int32* p) cil managed + { + // Code size 12 (0xc) + .maxstack 3 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.2 + IL_0003: conv.i + IL_0004: ldc.i4.4 + IL_0005: mul + IL_0006: add + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerArithmetic + + .method public hidebysig instance int64* + PointerArithmetic2(int64* p) cil managed + { + // Code size 12 (0xc) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldc.i4.3 + IL_0002: conv.i + IL_0003: ldc.i4.8 + IL_0004: mul + IL_0005: ldarg.1 + IL_0006: add + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerArithmetic2 + + .method public hidebysig instance int64* + PointerArithmetic3(int64* p) cil managed + { + // Code size 9 (0x9) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.3 + IL_0003: add + IL_0004: stloc.0 + IL_0005: br.s IL_0007 + + IL_0007: ldloc.0 + IL_0008: ret + } // end of method UnsafeCode::PointerArithmetic3 + + .method public hidebysig instance int64* + PointerArithmetic4(void* p) cil managed + { + // Code size 9 (0x9) + .maxstack 2 + .locals init (int64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.3 + IL_0003: add + IL_0004: stloc.0 + IL_0005: br.s IL_0007 + + IL_0007: ldloc.0 + IL_0008: ret + } // end of method UnsafeCode::PointerArithmetic4 + + .method public hidebysig instance int32 + PointerArithmetic5(void* p, + uint8* q, + int32 i) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldarg.3 + IL_0003: add + IL_0004: ldind.u1 + IL_0005: ldarg.1 + IL_0006: ldind.u1 + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmetic5 + + .method public hidebysig instance int32 + PointerArithmetic6(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int32 i) cil managed + { + // Code size 22 (0x16) + .maxstack 3 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: conv.i + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: mul + IL_000b: add + IL_000c: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::X + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: ldloc.0 + IL_0015: ret + } // end of method UnsafeCode::PointerArithmetic6 + + .method public hidebysig instance int32* + PointerArithmeticLong1(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldc.i4.4 + IL_0004: conv.i8 + IL_0005: mul + IL_0006: conv.i + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong1 + + .method public hidebysig instance int32* + PointerArithmeticLong2(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: ldc.i4.4 + IL_0003: conv.i8 + IL_0004: mul + IL_0005: conv.i + IL_0006: ldarg.1 + IL_0007: add + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong2 + + .method public hidebysig instance int32* + PointerArithmeticLong3(int32* p, + int64 offset) cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init (int32* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: ldc.i4.4 + IL_0004: conv.i8 + IL_0005: mul + IL_0006: conv.i + IL_0007: sub + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerArithmeticLong3 + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong1s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: conv.i8 + IL_000a: mul + IL_000b: conv.i + IL_000c: add + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong1s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong2s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.2 + IL_0002: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0008: conv.i8 + IL_0009: mul + IL_000a: conv.i + IL_000b: ldarg.1 + IL_000c: add + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong2s + + .method public hidebysig instance valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* + PointerArithmeticLong3s(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + int64 offset) cil managed + { + // Code size 18 (0x12) + .maxstack 3 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0009: conv.i8 + IL_000a: mul + IL_000b: conv.i + IL_000c: sub + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::PointerArithmeticLong3s + + .method public hidebysig instance int32 + PointerSubtraction(int64* p, + int64* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.8 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction + + .method public hidebysig instance int64 + PointerSubtractionLong(int64* p, + int64* q) cil managed + { + // Code size 12 (0xc) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.8 + IL_0005: div + IL_0006: conv.i8 + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtractionLong + + .method public hidebysig instance int32 + PointerSubtraction2(int64* p, + int16* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction2 + + .method public hidebysig instance int32 + PointerSubtraction3(void* p, + void* q) cil managed + { + // Code size 13 (0xd) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: conv.i4 + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method UnsafeCode::PointerSubtraction3 + + .method public hidebysig instance int64 + PointerSubtraction4(int8* p, + int8* q) cil managed + { + // Code size 12 (0xc) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: ldc.i4.1 + IL_0005: div + IL_0006: conv.i8 + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::PointerSubtraction4 + + .method public hidebysig instance int64 + PointerSubtraction5(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* p, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* q) cil managed + { + // Code size 17 (0x11) + .maxstack 2 + .locals init (int64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: sub + IL_0004: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000a: div + IL_000b: conv.i8 + IL_000c: stloc.0 + IL_000d: br.s IL_000f + + IL_000f: ldloc.0 + IL_0010: ret + } // end of method UnsafeCode::PointerSubtraction5 + + .method public hidebysig instance float64 + FixedMemberAccess(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m, + int32 i) cil managed + { + // Code size 44 (0x2c) + .maxstack 4 + .locals init (float64 V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers + IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000c: conv.u + IL_000d: ldarg.2 + IL_000e: conv.i + IL_000f: ldc.i4.4 + IL_0010: mul + IL_0011: add + IL_0012: ldind.i4 + IL_0013: conv.r8 + IL_0014: ldarg.1 + IL_0015: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_001a: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_001f: conv.u + IL_0020: ldarg.2 + IL_0021: conv.i + IL_0022: ldc.i4.8 + IL_0023: mul + IL_0024: add + IL_0025: ldind.r8 + IL_0026: add + IL_0027: stloc.0 + IL_0028: br.s IL_002a + + IL_002a: ldloc.0 + IL_002b: ret + } // end of method UnsafeCode::FixedMemberAccess + + .method public hidebysig instance float64* + FixedMemberBasePointer(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers* m) cil managed + { + // Code size 18 (0x12) + .maxstack 1 + .locals init (float64* V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles + IL_0007: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'e__FixedBuffer'::FixedElementField + IL_000c: conv.u + IL_000d: stloc.0 + IL_000e: br.s IL_0010 + + IL_0010: ldloc.0 + IL_0011: ret + } // end of method UnsafeCode::FixedMemberBasePointer + + .method public hidebysig instance string + UsePointer(float64* ptr) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (string V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: call instance string [mscorlib]System.Double::ToString() + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method UnsafeCode::UsePointer + + .method public hidebysig instance string + StackAlloc(int32 count) cil managed + { + // Code size 65 (0x41) + .maxstack 3 + .locals init (char* V_0, + char* V_1, + int32 V_2, + bool V_3, + string V_4) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: conv.u + IL_0003: ldc.i4.2 + IL_0004: mul.ovf.un + IL_0005: localloc + IL_0007: stloc.0 + IL_0008: ldc.i4.s 100 + IL_000a: conv.u + IL_000b: ldc.i4.2 + IL_000c: mul.ovf.un + IL_000d: localloc + IL_000f: stloc.1 + IL_0010: ldc.i4.0 + IL_0011: stloc.2 + IL_0012: br.s IL_002b + + IL_0014: nop + IL_0015: ldloc.0 + IL_0016: ldloc.2 + IL_0017: conv.i + IL_0018: ldc.i4.2 + IL_0019: mul + IL_001a: add + IL_001b: ldloc.2 + IL_001c: conv.u2 + IL_001d: stind.i2 + IL_001e: ldloc.1 + IL_001f: ldloc.2 + IL_0020: conv.i + IL_0021: ldc.i4.2 + IL_0022: mul + IL_0023: add + IL_0024: ldc.i4.0 + IL_0025: stind.i2 + IL_0026: nop + IL_0027: ldloc.2 + IL_0028: ldc.i4.1 + IL_0029: add + IL_002a: stloc.2 + IL_002b: ldloc.2 + IL_002c: ldarg.1 + IL_002d: clt + IL_002f: stloc.3 + IL_0030: ldloc.3 + IL_0031: brtrue.s IL_0014 + + IL_0033: ldarg.0 + IL_0034: ldloc.0 + IL_0035: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_003a: stloc.s V_4 + IL_003c: br.s IL_003e + + IL_003e: ldloc.s V_4 + IL_0040: ret + } // end of method UnsafeCode::StackAlloc + + .method public hidebysig instance string + StackAllocStruct(int32 count) cil managed + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct* V_1, + string V_2) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: ldc.i4.2 + IL_0003: mul.ovf + IL_0004: conv.u + IL_0005: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_000b: mul.ovf.un + IL_000c: localloc + IL_000e: stloc.0 + IL_000f: ldc.i4.s 10 + IL_0011: conv.u + IL_0012: sizeof ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct + IL_0018: mul.ovf.un + IL_0019: localloc + IL_001b: stloc.1 + IL_001c: ldarg.0 + IL_001d: ldloc.0 + IL_001e: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/SimpleStruct::Y + IL_0023: conv.u + IL_0024: call instance string ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::UsePointer(float64*) + IL_0029: stloc.2 + IL_002a: br.s IL_002c + + IL_002c: ldloc.2 + IL_002d: ret + } // end of method UnsafeCode::StackAllocStruct + + .method family hidebysig virtual instance void + Finalize() cil managed + { + .override [mscorlib]System.Object::Finalize + // Code size 26 (0x1a) + .maxstack 2 + IL_0000: nop + .try + { + IL_0001: nop + IL_0002: ldarg.0 + IL_0003: ldarg.0 + IL_0004: call instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + IL_0009: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::PassPointerAsRefParameter(int32*) + IL_000e: nop + IL_000f: leave.s IL_0019 + + } // end .try + finally + { + IL_0011: ldarg.0 + IL_0012: call instance void [mscorlib]System.Object::Finalize() + IL_0017: nop + IL_0018: endfinally + } // end handler + IL_0019: ret + } // end of method UnsafeCode::Finalize + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method UnsafeCode::.ctor + + .property instance int32* NullPointer() + { + .get instance int32* ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode::get_NullPointer() + } // end of property UnsafeCode::NullPointer +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 6fa460d11b..061e3015cb 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.IL.ControlFlow; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.Util; using System.IO; @@ -207,6 +208,8 @@ public static bool MemberIsHidden(MemberReference member, DecompilerSettings set return true; if (settings.AsyncAwait && AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(type)) return true; + if (settings.FixedBuffers && type.Name.StartsWith("<", StringComparison.Ordinal) && type.Name.Contains("__FixedBuffer")) + return true; } else if (type.IsCompilerGenerated()) { if (type.Name.StartsWith("", StringComparison.Ordinal)) return true; @@ -822,9 +825,37 @@ EntityDeclaration DoDecompile(FieldDefinition fieldDefinition, IField field, ITy } var fieldDecl = typeSystemAstBuilder.ConvertEntity(field); SetNewModifier(fieldDecl); + if (settings.FixedBuffers && IsFixedField(field, out var elementType, out var elementCount)) { + var fixedFieldDecl = new FixedFieldDeclaration(); + fieldDecl.Attributes.MoveTo(fixedFieldDecl.Attributes); + fixedFieldDecl.Modifiers = fieldDecl.Modifiers; + fixedFieldDecl.ReturnType = typeSystemAstBuilder.ConvertType(elementType); + fixedFieldDecl.Variables.Add(new FixedVariableInitializer(field.Name, new PrimitiveExpression(elementCount))); + fixedFieldDecl.Variables.Single().CopyAnnotationsFrom(((FieldDeclaration)fieldDecl).Variables.Single()); + fixedFieldDecl.CopyAnnotationsFrom(fieldDecl); + RemoveAttribute(fixedFieldDecl, fixedBufferAttributeTypeName); + return fixedFieldDecl; + } return fieldDecl; } + static readonly FullTypeName fixedBufferAttributeTypeName = new TopLevelTypeName("System.Runtime.CompilerServices", "FixedBufferAttribute"); + + internal static bool IsFixedField(IField field, out IType type, out int elementCount) + { + type = null; + elementCount = 0; + IAttribute attr = field.GetAttribute(fixedBufferAttributeTypeName, inherit: false); + if (attr != null && attr.PositionalArguments.Count == 2) { + if (attr.PositionalArguments[0] is TypeOfResolveResult trr && attr.PositionalArguments[1].ConstantValue is int length) { + type = trr.ReferencedType; + elementCount = length; + return true; + } + } + return false; + } + EntityDeclaration DoDecompile(PropertyDefinition propertyDefinition, IProperty property, ITypeResolveContext decompilationContext) { Debug.Assert(decompilationContext.CurrentMember == property); @@ -937,11 +968,11 @@ static AstType ConvertType(TypeReference type, ICustomAttributeProvider typeAttr string namepart = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name); AstType memberType; if ((options & (ConvertTypeOptions.IncludeOuterTypeName | ConvertTypeOptions.IncludeNamespace)) != 0) { - AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions); + AstType typeRef = ConvertType(type.DeclaringType, typeAttributes, ref typeIndex, options & ~ConvertTypeOptions.IncludeTypeParameterDefinitions); memberType = new MemberType { Target = typeRef, MemberName = namepart }; - if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { - AddTypeParameterDefininitionsTo(type, memberType); - } + if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { + AddTypeParameterDefininitionsTo(type, memberType); + } } else { memberType = new SimpleType(namepart); if ((options & ConvertTypeOptions.IncludeTypeParameterDefinitions) == ConvertTypeOptions.IncludeTypeParameterDefinitions) { @@ -1054,9 +1085,9 @@ static void ApplyTypeArgumentsTo(AstType baseType, List typeArguments) typeParameterCount = typeArguments.Count; st.TypeArguments.AddRange(typeArguments.GetRange(typeArguments.Count - typeParameterCount, typeParameterCount)); } else { - st.TypeArguments.AddRange(typeArguments); + st.TypeArguments.AddRange(typeArguments); - } + } } MemberType mt = baseType as MemberType; if (mt != null) { @@ -1106,7 +1137,7 @@ public Dictionary> CreateSequencePoints(SyntaxTr SequencePointBuilder spb = new SequencePointBuilder(); syntaxTree.AcceptVisitor(spb); return spb.GetSequencePoints(); - } + } #endregion } diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index cf81abcc62..2de0976f81 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -229,55 +229,38 @@ protected internal override TranslatedExpression VisitNewArr(NewArr inst, Transl protected internal override TranslatedExpression VisitLocAlloc(LocAlloc inst, TranslationContext context) { - IType elementType; - TranslatedExpression countExpression = TranslatePointerArgument(inst.Argument, context, out elementType); + TranslatedExpression countExpression; + PointerType pointerType; + if (inst.Argument.MatchBinaryNumericInstruction(BinaryNumericOperator.Mul, out var left, out var right) + && right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend).MatchSizeOf(out var elementType)) + { + // Determine the element type from the sizeof + countExpression = Translate(left.UnwrapConv(ConversionKind.ZeroExtend)); + pointerType = new PointerType(elementType); + } else { + // Determine the element type from the expected pointer type in this context + pointerType = context.TypeHint as PointerType; + if (pointerType != null && GetPointerArithmeticOffset( + inst.Argument, Translate(inst.Argument), + pointerType, checkForOverflow: true, + unwrapZeroExtension: true + ) is TranslatedExpression offset) + { + countExpression = offset; + elementType = pointerType.ElementType; + } else { + elementType = compilation.FindType(KnownTypeCode.Byte); + pointerType = new PointerType(elementType); + countExpression = Translate(inst.Argument); + } + } countExpression = countExpression.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this); - if (elementType == null) - elementType = compilation.FindType(KnownTypeCode.Byte); return new StackAllocExpression { Type = ConvertType(elementType), CountExpression = countExpression }.WithILInstruction(inst).WithRR(new ResolveResult(new PointerType(elementType))); } - /// - /// Translate the argument of an operation that deals with pointers: - /// * undoes the implicit multiplication with `sizeof(elementType)` and returns `elementType` - /// * on failure, translates the whole expression and returns `elementType = null`. - /// - TranslatedExpression TranslatePointerArgument(ILInstruction countExpr, TranslationContext context, out IType elementType) - { - ILInstruction left; - ILInstruction right; - if (countExpr.MatchBinaryNumericInstruction(BinaryNumericOperator.Mul, out left, out right) - && right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend).MatchSizeOf(out elementType)) - { - return Translate(left); - } - - var pointerTypeHint = context.TypeHint as PointerType; - if (pointerTypeHint == null) { - elementType = null; - return Translate(countExpr); - } - ResolveResult sizeofRR = resolver.ResolveSizeOf(pointerTypeHint.ElementType); - if (!(sizeofRR.IsCompileTimeConstant && sizeofRR.ConstantValue is int)) { - elementType = null; - return Translate(countExpr); - } - int typeSize = (int)sizeofRR.ConstantValue; - - if (countExpr.MatchBinaryNumericInstruction(BinaryNumericOperator.Mul, out left, out right) - && right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend).MatchLdcI4(typeSize)) - { - elementType = pointerTypeHint.ElementType; - return Translate(left); - } - - elementType = null; - return Translate(countExpr); - } - protected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, TranslationContext context) { return new PrimitiveExpression(inst.Value) @@ -494,6 +477,20 @@ TranslatedExpression TranslateCeq(Comp inst, out bool negateOutput) return right; } } + // Handle comparisons between unsafe pointers and null: + if (left.Type.Kind == TypeKind.Pointer && inst.Right.MatchLdcI(0)) { + negateOutput = false; + right = new NullReferenceExpression().WithRR(new ConstantResolveResult(SpecialType.NullType, null)) + .WithILInstruction(inst.Right); + return CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right) + .WithILInstruction(inst); + } else if (right.Type.Kind == TypeKind.Pointer && inst.Left.MatchLdcI(0)) { + negateOutput = false; + left = new NullReferenceExpression().WithRR(new ConstantResolveResult(SpecialType.NullType, null)) + .WithILInstruction(inst.Left); + return CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right) + .WithILInstruction(inst); + } // Special case comparisons with enum and char literals left = AdjustConstantExpressionToType(left, right.Type); @@ -504,12 +501,8 @@ TranslatedExpression TranslateCeq(Comp inst, out bool negateOutput) { // When comparing a delegate with null, the C# compiler generates a reference comparison. negateOutput = false; - return new BinaryOperatorExpression(left.Expression, inst.Kind.ToBinaryOperatorType(), right.Expression) - .WithILInstruction(inst) - .WithRR(new OperatorResolveResult( - compilation.FindType(KnownTypeCode.Boolean), - inst.Kind == ComparisonKind.Equality ? ExpressionType.Equal : ExpressionType.NotEqual, - left.ResolveResult, right.ResolveResult)); + return CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right) + .WithILInstruction(inst); } var rr = resolver.ResolveBinaryOperator(inst.Kind.ToBinaryOperatorType(), left.ResolveResult, right.ResolveResult) @@ -521,7 +514,15 @@ TranslatedExpression TranslateCeq(Comp inst, out bool negateOutput) if (inst.InputType == StackType.O) { targetType = compilation.FindType(KnownTypeCode.Object); } else { - targetType = TypeUtils.GetLargerType(NullableType.GetUnderlyingType(left.Type), NullableType.GetUnderlyingType(right.Type)); + var leftUType = NullableType.GetUnderlyingType(left.Type); + var rightUType = NullableType.GetUnderlyingType(right.Type); + if (leftUType.GetStackType() == inst.InputType && !leftUType.IsSmallIntegerType()) { + targetType = leftUType; + } else if (rightUType.GetStackType() == inst.InputType && !rightUType.IsSmallIntegerType()) { + targetType = rightUType; + } else { + targetType = compilation.FindType(inst.InputType.ToKnownTypeCode(leftUType.GetSign())); + } } if (inst.IsLifted) { targetType = NullableType.Create(compilation, targetType); @@ -539,9 +540,10 @@ TranslatedExpression TranslateCeq(Comp inst, out bool negateOutput) // If converting one input wasn't sufficient, convert both: left = left.ConvertTo(targetType, this); right = right.ConvertTo(targetType, this); - rr = new OperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), - BinaryOperatorExpression.GetLinqNodeType(BinaryOperatorType.Equality, false), - left.ResolveResult, right.ResolveResult); + rr = new OperatorResolveResult( + compilation.FindType(KnownTypeCode.Boolean), + BinaryOperatorExpression.GetLinqNodeType(inst.Kind.ToBinaryOperatorType(), false), + left.ResolveResult, right.ResolveResult); } } negateOutput = false; @@ -549,6 +551,17 @@ TranslatedExpression TranslateCeq(Comp inst, out bool negateOutput) .WithILInstruction(inst) .WithRR(rr); } + + ExpressionWithResolveResult CreateBuiltinBinaryOperator( + TranslatedExpression left, BinaryOperatorType type, TranslatedExpression right, + bool checkForOverflow = false) + { + return new BinaryOperatorExpression(left.Expression, type, right.Expression) + .WithRR(new OperatorResolveResult( + compilation.FindType(KnownTypeCode.Boolean), + BinaryOperatorExpression.GetLinqNodeType(type, checkForOverflow), + left.ResolveResult, right.ResolveResult)); + } /// /// Handle Comp instruction, operators other than equality/inequality. @@ -558,6 +571,12 @@ TranslatedExpression TranslateComp(Comp inst) var op = inst.Kind.ToBinaryOperatorType(); var left = Translate(inst.Left); var right = Translate(inst.Right); + + if (left.Type.Kind == TypeKind.Pointer && right.Type.Kind == TypeKind.Pointer) { + return CreateBuiltinBinaryOperator(left, op, right) + .WithILInstruction(inst); + } + left = PrepareArithmeticArgument(left, inst.InputType, inst.Sign, inst.IsLifted); right = PrepareArithmeticArgument(right, inst.InputType, inst.Sign, inst.IsLifted); @@ -652,7 +671,8 @@ protected internal override TranslatedExpression VisitBinaryNumericInstruction(B case BinaryNumericOperator.Mul: return HandleBinaryNumeric(inst, BinaryOperatorType.Multiply); case BinaryNumericOperator.Div: - return HandleBinaryNumeric(inst, BinaryOperatorType.Divide); + return HandlePointerSubtraction(inst) + ?? HandleBinaryNumeric(inst, BinaryOperatorType.Divide); case BinaryNumericOperator.Rem: return HandleBinaryNumeric(inst, BinaryOperatorType.Modulus); case BinaryNumericOperator.BitAnd: @@ -669,15 +689,202 @@ protected internal override TranslatedExpression VisitBinaryNumericInstruction(B throw new ArgumentOutOfRangeException(); } } - + + /// + /// Translates pointer arithmetic: + /// ptr + int + /// int + ptr + /// ptr - int + /// Returns null if 'inst' is not performing pointer arithmetic. + /// This function not handle 'ptr - ptr'! + /// + TranslatedExpression? HandlePointerArithmetic(BinaryNumericInstruction inst, TranslatedExpression left, TranslatedExpression right) + { + if (!(inst.Operator == BinaryNumericOperator.Add || inst.Operator == BinaryNumericOperator.Sub)) + return null; + if (inst.CheckForOverflow || inst.IsLifted) + return null; + if (!(inst.LeftInputType == StackType.I && inst.RightInputType == StackType.I)) + return null; + PointerType pointerType; + ILInstruction byteOffsetInst; + TranslatedExpression byteOffsetExpr; + if (left.Type.Kind == TypeKind.Pointer) { + byteOffsetInst = inst.Right; + byteOffsetExpr = right; + pointerType = (PointerType)left.Type; + } else if (right.Type.Kind == TypeKind.Pointer) { + if (inst.Operator != BinaryNumericOperator.Add) + return null; + byteOffsetInst = inst.Left; + byteOffsetExpr = left; + pointerType = (PointerType)right.Type; + } else { + return null; + } + TranslatedExpression offsetExpr = GetPointerArithmeticOffset(byteOffsetInst, byteOffsetExpr, pointerType, inst.CheckForOverflow) + ?? FallBackToBytePointer(); + if (!offsetExpr.Type.IsCSharpPrimitiveIntegerType()) { + // pointer arithmetic accepts all primitive integer types, but no enums etc. + StackType targetType = offsetExpr.Type.GetStackType() == StackType.I4 ? StackType.I4 : StackType.I8; + offsetExpr = offsetExpr.ConvertTo( + compilation.FindType(targetType.ToKnownTypeCode(offsetExpr.Type.GetSign())), + this); + } + + if (left.Type.Kind == TypeKind.Pointer) { + Debug.Assert(inst.Operator == BinaryNumericOperator.Add || inst.Operator == BinaryNumericOperator.Sub); + left = left.ConvertTo(pointerType, this); + right = offsetExpr; + } else { + Debug.Assert(inst.Operator == BinaryNumericOperator.Add); + Debug.Assert(right.Type.Kind == TypeKind.Pointer); + left = offsetExpr; + right = right.ConvertTo(pointerType, this); + } + var operatorType = inst.Operator == BinaryNumericOperator.Add ? BinaryOperatorType.Add : BinaryOperatorType.Subtract; + return new BinaryOperatorExpression(left, operatorType, right) + .WithILInstruction(inst) + .WithRR(new OperatorResolveResult( + pointerType, BinaryOperatorExpression.GetLinqNodeType(operatorType, inst.CheckForOverflow), + left.ResolveResult, right.ResolveResult)); + + TranslatedExpression FallBackToBytePointer() + { + pointerType = new PointerType(compilation.FindType(KnownTypeCode.Byte)); + return byteOffsetExpr; + } + } + + TranslatedExpression? GetPointerArithmeticOffset(ILInstruction byteOffsetInst, TranslatedExpression byteOffsetExpr, + PointerType pointerType, bool checkForOverflow, bool unwrapZeroExtension = false) + { + if (byteOffsetInst is Conv conv && conv.InputType == StackType.I8 && conv.ResultType == StackType.I) { + byteOffsetInst = conv.Argument; + } + int? elementSize = ComputeSizeOf(pointerType.ElementType); + if (elementSize == 1) { + return byteOffsetExpr; + } else if (byteOffsetInst is BinaryNumericInstruction mul && mul.Operator == BinaryNumericOperator.Mul) { + if (mul.CheckForOverflow != checkForOverflow) + return null; + if (mul.IsLifted) + return null; + if (elementSize > 0 && mul.Right.MatchLdcI(elementSize.Value) + || mul.Right.UnwrapConv(ConversionKind.SignExtend) is SizeOf sizeOf && sizeOf.Type.Equals(pointerType.ElementType)) + { + var countOffsetInst = mul.Left; + if (unwrapZeroExtension) { + countOffsetInst = countOffsetInst.UnwrapConv(ConversionKind.ZeroExtend); + } + return Translate(countOffsetInst); + } + } else if (byteOffsetInst.MatchLdcI(out long val)) { + // If the offset is a constant, it's possible that the compiler + // constant-folded the multiplication. + if (elementSize > 0 && (val % elementSize == 0) && val > 0) { + val /= elementSize.Value; + if (val <= int.MaxValue) { + return new PrimitiveExpression((int)val) + .WithILInstruction(byteOffsetInst) + .WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), val)); + } + } + } + return null; + } + + /// + /// Called for divisions, detect and handles the code pattern: + /// div(sub(a, b), sizeof(T)) + /// when a,b are of type T*. + /// This is what the C# compiler generates for pointer subtraction. + /// + TranslatedExpression? HandlePointerSubtraction(BinaryNumericInstruction inst) + { + Debug.Assert(inst.Operator == BinaryNumericOperator.Div); + if (inst.CheckForOverflow || inst.LeftInputType != StackType.I) + return null; + if (!(inst.Left is BinaryNumericInstruction sub && sub.Operator == BinaryNumericOperator.Sub)) + return null; + if (sub.CheckForOverflow) + return null; + // First, attempt to parse the 'sizeof' on the RHS + IType elementType; + if (inst.Right.MatchLdcI(out long elementSize)) { + elementType = null; + // OK, might be pointer subtraction if the element size matches + } else if (inst.Right.UnwrapConv(ConversionKind.SignExtend).MatchSizeOf(out elementType)) { + // OK, might be pointer subtraction if the element type matches + } else { + return null; + } + var left = Translate(sub.Left); + var right = Translate(sub.Right); + IType pointerType; + if (IsMatchingPointerType(left.Type)) { + pointerType = left.Type; + } else if (IsMatchingPointerType(right.Type)) { + pointerType = right.Type; + } else if (elementSize == 1 && left.Type.Kind == TypeKind.Pointer && right.Type.Kind == TypeKind.Pointer) { + // two pointers (neither matching), we're dividing by 1 (debug builds only), + // -> subtract two byte pointers + pointerType = new PointerType(compilation.FindType(KnownTypeCode.Byte)); + } else { + // neither is a matching pointer type + // -> not a pointer subtraction after all + return null; + } + // We got a pointer subtraction. + left = left.ConvertTo(pointerType, this); + right = right.ConvertTo(pointerType, this); + var rr = new OperatorResolveResult( + compilation.FindType(KnownTypeCode.Int64), + ExpressionType.Subtract, + left.ResolveResult, right.ResolveResult + ); + var result = new BinaryOperatorExpression( + left.Expression, BinaryOperatorType.Subtract, right.Expression + ).WithILInstruction(new[] { inst, sub }) + .WithRR(rr); + return result; + + bool IsMatchingPointerType(IType type) + { + if (type is PointerType pt) { + if (elementType != null) + return elementType.Equals(pt.ElementType); + else if (elementSize > 0) + return ComputeSizeOf(pt.ElementType) == elementSize; + } + return false; + } + } + + int? ComputeSizeOf(IType type) + { + var rr = resolver.ResolveSizeOf(type); + if (rr.IsCompileTimeConstant && rr.ConstantValue is int size) + return size; + else + return null; + } + TranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOperatorType op) { var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow); var left = Translate(inst.Left); var right = Translate(inst.Right); + + if (left.Type.Kind == TypeKind.Pointer || right.Type.Kind == TypeKind.Pointer) { + var ptrResult = HandlePointerArithmetic(inst, left, right); + if (ptrResult != null) + return ptrResult.Value; + } + left = PrepareArithmeticArgument(left, inst.LeftInputType, inst.Sign, inst.IsLifted); right = PrepareArithmeticArgument(right, inst.RightInputType, inst.Sign, inst.IsLifted); - + if (op == BinaryOperatorType.Subtract && inst.Left.MatchLdcI(0)) { IType rightUType = NullableType.GetUnderlyingType(right.Type); if (rightUType.IsKnownType(KnownTypeCode.Int32) || rightUType.IsKnownType(KnownTypeCode.Int64) || rightUType.IsCSharpSmallIntegerType()) { @@ -731,6 +938,7 @@ TranslatedExpression PrepareArithmeticArgument(TranslatedExpression arg, StackTy // If the argument is oversized (needs truncation to match stack size of its ILInstruction), // perform the truncation now. IType targetType = compilation.FindType(argStackType.ToKnownTypeCode(sign)); + argUType = targetType; if (isLifted) targetType = NullableType.Create(compilation, targetType); arg = arg.ConvertTo(targetType, this); @@ -979,7 +1187,7 @@ IType GetType(KnownTypeCode typeCode) // We just need to ensure the input type before the conversion is signed. // Also, if the argument was translated into an oversized C# type, // we need to perform the truncatation to the input stack type. - if (inputType.GetSign() != Sign.Signed || inputType.GetSize() > inputStackType.GetSize()) { + if (inputType.GetSign() != Sign.Signed || ValueMightBeOversized(arg.ResolveResult, inputStackType)) { // Note that an undersized C# type is handled just fine: // If it is unsigned we'll zero-extend it to the width of the inputStackType here, // and it is signed we just combine the two sign-extensions into a single sign-extending conversion. @@ -1035,12 +1243,48 @@ IType GetType(KnownTypeCode typeCode) // Case 4 (left-over extension from implicit conversion) can also be handled by our caller. return arg.WithILInstruction(inst); } - default: - return arg.ConvertTo(GetType(inst.TargetType.ToKnownTypeCode()), this, inst.CheckForOverflow) - .WithILInstruction(inst); + default: { + // We need to convert to inst.TargetType, or to an equivalent type. + IType targetType; + if (inst.TargetType == NullableType.GetUnderlyingType(context.TypeHint).ToPrimitiveType() + && NullableType.IsNullable(context.TypeHint) == inst.IsLifted) + { + targetType = context.TypeHint; + } else { + targetType = GetType(inst.TargetType.ToKnownTypeCode()); + } + return arg.ConvertTo(targetType, this, inst.CheckForOverflow) + .WithILInstruction(inst); + } } } + /// + /// Gets whether the ResolveResult computes a value that might be oversized for the specified stack type. + /// + bool ValueMightBeOversized(ResolveResult rr, StackType stackType) + { + IType inputType = NullableType.GetUnderlyingType(rr.Type); + if (inputType.GetSize() <= stackType.GetSize()) { + // The input type is smaller or equal to the stack type, + // it can't be an oversized value. + return false; + } + if (rr is OperatorResolveResult orr) { + if (stackType == StackType.I && orr.OperatorType == ExpressionType.Subtract + && orr.Operands.Count == 2 + && orr.Operands[0].Type.Kind == TypeKind.Pointer + && orr.Operands[1].Type.Kind == TypeKind.Pointer) + { + // Even though a pointer subtraction produces a value of type long in C#, + // the value will always fit in a native int. + return false; + } + } + // We don't have any information about the value, so it might be oversized. + return true; + } + protected internal override TranslatedExpression VisitCall(Call inst, TranslationContext context) { return new CallBuilder(this, typeSystem, settings).Build(inst); @@ -1211,19 +1455,41 @@ internal TranslatedExpression TranslateTarget(IMember member, ILInstruction targ protected internal override TranslatedExpression VisitLdObj(LdObj inst, TranslationContext context) { var target = Translate(inst.Target); - if (target.Expression is DirectionExpression && TypeUtils.IsCompatibleTypeForMemoryAccess(target.Type, inst.Type)) { - // we can dereference the managed reference by stripping away the 'ref' - var result = target.UnwrapChild(((DirectionExpression)target.Expression).Expression); + if (TypeUtils.IsCompatibleTypeForMemoryAccess(target.Type, inst.Type)) { + TranslatedExpression result; + if (target.Expression is DirectionExpression dirExpr) { + // we can dereference the managed reference by stripping away the 'ref' + result = target.UnwrapChild(dirExpr.Expression); + result.Expression.AddAnnotation(inst); // add LdObj in addition to the existing ILInstruction annotation + } else if (target.Type is PointerType pointerType) { + if (target.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.AddressOf) { + // We can dereference the pointer by stripping away the '&' + result = target.UnwrapChild(uoe.Expression); + result.Expression.AddAnnotation(inst); // add LdObj in addition to the existing ILInstruction annotation + } else { + // Dereference the existing pointer + result = new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression) + .WithILInstruction(inst) + .WithRR(new ResolveResult(pointerType.ElementType)); + } + } else { + // reference type behind non-DirectionExpression? + // this case should be impossible, but we can use a pointer cast + // just to make sure + target = target.ConvertTo(new PointerType(inst.Type), this); + return new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression) + .WithILInstruction(inst) + .WithRR(new ResolveResult(inst.Type)); + } // we don't convert result to inst.Type, because the LdObj type // might be inaccurate (it's often System.Object for all reference types), // and our parent node should already insert casts where necessary - result.Expression.AddAnnotation(inst); // add LdObj in addition to the existing ILInstruction annotation - + if (target.Type.IsSmallIntegerType() && inst.Type.IsSmallIntegerType() && target.Type.GetSign() != inst.Type.GetSign()) return result.ConvertTo(inst.Type, this); return result; } else { - // Cast pointer type if necessary: + // We need to cast the pointer type: target = target.ConvertTo(new PointerType(inst.Type), this); return new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression) .WithILInstruction(inst) @@ -1270,14 +1536,30 @@ protected internal override TranslatedExpression VisitLdLen(LdLen inst, Translat protected internal override TranslatedExpression VisitLdFlda(LdFlda inst, TranslationContext context) { - var expr = ConvertField(inst.Field, inst.Target); - return new DirectionExpression(FieldDirection.Ref, expr) - .WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type))); + if (settings.FixedBuffers && inst.Field.Name == "FixedElementField" + && inst.Target is LdFlda nestedLdFlda + && CSharpDecompiler.IsFixedField(nestedLdFlda.Field, out var elementType, out _)) + { + Expression result = ConvertField(nestedLdFlda.Field, nestedLdFlda.Target); + result.RemoveAnnotations(); + return result.WithRR(new ResolveResult(new PointerType(elementType))) + .WithILInstruction(inst); + } + var expr = ConvertField(inst.Field, inst.Target).WithILInstruction(inst); + if (inst.ResultType == StackType.I) { + // ldflda producing native pointer + return new UnaryOperatorExpression(UnaryOperatorType.AddressOf, expr) + .WithoutILInstruction().WithRR(new ResolveResult(new PointerType(expr.Type))); + } else { + // ldflda producing managed pointer + return new DirectionExpression(FieldDirection.Ref, expr) + .WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type))); + } } protected internal override TranslatedExpression VisitLdsFlda(LdsFlda inst, TranslationContext context) { - var expr = ConvertField(inst.Field); + var expr = ConvertField(inst.Field).WithILInstruction(inst); return new DirectionExpression(FieldDirection.Ref, expr) .WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type))); } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs index 04504b4b7a..9429704092 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs @@ -16,17 +16,15 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; +using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.TypeSystem; namespace ICSharpCode.Decompiler.CSharp.Transforms { public class IntroduceUnsafeModifier : DepthFirstAstVisitor, IAstTransform { - public static readonly object PointerArithmeticAnnotation = new PointerArithmetic(); - - sealed class PointerArithmetic {} - public void Run(AstNode compilationUnit, TransformContext context) { compilationUnit.AcceptVisitor(this); @@ -54,7 +52,15 @@ public override bool VisitPointerReferenceExpression(PointerReferenceExpression base.VisitPointerReferenceExpression(pointerReferenceExpression); return true; } - + + public override bool VisitSizeOfExpression(SizeOfExpression sizeOfExpression) + { + // C# sizeof(MyStruct) requires unsafe{} + // (not for sizeof(int), but that gets constant-folded and thus decompiled to 4) + base.VisitSizeOfExpression(sizeOfExpression); + return true; + } + public override bool VisitComposedType(ComposedType composedType) { if (composedType.PointerRank > 0) @@ -67,8 +73,11 @@ public override bool VisitUnaryOperatorExpression(UnaryOperatorExpression unaryO { bool result = base.VisitUnaryOperatorExpression(unaryOperatorExpression); if (unaryOperatorExpression.Operator == UnaryOperatorType.Dereference) { - BinaryOperatorExpression bop = unaryOperatorExpression.Expression as BinaryOperatorExpression; - if (bop != null && bop.Operator == BinaryOperatorType.Add && bop.Annotation() != null) { + var bop = unaryOperatorExpression.Expression as BinaryOperatorExpression; + if (bop != null && bop.Operator == BinaryOperatorType.Add + && bop.GetResolveResult() is OperatorResolveResult orr + && orr.Operands.FirstOrDefault()?.Type.Kind == TypeKind.Pointer) + { // transform "*(ptr + int)" to "ptr[int]" IndexerExpression indexer = new IndexerExpression(); indexer.Target = bop.Left.Detach(); @@ -118,5 +127,11 @@ public override bool VisitInvocationExpression(InvocationExpression invocationEx return true; return result; } + + public override bool VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer) + { + base.VisitFixedVariableInitializer(fixedVariableInitializer); + return true; + } } } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs index eda5781bf9..0abc0175ca 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs @@ -78,7 +78,7 @@ sealed class FindRequiredImports : DepthFirstAstVisitor public FindRequiredImports(TransformContext context) { - this.currentNamespace = context.DecompiledTypeDefinition != null ? context.DecompiledTypeDefinition.Namespace : string.Empty; + this.currentNamespace = context.DecompiledTypeDefinition?.Namespace ?? string.Empty; } bool IsParentOfCurrentNamespace(string ns) @@ -123,7 +123,12 @@ sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope) { this.context = new Stack(); - var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainAssembly, usingScope.Resolve(context.TypeSystem.Compilation)); + if (!string.IsNullOrEmpty(context.DecompiledTypeDefinition?.Namespace)) { + foreach (string ns in context.DecompiledTypeDefinition.Namespace.Split('.')) { + usingScope = new UsingScope(usingScope, ns); + } + } + var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainAssembly, usingScope.Resolve(context.TypeSystem.Compilation), context.DecompiledTypeDefinition); this.context.Push(currentContext); this.astBuilder = CreateAstBuilder(currentContext); } diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index 9e29709ef5..d4cb9a34aa 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -103,6 +103,21 @@ public bool AsyncAwait { } } + bool fixedBuffers = true; + + /// + /// Decompile C# 1.0 'public unsafe fixed int arr[10];' members. + /// + public bool FixedBuffers { + get { return fixedBuffers; } + set { + if (fixedBuffers != value) { + fixedBuffers = value; + OnPropertyChanged(); + } + } + } + bool liftNullables = true; /// diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs b/ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs index 30b7dea39a..a06218a54f 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs @@ -337,6 +337,7 @@ void ProcessPinnedRegion(PinnedRegion pinnedRegion) new PointerType(((ByReferenceType)oldVar.Type).ElementType), oldVar.Index); newVar.Name = oldVar.Name; + newVar.HasGeneratedName = oldVar.HasGeneratedName; oldVar.Function.Variables.Add(newVar); ReplacePinnedVar(oldVar, newVar, pinnedRegion); } else if (pinnedRegion.Variable.Type.IsKnownType(KnownTypeCode.String)) { @@ -383,6 +384,7 @@ void ProcessPinnedRegion(PinnedRegion pinnedRegion) if (nativeVar.Kind == VariableKind.Local) { newVar = new ILVariable(VariableKind.PinnedLocal, nativeVar.Type, nativeVar.Index); newVar.Name = nativeVar.Name; + newVar.HasGeneratedName = nativeVar.HasGeneratedName; nativeVar.Function.Variables.Add(newVar); ReplacePinnedVar(nativeVar, newVar, pinnedRegion); } else { diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index cf68e44469..c5d4786c57 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -3260,7 +3260,7 @@ public sealed override ILInstruction Clone() readonly IField field; /// Returns the field operand. public IField Field { get { return field; } } - public override StackType ResultType { get { return StackType.Ref; } } + public override StackType ResultType { get { return target.ResultType.IsIntegerType() ? StackType.I : StackType.Ref; } } protected override InstructionFlags ComputeFlags() { return target.Flags | (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow); diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 59c19a7427..cab30f5077 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -192,7 +192,8 @@ SupportsVolatilePrefix, SupportsUnalignedPrefix, ResultType("Void")), new OpCode("ldflda", "Load address of instance field", - CustomClassName("LdFlda"), CustomArguments("target"), MayThrowIfNotDelayed, HasFieldOperand, ResultType("Ref")), + CustomClassName("LdFlda"), CustomArguments("target"), MayThrowIfNotDelayed, HasFieldOperand, + ResultType("target.ResultType.IsIntegerType() ? StackType.I : StackType.Ref")), new OpCode("ldsflda", "Load static field address", CustomClassName("LdsFlda"), NoArguments, ResultType("Ref"), HasFieldOperand), diff --git a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs index 3382d6926f..5e4f30113a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs @@ -33,7 +33,7 @@ public bool MatchLdcF(double value) } /// - /// Matches either LdcI4 or LdcI8. + /// Matches ldc.i4, ldc.i8, and extending conversions. /// public bool MatchLdcI(out long val) { @@ -43,6 +43,17 @@ public bool MatchLdcI(out long val) val = intVal; return true; } + if (this is Conv conv) { + if (conv.Kind == ConversionKind.SignExtend) { + return conv.Argument.MatchLdcI(out val); + } else if (conv.Kind == ConversionKind.ZeroExtend && conv.InputType == StackType.I4) { + if (conv.Argument.MatchLdcI(out val)) { + // clear top 32 bits + val &= uint.MaxValue; + return true; + } + } + } return false; } diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index 3d23b9ab70..e877b951ad 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -226,14 +226,11 @@ static string GetNameFromInstruction(ILInstruction inst) { switch (inst) { case LdObj ldobj: - IField field; - if (ldobj.Target is LdFlda ldflda) - field = ldflda.Field; - else if (ldobj.Target is LdsFlda ldsflda) - field = ldsflda.Field; - else - break; - return CleanUpVariableName(field.Name); + return GetNameFromInstruction(ldobj.Target); + case LdFlda ldflda: + return CleanUpVariableName(ldflda.Field.Name); + case LdsFlda ldsflda: + return CleanUpVariableName(ldsflda.Field.Name); case CallInstruction call: if (call is NewObj) break; IMethod m = call.Method; diff --git a/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs b/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs index 8c8ddb2721..808285a095 100644 --- a/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs +++ b/ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs @@ -127,6 +127,28 @@ public static bool IsCSharpSmallIntegerType(this IType type) } } + /// + /// Gets whether the type is a C# primitive integer type: byte, sbyte, short, ushort, int, uint, long and ulong. + /// + /// Unlike the ILAst, C# does not consider bool, enums, pointers or IntPtr to be integers. + /// + public static bool IsCSharpPrimitiveIntegerType(this IType type) + { + switch (type.GetDefinition()?.KnownTypeCode) { + case KnownTypeCode.Byte: + case KnownTypeCode.SByte: + case KnownTypeCode.Int16: + case KnownTypeCode.UInt16: + case KnownTypeCode.Int32: + case KnownTypeCode.UInt32: + case KnownTypeCode.Int64: + case KnownTypeCode.UInt64: + return true; + default: + return false; + } + } + /// /// Gets whether the type is an IL integer type. /// Returns true for I4, I, or I8. @@ -282,6 +304,7 @@ public static PrimitiveType ToPrimitiveType(this KnownTypeCode knownTypeCode) case KnownTypeCode.Byte: return PrimitiveType.U1; case KnownTypeCode.UInt16: + case KnownTypeCode.Char: return PrimitiveType.U2; case KnownTypeCode.UInt32: return PrimitiveType.U4;