Browse Source

Add support for fixed-size buffers.

pull/924/head
Daniel Grunwald 8 years ago
parent
commit
0c6d6742fe
  1. 22
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs
  2. 128
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il
  3. 116
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il
  4. 112
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il
  5. 124
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il
  6. 31
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  7. 38
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  8. 7
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs
  9. 15
      ICSharpCode.Decompiler/DecompilerSettings.cs
  10. 2
      ICSharpCode.Decompiler/IL/Instructions.cs
  11. 3
      ICSharpCode.Decompiler/IL/Instructions.tt

22
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// 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
@ -26,6 +28,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -26,6 +28,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
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;
@ -235,6 +247,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -235,6 +247,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
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;
}
unsafe ~UnsafeCode()
{
this.PassPointerAsRefParameter(this.NullPointer);

128
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly p1cal2uj
.assembly '4mqlts3y'
{
.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
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module p1cal2uj.dll
// MVID: {BD577496-1116-4E18-AF25-DE99056CECA8}
.module '4mqlts3y.dll'
// MVID: {5733C4E7-C3DA-4F38-A641-CE223719D7AA}
.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: 0x03220000
// Image base: 0x01000000
// =============== CLASS MEMBERS DECLARATION ===================
@ -43,6 +43,71 @@ @@ -43,6 +43,71 @@
.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 '<Integers>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 '<Integers>e__FixedBuffer0'
.class sequential ansi sealed nested public beforefieldinit '<Doubles>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 '<Doubles>e__FixedBuffer1'
.class sequential ansi sealed nested public beforefieldinit '<Old>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 '<Old>e__FixedBuffer2'
.field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>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/'<Old>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
{
@ -860,6 +925,61 @@ @@ -860,6 +925,61 @@
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/'<Integers>e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers
IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_001a: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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/'<Doubles>e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0007: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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 family hidebysig virtual instance void
Finalize() cil managed
{

116
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly '0mxa1uxq'
.assembly '4wfrzmwx'
{
.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
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module '0mxa1uxq.dll'
// MVID: {EDB443DE-1443-48F8-8E42-03BAFC654447}
.module '4wfrzmwx.dll'
// MVID: {1CBCDACC-05B6-4B2D-BF36-5845CD657180}
.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: 0x00B60000
// Image base: 0x00520000
// =============== CLASS MEMBERS DECLARATION ===================
@ -43,6 +43,71 @@ @@ -43,6 +43,71 @@
.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 '<Integers>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 '<Integers>e__FixedBuffer0'
.class sequential ansi sealed nested public beforefieldinit '<Doubles>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 '<Doubles>e__FixedBuffer1'
.class sequential ansi sealed nested public beforefieldinit '<Old>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 '<Old>e__FixedBuffer2'
.field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>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/'<Old>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
{
@ -657,6 +722,49 @@ @@ -657,6 +722,49 @@
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/'<Integers>e__FixedBuffer0' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers
IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0019: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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/'<Doubles>e__FixedBuffer1' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0006: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>e__FixedBuffer1'::FixedElementField
IL_000b: conv.u
IL_000c: ret
} // end of method UnsafeCode::FixedMemberBasePointer
.method family hidebysig virtual instance void
Finalize() cil managed
{

112
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module UnsafeCode.dll
// MVID: {921693A0-E269-428D-8AB1-E3B34745B42B}
// MVID: {C46FA0A4-EE31-4A04-9894-41AA162DD602}
.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: 0x033D0000
// Image base: 0x00DE0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -47,6 +47,71 @@ @@ -47,6 +47,71 @@
.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 '<Integers>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 '<Integers>e__FixedBuffer'
.class sequential ansi sealed nested public beforefieldinit '<Doubles>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 '<Doubles>e__FixedBuffer'
.class sequential ansi sealed nested public beforefieldinit '<Old>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 '<Old>e__FixedBuffer'
.field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>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/'<Old>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
{
@ -663,6 +728,49 @@ @@ -663,6 +728,49 @@
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/'<Integers>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers
IL_0006: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0019: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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/'<Doubles>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0006: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>e__FixedBuffer'::FixedElementField
IL_000b: conv.u
IL_000c: ret
} // end of method UnsafeCode::FixedMemberBasePointer
.method family hidebysig virtual instance void
Finalize() cil managed
{

124
ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module UnsafeCode.dll
// MVID: {7BB1F8C9-F0A0-4D87-9A69-19FAC9915AFA}
// MVID: {A389E3D9-8350-4463-A41E-65C50B6E19ED}
.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: 0x015B0000
// Image base: 0x01620000
// =============== CLASS MEMBERS DECLARATION ===================
@ -47,6 +47,71 @@ @@ -47,6 +47,71 @@
.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 '<Integers>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 '<Integers>e__FixedBuffer'
.class sequential ansi sealed nested public beforefieldinit '<Doubles>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 '<Doubles>e__FixedBuffer'
.class sequential ansi sealed nested public beforefieldinit '<Old>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 '<Old>e__FixedBuffer'
.field public valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>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/'<Old>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
{
@ -866,6 +931,61 @@ @@ -866,6 +931,61 @@
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/'<Integers>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Integers
IL_0007: ldflda int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Integers>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/'<Doubles>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_001a: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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/'<Doubles>e__FixedBuffer' ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers::Doubles
IL_0007: ldflda float64 ICSharpCode.Decompiler.Tests.TestCases.Pretty.UnsafeCode/StructWithFixedSizeMembers/'<Doubles>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 family hidebysig virtual instance void
Finalize() cil managed
{

31
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.IL; @@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.ControlFlow;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Semantics;
namespace ICSharpCode.Decompiler.CSharp
{
@ -200,6 +201,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -200,6 +201,8 @@ namespace ICSharpCode.Decompiler.CSharp
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("<PrivateImplementationDetails>", StringComparison.Ordinal))
return true;
@ -735,9 +738,37 @@ namespace ICSharpCode.Decompiler.CSharp @@ -735,9 +738,37 @@ namespace ICSharpCode.Decompiler.CSharp
}
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);

38
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1450,10 +1450,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1450,10 +1450,16 @@ namespace ICSharpCode.Decompiler.CSharp
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) {
// Dereference the existing pointer
result = new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression)
.WithILInstruction(inst)
.WithRR(new ResolveResult(pointerType.ElementType));
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
@ -1518,14 +1524,30 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1518,14 +1524,30 @@ namespace ICSharpCode.Decompiler.CSharp
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<ResolveResult>();
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)));
}

7
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs

@ -57,6 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -57,6 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
// C# sizeof(MyStruct) requires unsafe{}
// (not for sizeof(int), but that gets constant-folded and thus decompiled to 4)
base.VisitSizeOfExpression(sizeOfExpression);
return true;
}
@ -126,5 +127,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -126,5 +127,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return true;
return result;
}
public override bool VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)
{
base.VisitFixedVariableInitializer(fixedVariableInitializer);
return true;
}
}
}

15
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -103,6 +103,21 @@ namespace ICSharpCode.Decompiler @@ -103,6 +103,21 @@ namespace ICSharpCode.Decompiler
}
}
bool fixedBuffers = true;
/// <summary>
/// Decompile C# 1.0 'public unsafe fixed int arr[10];' members.
/// </summary>
public bool FixedBuffers {
get { return fixedBuffers; }
set {
if (fixedBuffers != value) {
fixedBuffers = value;
OnPropertyChanged();
}
}
}
bool liftNullables = true;
/// <summary>

2
ICSharpCode.Decompiler/IL/Instructions.cs

@ -3242,7 +3242,7 @@ namespace ICSharpCode.Decompiler.IL @@ -3242,7 +3242,7 @@ namespace ICSharpCode.Decompiler.IL
readonly IField field;
/// <summary>Returns the field operand.</summary>
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);

3
ICSharpCode.Decompiler/IL/Instructions.tt

@ -192,7 +192,8 @@ @@ -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),

Loading…
Cancel
Save