// Sample client code for D API module gccjitd.examples.dapi; import gccjit.d; void main() { // Memory mangement is simple: all objects created are associated with a gcc_jit_context, // and get automatically cleaned up when the context is released. JITContext ctxt = new JITContext(); // Let's inject the equivalent of: // extern(C) int printf(in char *format, ...); // void hello_fn(in char *name) // { // printf("hello %s\n", name); // } // into the context. JITParam param_format = ctxt.newParam(JITTypeKind.CONST_CHAR_PTR, "format"); JITFunction printf_func = ctxt.newFunction(JITFunctionKind.IMPORTED, JITTypeKind.INT, "printf", true, param_format); JITParam param_name = ctxt.newParam(JITTypeKind.CONST_CHAR_PTR, "name"); JITFunction func = ctxt.newFunction(JITFunctionKind.EXPORTED, JITTypeKind.VOID, "hello_fn", false, param_name); JITBlock block = func.newBlock("initial"); block.addEval(ctxt.newCall(printf_func, ctxt.newRValue("hello %s\n"), param_name)); block.endWithReturn(); // OK, we're done populating the context. // The next line actually calls into GCC and runs the build, all // in a mutex for now, getting make a result object. // The result is actually a wrapper around a DSO. JITResult result = ctxt.compile(); ctxt.release(); // Look up a generated function by name, getting a void* back // from the result object (pointing to the machine code), and // cast it to the appropriate type for the function: alias hello_fn_type = void function(in char *); auto hello_fn = cast(hello_fn_type) result.getCode("hello_fn"); // We can now call the machine code: hello_fn("world"); // Presumably we'd call it more than once. // Once we're done with the code, this unloads the built DSO: result.release(); }