參考資訊:
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