ILVerification fails on delegate ctor of generated assembly
AqlaSolutions opened this issue · 2 comments
AqlaSolutions commented
[IL]: Error [CallCtor]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x00000001] call to .ctor only allowed to initialize this pointer from within a .ctor. Try newobj.
[IL]: Error [StackUnexpected]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x00000007][found ref '[TriAxis.RunSharp.Tests.12_Delegates.GenBookstore]ProcessBookDelegate'] Unexpected type on the stack.
[IL]: Error [ThisUninitReturn]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x0000000C] Return from .ctor when this is uninitialized.
[IL]: Error [CallCtor]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x00000001] call to .ctor only allowed to initialize this pointer from within a .ctor. Try newobj.
[IL]: Error [StackUnexpected]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x00000007][found ref '[TriAxis.RunSharp.Tests.12_Delegates.GenBookstore]ProcessBookDelegate'] Unexpected type on the stack.
[IL]: Error [ThisUninitReturn]: [.ProcessBookDelegate::.ctor(object, native int)][offset 0x0000000C] Return from .ctor when this is uninitialized.
TriAxis.RunSharp.Tests.12_Delegates.GenBookstore.zip
Source code:
public delegate void ProcessBookDelegate();
public class Test
{
public static void Main()
{
}
}
ildasm:
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi sealed ProcessBookDelegate
extends [System.Runtime]System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname
instance void .ctor(object 'object',
native int 'method') runtime managed
{
} // end of method ProcessBookDelegate::.ctor
.method public hidebysig newslot virtual
instance class [System.Runtime]System.IAsyncResult
BeginInvoke(class [System.Runtime]System.AsyncCallback callback,
object 'object') runtime managed
{
} // end of method ProcessBookDelegate::BeginInvoke
.method public hidebysig newslot virtual
instance void EndInvoke(class [System.Runtime]System.IAsyncResult result) runtime managed
{
} // end of method ProcessBookDelegate::EndInvoke
.method public hidebysig newslot virtual
instance void Invoke() runtime managed
{
} // end of method ProcessBookDelegate::Invoke
} // end of class ProcessBookDelegate
.class public auto ansi beforefieldinit Test
extends [System.Runtime]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: call instance void Test::$$ctor$PST06000007()
IL_000c: ret
} // end of method Test::.ctor
.method public hidebysig static void Main() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Test::Main
.method privatescope hidebysig instance void
$$ctor$PST06000007() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Test::$$ctor
} // end of class Test
The same code compiled for .NET 5 in VS generates almost same IL but passes ILVerification without errors:
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi sealed ProcessBookDelegate
extends [System.Runtime]System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname
instance void .ctor(object 'object',
native int 'method') runtime managed
{
} // end of method ProcessBookDelegate::.ctor
.method public hidebysig newslot virtual
instance class [System.Runtime]System.IAsyncResult
BeginInvoke(class [System.Runtime]System.AsyncCallback callback,
object 'object') runtime managed
{
} // end of method ProcessBookDelegate::BeginInvoke
.method public hidebysig newslot virtual
instance void EndInvoke(class [System.Runtime]System.IAsyncResult result) runtime managed
{
} // end of method ProcessBookDelegate::EndInvoke
.method public hidebysig newslot virtual
instance void Invoke() runtime managed
{
} // end of method ProcessBookDelegate::Invoke
} // end of class ProcessBookDelegate
.class public auto ansi beforefieldinit Test
extends [System.Runtime]System.Object
{
.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 [System.Runtime]System.Object::.ctor()
IL_0006: ret
} // end of method Test::.ctor
.method public hidebysig static void Main() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Test::Main
} // end of class Test
Re-saving the erroneous IL in dnSpy generates assembly that passes ILVerification:
unchanged.zip
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi sealed ProcessBookDelegate
extends [System.Private.CoreLib]System.MulticastDelegate
{
.method public hidebysig specialname rtspecialname
instance void .ctor(object 'object',
native int 'method') runtime managed
{
} // end of method ProcessBookDelegate::.ctor
.method public hidebysig newslot virtual
instance class [System.Private.CoreLib]System.IAsyncResult
BeginInvoke(class [System.Private.CoreLib]System.AsyncCallback callback,
object 'object') runtime managed
{
} // end of method ProcessBookDelegate::BeginInvoke
.method public hidebysig newslot virtual
instance void EndInvoke(class [System.Private.CoreLib]System.IAsyncResult result) runtime managed
{
} // end of method ProcessBookDelegate::EndInvoke
.method public hidebysig newslot virtual
instance void Invoke() runtime managed
{
} // end of method ProcessBookDelegate::Invoke
} // end of class ProcessBookDelegate
.class public auto ansi beforefieldinit Test
extends [System.Private.CoreLib]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: call instance void Test::$$ctor$PST06000007()
IL_000c: ret
} // end of method Test::.ctor
.method public hidebysig static void Main() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Test::Main
.method privatescope hidebysig instance void
$$ctor$PST06000007() cil managed
{
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Test::$$ctor
} // end of class Test
The only difference in this fix is using System.Private.CoreLib
library instead of System.Runtime
and that it's a dll, not exe.
Expected behavior: generated by ILPack assembly should pass IL verification without issues.
vermorel commented
@AqlaSolutions Thanks a lot for the report. I don't have resources to devote to this at this point of time, but it's a nice precisely report nonetheless.