I'm trying to use Reflection.Emit to generate the code for Call method of following code:
public unsafe class Program
{
public struct ATest
{
public int Test;
}
public struct Test
{
public Vtable* vtbl;
public struct Vtable
{
public delegate * unmanaged[Stdcall]<Test*, ATest> ptr;
}
}
public static ATest Call(Test* instance)
{
return ((delegate * unmanaged[Stdcall, MemberFunction]<Test*, ATest>)instance->vtbl->ptr)(instance);
}
}
I've decompiled the method using sharplab.io and got following msil:
// Methods
.method public hidebysig static
valuetype Program/ATest Call (
valuetype Program/Test* 'instance'
) cil managed
{
// Method begins at RVA 0x2050
// Code size 25 (0x19)
.maxstack 2
.locals init (
[0] method unmanaged valuetype Program/ATest modopt([System.Private.CoreLib]System.Runtime.CompilerServices.CallConvMemberFunction) modopt([System.Private.CoreLib]System.Runtime.CompilerServices.CallConvStdcall) *(valuetype Program/Test*),
[1] valuetype Program/ATest
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld valuetype Program/Test/Vtable* Program/Test::vtbl
IL_0007: ldfld method unmanaged stdcall valuetype Program/ATest *(valuetype Program/Test*) Program/Test/Vtable::ptr
IL_000c: stloc.0
IL_000d: ldarg.0
IL_000e: ldloc.0
IL_000f: calli unmanaged valuetype Program/ATest modopt([System.Private.CoreLib]System.Runtime.CompilerServices.CallConvMemberFunction) modopt([System.Private.CoreLib]System.Runtime.CompilerServices.CallConvStdcall)(valuetype Program/Test*)
IL_0014: stloc.1
IL_0015: br.s IL_0017
IL_0017: ldloc.1
IL_0018: ret
} // end of method Program::Call
I've tried to generete MSIL instructions using reflection.emit, but I don't know how to emit the line IL_000f:
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, vtableField);
il.Emit(OpCodes.Ldfld, methodField);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_0);
il.EmitCalli(???);
The issue is, that this line in MSIL has both modopt(MemberFunction) and mopopt(Stdcall), and I do not see this exposed anywhere in il.EmitCalli method.
Can someone help?