CIL - How do I use a public static literal field?

1.1k views Asked by At

This might be a dumb question but I'm really curious if I can do this. I wrote the following sample program:

class Test1 {

    public const int b = 8;
    public static int z = 3;

    public static void Main(string[] args){
        const int q = 6;
        Console.WriteLine(q);
        Console.WriteLine(b);
        Console.WriteLine(z);

    }
}

Y compiled this using mcs and then I diassembled the generated exe with monodis. Obtained the following code:

.field public static literal  int32 b = int32(0x00000008)
.field  public static  int32 z

// method line 2
.method public static hidebysig 
       default void Main (string[] args)  cil managed 
{
    // Method begins at RVA 0x2058
      .entrypoint
      // Code size 23 (0x17)
      .maxstack 8
      IL_0000:  ldc.i4.6 
      IL_0001:  call void class [mscorlib]System.Console::WriteLine(int32)
      IL_0006:  ldc.i4.8 
      IL_0007:  call void class [mscorlib]System.Console::WriteLine(int32)
      IL_000c:  ldsfld int32 Test.Test1::z
      IL_0011:  call void class [mscorlib]System.Console::WriteLine(int32)
      IL_0016:  ret 
} // end of method Test1::Main

I want to use ldsfld to load the value of b. If I change IL_0006 to ldsfld int32 Test.Test1::b, it will assemble, but when I run the executable I obtain an excpetion:

Unhandled Exception:
System.InvalidProgramException: Invalid IL code in Test.Test1:Main 
(string[]): IL_0006: ldsfld    0x04000001


[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException: 
Invalid IL code in Test.Test1:Main (string[]): IL_0006: ldsfld    0x04000001

Is there any way to use the static literal instead of just using ldc?

1

There are 1 answers

2
AudioBubble On BEST ANSWER

You already have comments-as-answers from a C# perspective, but the CIL spec is more appropriate and rather explicit on it too:

I.8.6.1.2 Location signatures

The literal constraint promises that the value of the location is actually a fixed value of a built-in type. The value is specified as part of the constraint. Compilers are required to replace all references to the location with its value, and the VES therefore need not allocate space for the location. This constraint, while logically applicable to any location, shall only be placed on static fields of compound types. Fields that are so marked are not permitted to be referenced from CIL (they shall be in-lined to their constant value at compile time), but are available using reflection and tools that directly deal with the metadata.

So, no, there is no way at all to reference that field directly, and there isn't supposed to be.