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.