【问题标题】:Help with InvalidProgramException (Invalid IL Code?)帮助解决 InvalidProgramException(无效的 IL 代码?)
【发布时间】:2011-02-24 23:41:50
【问题描述】:

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

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 我不知道为什么。

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

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

附加信息:

  • IScope是一个接口
  • BlockScope 实现 IScope
  • Function 有一个 public IScope Scope { get; private set; }
  • Mono 2.6.7(Boehm, AMD64) 和 Mono 2.8(Boehm with typed GC and Parallel Mark, AMD64) 均出现此错误

【问题讨论】:

    标签: .net exception mono cil reflection.emit


    【解决方案1】:

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

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

    至于您的第二个问题,您使用 IL_0004 处的指令使评估堆栈失衡。 ldftn 的堆栈转换是“... -> ..., ftn”。这意味着它不需要评估堆栈参数,只有直接元数据令牌。通过将 IL_000b 更改为 pop,您会弹出 ldftn 推送的内容,而不是 IL_0004 推送的内容。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-03
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      相关资源
      最近更新 更多