程式語言 - GNU - libgccjit - Hello, world!



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