2013-01-11 7 views
5

reflection.emitで関数を呼び出す前にスタックにロードする必要のあることを誰かに説明することはできますか?リフレクションスタックとメソッドコールを発行

私は非常に単純な方法

public static void Execute(string 1, string 2) 

を持っている私は、動的に以下のクラスにメソッドを生成する(残りの部分を忘れて、私は彼らが整理だ)

public class Test{ 
    public string s1; 

    public void Run(string s2) 
    { 
     MyOtherClass.Execute(s2,s1) 
    } 
} 

私はコピーを持っています参照のために、上記のテストの "私は、次のオペコードが"呼び出し "の前に、放出されたことに気づいた。

  1. ldarg_1
  2. ldarg_0
  3. ldfld

質問がldarg_0が何をやっているのですか?私は呼び出しに2つの引数しか必要としません、なぜCLRはldarg_0をスタックにプッシュする必要がありますか?

+0

周囲のILを提供できますか? –

答えて

9

arg.0は、thisを含み、ldfld string Test:s1は、スタックにthis.s1をプッシュする必要があります。

.method public hidebysig instance void Run(string s2) cil managed 
{ 
    .maxstack 8          // maximum stack size 8 
    ldarg.1           // push argument s2 
    ldarg.0           // push this 
    ldfld string Test::s1       // pop this, push this.s1 
    call void MyOtherClass::Execute(string, string) // call 
    ret            // return 
} 
+0

ありがとう!私は今私が逃したものを知っている。 – Alwyn

2

宣言の順にメソッドの引数をプッシュし、メソッドが静的でない場合はオブジェクト参照をプッシュする必要があります。あなたのテストケースでは、メンバーフィールド(s1)にアクセスしているので、リファレンスが必要です。それはldarg_0が提供するものです。その後、ldfldthisの参照をポップし、フィールドの値を評価スタックにプッシュします。

関連する問題