帮助InvalidProgramException(无效的IL代码?)

时间:2011-02-24 23:41:51

标签: .net exception mono cil reflection.emit

我在使用单声道System.Reflection.Emit导出的程序集中遇到了一个奇怪的错误。 在尝试运行我的程序集时,我得到一个InvalidProgramException:无效的IL代码。

monodis给了我这个CIL结果(这与我用Emit导出的结果一致):

.method public static hidebysig 
       default void f_main (class [Pine.Core]Pine.Core.Function A_0, class [Pine.Core]Pine.Core.ValueList A_1)  cil managed 
{
    // Method begins at RVA 0x2144
    // Code size 26 (0x1a)
    .maxstack 4
    .locals init (
        class [Pine.Core]Pine.Core.Function V_0,
        class [Pine.Core]Pine.Core.IScope   V_1,
        class [Pine.Core]Pine.Core.ValueList    V_2,
        class [Pine.Core]Pine.Core.IScope   V_3)
    IL_0000:  ldarg.0 
    IL_0001:  stloc.0 
    IL_0002:  ldarg.1 
    IL_0003:  stloc.2 
    IL_0004:  ldloc.0 
    IL_0005:  ldftn instance class [Pine.Core]Pine.Core.IScope class [Pine.Core]Pine.Core.Function::get_Scope()
    IL_000b:  stloc.1 
    IL_000c:  ldloc.1 
    IL_000d:  newobj instance void class [Pine.Core]Pine.Core.BlockScope::'.ctor'(class [Pine.Core]Pine.Core.IScope)
    IL_0012:  stloc.3 
    IL_0013:  ldloc.2 
    IL_0014:  call instance void class [Pine.Core]Pine.Core.ValueList::Clear()
    IL_0019:  ret 
} // end of method PineType::f_main

错误发生在IL_000b: stloc.1 我不明白为什么。

我尝试用pop指令替换stloc.1。当我这样做时,错误发生在IL_0019: ret

我真的不知道为什么会这样。有什么想法吗?

其他信息:

  • IScope是一个界面
  • BlockScope实施IScope
  • Function有一个public IScope Scope { get; private set; }
  • 我在Mono 2.6.7(Boehm,AMD64)和Mono 2.8(带有GC和并行标记的Boehm,AMD64)上都出现此错误。

1 个答案:

答案 0 :(得分:5)

编辑:从代码判断,也许IL_0005是一个call / callvirt而不是ldftn?也许发光使用了错误的操作码?

Local 1是一个IScope。 ldftn将函数指针(native int)推送到评估堆栈。 IL_000b上的存储指令无法验证,因为本机int不是验证者可分配给IScope。

至于你的第二个问题,你已经用IL_0004的指令使评估堆栈失去平衡。 ldftn的堆栈转换是“...... - > ...,ftn”。这意味着它不采用评估堆栈参数,只采用直接元数据标记。通过将IL_000b更改为弹出窗口,可以弹出ldftn推送的内容,而不是IL_0004推送的内容。

我不清楚你正在尝试做什么。您不能将单个函数指针视为接口(您可以将其视为概念上至少作为指向v表的指针)。您需要实例化实现该接口的类型。你可以用函数指针做什么是从它创建一个委托 - Delegate有一个(object,native int)重载.ctor。那就是我假设IL_0004推送的对象引用会起作用的地方(这个.ctor的第一个参数)。当然,您也可以直接调用函数指针。由于我不熟悉您正在与之交互的对象模型,我不能说正确的方法是什么。