Reputation: 8337
Can someone explain to me what needs to be loaded into the stack prior to making a function call via reflection.emit?
I have a very simple method
public static void Execute(string 1, string 2)
I want to generate the method in the following class dynamically (forget the rest, I got them sorted out)
public class Test{
public string s1;
public void Run(string s2)
{
MyOtherClass.Execute(s2,s1)
}
}
I have a copy of the above test, for reference, and I noticed the following opcodes were emitted, prior to the "call".
The question is what's ldarg_0 doing there? I only need 2 arguments for the call, why does the CLR requires ldarg_0 to be pushed to the stack?
Upvotes: 5
Views: 1197
Reputation: 59655
arg.0
contains this
and is required by ldfld string Test:s1
to push this.s1
onto the stack.
.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
}
Upvotes: 9
Reputation: 20076
You need to push the method's arguments in order of declaration and an object reference if the method is not static. In your test case, you are accessing a member field (s1
), so you need the this
reference for it. That's what ldarg_0
provides. The subsequent ldfld
pops the this
reference and pushes the field's value onto the evaluation stack.
Upvotes: 2