On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote:
>> Reusing the compiler for this seems like the only way to go.
>> But, we did look at using g++ to parse C++ expressions from gdb,
>> and it was too slow :-(. We're going to look again, at least to
>> generate some bug reports if we can.
>
> It's a tough problem, particularly as C/C++ and their compilers
> were not designed for a read-eval-print-loop environment.
This of course is trivial to do, and reasonably fast as well. We have an
existence proof that they can generate a call on the target system, all one
needs to do would be to locate the target compiler, compile up a strapping
routine, push a dlopen of that routine onto the target system and then call
dlsym to grab a handle to it. The strapping routine can set up an environment
and communication channels as needed. If could even allocate a thread and have
it always be live (non-stop), if one wanted.
Oh, and the benefit, the language supported by the code closely matches the
compiler. Speed, 1/40 of a second, fast enough for command like use. Want to
evaluate it 1000000 times, sure, just be sure to cache the dlopen/dlsym, and
notice that you can do a million invocations, well, I'd guess a million times
faster than gdb currently.
If gdb won't solve these problem, dump it, move to lldb, I can assure you, they
will not fail to solve the problem, just because gdb can't or won't. The name
of the game is compete or die.
If you use the clang libraries, you can read eval, print... and the performance
would likely be even better. After all, it can be used to do OpenCL style
programming, and that certainly was built for speed. So, I reject the idea
this all isn't trivial.
$ cat eval.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <sys/time.h>
int main() {
char buf[4096];
while (fgets (buf, sizeof (buf), stdin) != NULL) {
struct timeval tv1, tv2;
gettimeofday(&tv1, 0);
FILE *fp = popen ("gcc -w -xc - -shared -o test.so", "w");
if (fputs (buf, fp) < 0) {
printf ("write fails\n");
exit (1);
}
if (pclose (fp) != 0) {
printf ("compile fails\n");
exit (1);
}
void *vp = dlopen("test.so", RTLD_NOW|RTLD_LOCAL|RTLD_FIRST);
void *fcn = dlsym (vp, "eval");
if (fcn) {
void (*func)();
func = fcn;
printf("about to run\n");
func();
gettimeofday(&tv2, 0);
printf("done running, took %ld usecs\n", tv2.tv_sec*1000000 + tv2.tv_usec
- tv1.tv_sec*1000000 - tv1.tv_usec);
} else {
printf ("eval not found\n");
}
if (dlclose (vp) < 0) {
printf ("dlclose fails\n");
exit (1);
}
}
}
$ gcc eval.c -o eval -O3
$ ./eval
int eval () { printf ("hi\n"); }
about to run
hi
done running, took 28419 usecs
int eval () { printf ("hi\n"); }
about to run
hi
done running, took 29300 usecs
int eval () { printf ("hi\n"); }
about to run
hi
done running, took 25755 usecs
int eval () { printf ("hi\n"); }
about to run
hi
done running, took 28295 usecs
Maybe your thinking of lisp, certainly that language makes it hard. ;-P