Why is it necessary to load every argument onto the stack in CIL method?

434 Views Asked by At

in my application I need to dynamically create a type that contains multiple properties. I am aware that in cases such as this, one has to generate an CIL for both getter and setter methods of a property by using an ILGenerator.

More by a trial and error than anything else, I've finally arrived to the following code that generates a setter method for me:

MethodBuilder setMethod = customTypeBuilder.DefineMethod(propertyName + "_set", MethodAttributes.Public | MethodAttributes.HideBySig, null, new Type[] {propertyType});
ILGenerator setIlGenerator = setMethod.GetILGenerator();
setIlGenerator.Emit(OpCodes.Ldarg_0);
setIlGenerator.Emit(OpCodes.Ldarg_1);
setIlGenerator.Emit(OpCodes.Stfld, backingField);
setIlGenerator.Emit(OpCodes.Ret);

The code works well enough, but there is one thing I don't understand about it. Why is it necessary to call the 'Ldarg_0' instruction?

I know that it refers to the implicit first argument of the method, the "this" reference, so the actual value for the setter is stored in the second argument. I thought that it should be sufficient to call the Ldarg_1 instruction only, which would push the second argument to the stack (in the end, in the setter, I have no need of examining the "this" reference so I don't need to do anything with it), but this results in the TargetInvocationException being thrown when I attempt to set the value of the property.

Thank you!

1

There are 1 best solutions below

1
On BEST ANSWER

If you didn't push the "this" value onto the stack, how would Stfld know which object's field to change? You could be trying to write a setter like this:

public int Bizarre
{
    set { otherObject.Field = value; }
}

Basically, Stfld is documented to need two values on the stack: one for the "target" of the new value, and one for the value itself. Admittedly the stack transition diagram in ECMA 335 is clearer:

…, obj, value => …,

In other words: "stfld will pop the top two elements off the stack".