2011-02-24 8 views
2

モノでSystem.Reflection.Emitでエクスポートされたアセンブリに変なバグがあります。 アセンブリを実行しようとすると、InvalidProgramExceptionが返されます。ILコードが無効です。InvalidProgramExceptionのヘルプ(無効なILコードですか?)

.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で起こる:

monodisは私に(私はエミットでエクスポートするものと一致している)、このCIL結果を提供します。

stloc.1をpop命令に置き換えようとしました。私がそうすると、エラーが発生しますIL_0019: ret

これはなぜこのように動作しているのかわかりません。何か案は?

追加情報:

  • IScope
  • BlockScopeIScope
  • Functionpublic IScope Scope { get; private set; }
  • が、私はモノ2.6.7(ベーム、AMD64)とMonoの両方で、このエラーを取得している実装インタフェースです2.8(Boehm型GCおよびパラレルマーク付き、AMD64)

答えて

4

編集:コードから判断すると、おそらくIL_0005はldftnではなくcall/callvirtになりますか?おそらく発光が間違ったオペコードを使用していますか?

ローカル1はIScopeです。 ldftnは、関数ポインタ(native int)を評価スタックにプッシュします。 IL_000bのストア命令は、ネイティブのintがベリファイアに割り当てられないため、検証可能ではありません。

第2の問題は、評価スタックとIL_0004の命令のアンバランスをとったことです。 ldftnのスタック遷移は "... - > ... ftn"です。つまり、評価スタックの引数は取らず、即時のメタデータトークンのみを使用します。 IL_000bをpopに変更すると、ldftnがプッシュしたものがポップされますが、IL_0004がプッシュしたものはポップしません。

あなたに何をしようとしているのか分かりません。 1つの関数ポインタをインタフェースとして扱うことはできません(概念的には、少なくともvテーブルへのポインタと考えることができます)。インターフェイスを実装する型をインスタンス化する必要があります。関数ポインタでできることは、そこからデリゲートを作成することです。デリゲートには、.ctorの(オブジェクト、ネイティブint)オーバーロードがあります。それはIL_0004によってプッシュされたオブジェクトリファレンスが演奏されると仮定したところです(この.ctorへの最初の引数)。もちろん、関数ポインタを直接呼び出しても構いません。あなたがこのオブジェクトモデルに慣れていないので、私は正しいアプローチが何であるかは言えません。

関連する問題