Freigeben über


Resolving functions and func-eval syntax

I got a question about MDbg's func-eval syntax, which brings up a nice point about function resolution:

Is it possible to evaluate a function by specifying an instance variable instead of the fully qualified name of the class?

f ex.get_StackTrace

... is so much nicer than ...

System.Exception.get_StackTrace ex

I really could have titled this post "Why VS's Expression Evaluator rocks".  VS will let you do the nice syntax that looks like what you'd type in C#. (VS even handles overloaded function resolution in the evaluators!) Currently Mdbg's syntax is too low-level to let you input direct C# expressions for func-eval. Somebody could enhance Mdbg (or write an extension) that offers a nicer evaluation syntax. Since VS has the nice syntax, it's obviously possible. It was just not a priority for Mdbg.

A design issue about dealing with ambiguity
Ultimately, to invoke a function, we need the exact Function id (an ICorDebugFunction in ICD, a token / signature in the metadata/IL), and some parameters. Ultimately, func-evals boil down to a call to ICorDebugEval2::CallParameterizeFunction which  takes a Function to call ("System.Exception::get_StackTrace" in this case), and a set of parameters. For instance-methods, the 'this' pointer is the first parameter. This mimics the IL opcodes as well.
Getting to this basic level from source-language can be non-trivial. Consider how to interpret: "x.Function(y)". Is that:

1)  Instance: Instance method, 1 parameter where 'x' is the this-pointer
    Function(x,y)  

2)  Static: Static method, x is the class.
    x::Function(y) 

3)  Inheritence: What if Function is polymorphic and x derives from C, and you actually want to call the base class, ala C#'s base keyword. (ICorDebug always does virtual-dispatch for func-eval, but we're focusing on a design here, so let's ignore that for now).
    C::Function(x,y)

4) Overloaded functions: What if Function is overloaded for different types of y.
    x.Function((int) y)
    x.Function((String) y) ...
 
5) Property syntax and 'special' function names. What if  'Function' is actually a property (where Y is an index), and so the language actually emits a name like 'get_Function' instead of just 'Function'.
   x.get_Function(y)

Stripping out all the language semantics and just going with a {Function, parameter-list} invocation avoids these ambiguities; although I certainly admit it is harder to use.