[Mono-list] Executing Programmer-Specified Method from Within Mono

Paolo Molaro lupus@ximian.com
Fri, 12 Mar 2004 15:55:45 +0100


On 03/10/04 Hamza Karamali wrote:
> While compiling a certain method in mini_method_compile, I want to invoke
> a method written in C# (I know the name) and pass as an argument to the
> method a certain local variable (e.g. local[12]).  The C# method returns a
> boolean, and I want to check the value of this returned result.
> 
> Can anyone give me any tips on how I can accomplish this?
> 
> Thanks,
> 
> Hamza.
> 
> PS: To make the scenario clearer, here is exactly what I'm doing
> 
> 1. Mono is compiling methodA and is currently in the mini_method_compile
> function.
> 
> 2. I want to invoke methodB *from within Mono*, and pass it as an argument
> local[12], which is one of the local variables of methodA.
> 
> 3. methodB returns a boolean.  I want to find out whether it returned true
> or false.

Note that a local variable value exists only once a method is actually
executed, so what you say is not possible. My guess is that you want one
of two things:
1) invoke a managed method from C code (it doesn't matter if it's from
mini_method_compile() or not): use mono_runtime_invoke () from the
metadata/object.h header file.
2) inject a call to methodB inside the method you're currently
compiling and make it act upon the result. This is not very simple, but
you can look at how IL opcodes that do the same thing you need are
handled and do a bit of cut & paste. Basically you need to create
by hand the internal representation data structures.
For example, to load a local, you can just look at the CEE_LDLOC case in
the big switch:
	MonoInst *load;
	NEW_LOCLOAD (cfg, load, 12);
will create in load the code. Then you need to synthetize the call: have
a look at the CEE_CALL case (ignore all the special cases). It basically
is a call to:
	temp = mono_emit_method_call_spilled (cfg, bblock, called_method, method_signature, 
		&load, ip, NULL);

Where temp is a boolean local created with mono_compile_create_var ().
Then you can look at the code emitted for BRTRUE/BRFALSE and do the
same. You'll likely need to create additional basic blocks to support
the jumps and connect them in the graph: you'll insert more handling code 
inside them.

lupus

-- 
-----------------------------------------------------------------
lupus@debian.org                                     debian/rules
lupus@ximian.com                             Monkeys do it better