runtime eval / mixin inside a D shell or debugging session
timotheecour
thelastmammoth at gmail.com
Sun Sep 2 14:47:32 PDT 2012
Is anyone working on a runtime eval/mixin functionality?
I would like to be able to support:
int a=0;
mixinRT("load(`libfun.so`)"); //loads symbols + their demangled
version via an associative array
mixinRT("auto y=myFun(a);"); //creates a Variable y with 'runtime
type' inferred from myFun's function type
mixinRT("display(y);"); //crashes due to a bug
//the user recompiles libfun.so to correct the bug in display
mixinRT("load(`libfun.so`)"); //reloads symbols but y is still in
scope.
mixinRT("display(y);"); //works now
This would be extremely useful inside a debugging session (eg
after a breakpoint) to make full use of D for variable
introspection, or for quick code development/testing ala
python/matlab style, and writing a D shell among other scenarios.
Even a limited subset of D would still be useful in the meantime.
Eg usage: above, myFun takes a long time to compute and we want
to debug the rest of the program without having to recompute y or
save it to disk and loading it after each recompilation.
My current/planned approach is to:
* save a dynamic lib libfun.so which contains metadata about each
funtion using __traits(allMembers), ParameterTypeTuple!(fun),
ReturnType!fun).
* write a D shell with foreach(line; stdin.byLine()) that:
* loads libfun.so (or whatever the user inputs) via dlopen
* parses each line, extracting function name and arguments (eg:
"int y=myFun(a);")
* catch segfaults / errors with unix signals so we don't
interrupt the D shell loop
* find myFun inside libfun's demangled name map and get handle to
function via dlsym
* the tricky part is to automatically cast the handle to the
right function type (given in libfun's metadata), and create a
variable stack that wraps the variables created in the D shell,
each variable having a "runtime type" + value. Not sure how to do
that yet without hardcoding possible input/output types and
trying them all with a switch. It might be possible with inline
assembly but help would be welcome.
Is there a simpler way or existing project?
There was some discussion and some initial code for runtime
loading a shared lib and using the associative array to access
function by their demangled names:
(http://forum.dlang.org/thread/mailman.370.1342262936.31962.digitalmars-d@puremagic.com?page=2)
As for safety concerns raised in that thread, this feature could
be enabled/disabled with a version compiler switch, but is
clearly useful for debugging/development.
And then there is flectioned (http://flectioned.kuehne.cn/) which
should support runtime function call evaluation, eg: call(parent,
"bar", "Berta", 5); which would call parent("bar","Berta",5). It
has limitations: code is quite old and doesn't work under latest
DMD, nor on OSX, and is limited to int or string input arguments,
etc.
Running a new dmd session passing in the string to compile is not
a good option as we want to operate on the existing variables in
scope and avoid disk save/loads of those variables.
Thanks for suggestions!
More information about the Digitalmars-d
mailing list