Hi,

Not sure if this is related to mono-cecil as I may be trying to do
something that can't be done in IL.

I've got my method in-lining almost done now. I'm having trouble with
structures at the moment.

I'm trying to create additional local vars that take a copy of the
contents of the evaluation stack.

So if a call looks like:

ldloc 0
call MyObj::Foo()

I change this to:

ldloc 0
stloc 1  (Created a new local var which is the same type of
'ThisParameter' from MyObj::Foo() )
ldloc 1
call MyObj::Foo()

This all works for Object types.

However now I want to do the same for structures which are value
types. I know this won't work correctly as a valuetype is copied.
However the C# compiler produces the following code.

ldloca 0  (load address of the structure)
call MyStruct::Foo()

If I inject code that does this:

ldloca 0
stloc 1  (Created a new local var which is the same type of
'ThisParameter' from MyStruct::Foo() )
ldloca 1 (neither ldloca and ldloc work here)
call MyObj::Foo()

I can't get it to work. I think this is because the address was loaded
using 'ldloca 0' and I can't actually store this address to a
VariableDefinition. I've look in Cecil and can't see anyway to create
a local variable for an address type. So is this possible? I suspect
I'm trying to do something that is not possible in IL. I guess
parameters can be passed by ref but VariableDefinitions can't do this.

By the way the reason I'm doing this is to make in-lining the method
easier. To replace a 'call' it pops each parameter from the evaluation
stack into a new temporary local, then maps each 'ldarg' instruction
in the call method to 'ldloc' instructions. It also handles any
'ldarga' instructions as well.

However this technique doesn't work with structures as these are
loaded via their address and accessed in the method using 'ldarg'. So
I need to a better way to do this.

I can of course attempt to unwind the evaluation stack and figure out
which instructions are being used to push data onto the stack for
parameters, which will remove the need to create additional locals but
in a previous post I've already discussed those issues.

Is what I'm doing valid in terms of IL. I think I need an instructions
such as 'stloca' which would store the address of an item into a local
but that doesn't exist so I guessing this is not the way IL should be
used. I did find 'cpobj', 'ldobj' which I'm wondering if they could be
used. Alternatively do I need to 'box' the type first?

Its strange that an address can be loaded using 'ldloca' and then used
inside a method by calling 'ldarg' so there must be some internal
mechanic that allows a load instruction to use an address but is there
a way to store an address to a local var rather than an argument.

So mono.cecil has the 'ThisParameter' on the method body, but I can't
find any properties that show the parameter will be passed by address.
Can I assume that IL only every loads the address of structures for
the 'this' parameter (which would make sense)?

I think I'm attempting something really stupid here so any ideas would
be greatly appreciated.

Thanks

Mort.

-- 
--
mono-cecil

Reply via email to