forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompiling.html
More file actions
331 lines (294 loc) · 15.7 KB
/
Copy pathcompiling.html
File metadata and controls
331 lines (294 loc) · 15.7 KB
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<h1 id="compiling">Compiling</h1>
<h2>Overview</h2>
<p>Duktape doesn't have an official Makefile or a build script: given the
number of different portability targets, maintaining an official build
script would be difficult. Instead, you should add Duktape to your existing
build process in whatever way is most natural.</p>
<p>Duktape is compiled with a C or C++ compiler (C99 is recommended)
and then linked to your program in some way; the exact details vary between
platforms and toolchains. For example, you can:</p>
<ul>
<li>Compile Duktape together with your program without an explicit linking
step.</li>
<li>Compile Duktape as a static library, and link the static library with
your program.</li>
<li>Compile Duktape as a dynamic library, and link the dynamic library with
your program (you'll need <code>DUK_OPT_DLL_BUILD</code>).</li>
</ul>
<p>There are two alternative distribution formats for the Duktape source:
a single source file and separate source files. The single source file
version consists of <code>duktape.h</code> and <code>duktape.c</code>.
The separate source files version consists of <code>duktape.h</code> and
a set of separate source files. The single source file version is preferred,
but separate files work better with some toolchains.</p>
<p>All Duktape API functions are potentially macros, and the implementation
of a certain API primitive may change between a macro and an actual function
even between compatible releases. This has two implications:</p>
<ul>
<li><b>Include <code>duktape.h</code> in application code</b>. This is
good practice in general, but without the header your compiler will
incorrectly assume that all Duktape API functions are actual functions
which will cause linking to fail.</li>
<li><b>Compile Duktape and your application with the exactly same Duktape
version</b>. Even compatible versions may be binary incompatible
because a function was changed into a macro or vice versa.</li>
</ul>
<p>Duktape has many features which can be controlled during compilation,
see feature options below. Some options after binary compatibility of
Duktape and the application. Because of this:</p>
<ul>
<li><b>Use the same feature options and the same compiler when compiling
Duktape and your application</b>. This is especially important when
Duktape is compiled as a library in a separate step.</li>
</ul>
<h2>Recommended compiler options</h2>
<p>If you compile Duktape with no compiler options, Duktape will detect the
compiler and the platform automatically and select defaults appropriate in
most cases. Recommended compiler options (for GCC/clang, use similar options
in your compiler):</p>
<ul>
<li><code>-std=c99</code>: recommended to ensure C99 semantics
which improve C type detection and allows Duktape to use variadic
macros</li>
<li><code>-Os</code>: optimize for smallest footprint, which is usually
desired when embedding Duktape</li>
<li><code>-fomit-frame-pointer</code>: omit frame pointer, further reduces
footprint but may interfere with debugging (leave out from debug builds)</li>
<li><code>-fstrict-aliasing</code>: use strict aliasing rules, Duktape
is compatible with these and they improve the resulting C code</li>
<li><code>-DDUK_OPT_DLL_BUILD</code>: needed when Duktape is built as a DLL
(the option is needed for both Duktape and application build)</li>
</ul>
<p>If you're using Duktape on a platform where Duktape's automatic feature
detection doesn't (yet) work, you may need to force a specific byte order or
alignment requirements with feature options described below.</p>
<h2>Duktape feature defaults</h2>
<p>Duktape feature defaults are, at a high level:</p>
<ul>
<li>Full Ecmascript E5/E5.1 compliance
(including the optional
<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-B">Annex B</a>
features), except for intentional real world compatibility deviations
(see <a href="#custombehavior">Custom behavior</a>)</li>
<li>Some <a href="#es6features">features borrowed from ES6</a></li>
<li>Packed value representation (8 bytes per value) when available,
unpacked value representation (usually bytes per value) when not</li>
<li>Reference counting and mark-and-sweep garbage collection</li>
<li>Full error messages and tracebacks</li>
<li>No debug printing, no asserts, etc</li>
</ul>
<p>Usually these automatic defaults are OK. If you're working on a constrained
platform, you may need to add specific options to reduce memory footprint or to
minimize garbage collection pauses.</p>
<h2>Feature options (DUK_OPT_xxx)</h2>
<p>If you wish to modify the defaults, you can provide feature options in the
form of <code>DUK_OPT_xxx</code> compiler defines. These will be taken into
account by the internal <code>duk_features.h</code> file, which resolves the
final internal features based on feature requests, compiler features, and
platform features. The full list of feature options is described in
<a href="https://github.com/svaarala/duktape/blob/master/doc/feature-options.rst">feature-options.rst</a>.</p>
<div class="note">
If you use Duktape feature options, you must define the feature options both
when compiling Duktape and when compiling any application code using the
<code>duktape.h</code> header. This is necessary because some feature options
affect the binary compatibility of the Duktape API.
</div>
<p>The table below summarizes the most commonly needed feature options, in no
particular order:</p>
<table>
<thead>
<tr>
<th>Define</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="definename">DUK_OPT_DLL_BUILD</td>
<td>Build Duktape as a DLL, affects symbol visibility declarations.
Most concretely, enables <code>__declspec(dllexport)</code> and
<code>__declspec(dllimport)</code> on Windows builds. This option
must be used also for application build when Duktape is linked as
a DLL (otherwise <code>__declspec(dllimport)</code> won't be used).</td>
</tr>
<tr>
<td class="definename">DUK_OPT_NO_PACKED_TVAL</td>
<td>Don't use the packed 8-byte internal value representation even if otherwise
possible. The packed representation has more platform/compiler portability
issues than the unpacked one.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_FORCE_ALIGN</td>
<td>Use <code>-DDUK_OPT_FORCE_ALIGN=4</code> or <code>-DDUK_OPT_FORCE_ALIGN=8</code>
to force a specific struct/value alignment instead of relying on Duktape's
automatic detection. This shouldn't normally be needed.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_FORCE_BYTEORDER</td>
<td>Use this to skip byte order detection and force a specific byte order:
<code>1</code> for little endian, <code>2</code> for ARM "mixed" endian
(integers little endian, IEEE doubles mixed endian), <code>3</code> for
big endian. Byte order detection relies on unstandardized platform
specific header files, so this may be required for custom platforms if
compilation fails in endianness detection.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_NO_REFERENCE_COUNTING</td>
<td>Disable reference counting and use only mark-and-sweep for garbage collection.
Although this reduces memory footprint of heap objects, the downside is much
more fluctuation in memory usage.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_NO_MARK_AND_SWEEP</td>
<td>Disable mark-and-sweep and use only reference counting for garbage collection.
This reduces code footprint and eliminates garbage collection pauses, but
objects participating in unreachable reference cycles won't be collected until
the Duktape heap is destroyed. In particular, function instances won't be
collected because they're always in a reference cycle with their default
prototype object. Unreachable objects are collected if you break reference
cycles manually (and are always freed when a heap is destroyed).</td>
</tr>
<tr>
<td class="definename">DUK_OPT_NO_VOLUNTARY_GC</td>
<td>Disable voluntary periodic mark-and-sweep collection. A mark-and-sweep
collection is still triggered in an out-of-memory condition. This option
should usually be combined with reference counting, which collects all
non-cyclical garbage. Application code should also request an explicit
garbage collection from time to time when appropriate. When this option
is used, Duktape will have no garbage collection pauses in ordinary use,
which is useful for timing sensitive applications like games.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_TRACEBACK_DEPTH</td>
<td>Override default traceback collection depth. The default is currently 10.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_NO_FILE_IO</td>
<td>Disable use of ANSI C file I/O which might be a portability issue on some
platforms. Causes <code>duk_eval_file()</code> to throw an error,
makes built-in <code>print()</code> and <code>alert()</code> no-ops,
and suppresses writing of a panic message to <code>stderr</code> on panic.
This option does not suppress debug printing so don't enable debug printing
if you wish to avoid I/O.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_PANIC_HANDLER(code,msg)</td>
<td>Provide a custom panic handler, see detailed description below.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_SELF_TESTS</td>
<td>Perform run-time self tests when a Duktape heap is created. Catches
platform/compiler problems which cannot be reliably detected during
compile time. Not enabled by default because of the extra footprint.</td>
</tr>
<tr>
<td class="definename">DUK_OPT_ASSERTIONS</td>
<td>Enable internal assert checks. These slow down execution considerably
so only use when debugging.</td>
</tr>
</tbody>
</table>
<h2>Suggested feature options for some environments</h2>
<ul>
<li id="timing-sensitive-options">Timing sensitive applications, e.g. games: see
<a href="https://github.com/svaarala/duktape/blob/master/doc/timing-sensitive.rst">timing-sensitive.rst</a></li>
<li id="memory-constrained-options">Memory constrained applications: see
<a href="https://github.com/svaarala/duktape/blob/master/doc/low-memory.rst">low-memory.rst</a></li>
</ul>
<h2>DUK_OPT_PANIC_HANDLER</h2>
<p>The default panic handler will print an error message to stdout unless I/O is
disabled by <code>DUK_OPT_NO_FILE_IO</code>. It will then call <code>abort()</code>
or cause a segfault if <code>DUK_OPT_SEGFAULT_ON_PANIC</code> is defined.</p>
<p>This is not always the best behavior for production applications which may
already have better panic recovery mechanisms. To replace the default panic
handler, see
<a href="https://github.com/svaarala/duktape/blob/master/doc/feature-options.rst">feature-options.rst</a>.</p>
<h2>Memory management alternatives</h2>
<p>There are three supported memory management alternatives:</p>
<ul>
<li><b>Reference counting and mark-and-sweep (default)</b>: heap objects are
freed immediately when they become unreachable except for objects
participating in unreachable reference cycles. Such objects are freed by
a periodic voluntary, stop the world mark-and-sweep collection.
Mark-and-sweep is also used as the emergency garbage collector if
memory allocation fails.</li>
<li><b>Reference counting only</b>: reduces code footprint and eliminates
garbage collection pauses, but objects in unreachable reference cycles
are not collected until the Duktape heap is destroyed. This alternative
is not recommended unless the reference cycles are not an issue. See notes
below.</li>
<li><b>Mark-and-sweep only</b>: reduces code footprint and memory footprint
(heap headers don't need to store a reference count), but there is more
memory usage variance than in the default case. The frequency of voluntary,
stop the world mark-and-sweep collections is also higher than in the default
case where reference counting is expected to handle almost all memory
management.</li>
</ul>
<p>When using only reference counting it is important to avoid creating
unreachable reference cycles. Reference cycles are usually easy to avoid in
application code e.g. by using only forward pointers in data structures. Even
if reference cycles are necessary, garbage collection can be allowed to work
simply by breaking the cycles before deleting the final references to such objects.
For example, if you have a tree structure where nodes maintain references to
both children and parents (creating reference cycles for each node) you could
walk the tree and set the parent reference to <code>null</code> before deleting
the final reference to the tree.</p>
<p>Unfortunately every Ecmascript function instance is required to be in a
reference loop with an automatic prototype object created for the function.
You can break this loop manually if you wish. For internal technical reasons,
named function expressions are also in a reference loop; this loop cannot be
broken from user code and only mark-and-sweep can collect such functions.
See <a href="#limitations">Limitations</a>.</p>
<h2 id="duktape-cplusplus">Using a C++ compiler</h2>
<p>Duktape works with both C and C++ compilers and applications. You can
compile Duktape and the application with a C or a C++ compiler in any
combination. Even so, it is recommended to compile both Duktape and the
application with the same compiler (i.e. both with a C compiler or both
with a C++ compiler) and with the same compiler options.</p>
<p>The <code>duktape.h</code> header contains the necessary glue to make all
of these combinations work. Specifically, all symbols needed by Duktape
public API are inside a <code>extern "C" { ... }</code> wrapper (active only
if compiled with a C++ compiler). This ensures that such symbols are defined
and used without C++ name mangling. Specifically:</p>
<ul>
<li>When compiling Duktape itself with a C++ compiler, symbols needed by
Duktape public API are not mangled. Other Duktape internal symbols will
be mangled, but are not externally visible and should thus cause no
problems even if the application is compiled with a C compiler.</li>
<li>When compiling an application with a C++ compiler, the wrapper ensures
that Duktape public API symbols used by the application are looked up
without mangling.</li>
</ul>
<p>If you mix C and C++ compilation, you should do the final linking with the
C++ toolchain. At least when mixing gcc/g++ you may encounter something like:</p>
<pre>
$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ gcc -o duk duktape.o duk_cmdline.o -lm -lreadline -lncurses
duktape.o:(.eh_frame+0x1ab): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
</pre>
<p>One fix is to use <code>g++</code> for linking:</p>
<pre>
$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ g++ -o duk duktape.o duk_cmdline.o -lm -lreadline -lncurses
</pre>
<p>Because <code>duktape.h</code> selects C/C++ data types needed by
Duktape and also does other feature detection, mixing C and C++ compilers
could theoretically cause the C and C++ compilers to end up with different
active features or data types. If that were to happen, Duktape and the
application would be binary incompatible (which would be difficult to
diagnose). This is usually not an issue, but to avoid the potential, compile
Duktape and the application with the same compiler.</p>
<h2>Compiler warnings</h2>
<p>Current goal is for the Duktape compile to be clean when:</p>
<ul>
<li>using a major compiler (e.g. gcc, clang, MSVC, mingw);</li>
<li>the compiler is in C99 mode; and</li>
<li>warnings are enabled (e.g. <code>-Wall</code> in gcc/clang).</li>
</ul>
<p>There are still some warnings present when you compile with
<code>-Wextra</code> or equivalent option.</p>
<p>There may be some warnings when compiling with a pre-C99 compiler
(or a C99 compiler without a <code>-std=c99</code> option or similar).</p>