1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
.. 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.
|