views:

84

answers:

1

I am using Reflection.Emit to build a mathematical expression parser (e.g. 2+2). A class takes in an infix expression (e.g. 2+2), turns it into a postfix expression (e.g. 2 2 +), and then another class compiles that postfix expression into IL and creates a DynamicMethod. From there, the expression can be evaluated as if it had been created at compile time, with similar speed.

This compiler also supports implicit multiplication, so something like x(2 + 2) evaluates as x * (2 + 2)

Right now, I am attempting to implement user-defined functions (e.g. f(x)). A problem arises when I try to differentiate between implicit multiplication, as shown above, and user defined functions. An example of this is if a user inputs x(5), how do I know whether they want to multiply x by 5, or invoke the x function with an argument of 5?

To solve this, in the previous case, the compiler inserts an if statement into the IL stream. It calls a function to determine if the function is defined with the identifier of x. If there is, then it inserts a MethodInfo instance onto the stack through an out variable and a local.

My actual question is, is it possible to execute a method using the MethodInfo instance on the stack that is equivalent in speed to calling IlGenerator.Emit(OpCodes.Call, MethodInfo) during compilation?

Thanks.

+1  A: 

The only way I am aware of that allows you to invoke a MethodInfo instance on the stack is by invoking the Invoke method on it. I’m sure you are already aware of this possibility, but you fear that it may be too slow. I recommend that you try it and time the performance under stress. You might find that it is fast enough for your purposes.

If it isn’t, then you will have to think about how to restructure your design so that you don’t pass around MethodInfo instances. You could, for example, pass managed function pointers instead. Those are the things that the ldftn and ldvirtftn instructions return. You can then use the calli instruction to invoke one of those. You will need to construct the “call-site description”, which calli expects as an operand, using the SignatureHelper class.

Timwi
Thanks a lot! While I didn't use the exact solution here, it led me to a different way of dealing with it.
nasufara
@nasufara: Please consider explaining the solution you found in a separate answer so that others can benefit from it.
Timwi