Skip to content

Instantly share code, notes, and snippets.

@allykzam
Created June 23, 2015 13:15
Show Gist options
  • Save allykzam/ed296d501e628932c367 to your computer and use it in GitHub Desktop.
Save allykzam/ed296d501e628932c367 to your computer and use it in GitHub Desktop.
Decompiled record update syntax to see what the IL is doing

Original code is in Record updates.fs, the IL output for the type is in type.il, and the IL output for the function is in func.il. Also included ILSpy's interpretation of the function into C# code in func.cs.

// Program
public static int test()
{
Program.test test = new Program.test(FSharpOption<Program.test>.Some(new Program.test(null, 3)), 2);
Program.test test2 = test;
Program.test test3 = new Program.test(test2.One@, 3);
return test3.Two@;
}
.method public static
int32 test () cil managed
{
// Method begins at RVA 0x2050
// Code size 42 (0x2a)
.maxstack 4
.locals init (
[0] class Program/test,
[1] class Program/test,
[2] class Program/test
)
IL_0000: nop
IL_0001: ldnull
IL_0002: ldc.i4.3
IL_0003: newobj instance void Program/test::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>, int32)
IL_0008: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<!0> class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>::Some(!0)
IL_000d: ldc.i4.2
IL_000e: newobj instance void Program/test::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>, int32)
IL_0013: stloc.0
IL_0014: ldloc.0
IL_0015: stloc.2
IL_0016: ldloc.2
IL_0017: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_001c: ldc.i4.3
IL_001d: newobj instance void Program/test::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>, int32)
IL_0022: stloc.1
IL_0023: ldloc.1
IL_0024: ldfld int32 Program/test::Two@
IL_0029: ret
} // end of method Program::test
type test =
{
One : test option;
Two : int;
}
let test() =
let x = { One = Some({ One = None; Two = 3;}); Two = 2; }
let y = { x with Two = 3; }
y.Two
.class nested public auto ansi sealed serializable test
extends [mscorlib]System.Object
implements class [mscorlib]System.IEquatable`1<class Program/test>,
[mscorlib]System.Collections.IStructuralEquatable,
class [mscorlib]System.IComparable`1<class Program/test>,
[mscorlib]System.IComparable,
[mscorlib]System.Collections.IStructuralComparable
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 02 00 00 00 00 00
)
// Fields
.field assembly class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> One@
.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
01 00 00 00 00 00 00 00
)
.field assembly int32 Two@
.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (
01 00 00 00 00 00 00 00
)
// Methods
.method public hidebysig specialname
instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> get_One () cil managed
{
// Method begins at RVA 0x20bc
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0006: ret
} // end of method test::get_One
.method public hidebysig specialname
instance int32 get_Two () cil managed
{
// Method begins at RVA 0x20c4
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 Program/test::Two@
IL_0006: ret
} // end of method test::get_Two
.method public specialname rtspecialname
instance void .ctor (
class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> one,
int32 two
) cil managed
{
// Method begins at RVA 0x20cc
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_000d: ldarg.0
IL_000e: ldarg.2
IL_000f: stfld int32 Program/test::Two@
IL_0014: ret
} // end of method test::.ctor
.method public final hidebysig virtual
instance int32 CompareTo (
class Program/test obj
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x20e4
// Code size 115 (0x73)
.maxstack 5
.locals init (
[0] int32,
[1] class [mscorlib]System.Collections.IComparer,
[2] int32,
[3] int32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: cgt.un
IL_0005: brfalse.s IL_0009
IL_0007: br.s IL_000b
IL_0009: br.s IL_0065
IL_000b: ldarg.1
IL_000c: ldnull
IL_000d: cgt.un
IL_000f: brfalse.s IL_0013
IL_0011: br.s IL_0015
IL_0013: br.s IL_0063
IL_0015: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer()
IL_001a: ldarg.0
IL_001b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0020: ldarg.1
IL_0021: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0026: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic<class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>>(class [mscorlib]System.Collections.IComparer, !!0, !!0)
IL_002b: stloc.0
IL_002c: ldloc.0
IL_002d: ldc.i4.0
IL_002e: bge.s IL_0032
IL_0030: br.s IL_0034
IL_0032: br.s IL_0036
IL_0034: ldloc.0
IL_0035: ret
IL_0036: ldloc.0
IL_0037: ldc.i4.0
IL_0038: ble.s IL_003c
IL_003a: br.s IL_003e
IL_003c: br.s IL_0040
IL_003e: ldloc.0
IL_003f: ret
IL_0040: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer()
IL_0045: stloc.1
IL_0046: ldarg.0
IL_0047: ldfld int32 Program/test::Two@
IL_004c: stloc.2
IL_004d: ldarg.1
IL_004e: ldfld int32 Program/test::Two@
IL_0053: stloc.3
IL_0054: ldloc.2
IL_0055: ldloc.3
IL_0056: bge.s IL_005a
IL_0058: br.s IL_005c
IL_005a: br.s IL_005e
IL_005c: ldc.i4.m1
IL_005d: ret
IL_005e: ldloc.2
IL_005f: ldloc.3
IL_0060: cgt
IL_0062: ret
IL_0063: ldc.i4.1
IL_0064: ret
IL_0065: ldarg.1
IL_0066: ldnull
IL_0067: cgt.un
IL_0069: brfalse.s IL_006d
IL_006b: br.s IL_006f
IL_006d: br.s IL_0071
IL_006f: ldc.i4.m1
IL_0070: ret
IL_0071: ldc.i4.0
IL_0072: ret
} // end of method test::CompareTo
.method public final hidebysig virtual
instance int32 CompareTo (
object obj
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2164
// Code size 14 (0xe)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: unbox.any Program/test
IL_0008: callvirt instance int32 Program/test::CompareTo(class Program/test)
IL_000d: ret
} // end of method test::CompareTo
.method public final hidebysig virtual
instance int32 CompareTo (
object obj,
class [mscorlib]System.Collections.IComparer comp
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2174
// Code size 135 (0x87)
.maxstack 5
.locals init (
[0] class Program/test,
[1] class Program/test,
[2] int32,
[3] class [mscorlib]System.Collections.IComparer,
[4] int32,
[5] int32
)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: unbox.any Program/test
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: stloc.1
IL_000a: ldarg.0
IL_000b: ldnull
IL_000c: cgt.un
IL_000e: brfalse.s IL_0012
IL_0010: br.s IL_0017
IL_0012: br IL_0074
IL_0017: ldarg.1
IL_0018: unbox.any Program/test
IL_001d: ldnull
IL_001e: cgt.un
IL_0020: brfalse.s IL_0024
IL_0022: br.s IL_0026
IL_0024: br.s IL_0072
IL_0026: ldarg.2
IL_0027: ldarg.0
IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_002d: ldloc.1
IL_002e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0033: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic<class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>>(class [mscorlib]System.Collections.IComparer, !!0, !!0)
IL_0038: stloc.2
IL_0039: ldloc.2
IL_003a: ldc.i4.0
IL_003b: bge.s IL_003f
IL_003d: br.s IL_0041
IL_003f: br.s IL_0043
IL_0041: ldloc.2
IL_0042: ret
IL_0043: ldloc.2
IL_0044: ldc.i4.0
IL_0045: ble.s IL_0049
IL_0047: br.s IL_004b
IL_0049: br.s IL_004d
IL_004b: ldloc.2
IL_004c: ret
IL_004d: ldarg.2
IL_004e: stloc.3
IL_004f: ldarg.0
IL_0050: ldfld int32 Program/test::Two@
IL_0055: stloc.s 4
IL_0057: ldloc.1
IL_0058: ldfld int32 Program/test::Two@
IL_005d: stloc.s 5
IL_005f: ldloc.s 4
IL_0061: ldloc.s 5
IL_0063: bge.s IL_0067
IL_0065: br.s IL_0069
IL_0067: br.s IL_006b
IL_0069: ldc.i4.m1
IL_006a: ret
IL_006b: ldloc.s 4
IL_006d: ldloc.s 5
IL_006f: cgt
IL_0071: ret
IL_0072: ldc.i4.1
IL_0073: ret
IL_0074: ldarg.1
IL_0075: unbox.any Program/test
IL_007a: ldnull
IL_007b: cgt.un
IL_007d: brfalse.s IL_0081
IL_007f: br.s IL_0083
IL_0081: br.s IL_0085
IL_0083: ldc.i4.m1
IL_0084: ret
IL_0085: ldc.i4.0
IL_0086: ret
} // end of method test::CompareTo
.method public final hidebysig virtual
instance int32 GetHashCode (
class [mscorlib]System.Collections.IEqualityComparer comp
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2208
// Code size 67 (0x43)
.maxstack 7
.locals init (
[0] int32,
[1] class [mscorlib]System.Collections.IEqualityComparer
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: cgt.un
IL_0005: brfalse.s IL_0009
IL_0007: br.s IL_000b
IL_0009: br.s IL_0041
IL_000b: ldc.i4.0
IL_000c: stloc.0
IL_000d: ldc.i4 -1640531527
IL_0012: ldarg.1
IL_0013: stloc.1
IL_0014: ldarg.0
IL_0015: ldfld int32 Program/test::Two@
IL_001a: ldloc.0
IL_001b: ldc.i4.6
IL_001c: shl
IL_001d: ldloc.0
IL_001e: ldc.i4.2
IL_001f: shr
IL_0020: add
IL_0021: add
IL_0022: add
IL_0023: stloc.0
IL_0024: ldc.i4 -1640531527
IL_0029: ldarg.1
IL_002a: ldarg.0
IL_002b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0030: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic<class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>>(class [mscorlib]System.Collections.IEqualityComparer, !!0)
IL_0035: ldloc.0
IL_0036: ldc.i4.6
IL_0037: shl
IL_0038: ldloc.0
IL_0039: ldc.i4.2
IL_003a: shr
IL_003b: add
IL_003c: add
IL_003d: add
IL_003e: stloc.0
IL_003f: ldloc.0
IL_0040: ret
IL_0041: ldc.i4.0
IL_0042: ret
} // end of method test::GetHashCode
.method public final hidebysig virtual
instance int32 GetHashCode () cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2258
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer()
IL_0007: callvirt instance int32 Program/test::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer)
IL_000c: ret
} // end of method test::GetHashCode
.method public final hidebysig virtual
instance bool Equals (
object obj,
class [mscorlib]System.Collections.IEqualityComparer comp
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2268
// Code size 80 (0x50)
.maxstack 5
.locals init (
[0] class Program/test,
[1] class Program/test,
[2] class [mscorlib]System.Collections.IEqualityComparer
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: cgt.un
IL_0005: brfalse.s IL_0009
IL_0007: br.s IL_000b
IL_0009: br.s IL_0048
IL_000b: ldarg.1
IL_000c: isinst Program/test
IL_0011: stloc.0
IL_0012: ldloc.0
IL_0013: brfalse.s IL_0017
IL_0015: br.s IL_0019
IL_0017: br.s IL_0046
IL_0019: ldloc.0
IL_001a: stloc.1
IL_001b: ldarg.2
IL_001c: ldarg.0
IL_001d: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0022: ldloc.1
IL_0023: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0028: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic<class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>>(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0)
IL_002d: brfalse.s IL_0031
IL_002f: br.s IL_0033
IL_0031: br.s IL_0044
IL_0033: ldarg.2
IL_0034: stloc.2
IL_0035: ldarg.0
IL_0036: ldfld int32 Program/test::Two@
IL_003b: ldloc.1
IL_003c: ldfld int32 Program/test::Two@
IL_0041: ceq
IL_0043: ret
IL_0044: ldc.i4.0
IL_0045: ret
IL_0046: ldc.i4.0
IL_0047: ret
IL_0048: ldarg.1
IL_0049: ldnull
IL_004a: cgt.un
IL_004c: ldc.i4.0
IL_004d: ceq
IL_004f: ret
} // end of method test::Equals
.method public final hidebysig virtual
instance bool Equals (
class Program/test obj
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x22c4
// Code size 71 (0x47)
.maxstack 4
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: cgt.un
IL_0005: brfalse.s IL_0009
IL_0007: br.s IL_000b
IL_0009: br.s IL_003f
IL_000b: ldarg.1
IL_000c: ldnull
IL_000d: cgt.un
IL_000f: brfalse.s IL_0013
IL_0011: br.s IL_0015
IL_0013: br.s IL_003d
IL_0015: ldarg.0
IL_0016: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_001b: ldarg.1
IL_001c: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::One@
IL_0021: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic<class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test>>(!!0, !!0)
IL_0026: brfalse.s IL_002a
IL_0028: br.s IL_002c
IL_002a: br.s IL_003b
IL_002c: ldarg.0
IL_002d: ldfld int32 Program/test::Two@
IL_0032: ldarg.1
IL_0033: ldfld int32 Program/test::Two@
IL_0038: ceq
IL_003a: ret
IL_003b: ldc.i4.0
IL_003c: ret
IL_003d: ldc.i4.0
IL_003e: ret
IL_003f: ldarg.1
IL_0040: ldnull
IL_0041: cgt.un
IL_0043: ldc.i4.0
IL_0044: ceq
IL_0046: ret
} // end of method test::Equals
.method public final hidebysig virtual
instance bool Equals (
object obj
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2318
// Code size 25 (0x19)
.maxstack 4
.locals init (
[0] class Program/test
)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: isinst Program/test
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: brfalse.s IL_000d
IL_000b: br.s IL_000f
IL_000d: br.s IL_0017
IL_000f: ldarg.0
IL_0010: ldloc.0
IL_0011: callvirt instance bool Program/test::Equals(class Program/test)
IL_0016: ret
IL_0017: ldc.i4.0
IL_0018: ret
} // end of method test::Equals
// Properties
.property instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> One()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = (
01 00 04 00 00 00 00 00 00 00 00 00
)
.get instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<class Program/test> Program/test::get_One()
}
.property instance int32 Two()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = (
01 00 04 00 00 00 01 00 00 00 00 00
)
.get instance int32 Program/test::get_Two()
}
} // end of class test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment