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 をスタックにプッシュする必要があるのはなぜですか?

4

2 に答える 2

9

arg.0が含まれており、スタックにプッシュするためにthis必要です。ldfld string Test:s1this.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
}
于 2013-01-11T01:58:22.443 に答える
2

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

于 2013-01-11T01:56:18.983 に答える