1 2 // Sample client code for C API 3 4 module gccjitd.examples.capi; 5 6 import gccjit.c; 7 8 void main() 9 { 10 // Memory mangement is simple: all objects created are associated with a gcc_jit_context, 11 // and get automatically cleaned up when the context is released. 12 gcc_jit_context *ctxt = gcc_jit_context_acquire(); 13 14 // Let's inject the equivalent of: 15 // extern(C) int printf(in char *format, ...); 16 // void hello_fn(in char *name) 17 // { 18 // printf("hello %s\n", name); 19 // } 20 // into the context. 21 gcc_jit_type *const_char_ptr_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 22 gcc_jit_param *param_format = 23 gcc_jit_context_new_param(ctxt, null, const_char_ptr_type, "format"); 24 gcc_jit_function *printf_func = 25 gcc_jit_context_new_function(ctxt, null, GCC_JIT_FUNCTION_IMPORTED, 26 gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_INT), 27 "printf", 1, ¶m_format, 1); 28 29 gcc_jit_param *param_name = 30 gcc_jit_context_new_param(ctxt, null, const_char_ptr_type, "name"); 31 gcc_jit_function *func = 32 gcc_jit_context_new_function(ctxt, null, GCC_JIT_FUNCTION_EXPORTED, 33 gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_VOID), 34 "hello_fn", 1, ¶m_name, 0); 35 36 gcc_jit_rvalue *args[2]; 37 args[0] = gcc_jit_context_new_string_literal(ctxt, "hello %s\n"); 38 args[1] = gcc_jit_param_as_rvalue(param_name); 39 40 gcc_jit_block *block = gcc_jit_function_new_block(func, "initial"); 41 gcc_jit_block_add_eval(block, null, 42 gcc_jit_context_new_call(ctxt, null, printf_func, 2, args.ptr)); 43 gcc_jit_block_end_with_void_return(block, null); 44 45 // OK, we're done populating the context. 46 // The next line actually calls into GCC and runs the build, all 47 // in a mutex for now, getting make a result object. 48 // The result is actually a wrapper around a DSO. 49 gcc_jit_result *result = gcc_jit_context_compile(ctxt); 50 51 // Now that we have result, we're done with ctxt. Releasing it will 52 // automatically clean up all of the objects created within it. 53 gcc_jit_context_release(ctxt); 54 55 // Look up a generated function by name, getting a void* back 56 // from the result object (pointing to the machine code), and 57 // cast it to the appropriate type for the function: 58 alias hello_fn_type = void function(in char *); 59 auto hello_fn = cast(hello_fn_type)gcc_jit_result_get_code(result, "hello_fn"); 60 61 // We can now call the machine code: 62 hello_fn("world"); 63 64 // Presumably we'd call it more than once. 65 // Once we're done with the code, this unloads the built DSO: 66 gcc_jit_result_release(result); 67 } 68