參考資訊:
https://gcc.gnu.org/onlinedocs/jit/
main.c
#include <stdio.h>
#include <stdlib.h>
#include <libgccjit.h>
int main(int argc, char *argv[])
{
void (*pfn)(const char *);
gcc_jit_result *r = NULL;
gcc_jit_context *ctx = NULL;
gcc_jit_rvalue *args[2] = { 0 };
gcc_jit_type *_int = NULL;
gcc_jit_type *_void = NULL;
gcc_jit_type *_pchar = NULL;
ctx = gcc_jit_context_acquire();
_int = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT);
_void = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_VOID);
_pchar = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CONST_CHAR_PTR);
gcc_jit_param *param_name = gcc_jit_context_new_param(ctx, NULL, _pchar, "name");
gcc_jit_function *exp = gcc_jit_context_new_function(ctx, NULL, GCC_JIT_FUNCTION_EXPORTED, _void, "test", 1, ¶m_name, 0);
gcc_jit_param *param_format = gcc_jit_context_new_param(ctx, NULL, _pchar, "format");
gcc_jit_function *imp = gcc_jit_context_new_function(ctx, NULL, GCC_JIT_FUNCTION_IMPORTED, _int, "printf", 1, ¶m_format, 1);
gcc_jit_block *block = gcc_jit_function_new_block(exp, NULL);
args[0] = gcc_jit_context_new_string_literal(ctx, "%s\n");
args[1] = gcc_jit_param_as_rvalue(param_name);
gcc_jit_block_add_eval(block, NULL, gcc_jit_context_new_call(ctx, NULL, imp, 2, args));
gcc_jit_block_end_with_void_return(block, NULL);
r = gcc_jit_context_compile(ctx);
pfn = gcc_jit_result_get_code(r, "test");
pfn("Hello, world!");
gcc_jit_result_release(r);
gcc_jit_context_release(ctx);
return 0;
}
編譯、執行
$ g++ main.cpp -o test -lgccjit -ggdb
$ ./test
Hello, world!
$ gdb ./test
(gdb) b main.c:32
(gdb) r
(gdb) disas pfn
0x00007ffff7f8a109 <+0>: push %rbp
0x00007ffff7f8a10a <+1>: mov %rsp,%rbp
0x00007ffff7f8a10d <+4>: sub $0x10,%rsp
0x00007ffff7f8a111 <+8>: mov %rdi,-0x8(%rbp)
0x00007ffff7f8a115 <+12>: mov -0x8(%rbp),%rax
0x00007ffff7f8a119 <+16>: mov %rax,%rsi
0x00007ffff7f8a11c <+19>: lea 0xedd(%rip),%rax # 0x7ffff7f8b000
0x00007ffff7f8a123 <+26>: mov %rax,%rdi
0x00007ffff7f8a126 <+29>: mov $0x0,%eax
0x00007ffff7f8a12b <+34>: call 0x7ffff7f8a030 <printf@plt>
0x00007ffff7f8a130 <+39>: leave
0x00007ffff7f8a131 <+40>: ret