I am trying to make a compiler to CIL (Microsoft IL). After the IL file is written, I generate the corresponding .exe file, using ilasm (CIL Assembler). After I tried to add generics, I get the following error when trying to run the executable:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'fungjprg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Signature has bad element type. (Exception from HRESULT: 0x80131247) ---> System.Runtime.InteropServices.COMException: Signature has bad element type. (Exception from HRESULT: 0x80131247)
--- End of inner exception stack trace ---
I really do not understand where this is coming from, as everything used to work perfectly before trying to compile generic types. Moreover, as I though my IL code is bad, I wrote a simple generic program in C#, and took its generated IL (using ILDASM), and tried to run it, but I am getting the exact same error.
C# code:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(new A<int>(3).f());
}
}
class A<X>
{
X val;
public A(X val)
{
this.val = val;
}
public X f()
{
return this.val;
}
}
My CIL file:
.assembly extern System.Runtime
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A)
.ver 4:0:0:0
}
.assembly extern System.Console
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A)
.ver 4:0:0:0
}
.assembly fungjprg
{
.hash algorithm 0x00008004 // I tried to add/remove this, same result...
.ver 1:0:0:0 // I tried to add/remove this, same result...
}
.class private auto ansi beforefieldinit fungjprg.A`1<X>
extends [System.Runtime]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor(!X val) cil managed
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: stfld !0 class fungjprg.A`1<!X>::val
IL_000f: ret
}
.method public hidebysig instance !X f() cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init (!X V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld !0 class fungjprg.A`1<!X>::val
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
}
}
.field private !X val
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 8
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: newobj instance void class fungjprg.A`1<int32>::.ctor(!0)
IL_0007: call instance !0 class fungjprg.A`1<int32>::f()
IL_000c: call void [System.Console]System.Console::WriteLine(int32)
IL_0011: nop
IL_0012: ret
}
ILASM output:
Microsoft (R) .NET Framework IL Assembler. Version 4.8.3752.0
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'compiledprogram.fungj' to EXE --> 'compiledprogram.exe'
Source file is ANSI
Assembled method fungjprg.A`1::.ctor
Assembled method fungjprg.A`1::f
compiledprogram.fungj(54) : warning : Non-static global field, made static
Assembled global method Main
Creating PE file
Emitting classes:
Class 1: fungjprg.A`1
Emitting fields and methods:
Global Fields: 1; Methods: 1;
Class 1 Methods: 2;
Emitting events and properties:
Global
Class 1
Writing PE file
Operation completed successfully
I tried to sign the IL file with a strong name key, but the error still persists (the only difference is that the PublicKeyToken is not null anymore)
According your CIL file .field private !X val
is not a part of class A. That's weird, because according to C# code it looks a part of it.
Try to move .field private !X val
into the class scope, something like that
.class private auto ansi beforefieldinit fungjprg.A`1<X>
extends [System.Runtime]System.Object
{
.field private !X val
.method public hidebysig specialname rtspecialname
instance void .ctor(!X val) cil managed
{
// method code..
}
}
Edit: I ran your CIL file with the fix and it works for me
User contributions licensed under CC BY-SA 3.0