目的
コンパイラをその場で起動して実行してもそれはJust In Timeなコンパイルと呼べる。
g++を system
で呼んで dlopen
で開いて関数を探して呼んでも目的は達成できる。
C++のコードを書いて吐き出してコンパイルするまでのオーバーヘッドは大きいが、代わりに定数などをJITコンパイル対象のコードの中に埋め込めるので関数が充分に重い場合にはペイすることもある。
コード
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <functional>
#include <dlfcn.h>
int main() {
std::string code = R"(
#include <iostream>
extern "C" int hello() {
std::cout << "This function is JIT compiled\n";
return 128;
}
)";
std::ofstream of;
of.open("tmp.cpp");
of << code;
of.close();
system("g++ -std=c++11 -c -O2 tmp.cpp -o tmp.o -fPIC && g++ -shared -o tmp.so tmp.o");
void* dll = dlopen("./tmp.so", RTLD_LAZY);
if (!dll) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
int (*hello)() = (int(*)())dlsym(dll, "hello");
if (char* error = dlerror()) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
std::cerr << "result: " << hello() << std::endl;
dlclose(dll);
}
実行結果
result: this function is JIT compiled
128