| .. Copyright (C) 2014-2021 Free Software Foundation, Inc. |
| Originally contributed by David Malcolm <dmalcolm@redhat.com> |
| |
| This is free software: you can redistribute it and/or modify it |
| under the terms of the GNU General Public License as published by |
| the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see |
| <http://www.gnu.org/licenses/>. |
| |
| .. default-domain:: c |
| |
| Compiling a context |
| =================== |
| |
| Once populated, a :c:type:`gcc_jit_context *` can be compiled to |
| machine code, either in-memory via :c:func:`gcc_jit_context_compile` or |
| to disk via :c:func:`gcc_jit_context_compile_to_file`. |
| |
| You can compile a context multiple times (using either form of |
| compilation), although any errors that occur on the context will |
| prevent any future compilation of that context. |
| |
| In-memory compilation |
| ********************* |
| |
| .. function:: gcc_jit_result *\ |
| gcc_jit_context_compile (gcc_jit_context *ctxt) |
| |
| This calls into GCC and builds the code, returning a |
| `gcc_jit_result *`. |
| |
| If the result is non-NULL, the caller becomes responsible for |
| calling :func:`gcc_jit_result_release` on it once they're done |
| with it. |
| |
| .. type:: gcc_jit_result |
| |
| A `gcc_jit_result` encapsulates the result of compiling a context |
| in-memory, and the lifetimes of any machine code functions or globals |
| that are within the result. |
| |
| .. function:: void *\ |
| gcc_jit_result_get_code (gcc_jit_result *result,\ |
| const char *funcname) |
| |
| Locate a given function within the built machine code. |
| |
| Functions are looked up by name. For this to succeed, a function |
| with a name matching `funcname` must have been created on |
| `result`'s context (or a parent context) via a call to |
| :func:`gcc_jit_context_new_function` with `kind` |
| :macro:`GCC_JIT_FUNCTION_EXPORTED`: |
| |
| .. code-block:: c |
| |
| gcc_jit_context_new_function (ctxt, |
| any_location, /* or NULL */ |
| /* Required for func to be visible to |
| gcc_jit_result_get_code: */ |
| GCC_JIT_FUNCTION_EXPORTED, |
| any_return_type, |
| /* Must string-compare equal: */ |
| funcname, |
| /* etc */); |
| |
| If such a function is not found (or `result` or `funcname` are |
| ``NULL``), an error message will be emitted on stderr and |
| ``NULL`` will be returned. |
| |
| If the function is found, the result will need to be cast to a |
| function pointer of the correct type before it can be called. |
| |
| Note that the resulting machine code becomes invalid after |
| :func:`gcc_jit_result_release` is called on the |
| :type:`gcc_jit_result *`; attempting to call it after that may lead |
| to a segmentation fault. |
| |
| .. function:: void *\ |
| gcc_jit_result_get_global (gcc_jit_result *result,\ |
| const char *name) |
| |
| Locate a given global within the built machine code. |
| |
| Globals are looked up by name. For this to succeed, a global |
| with a name matching `name` must have been created on |
| `result`'s context (or a parent context) via a call to |
| :func:`gcc_jit_context_new_global` with `kind` |
| :macro:`GCC_JIT_GLOBAL_EXPORTED`. |
| |
| If the global is found, the result will need to be cast to a |
| pointer of the correct type before it can be called. |
| |
| This is a *pointer* to the global, so e.g. for an :c:type:`int` this is |
| an :c:type:`int *`. |
| |
| For example, given an ``int foo;`` created this way: |
| |
| .. code-block:: c |
| |
| gcc_jit_lvalue *exported_global = |
| gcc_jit_context_new_global (ctxt, |
| any_location, /* or NULL */ |
| GCC_JIT_GLOBAL_EXPORTED, |
| int_type, |
| "foo"); |
| |
| we can access it like this: |
| |
| .. code-block:: c |
| |
| int *ptr_to_foo = |
| (int *)gcc_jit_result_get_global (result, "foo"); |
| |
| If such a global is not found (or `result` or `name` are |
| ``NULL``), an error message will be emitted on stderr and |
| ``NULL`` will be returned. |
| |
| Note that the resulting address becomes invalid after |
| :func:`gcc_jit_result_release` is called on the |
| :type:`gcc_jit_result *`; attempting to use it after that may lead |
| to a segmentation fault. |
| |
| .. function:: void\ |
| gcc_jit_result_release (gcc_jit_result *result) |
| |
| Once we're done with the code, this unloads the built .so file. |
| This cleans up the result; after calling this, it's no longer |
| valid to use the result, or any code or globals that were obtained |
| by calling :func:`gcc_jit_result_get_code` or |
| :func:`gcc_jit_result_get_global` on it. |
| |
| |
| Ahead-of-time compilation |
| ************************* |
| |
| Although libgccjit is primarily aimed at just-in-time compilation, it |
| can also be used for implementing more traditional ahead-of-time |
| compilers, via the :c:func:`gcc_jit_context_compile_to_file` |
| API entrypoint. |
| |
| .. function:: void \ |
| gcc_jit_context_compile_to_file (gcc_jit_context *ctxt, \ |
| enum gcc_jit_output_kind output_kind,\ |
| const char *output_path) |
| |
| Compile the :c:type:`gcc_jit_context *` to a file of the given |
| kind. |
| |
| :c:func:`gcc_jit_context_compile_to_file` ignores the suffix of |
| ``output_path``, and insteads uses the given |
| :c:type:`enum gcc_jit_output_kind` to decide what to do. |
| |
| .. note:: |
| |
| This is different from the ``gcc`` program, which does make use of the |
| suffix of the output file when determining what to do. |
| |
| .. type:: enum gcc_jit_output_kind |
| |
| The available kinds of output are: |
| |
| ============================================== ============== |
| Output kind Typical suffix |
| ============================================== ============== |
| :c:macro:`GCC_JIT_OUTPUT_KIND_ASSEMBLER` .s |
| :c:macro:`GCC_JIT_OUTPUT_KIND_OBJECT_FILE` .o |
| :c:macro:`GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY` .so or .dll |
| :c:macro:`GCC_JIT_OUTPUT_KIND_EXECUTABLE` None, or .exe |
| ============================================== ============== |
| |
| .. c:macro:: GCC_JIT_OUTPUT_KIND_ASSEMBLER |
| |
| Compile the context to an assembler file. |
| |
| .. c:macro:: GCC_JIT_OUTPUT_KIND_OBJECT_FILE |
| |
| Compile the context to an object file. |
| |
| .. c:macro:: GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY |
| |
| Compile the context to a dynamic library. |
| |
| There is currently no support for specifying other libraries to link |
| against. |
| |
| .. c:macro:: GCC_JIT_OUTPUT_KIND_EXECUTABLE |
| |
| Compile the context to an executable. |
| |
| There is currently no support for specifying libraries to link |
| against. |