问题
Suppose I generate a C program during execution time:
source = "int add_x_y(int x, int y){ return x + y; }";
source_size = 42;
I want the following function:
void* compile(char* source, int source_size);
Such that:
int (*f)(int,int) = compile(source, source_size);
printf("%d\n",f(2,3));
Outputs:
5
And compile
can't depend on external tools (compilers), as I'd like to use it in emscripten (which converts a C program to a .js file).
Is that possible?
回答1:
Someone else can probably fill in some of the specifics better than I, but if you don't mind calling out to GCC or linking to it, it should be doable. If you write the code out to a file, then compile the file into a shared library (.SO). From there, it's a simple matter of loading the shared library and getting the address of the desired symbol.
回答2:
It is operating system and processor specific. I suppose you are on Linux x86-64 (64 bits x86) or ia32 (32 bits x86)
You could use tinycc (it is a compiler which compiles quickly C code to very slow and unoptimized machine code) which provides a library libtcc
containing a tcc_compile_string
function.
You could use a JIT-compiling library like libjit, GNU lightning, asmjit, LLVM (and GCC 5 will have JIT-ing abilities).
And you simply could write your string to some temporary C file /tmp/genfoo.c
(if that file sits in a tmpfs
filesystem, no real disk IO is involved, so it is fast) and then fork a real command:
gcc -Wall -fPIC -shared -O /tmp/genfoo.c -o /tmp/genfoo.so
then dlopen(3) the produced /tmp/genfoo.so
shared object (and dlsym
to get a function pointer from its name).
If you want performance of the generated code, you need a real optimizing compiler like GCC or Clang/LLVM; the overhead of writing a temporary source file (and parsing it in the compiler) is negligible: most of the work is inside the compiler in optimization passes. Generating C code is practical, specially when you want the generated code to be optimized by some C compiler.
Notice that all these techniques probably won't work inside emscripten, simply because you probably cannot cast a data pointer to a function pointer there (legally that cast is probably unspecified behavior in C99, but all the approaches I mention above need it, and you are doing such a cast in your question)! If you need to generate code inside a browser, you probably need to generate some Javascript or a subset of it (e.g. for asm.js). See calling Javascript from C/C++ in Emscripten
If you are developing a language to be run inside the browser, make that language generate some Javascript (e.g. asm.js
).
See also NaCl (Native Client on Google browsers)
来源:https://stackoverflow.com/questions/26392477/how-to-compile-a-c-code-during-execution-time-and-get-a-pointer-to-the-correspo