2016-10-15 9 views
2

私はjmpオペコードの使い方を見ていますが、これまでのところ、ジェネリックメソッドを呼び出すことはできませんでした(’)。私のテストでは、その引数を返すメソッドと、最初のメソッドにジャンプするjmpオペコードだけのメソッドがあります。私の問題は、非一般的な方法(例えば、に次のId2のシグネチャを持つシグネチャを使用)にジャンプすると実行時にエラーが発生しない一方、一般的な方法(例:jmp !!0 Program::Id<int32>(!!0)にID: static T Id<T>(T x))“ Common Language Runtimeが無効なプログラム”の例外を検出しました。その問題の原因は何か?.Net CIL jmpオペコードとジェネリックメソッド

P.S. :ここで’ s a gistと私のテストで使用していたCIL。 Id2にジャンプし、Idにジャンプする行のコメントをIdIntに書き込むと、前述の例外を除いて実行時に失敗します。 IdIntId2には、StringBuilder doesn ’のような参照型が返されますが、それは失敗します。

+1

コンパイル可能なサンプルを投稿できますか? – thehennyy

+0

@thehennyy良い点、私はテストILと要点を追加しました。 – arjanen

+0

コードでpeverifyを実行しようとしましたか? – svick

答えて

2

ECMA-335パーティションIIIセクション3.37 - JMP、言う:メタデータトークンである方法で指定された方法に

転送制御(methodref又は methoddefいずれか(パーティションIIを参照)。現在の引数は、宛先方法に転送される。

両方MemberRefとMethodDefトークンは、非ジェネリックメソッドおよびオープンジェネリックメソッドを参照することができるが、閉じたジェネリックメソッドを参照することは許容されるように記載されていないMethodSpecトークンを必要とします。

jmpがジェネリックメソッドをサポートしていない可能性があるのは、同じジェネリックメソッドの異なるインスタンス化でネイティブコードを再利用するjitsの機能を妨げるからです。

+0

答えをいただきありがとうございます。私は閉じたジェネリックメソッドにジャンプしているためです。オープンジェネリックメソッドにジャンプするこの[第2の要点](https://gist.github.com/Bebere/6240be508093f51e0647a9649c8bae2c)が動作します。 – arjanen

+0

2番目の要点にオープンジェネリックメソッドを使用していません。それに渡すタイプ引数はId2から来ています。これは私の答えが間違っていることを意味します。私は本当の答えは、型引数のセットに関する情報が他の引数のように呼び出し元から呼び出し先に渡されていることであり、実行時には 'Id'が' Id2'呼び出しから継承した型引数を正しく解釈する必要があります。 –

関連する問題