duktape 0.11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3668 @@
1
+ /*
2
+ * Duktape public API for Duktape 0.11.0.
3
+ * See the API reference for documentation on call semantics.
4
+ * The exposed API is inside the DUK_API_PUBLIC_H_INCLUDED
5
+ * include guard. Other parts of the header are Duktape
6
+ * internal and related to platform/compiler/feature detection.
7
+ *
8
+ * Git commit 621b545c474dd7a3def7aefed0557b1a825a4578 (v0.10.0-827-g621b545).
9
+ *
10
+ * See Duktape AUTHORS.txt and LICENSE.txt for copyright and
11
+ * licensing information.
12
+ */
13
+
14
+ /* LICENSE.txt */
15
+ /*
16
+ * ===============
17
+ * Duktape license
18
+ * ===============
19
+ *
20
+ * (http://opensource.org/licenses/MIT)
21
+ *
22
+ * Copyright (c) 2013-2014 by Duktape authors (see AUTHORS.txt)
23
+ *
24
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
25
+ * of this software and associated documentation files (the "Software"), to deal
26
+ * in the Software without restriction, including without limitation the rights
27
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28
+ * copies of the Software, and to permit persons to whom the Software is
29
+ * furnished to do so, subject to the following conditions:
30
+ *
31
+ * The above copyright notice and this permission notice shall be included in
32
+ * all copies or substantial portions of the Software.
33
+ *
34
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40
+ * THE SOFTWARE.
41
+ *
42
+ */
43
+
44
+ /* AUTHORS.txt */
45
+ /*
46
+ * ===============
47
+ * Duktape authors
48
+ * ===============
49
+ *
50
+ * Copyright
51
+ * =========
52
+ *
53
+ * Duktape copyrights are held by its authors. Each author has a copyright
54
+ * to their contribution, and agrees to irrevocably license the contribution
55
+ * under the Duktape ``LICENSE.txt``.
56
+ *
57
+ * Authors
58
+ * =======
59
+ *
60
+ * Please include an e-mail address, a link to your GitHub profile, or something
61
+ * similar to allow your contribution to be identified accurately.
62
+ *
63
+ * The following people have contributed code and agreed to irrevocably license
64
+ * their contributions under the Duktape ``LICENSE.txt`` (in order of appearance):
65
+ *
66
+ * * Sami Vaarala <sami.vaarala@iki.fi>
67
+ * * Niki Dobrev
68
+ * * Andreas \u00d6man <andreas@lonelycoder.com>
69
+ *
70
+ * Other contributions
71
+ * ===================
72
+ *
73
+ * The following people have contributed something other than code (e.g. reported
74
+ * bugs, provided ideas, etc; in order of appearance):
75
+ *
76
+ * * Greg Burns
77
+ * * Anthony Rabine
78
+ * * Carlos Costa
79
+ * * Aur\u00e9lien Bouilland
80
+ * * Preet Desai (Pris Matic)
81
+ * * judofyr (http://www.reddit.com/user/judofyr)
82
+ * * Jason Woofenden
83
+ * * Micha\u0142 Przyby\u015b
84
+ * * Anthony Howe
85
+ * * Conrad Pankoff
86
+ * * Jim Schimpf
87
+ * * Rajaran Gaunker (https://github.com/zimbabao)
88
+ * * Andreas \u00d6man
89
+ * * Doug Sanden
90
+ * * Remo Eichenberger (https://github.com/remoe)
91
+ */
92
+
93
+ #ifndef DUKTAPE_H_INCLUDED
94
+ #define DUKTAPE_H_INCLUDED
95
+
96
+ /*
97
+ * Determine platform features, select feature selection defines
98
+ * (e.g. _XOPEN_SOURCE), include system headers, and define DUK_USE_XXX
99
+ * defines which are (only) checked in Duktape internal code for
100
+ * activated features. Duktape feature selection is based on automatic
101
+ * feature detection, user supplied DUK_OPT_xxx defines, and optionally
102
+ * a "duk_custom.h" user header (if DUK_OPT_HAVE_CUSTOM_H is defined).
103
+ *
104
+ * When compiling Duktape, DUK_COMPILING_DUKTAPE is set, and this file
105
+ * is included before any system headers are included. Feature selection
106
+ * defines (e.g. _XOPEN_SOURCE) are defined here before any system headers
107
+ * are included (which is a requirement for system headers to work correctly).
108
+ * This file is responsible for including all system headers and contains
109
+ * all platform dependent cruft in general. When compiling user code,
110
+ * DUK_COMPILING_DUKTAPE is not defined, and we must avoid e.g. defining
111
+ * unnecessary feature selection defines.
112
+ *
113
+ * The general order of handling:
114
+ * - Compiler feature detection (require no includes)
115
+ * - Intermediate platform detection (-> easier platform defines)
116
+ * - Platform detection, system includes, byte order detection, etc
117
+ * - ANSI C wrappers (e.g. DUK_MEMCMP), wrappers for constants, etc
118
+ * - DUK_USE_xxx defines are resolved based on input defines
119
+ * - Duktape Date provider settings
120
+ * - Final sanity checks
121
+ *
122
+ * DUK_F_XXX are internal feature detection macros which should not be
123
+ * used outside this header.
124
+ *
125
+ * Useful resources:
126
+ *
127
+ * http://sourceforge.net/p/predef/wiki/Home/
128
+ * http://sourceforge.net/p/predef/wiki/Architectures/
129
+ * http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor
130
+ * http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types
131
+ *
132
+ * Preprocessor defines available in a particular GCC:
133
+ *
134
+ * gcc -dM -E - </dev/null # http://www.brain-dump.org/blog/entry/107
135
+ */
136
+
137
+ #ifndef DUK_FEATURES_H_INCLUDED
138
+ #define DUK_FEATURES_H_INCLUDED
139
+
140
+ /*
141
+ * Compiler features
142
+ */
143
+
144
+ #undef DUK_F_C99
145
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
146
+ #define DUK_F_C99
147
+ #endif
148
+
149
+ #undef DUK_F_CPP
150
+ #if defined(__cplusplus)
151
+ #define DUK_F_CPP
152
+ #endif
153
+
154
+ #undef DUK_F_CPP11
155
+ #if defined(__cplusplus) && (__cplusplus >= 201103L)
156
+ #define DUK_F_CPP11
157
+ #endif
158
+
159
+ /*
160
+ * Provides the duk_rdtsc() inline function (if available), limited to
161
+ * GCC C99.
162
+ *
163
+ * See: http://www.mcs.anl.gov/~kazutomo/rdtsc.html
164
+ */
165
+
166
+ /* XXX: more accurate detection of what gcc versions work; more inline
167
+ * asm versions for other compilers.
168
+ */
169
+ #if defined(__GNUC__) && defined(__i386__) && defined(DUK_F_C99) && \
170
+ !defined(__cplusplus) /* unsigned long long not standard */
171
+ static __inline__ unsigned long long duk_rdtsc(void) {
172
+ unsigned long long int x;
173
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
174
+ return x;
175
+ }
176
+ #define DUK_RDTSC_AVAILABLE 1
177
+ #elif defined(__GNUC__) && defined(__x86_64__) && defined(DUK_F_C99) && \
178
+ !defined(__cplusplus) /* unsigned long long not standard */
179
+ static __inline__ unsigned long long duk_rdtsc(void) {
180
+ unsigned hi, lo;
181
+ __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
182
+ return ((unsigned long long) lo) | (((unsigned long long) hi) << 32);
183
+ }
184
+ #define DUK_RDTSC_AVAILABLE 1
185
+ #else
186
+ /* not available */
187
+ #undef DUK_RDTSC_AVAILABLE
188
+ #endif
189
+
190
+ /*
191
+ * Intermediate platform, architecture, and compiler detection. These are
192
+ * hopelessly intertwined - e.g. architecture defines depend on compiler etc.
193
+ *
194
+ * Provide easier defines for platforms and compilers which are often tricky
195
+ * or verbose to detect. The intent is not to provide intermediate defines for
196
+ * all features; only if existing feature defines are inconvenient.
197
+ */
198
+
199
+ /* Intel x86 (32-bit) */
200
+ #if defined(i386) || defined(__i386) || defined(__i386__) || \
201
+ defined(__i486__) || defined(__i586__) || defined(__i686__) || \
202
+ defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \
203
+ defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)
204
+ #define DUK_F_X86
205
+ #endif
206
+
207
+ /* AMD64 (64-bit) */
208
+ #if defined(__amd64__) || defined(__amd64) || \
209
+ defined(__x86_64__) || defined(__x86_64) || \
210
+ defined(_M_X64) || defined(_M_AMD64)
211
+ #define DUK_F_X64
212
+ #endif
213
+
214
+ /* X32: 64-bit with 32-bit pointers (allows packed tvals). X32 support is
215
+ * not very mature yet.
216
+ *
217
+ * https://sites.google.com/site/x32abi/
218
+ */
219
+ #if defined(DUK_F_X64) && \
220
+ (defined(_ILP32) || defined(__ILP32__))
221
+ #define DUK_F_X32
222
+ /* define only one of: DUK_F_X86, DUK_F_X32, or DUK_F_X64 */
223
+ #undef DUK_F_X64
224
+ #undef DUK_F_X86
225
+ #endif
226
+
227
+ /* ARM */
228
+ #if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM)
229
+ #define DUK_F_ARM
230
+ #endif
231
+
232
+ /* MIPS */
233
+ /* FIXME: 32-bit vs. 64-bit MIPS */
234
+ #if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \
235
+ defined(_R3000) || defined(_R4000) || defined(_R5900) || \
236
+ defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \
237
+ defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \
238
+ defined(__mips) || defined(__MIPS__)
239
+ #define DUK_F_MIPS
240
+ #endif
241
+
242
+ /* Motorola 68K. Not defined by VBCC, so user must define one of these
243
+ * manually when using VBCC.
244
+ */
245
+ #if defined(__m68k__) || defined(M68000) || defined(__MC68K__)
246
+ #define DUK_F_M68K
247
+ #endif
248
+
249
+ /* Linux */
250
+ #if defined(__linux) || defined(__linux__) || defined(linux)
251
+ #define DUK_F_LINUX
252
+ #endif
253
+
254
+ /* FreeBSD */
255
+ #if defined(__FreeBSD__) || defined(__FreeBSD)
256
+ #define DUK_F_FREEBSD
257
+ #endif
258
+
259
+ /* NetBSD */
260
+ #if defined(__NetBSD__) || defined(__NetBSD)
261
+ #define DUK_F_NETBSD
262
+ #endif
263
+
264
+ /* OpenBSD */
265
+ #if defined(__OpenBSD__) || defined(__OpenBSD)
266
+ #define DUK_F_OPENBSD
267
+ #endif
268
+
269
+ /* BSD variant */
270
+ #if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \
271
+ defined(__bsdi__) || defined(__DragonFly__)
272
+ #define DUK_F_BSD
273
+ #endif
274
+
275
+ /* Generic Unix */
276
+ #if defined(__unix) || defined(__unix__) || defined(unix) || \
277
+ defined(DUK_F_LINUX) || defined(DUK_F_BSD)
278
+ #define DUK_F_UNIX
279
+ #endif
280
+
281
+ /* Windows (32-bit or above) */
282
+ #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \
283
+ defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
284
+ #define DUK_F_WINDOWS
285
+ #endif
286
+
287
+ /* Atari ST TOS. __TOS__ defined by PureC (which doesn't work as a target now
288
+ * because int is 16-bit, to be fixed). No platform define in VBCC apparently,
289
+ * so to use with VBCC, user must define '__TOS__' manually.
290
+ */
291
+ #if defined(__TOS__)
292
+ #define DUK_F_TOS
293
+ #endif
294
+
295
+ /* AmigaOS. Neither AMIGA nor __amigaos__ is defined on VBCC, so user must
296
+ * define 'AMIGA' manually.
297
+ */
298
+ #if defined(AMIGA) || defined(__amigaos__)
299
+ #define DUK_F_AMIGAOS
300
+ #endif
301
+
302
+ /* Flash player (e.g. Crossbridge) */
303
+ #if defined(__FLASHPLAYER__)
304
+ #define DUK_F_FLASHPLAYER
305
+ #endif
306
+
307
+ /* Emscripten (provided explicitly by user), improve if possible */
308
+ #if defined(EMSCRIPTEN)
309
+ #define DUK_F_EMSCRIPTEN
310
+ #endif
311
+
312
+ /* QNX */
313
+ #if defined(__QNX__)
314
+ #define DUK_F_QNX
315
+ #endif
316
+
317
+ /* GCC and GCC version convenience define. */
318
+ #if defined(__GNUC__)
319
+ #define DUK_F_GCC
320
+ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
321
+ /* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */
322
+ #define DUK_F_GCC_VERSION (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)
323
+ #else
324
+ #error cannot figure out gcc version
325
+ #endif
326
+ #endif
327
+
328
+ /* Clang */
329
+ #if defined(__clang__)
330
+ #define DUK_F_CLANG
331
+ #endif
332
+
333
+ /* MSVC */
334
+ #if defined(_MSC_VER)
335
+ /* MSVC preprocessor defines: http://msdn.microsoft.com/en-us/library/b0084kay.aspx
336
+ * _MSC_FULL_VER includes the build number, but it has at least two formats, see e.g.
337
+ * BOOST_MSVC_FULL_VER in http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp
338
+ */
339
+ #define DUK_F_MSVC
340
+ #endif
341
+
342
+ /* MinGW */
343
+ #if defined(__MINGW32__) || defined(__MINGW64__)
344
+ #define DUK_F_MINGW
345
+ #endif
346
+
347
+ /* BCC (Bruce's C compiler): this is a "torture target" for compilation */
348
+ #if defined(__BCC__) || defined(__BCC_VERSION__)
349
+ #define DUK_F_BCC
350
+ #endif
351
+
352
+ #if defined(__VBCC__)
353
+ #define DUK_F_VBCC
354
+ #endif
355
+
356
+ #if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \
357
+ !defined(DUK_F_BCC)
358
+ /* ULL / LL preprocessor constants should be avoided because they're not
359
+ * always available. With suitable options, some compilers will support
360
+ * 64-bit integer types but won't support ULL / LL preprocessor constants.
361
+ * Assume C99/C++11 environments have these. However, BCC is nominally
362
+ * C99 but doesn't support these constants.
363
+ */
364
+ #define DUK_F_ULL_CONSTS
365
+ #endif
366
+
367
+ /*
368
+ * Platform detection, system includes, Date provider selection.
369
+ *
370
+ * Feature selection (e.g. _XOPEN_SOURCE) must happen before any system
371
+ * headers are included. This header should avoid providing any feature
372
+ * selection defines when compiling user code (only when compiling Duktape
373
+ * itself). If a feature selection option is required for user code to
374
+ * compile correctly (e.g. it is needed for type detection), it should
375
+ * probably be -checked- here, not defined here.
376
+ *
377
+ * Date provider selection seems a bit out-of-place here, but since
378
+ * the date headers and provider functions are heavily platform
379
+ * specific, there's little point in duplicating the platform if-else
380
+ * ladder. All platform specific Date provider functions are in
381
+ * duk_bi_date.c; here we provide appropriate #defines to enable them,
382
+ * and include all the necessary system headers so that duk_bi_date.c
383
+ * compiles. Date "providers" are:
384
+ *
385
+ * NOW = getting current time (required)
386
+ * TZO = getting local time offset (required)
387
+ * PRS = parse datetime (optional)
388
+ * FMT = format datetime (optional)
389
+ *
390
+ * There's a lot of duplication here, unfortunately, because many
391
+ * platforms have similar (but not identical) headers, Date providers,
392
+ * etc. The duplication could be removed by more complicated nested
393
+ * #ifdefs, but it would then be more difficult to make fixes which
394
+ * affect only a specific platform.
395
+ *
396
+ * FIXME: add a way to provide custom functions to provide the critical
397
+ * primitives; this would be convenient when porting to unknown platforms
398
+ * (rather than muck with Duktape internals).
399
+ */
400
+
401
+ #if defined(DUK_COMPILING_DUKTAPE) && \
402
+ (defined(DUK_F_LINUX) || defined(DUK_F_EMSCRIPTEN))
403
+ /* A more recent Emscripten (2014-05) seems to lack "linux" environment
404
+ * defines, so check for Emscripten explicitly.
405
+ */
406
+ #ifndef _POSIX_C_SOURCE
407
+ #define _POSIX_C_SOURCE 200809L
408
+ #endif
409
+ #ifndef _GNU_SOURCE
410
+ #define _GNU_SOURCE /* e.g. getdate_r */
411
+ #endif
412
+ #ifndef _XOPEN_SOURCE
413
+ #define _XOPEN_SOURCE /* e.g. strptime */
414
+ #endif
415
+ #endif
416
+
417
+ #if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)
418
+ /* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */
419
+ #define _XOPEN_SOURCE 600
420
+ #define _POSIX_C_SOURCE 200112L
421
+ #endif
422
+
423
+ #undef DUK_F_MSVC_CRT_SECURE
424
+ #if defined(DUK_F_WINDOWS) && defined(_MSC_VER)
425
+ /* http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx
426
+ * http://msdn.microsoft.com/en-us/library/wd3wzwts.aspx
427
+ * Seem to be available since VS2005.
428
+ */
429
+ #if (_MSC_VER >= 1400)
430
+ /* VS2005+, secure CRT functions are preferred. Windows Store applications
431
+ * (and probably others) should use these.
432
+ */
433
+ #define DUK_F_MSVC_CRT_SECURE
434
+ #endif
435
+ #if (_MSC_VER < 1700)
436
+ /* VS2012+ has stdint.h, < VS2012 does not (but it's available for download). */
437
+ #define DUK_F_NO_STDINT_H
438
+ #endif
439
+ /* Initial fix: disable secure CRT related warnings when compiling Duktape
440
+ * itself (must be defined before including Windows headers). Don't define
441
+ * for user code including duktape.h.
442
+ */
443
+ #if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)
444
+ #define _CRT_SECURE_NO_WARNINGS
445
+ #endif
446
+ #endif /* DUK_F_WINDOWS && _MSC_VER */
447
+
448
+ #if defined(DUK_F_TOS) || defined(DUK_F_BCC)
449
+ #define DUK_F_NO_STDINT_H
450
+ #endif
451
+
452
+ #if defined(__APPLE__)
453
+ /* Mac OSX, iPhone, Darwin */
454
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
455
+ #define DUK_USE_DATE_TZO_GMTIME_R
456
+ #define DUK_USE_DATE_PRS_STRPTIME
457
+ #define DUK_USE_DATE_FMT_STRFTIME
458
+ #include <architecture/byte_order.h>
459
+ #include <limits.h>
460
+ #include <sys/param.h>
461
+ #include <sys/time.h>
462
+ #include <time.h>
463
+ #elif defined(DUK_F_OPENBSD)
464
+ /* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */
465
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
466
+ #define DUK_USE_DATE_TZO_GMTIME_R
467
+ #define DUK_USE_DATE_PRS_STRPTIME
468
+ #define DUK_USE_DATE_FMT_STRFTIME
469
+ #include <sys/types.h>
470
+ #include <sys/endian.h>
471
+ #include <limits.h>
472
+ #include <sys/param.h>
473
+ #include <sys/time.h>
474
+ #include <time.h>
475
+ #elif defined(DUK_F_BSD)
476
+ /* other BSD */
477
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
478
+ #define DUK_USE_DATE_TZO_GMTIME_R
479
+ #define DUK_USE_DATE_PRS_STRPTIME
480
+ #define DUK_USE_DATE_FMT_STRFTIME
481
+ #include <sys/types.h>
482
+ #include <sys/endian.h>
483
+ #include <limits.h>
484
+ #include <sys/param.h>
485
+ #include <sys/time.h>
486
+ #include <time.h>
487
+ #elif defined(DUK_F_TOS)
488
+ /* Atari ST TOS */
489
+ #define DUK_USE_DATE_NOW_TIME
490
+ #define DUK_USE_DATE_TZO_GMTIME
491
+ /* no parsing (not an error) */
492
+ #define DUK_USE_DATE_FMT_STRFTIME
493
+ #include <limits.h>
494
+ #include <time.h>
495
+ #elif defined(DUK_F_AMIGAOS)
496
+ #if defined(DUK_F_M68K)
497
+ /* AmigaOS on M68k */
498
+ #define DUK_USE_DATE_NOW_TIME
499
+ #define DUK_USE_DATE_TZO_GMTIME
500
+ /* no parsing (not an error) */
501
+ #define DUK_USE_DATE_FMT_STRFTIME
502
+ #include <limits.h>
503
+ #include <time.h>
504
+ #else
505
+ #error AmigaOS but not M68K, not supported now
506
+ #endif
507
+ #elif defined(DUK_F_WINDOWS)
508
+ /* Windows 32-bit and 64-bit are currently the same. */
509
+ /* MSVC does not have sys/param.h */
510
+ #define DUK_USE_DATE_NOW_WINDOWS
511
+ #define DUK_USE_DATE_TZO_WINDOWS
512
+ /* Note: PRS and FMT are intentionally left undefined for now. This means
513
+ * there is no platform specific date parsing/formatting but there is still
514
+ * the ISO 8601 standard format.
515
+ */
516
+ #include <windows.h>
517
+ #include <limits.h>
518
+ #elif defined(DUK_F_FLASHPLAYER)
519
+ /* Crossbridge */
520
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
521
+ #define DUK_USE_DATE_TZO_GMTIME_R
522
+ #define DUK_USE_DATE_PRS_STRPTIME
523
+ #define DUK_USE_DATE_FMT_STRFTIME
524
+ #include <endian.h>
525
+ #include <limits.h>
526
+ #include <sys/param.h>
527
+ #include <sys/time.h>
528
+ #include <time.h>
529
+ #elif defined(DUK_F_QNX)
530
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
531
+ #define DUK_USE_DATE_TZO_GMTIME_R
532
+ #define DUK_USE_DATE_PRS_STRPTIME
533
+ #define DUK_USE_DATE_FMT_STRFTIME
534
+ #include <sys/types.h>
535
+ #include <limits.h>
536
+ #include <sys/param.h>
537
+ #include <sys/time.h>
538
+ #include <time.h>
539
+ #elif defined(DUK_F_LINUX)
540
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
541
+ #define DUK_USE_DATE_TZO_GMTIME_R
542
+ #define DUK_USE_DATE_PRS_STRPTIME
543
+ #define DUK_USE_DATE_FMT_STRFTIME
544
+ #include <sys/types.h>
545
+ #if defined(DUK_F_BCC)
546
+ /* no endian.h */
547
+ #else
548
+ #include <endian.h>
549
+ #endif /* DUK_F_BCC */
550
+ #include <limits.h>
551
+ #include <sys/param.h>
552
+ #include <sys/time.h>
553
+ #include <time.h>
554
+ #elif defined(__posix)
555
+ /* POSIX */
556
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
557
+ #define DUK_USE_DATE_TZO_GMTIME_R
558
+ #define DUK_USE_DATE_PRS_STRPTIME
559
+ #define DUK_USE_DATE_FMT_STRFTIME
560
+ #include <sys/types.h>
561
+ #include <endian.h>
562
+ #include <limits.h>
563
+ #include <sys/param.h>
564
+ #include <sys/time.h>
565
+ #include <time.h>
566
+ #else
567
+ /* Other UNIX, hopefully others */
568
+ #define DUK_USE_DATE_NOW_GETTIMEOFDAY
569
+ #define DUK_USE_DATE_TZO_GMTIME_R
570
+ #define DUK_USE_DATE_PRS_STRPTIME
571
+ #define DUK_USE_DATE_FMT_STRFTIME
572
+ #include <sys/types.h>
573
+ #if defined(DUK_F_BCC)
574
+ /* no endian.h */
575
+ #else
576
+ #include <endian.h>
577
+ #endif /* DUK_F_BCC */
578
+ #include <limits.h>
579
+ #include <sys/param.h>
580
+ #include <sys/time.h>
581
+ #include <time.h>
582
+ #endif
583
+
584
+ /* Shared includes */
585
+ #include <stdio.h>
586
+ #include <stdlib.h>
587
+ #include <string.h>
588
+ #include <stdarg.h> /* varargs */
589
+ #include <setjmp.h>
590
+ #include <stddef.h> /* e.g. ptrdiff_t */
591
+ #if defined(DUK_F_NO_STDINT_H)
592
+ /* stdint.h not available */
593
+ #else
594
+ /* technically C99 (C++11) but found in many systems */
595
+ #include <stdint.h>
596
+ #endif
597
+ #include <math.h>
598
+
599
+ /*
600
+ * Detection for specific libc variants (like uclibc) and other libc specific
601
+ * features. Potentially depends on the #includes above.
602
+ */
603
+
604
+ #if defined(__UCLIBC__)
605
+ #define DUK_F_UCLIBC
606
+ #endif
607
+
608
+ /*
609
+ * Wrapper typedefs and constants for integer types, also sanity check types.
610
+ *
611
+ * C99 typedefs are quite good but not always available, and we want to avoid
612
+ * forcibly redefining the C99 typedefs. So, there are Duktape wrappers for
613
+ * all C99 typedefs and Duktape code should only use these typedefs. Type
614
+ * detection when C99 is not supported is best effort and may end up detecting
615
+ * some types incorrectly.
616
+ *
617
+ * Pointer sizes are a portability problem: pointers to different types may
618
+ * have a different size and function pointers are very difficult to manage
619
+ * portably.
620
+ *
621
+ * http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types
622
+ *
623
+ * Note: there's an interesting corner case when trying to define minimum
624
+ * signed integer value constants which leads to the current workaround of
625
+ * defining e.g. -0x80000000 as (-0x7fffffffL - 1L). See doc/code-issues.txt
626
+ * for a longer discussion.
627
+ *
628
+ * Note: avoid typecasts and computations in macro integer constants as they
629
+ * can then no longer be used in macro relational expressions (such as
630
+ * #if DUK_SIZE_MAX < 0xffffffffUL). There is internal code which relies on
631
+ * being able to compare DUK_SIZE_MAX against a limit.
632
+ */
633
+
634
+ /* FIXME: add feature options to force basic types from outside? */
635
+
636
+ #if !defined(INT_MAX)
637
+ #error INT_MAX not defined
638
+ #endif
639
+
640
+ /* Check that architecture is two's complement, standard C allows e.g.
641
+ * INT_MIN to be -2**31+1 (instead of -2**31).
642
+ */
643
+ #if defined(INT_MAX) && defined(INT_MIN)
644
+ #if INT_MAX != -(INT_MIN + 1)
645
+ #error platform does not seem complement of two
646
+ #endif
647
+ #else
648
+ #error cannot check complement of two
649
+ #endif
650
+
651
+ /* Pointer size determination based on architecture.
652
+ * XXX: unsure about BCC correctness.
653
+ */
654
+ #if defined(DUK_F_X86) || defined(DUK_F_X32) || \
655
+ defined(DUK_F_BCC) || \
656
+ (defined(__WORDSIZE) && (__WORDSIZE == 32))
657
+ #define DUK_F_32BIT_PTRS
658
+ #elif defined(DUK_F_X64) || \
659
+ (defined(__WORDSIZE) && (__WORDSIZE == 64))
660
+ #define DUK_F_64BIT_PTRS
661
+ #else
662
+ /* not sure, not needed with C99 anyway */
663
+ #endif
664
+
665
+ /* Intermediate define for 'have inttypes.h' */
666
+ #undef DUK_F_HAVE_INTTYPES
667
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
668
+ !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))
669
+ /* vbcc + AmigaOS has C99 but no inttypes.h */
670
+ #define DUK_F_HAVE_INTTYPES
671
+ #elif defined(__cplusplus) && (__cplusplus >= 201103L)
672
+ /* C++11 apparently ratified stdint.h */
673
+ #define DUK_F_HAVE_INTTYPES
674
+ #endif
675
+
676
+ /* Basic integer typedefs and limits, preferably from inttypes.h, otherwise
677
+ * through automatic detection.
678
+ */
679
+ #if defined(DUK_F_HAVE_INTTYPES)
680
+ /* C99 */
681
+ #define DUK_F_HAVE_64BIT
682
+ #include <inttypes.h>
683
+
684
+ typedef uint8_t duk_uint8_t;
685
+ typedef int8_t duk_int8_t;
686
+ typedef uint16_t duk_uint16_t;
687
+ typedef int16_t duk_int16_t;
688
+ typedef uint32_t duk_uint32_t;
689
+ typedef int32_t duk_int32_t;
690
+ typedef uint64_t duk_uint64_t;
691
+ typedef int64_t duk_int64_t;
692
+ typedef uint_least8_t duk_uint_least8_t;
693
+ typedef int_least8_t duk_int_least8_t;
694
+ typedef uint_least16_t duk_uint_least16_t;
695
+ typedef int_least16_t duk_int_least16_t;
696
+ typedef uint_least32_t duk_uint_least32_t;
697
+ typedef int_least32_t duk_int_least32_t;
698
+ typedef uint_least64_t duk_uint_least64_t;
699
+ typedef int_least64_t duk_int_least64_t;
700
+ typedef uint_fast8_t duk_uint_fast8_t;
701
+ typedef int_fast8_t duk_int_fast8_t;
702
+ typedef uint_fast16_t duk_uint_fast16_t;
703
+ typedef int_fast16_t duk_int_fast16_t;
704
+ typedef uint_fast32_t duk_uint_fast32_t;
705
+ typedef int_fast32_t duk_int_fast32_t;
706
+ typedef uint_fast64_t duk_uint_fast64_t;
707
+ typedef int_fast64_t duk_int_fast64_t;
708
+ typedef uintptr_t duk_uintptr_t;
709
+ typedef intptr_t duk_intptr_t;
710
+ typedef uintmax_t duk_uintmax_t;
711
+ typedef intmax_t duk_intmax_t;
712
+
713
+ #define DUK_UINT8_MIN 0
714
+ #define DUK_UINT8_MAX UINT8_MAX
715
+ #define DUK_INT8_MIN INT8_MIN
716
+ #define DUK_INT8_MAX INT8_MAX
717
+ #define DUK_UINT_LEAST8_MIN 0
718
+ #define DUK_UINT_LEAST8_MAX UINT_LEAST8_MAX
719
+ #define DUK_INT_LEAST8_MIN INT_LEAST8_MIN
720
+ #define DUK_INT_LEAST8_MAX INT_LEAST8_MAX
721
+ #define DUK_UINT_FAST8_MIN 0
722
+ #define DUK_UINT_FAST8_MAX UINT_FAST8_MAX
723
+ #define DUK_INT_FAST8_MIN INT_FAST8_MIN
724
+ #define DUK_INT_FAST8_MAX INT_FAST8_MAX
725
+ #define DUK_UINT16_MIN 0
726
+ #define DUK_UINT16_MAX UINT16_MAX
727
+ #define DUK_INT16_MIN INT16_MIN
728
+ #define DUK_INT16_MAX INT16_MAX
729
+ #define DUK_UINT_LEAST16_MIN 0
730
+ #define DUK_UINT_LEAST16_MAX UINT_LEAST16_MAX
731
+ #define DUK_INT_LEAST16_MIN INT_LEAST16_MIN
732
+ #define DUK_INT_LEAST16_MAX INT_LEAST16_MAX
733
+ #define DUK_UINT_FAST16_MIN 0
734
+ #define DUK_UINT_FAST16_MAX UINT_FAST16_MAX
735
+ #define DUK_INT_FAST16_MIN INT_FAST16_MIN
736
+ #define DUK_INT_FAST16_MAX INT_FAST16_MAX
737
+ #define DUK_UINT32_MIN 0
738
+ #define DUK_UINT32_MAX UINT32_MAX
739
+ #define DUK_INT32_MIN INT32_MIN
740
+ #define DUK_INT32_MAX INT32_MAX
741
+ #define DUK_UINT_LEAST32_MIN 0
742
+ #define DUK_UINT_LEAST32_MAX UINT_LEAST32_MAX
743
+ #define DUK_INT_LEAST32_MIN INT_LEAST32_MIN
744
+ #define DUK_INT_LEAST32_MAX INT_LEAST32_MAX
745
+ #define DUK_UINT_FAST32_MIN 0
746
+ #define DUK_UINT_FAST32_MAX UINT_FAST32_MAX
747
+ #define DUK_INT_FAST32_MIN INT_FAST32_MIN
748
+ #define DUK_INT_FAST32_MAX INT_FAST32_MAX
749
+ #define DUK_UINT64_MIN 0
750
+ #define DUK_UINT64_MAX UINT64_MAX
751
+ #define DUK_INT64_MIN INT64_MIN
752
+ #define DUK_INT64_MAX INT64_MAX
753
+ #define DUK_UINT_LEAST64_MIN 0
754
+ #define DUK_UINT_LEAST64_MAX UINT_LEAST64_MAX
755
+ #define DUK_INT_LEAST64_MIN INT_LEAST64_MIN
756
+ #define DUK_INT_LEAST64_MAX INT_LEAST64_MAX
757
+ #define DUK_UINT_FAST64_MIN 0
758
+ #define DUK_UINT_FAST64_MAX UINT_FAST64_MAX
759
+ #define DUK_INT_FAST64_MIN INT_FAST64_MIN
760
+ #define DUK_INT_FAST64_MAX INT_FAST64_MAX
761
+
762
+ #define DUK_UINTPTR_MIN 0
763
+ #define DUK_UINTPTR_MAX UINTPTR_MAX
764
+ #define DUK_INTPTR_MIN INTPTR_MIN
765
+ #define DUK_INTPTR_MAX INTPTR_MAX
766
+
767
+ #define DUK_UINTMAX_MIN 0
768
+ #define DUK_UINTMAX_MAX UINTMAX_MAX
769
+ #define DUK_INTMAX_MIN INTMAX_MIN
770
+ #define DUK_INTMAX_MAX INTMAX_MAX
771
+
772
+ #define DUK_SIZE_MIN 0
773
+ #define DUK_SIZE_MAX SIZE_MAX
774
+
775
+ #else /* C99 types */
776
+
777
+ /* When C99 types are not available, we use heuristic detection to get
778
+ * the basic 8, 16, 32, and (possibly) 64 bit types. The fast/least
779
+ * types are then assumed to be exactly the same for now: these could
780
+ * be improved per platform but C99 types are very often now available.
781
+ * 64-bit types are not available on all platforms; this is OK at least
782
+ * on 32-bit platforms.
783
+ *
784
+ * This detection code is necessarily a bit hacky and can provide typedefs
785
+ * and defines that won't work correctly on some exotic platform.
786
+ */
787
+
788
+ #if (defined(CHAR_BIT) && (CHAR_BIT == 8)) || \
789
+ (defined(UCHAR_MAX) && (UCHAR_MAX == 255))
790
+ typedef unsigned char duk_uint8_t;
791
+ typedef signed char duk_int8_t;
792
+ #else
793
+ #error cannot detect 8-bit type
794
+ #endif
795
+
796
+ #if defined(USHRT_MAX) && (USHRT_MAX == 65535UL)
797
+ typedef unsigned short duk_uint16_t;
798
+ typedef signed short duk_int16_t;
799
+ #elif defined(UINT_MAX) && (UINT_MAX == 65535UL)
800
+ /* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */
801
+ typedef unsigned int duk_uint16_t;
802
+ typedef signed int duk_int16_t;
803
+ #else
804
+ #error cannot detect 16-bit type
805
+ #endif
806
+
807
+ #if defined(UINT_MAX) && (UINT_MAX == 4294967295UL)
808
+ typedef unsigned int duk_uint32_t;
809
+ typedef signed int duk_int32_t;
810
+ #elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295UL)
811
+ /* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */
812
+ typedef unsigned long duk_uint32_t;
813
+ typedef signed long duk_int32_t;
814
+ #else
815
+ #error cannot detect 32-bit type
816
+ #endif
817
+
818
+ /* 64-bit type detection is a bit tricky.
819
+ *
820
+ * ULLONG_MAX is a standard define. __LONG_LONG_MAX__ and __ULONG_LONG_MAX__
821
+ * are used by at least GCC (even if system headers don't provide ULLONG_MAX).
822
+ * Some GCC variants may provide __LONG_LONG_MAX__ but not __ULONG_LONG_MAX__.
823
+ *
824
+ * ULL / LL constants are rejected / warned about by some compilers, even if
825
+ * the compiler has a 64-bit type and the compiler/system headers provide an
826
+ * unsupported constant (ULL/LL)! Try to avoid using ULL / LL constants.
827
+ * As a side effect we can only check that e.g. ULONG_MAX is larger than 32
828
+ * bits but can't be sure it is exactly 64 bits. Self tests will catch such
829
+ * cases.
830
+ */
831
+ #undef DUK_F_HAVE_64BIT
832
+ #if !defined(DUK_F_HAVE_64BIT) && defined(ULONG_MAX)
833
+ #if (ULONG_MAX > 4294967295UL)
834
+ #define DUK_F_HAVE_64BIT
835
+ typedef unsigned long duk_uint64_t;
836
+ typedef signed long duk_int64_t;
837
+ #endif
838
+ #endif
839
+ #if !defined(DUK_F_HAVE_64BIT) && defined(ULLONG_MAX)
840
+ #if (ULLONG_MAX > 4294967295UL)
841
+ #define DUK_F_HAVE_64BIT
842
+ typedef unsigned long long duk_uint64_t;
843
+ typedef signed long long duk_int64_t;
844
+ #endif
845
+ #endif
846
+ #if !defined(DUK_F_HAVE_64BIT) && defined(__ULONG_LONG_MAX__)
847
+ #if (__ULONG_LONG_MAX__ > 4294967295UL)
848
+ #define DUK_F_HAVE_64BIT
849
+ typedef unsigned long long duk_uint64_t;
850
+ typedef signed long long duk_int64_t;
851
+ #endif
852
+ #endif
853
+ #if !defined(DUK_F_HAVE_64BIT) && defined(__LONG_LONG_MAX__)
854
+ #if (__LONG_LONG_MAX__ > 2147483647L)
855
+ #define DUK_F_HAVE_64BIT
856
+ typedef unsigned long long duk_uint64_t;
857
+ typedef signed long long duk_int64_t;
858
+ #endif
859
+ #endif
860
+ #if !defined(DUK_F_HAVE_64BIT) && \
861
+ (defined(DUK_F_MINGW) || defined(DUK_F_MSVC))
862
+ /* Both MinGW and MSVC have a 64-bit type. */
863
+ #define DUK_F_HAVE_64BIT
864
+ typedef unsigned long duk_uint64_t;
865
+ typedef signed long duk_int64_t;
866
+ #endif
867
+ #if !defined(DUK_F_HAVE64BIT)
868
+ /* cannot detect 64-bit type, not always needed so don't error */
869
+ #endif
870
+
871
+ typedef duk_uint8_t duk_uint_least8_t;
872
+ typedef duk_int8_t duk_int_least8_t;
873
+ typedef duk_uint16_t duk_uint_least16_t;
874
+ typedef duk_int16_t duk_int_least16_t;
875
+ typedef duk_uint32_t duk_uint_least32_t;
876
+ typedef duk_int32_t duk_int_least32_t;
877
+ typedef duk_uint8_t duk_uint_fast8_t;
878
+ typedef duk_int8_t duk_int_fast8_t;
879
+ typedef duk_uint16_t duk_uint_fast16_t;
880
+ typedef duk_int16_t duk_int_fast16_t;
881
+ typedef duk_uint32_t duk_uint_fast32_t;
882
+ typedef duk_int32_t duk_int_fast32_t;
883
+ #if defined(DUK_F_HAVE_64BIT)
884
+ typedef duk_uint64_t duk_uint_least64_t;
885
+ typedef duk_int64_t duk_int_least64_t;
886
+ typedef duk_uint64_t duk_uint_fast64_t;
887
+ typedef duk_int64_t duk_int_fast64_t;
888
+ #endif
889
+ #if defined(DUK_F_HAVE_64BIT)
890
+ typedef duk_uint64_t duk_uintmax_t;
891
+ typedef duk_int64_t duk_intmax_t;
892
+ #else
893
+ typedef duk_uint32_t duk_uintmax_t;
894
+ typedef duk_int32_t duk_intmax_t;
895
+ #endif
896
+
897
+ /* Note: the funny looking computations for signed minimum 16-bit, 32-bit, and
898
+ * 64-bit values are intentional as the obvious forms (e.g. -0x80000000L) are
899
+ * -not- portable. See code-issues.txt for a detailed discussion.
900
+ */
901
+ #define DUK_UINT8_MIN 0UL
902
+ #define DUK_UINT8_MAX 0xffUL
903
+ #define DUK_INT8_MIN (-0x80L)
904
+ #define DUK_INT8_MAX 0x7fL
905
+ #define DUK_UINT_LEAST8_MIN 0UL
906
+ #define DUK_UINT_LEAST8_MAX 0xffUL
907
+ #define DUK_INT_LEAST8_MIN (-0x80L)
908
+ #define DUK_INT_LEAST8_MAX 0x7fL
909
+ #define DUK_UINT_FAST8_MIN 0UL
910
+ #define DUK_UINT_FAST8_MAX 0xffUL
911
+ #define DUK_INT_FAST8_MIN (-0x80L)
912
+ #define DUK_INT_FAST8_MAX 0x7fL
913
+ #define DUK_UINT16_MIN 0UL
914
+ #define DUK_UINT16_MAX 0xffffUL
915
+ #define DUK_INT16_MIN (-0x7fffL - 1L)
916
+ #define DUK_INT16_MAX 0x7fffL
917
+ #define DUK_UINT_LEAST16_MIN 0UL
918
+ #define DUK_UINT_LEAST16_MAX 0xffffUL
919
+ #define DUK_INT_LEAST16_MIN (-0x7fffL - 1L)
920
+ #define DUK_INT_LEAST16_MAX 0x7fffL
921
+ #define DUK_UINT_FAST16_MIN 0UL
922
+ #define DUK_UINT_FAST16_MAX 0xffffUL
923
+ #define DUK_INT_FAST16_MIN (-0x7fffL - 1L)
924
+ #define DUK_INT_FAST16_MAX 0x7fffL
925
+ #define DUK_UINT32_MIN 0UL
926
+ #define DUK_UINT32_MAX 0xffffffffUL
927
+ #define DUK_INT32_MIN (-0x7fffffffL - 1L)
928
+ #define DUK_INT32_MAX 0x7fffffffL
929
+ #define DUK_UINT_LEAST32_MIN 0UL
930
+ #define DUK_UINT_LEAST32_MAX 0xffffffffUL
931
+ #define DUK_INT_LEAST32_MIN (-0x7fffffffL - 1L)
932
+ #define DUK_INT_LEAST32_MAX 0x7fffffffL
933
+ #define DUK_UINT_FAST32_MIN 0UL
934
+ #define DUK_UINT_FAST32_MAX 0xffffffffUL
935
+ #define DUK_INT_FAST32_MIN (-0x7fffffffL - 1L)
936
+ #define DUK_INT_FAST32_MAX 0x7fffffffL
937
+
938
+ /* 64-bit constants. Since LL / ULL constants are not always available,
939
+ * use computed values. These values can't be used in preprocessor
940
+ * comparisons; flag them as such.
941
+ */
942
+ #if defined(DUK_F_HAVE_64BIT)
943
+ #define DUK_UINT64_MIN ((duk_uint64_t) 0)
944
+ #define DUK_UINT64_MAX ((duk_uint64_t) -1)
945
+ #define DUK_INT64_MIN ((duk_int64_t) (~(DUK_UINT64_MAX >> 1)))
946
+ #define DUK_INT64_MAX ((duk_int64_t) (DUK_UINT64_MAX >> 1))
947
+ #define DUK_UINT_LEAST64_MIN DUK_UINT64_MIN
948
+ #define DUK_UINT_LEAST64_MAX DUK_UINT64_MAX
949
+ #define DUK_INT_LEAST64_MIN DUK_INT64_MIN
950
+ #define DUK_INT_LEAST64_MAX DUK_INT64_MAX
951
+ #define DUK_UINT_FAST64_MIN DUK_UINT64_MIN
952
+ #define DUK_UINT_FAST64_MAX DUK_UINT64_MAX
953
+ #define DUK_INT_FAST64_MIN DUK_INT64_MIN
954
+ #define DUK_INT_FAST64_MAX DUK_INT64_MAX
955
+ #define DUK_UINT64_MIN_COMPUTED
956
+ #define DUK_UINT64_MAX_COMPUTED
957
+ #define DUK_INT64_MIN_COMPUTED
958
+ #define DUK_INT64_MAX_COMPUTED
959
+ #define DUK_UINT_LEAST64_MIN_COMPUTED
960
+ #define DUK_UINT_LEAST64_MAX_COMPUTED
961
+ #define DUK_INT_LEAST64_MIN_COMPUTED
962
+ #define DUK_INT_LEAST64_MAX_COMPUTED
963
+ #define DUK_UINT_FAST64_MIN_COMPUTED
964
+ #define DUK_UINT_FAST64_MAX_COMPUTED
965
+ #define DUK_INT_FAST64_MIN_COMPUTED
966
+ #define DUK_INT_FAST64_MAX_COMPUTED
967
+ #endif
968
+
969
+ #if defined(DUK_F_HAVE_64BIT)
970
+ #define DUK_UINTMAX_MIN DUK_UINT64_MIN
971
+ #define DUK_UINTMAX_MAX DUK_UINT64_MAX
972
+ #define DUK_INTMAX_MIN DUK_INT64_MIN
973
+ #define DUK_INTMAX_MAX DUK_INT64_MAX
974
+ #define DUK_UINTMAX_MIN_COMPUTED
975
+ #define DUK_UINTMAX_MAX_COMPUTED
976
+ #define DUK_INTMAX_MIN_COMPUTED
977
+ #define DUK_INTMAX_MAX_COMPUTED
978
+ #else
979
+ #define DUK_UINTMAX_MIN 0UL
980
+ #define DUK_UINTMAX_MAX 0xffffffffUL
981
+ #define DUK_INTMAX_MIN (-0x7fffffffL - 1L)
982
+ #define DUK_INTMAX_MAX 0x7fffffffL
983
+ #endif
984
+
985
+ /* This detection is not very reliable. */
986
+ #if defined(DUK_F_32BIT_PTRS)
987
+ typedef duk_int32_t duk_intptr_t;
988
+ typedef duk_uint32_t duk_uintptr_t;
989
+ #define DUK_UINTPTR_MIN DUK_UINT32_MIN
990
+ #define DUK_UINTPTR_MAX DUK_UINT32_MAX
991
+ #define DUK_INTPTR_MIN DUK_INT32_MIN
992
+ #define DUK_INTPTR_MAX DUK_INT32_MAX
993
+ #elif defined(DUK_F_64BIT_PTRS) && defined(DUK_F_HAVE_64BIT)
994
+ typedef duk_int64_t duk_intptr_t;
995
+ typedef duk_uint64_t duk_uintptr_t;
996
+ #define DUK_UINTPTR_MIN DUK_UINT64_MIN
997
+ #define DUK_UINTPTR_MAX DUK_UINT64_MAX
998
+ #define DUK_INTPTR_MIN DUK_INT64_MIN
999
+ #define DUK_INTPTR_MAX DUK_INT64_MAX
1000
+ #define DUK_UINTPTR_MIN_COMPUTED
1001
+ #define DUK_UINTPTR_MAX_COMPUTED
1002
+ #define DUK_INTPTR_MIN_COMPUTED
1003
+ #define DUK_INTPTR_MAX_COMPUTED
1004
+ #else
1005
+ #error cannot determine intptr type
1006
+ #endif
1007
+
1008
+ /* SIZE_MAX may be missing so use an approximate value for it. */
1009
+ #undef DUK_SIZE_MAX_COMPUTED
1010
+ #if !defined(SIZE_MAX)
1011
+ #define DUK_SIZE_MAX_COMPUTED
1012
+ #define SIZE_MAX ((size_t) (-1))
1013
+ #endif
1014
+ #define DUK_SIZE_MIN 0
1015
+ #define DUK_SIZE_MAX SIZE_MAX
1016
+
1017
+ #endif /* C99 types */
1018
+
1019
+ /* A few types are assumed to always exist. */
1020
+ typedef size_t duk_size_t;
1021
+ typedef ptrdiff_t duk_ptrdiff_t;
1022
+
1023
+ /* The best type for an "all around int" in Duktape internals is "at least
1024
+ * 32 bit signed integer" which is most convenient. Same for unsigned type.
1025
+ * Prefer 'int' when large enough, as it is almost always a convenient type.
1026
+ */
1027
+ #if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL)
1028
+ typedef int duk_int_t;
1029
+ typedef unsigned int duk_uint_t;
1030
+ #define DUK_INT_MIN INT_MIN
1031
+ #define DUK_INT_MAX INT_MAX
1032
+ #define DUK_UINT_MIN 0
1033
+ #define DUK_UINT_MAX UINT_MAX
1034
+ #else
1035
+ typedef duk_int_fast32_t duk_int_t;
1036
+ typedef duk_uint_fast32_t duk_uint_t;
1037
+ #define DUK_INT_MIN DUK_INT_FAST32_MIN
1038
+ #define DUK_INT_MAX DUK_INT_FAST32_MAX
1039
+ #define DUK_UINT_MIN DUK_UINT_FAST32_MIN
1040
+ #define DUK_UINT_MAX DUK_UINT_FAST32_MAX
1041
+ #endif
1042
+
1043
+ /* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this
1044
+ * distinction matters for the CPU. These types are used mainly in the
1045
+ * executor where it might really matter.
1046
+ */
1047
+ typedef duk_int_fast32_t duk_int_fast_t;
1048
+ typedef duk_uint_fast32_t duk_uint_fast_t;
1049
+ #define DUK_INT_FAST_MIN DUK_INT_FAST32_MIN
1050
+ #define DUK_INT_FAST_MAX DUK_INT_FAST32_MAX
1051
+ #define DUK_UINT_FAST_MIN DUK_UINT_FAST32_MIN
1052
+ #define DUK_UINT_FAST_MAX DUK_UINT_FAST32_MAX
1053
+
1054
+ /* Small integers (16 bits or more) can fall back to the 'int' type, but
1055
+ * have a typedef so they are marked "small" explicitly.
1056
+ */
1057
+ typedef int duk_small_int_t;
1058
+ typedef unsigned int duk_small_uint_t;
1059
+ #define DUK_SMALL_INT_MIN INT_MIN
1060
+ #define DUK_SMALL_INT_MAX INT_MAX
1061
+ #define DUK_SMALL_UINT_MIN 0
1062
+ #define DUK_SMALL_UINT_MAX UINT_MAX
1063
+
1064
+ /* Fast variants of small integers, again for really fast paths like the
1065
+ * executor.
1066
+ */
1067
+ typedef duk_int_fast16_t duk_small_int_fast_t;
1068
+ typedef duk_uint_fast16_t duk_small_uint_fast_t;
1069
+ #define DUK_SMALL_INT_FAST_MIN DUK_INT_FAST16_MIN
1070
+ #define DUK_SMALL_INT_FAST_MAX DUK_INT_FAST16_MAX
1071
+ #define DUK_SMALL_UINT_FAST_MIN DUK_UINT_FAST16_MIN
1072
+ #define DUK_SMALL_UINT_FAST_MAX DUK_UINT_FAST16_MAX
1073
+
1074
+ /* Boolean values are represented with the platform 'int'. */
1075
+ typedef duk_small_int_t duk_bool_t;
1076
+ #define DUK_BOOL_MIN DUK_SMALL_INT_MIN
1077
+ #define DUK_BOOL_MAX DUK_SMALL_INT_MAX
1078
+
1079
+ /* Index values must have at least 32-bit signed range. */
1080
+ typedef duk_int_t duk_idx_t;
1081
+ #define DUK_IDX_MIN DUK_INT_MIN
1082
+ #define DUK_IDX_MAX DUK_INT_MAX
1083
+
1084
+ /* Array index values, could be exact 32 bits.
1085
+ * Currently no need for signed duk_arridx_t.
1086
+ */
1087
+ typedef duk_uint_t duk_uarridx_t;
1088
+ #define DUK_UARRIDX_MIN DUK_UINT_MIN
1089
+ #define DUK_UARRIDX_MAX DUK_UINT_MAX
1090
+
1091
+ /* Duktape/C function return value, platform int is enough for now to
1092
+ * represent 0, 1, or negative error code. Must be compatible with
1093
+ * assigning truth values (e.g. duk_ret_t rc = (foo == bar);).
1094
+ */
1095
+ typedef duk_small_int_t duk_ret_t;
1096
+ #define DUK_RET_MIN DUK_SMALL_INT_MIN
1097
+ #define DUK_RET_MAX DUK_SMALL_INT_MAX
1098
+
1099
+ /* Error codes are represented with platform int. High bits are used
1100
+ * for flags and such, so 32 bits are needed.
1101
+ */
1102
+ typedef duk_int_t duk_errcode_t;
1103
+ #define DUK_ERRCODE_MIN DUK_INT_MIN
1104
+ #define DUK_ERRCODE_MAX DUK_INT_MAX
1105
+
1106
+ /* Codepoint type. Must be 32 bits or more because it is used also for
1107
+ * internal codepoints. The type is signed because negative codepoints
1108
+ * are used as internal markers (e.g. to mark EOF or missing argument).
1109
+ * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to
1110
+ * ensure duk_uint32_t casts back and forth nicely. Almost everything
1111
+ * else uses the signed one.
1112
+ */
1113
+ typedef duk_int_t duk_codepoint_t;
1114
+ typedef duk_uint_t duk_ucodepoint_t;
1115
+ #define DUK_CODEPOINT_MIN DUK_INT_MIN
1116
+ #define DUK_CODEPOINT_MAX DUK_INT_MAX
1117
+ #define DUK_UCODEPOINT_MIN DUK_UINT_MIN
1118
+ #define DUK_UCODEPOINT_MAX DUK_UINT_MAX
1119
+
1120
+ /* IEEE double typedef. */
1121
+ typedef double duk_double_t;
1122
+
1123
+ /* We're generally assuming that we're working on a platform with a 32-bit
1124
+ * address space. If DUK_SIZE_MAX is a typecast value (which is necessary
1125
+ * if SIZE_MAX is missing), the check must be avoided because the
1126
+ * preprocessor can't do a comparison.
1127
+ */
1128
+ #if !defined(DUK_SIZE_MAX)
1129
+ #error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX
1130
+ #elif !defined(DUK_SIZE_MAX_COMPUTED)
1131
+ #if DUK_SIZE_MAX < 0xffffffffUL
1132
+ /* XXX: compare against a lower value; can SIZE_MAX realistically be
1133
+ * e.g. 0x7fffffffUL on a 32-bit system?
1134
+ */
1135
+ #error size_t is too small
1136
+ #endif
1137
+ #endif
1138
+
1139
+ /* Convenience define: 32-bit pointers. 32-bit platforms are an important
1140
+ * footprint optimization target, and this define allows e.g. struct sizes
1141
+ * to be organized for compactness.
1142
+ */
1143
+
1144
+ #undef DUK_USE_32BIT_PTRS
1145
+ #if defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)
1146
+ #if DUK_UINTPTR_MAX <= 0xffffffffUL
1147
+ #define DUK_USE_32BIT_PTRS
1148
+ #endif
1149
+ #endif
1150
+
1151
+ /*
1152
+ * Check whether we should use 64-bit integers
1153
+ */
1154
+
1155
+ /* Quite incomplete now. Use 64-bit types if detected (C99 or other detection)
1156
+ * unless they are known to be unreliable. For instance, 64-bit types are
1157
+ * available on VBCC but seem to misbehave.
1158
+ */
1159
+ #if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)
1160
+ #define DUK_USE_64BIT_OPS
1161
+ #else
1162
+ #undef DUK_USE_64BIT_OPS
1163
+ #endif
1164
+
1165
+ /*
1166
+ * Alignment requirement and support for unaligned accesses
1167
+ *
1168
+ * Assume unaligned accesses are not supported unless specifically allowed
1169
+ * in the target platform. Some platforms may support unaligned accesses
1170
+ * but alignment to 4 or 8 may still be desirable.
1171
+ */
1172
+
1173
+ #undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
1174
+ #undef DUK_USE_ALIGN_4
1175
+ #undef DUK_USE_ALIGN_8
1176
+
1177
+ #if defined(DUK_F_EMSCRIPTEN)
1178
+ /* Required on at least some targets, so use whenever Emscripten used,
1179
+ * regardless of compilation target.
1180
+ */
1181
+ #define DUK_USE_ALIGN_8
1182
+ #elif defined(DUK_F_ARM)
1183
+ #define DUK_USE_ALIGN_4
1184
+ #elif defined(DUK_F_MIPS)
1185
+ #define DUK_USE_ALIGN_4
1186
+ #elif defined(DUK_F_X86) || defined(DUK_F_X32) || defined(DUK_F_X64) || \
1187
+ defined(DUK_F_BCC)
1188
+ #define DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
1189
+ #else
1190
+ /* unknown, use safe default */
1191
+ #define DUK_USE_ALIGN_8
1192
+ #endif
1193
+
1194
+ /* User forced alignment to 4 or 8. */
1195
+ #if defined(DUK_OPT_FORCE_ALIGN)
1196
+ #undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
1197
+ #undef DUK_USE_ALIGN_4
1198
+ #undef DUK_USE_ALIGN_8
1199
+ #if (DUK_OPT_FORCE_ALIGN == 4)
1200
+ #define DUK_USE_ALIGN_4
1201
+ #elif (DUK_OPT_FORCE_ALIGN == 8)
1202
+ #define DUK_USE_ALIGN_8
1203
+ #else
1204
+ #error invalid DUK_OPT_FORCE_ALIGN value
1205
+ #endif
1206
+ #endif
1207
+
1208
+ /* Compiler specific hackery needed to force struct size to match aligment,
1209
+ * see e.g. duk_hbuffer.h.
1210
+ *
1211
+ * http://stackoverflow.com/questions/11130109/c-struct-size-alignment
1212
+ * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment
1213
+ */
1214
+ #if defined(DUK_F_MSVC)
1215
+ #define DUK_USE_PACK_MSVC_PRAGMA
1216
+ #elif defined(DUK_F_GCC)
1217
+ #define DUK_USE_PACK_GCC_ATTR
1218
+ #elif defined(DUK_F_CLANG)
1219
+ #define DUK_USE_PACK_CLANG_ATTR
1220
+ #else
1221
+ #define DUK_USE_PACK_DUMMY_MEMBER
1222
+ #endif
1223
+
1224
+ #ifdef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
1225
+ #define DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS
1226
+ #else
1227
+ #undef DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS
1228
+ #endif
1229
+
1230
+ /* Object property allocation layout has implications for memory and code
1231
+ * footprint and generated code size/speed. The best layout also depends
1232
+ * on whether the platform has alignment requirements or benefits from
1233
+ * having mostly aligned accesses.
1234
+ */
1235
+ #undef DUK_USE_HOBJECT_LAYOUT_1
1236
+ #undef DUK_USE_HOBJECT_LAYOUT_2
1237
+ #undef DUK_USE_HOBJECT_LAYOUT_3
1238
+ #if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) && \
1239
+ !defined(DUK_USE_ALIGN_4) && !defined(DUK_USE_ALIGN_8)
1240
+ /* On platforms without any alignment issues, layout 1 is preferable
1241
+ * because it compiles to slightly less code and provides direct access
1242
+ * to property keys.
1243
+ */
1244
+ #define DUK_USE_HOBJECT_LAYOUT_1
1245
+ #else
1246
+ /* On other platforms use layout 2, which requires some padding but
1247
+ * is a bit more natural than layout 3 in ordering the entries. Layout
1248
+ * 3 is currently not used.
1249
+ */
1250
+ #define DUK_USE_HOBJECT_LAYOUT_2
1251
+ #endif
1252
+
1253
+ /*
1254
+ * Byte order and double memory layout detection
1255
+ *
1256
+ * Endianness detection is a major portability hassle because the macros
1257
+ * and headers are not standardized. There's even variance across UNIX
1258
+ * platforms. Even with "standard" headers, details like underscore count
1259
+ * varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used
1260
+ * (Crossbridge has a single underscore, for instance).
1261
+ *
1262
+ * The checks below are structured with this in mind: several approaches are
1263
+ * used, and at the end we check if any of them worked. This allows generic
1264
+ * approaches to be tried first, and platform/compiler specific hacks tried
1265
+ * last. As a last resort, the user can force a specific endianness, as it's
1266
+ * not likely that automatic detection will work on the most exotic platforms.
1267
+ *
1268
+ * Duktape supports little and big endian machines. There's also support
1269
+ * for a hybrid used by some ARM machines where integers are little endian
1270
+ * but IEEE double values use a mixed order (12345678 -> 43218765). This
1271
+ * byte order for doubles is referred to as "mixed endian".
1272
+ */
1273
+
1274
+ #undef DUK_F_BYTEORDER
1275
+ #undef DUK_USE_BYTEORDER_FORCED
1276
+
1277
+ /* DUK_F_BYTEORDER is set as an intermediate value when detection
1278
+ * succeeds, to one of:
1279
+ * 1 = little endian
1280
+ * 2 = mixed (arm hybrid) endian
1281
+ * 3 = big endian
1282
+ */
1283
+
1284
+ /* For custom platforms allow user to define byteorder explicitly.
1285
+ * Since endianness headers are not standardized, this is a useful
1286
+ * workaround for custom platforms for which endianness detection
1287
+ * is not directly supported. Perhaps custom hardware is used and
1288
+ * user cannot submit upstream patches.
1289
+ */
1290
+ #if defined(DUK_OPT_FORCE_BYTEORDER)
1291
+ #if (DUK_OPT_FORCE_BYTEORDER == 1)
1292
+ #define DUK_F_BYTEORDER 1
1293
+ #elif (DUK_OPT_FORCE_BYTEORDER == 2)
1294
+ #define DUK_F_BYTEORDER 2
1295
+ #elif (DUK_OPT_FORCE_BYTEORDER == 3)
1296
+ #define DUK_F_BYTEORDER 3
1297
+ #else
1298
+ #error invalid DUK_OPT_FORCE_BYTEORDER value
1299
+ #endif
1300
+ #define DUK_USE_BYTEORDER_FORCED
1301
+ #endif /* DUK_OPT_FORCE_BYTEORDER */
1302
+
1303
+ /* More or less standard endianness predefines provided by header files.
1304
+ * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER
1305
+ * will be big endian, see: http://lists.mysql.com/internals/443.
1306
+ */
1307
+ #if !defined(DUK_F_BYTEORDER)
1308
+ #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \
1309
+ defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \
1310
+ defined(__LITTLE_ENDIAN__)
1311
+ /* Integer little endian */
1312
+ #if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \
1313
+ defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN)
1314
+ #define DUK_F_BYTEORDER 1
1315
+ #elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \
1316
+ defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)
1317
+ #define DUK_F_BYTEORDER 2
1318
+ #elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)
1319
+ /* Float word order not known, assume not a hybrid. */
1320
+ #define DUK_F_BYTEORDER 1
1321
+ #else
1322
+ /* byte order is little endian but cannot determine IEEE double word order */
1323
+ #endif /* float word order */
1324
+ #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \
1325
+ defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \
1326
+ defined(__BIG_ENDIAN__)
1327
+ /* Integer big endian */
1328
+ #if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \
1329
+ defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)
1330
+ #define DUK_F_BYTEORDER 3
1331
+ #elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)
1332
+ /* Float word order not known, assume not a hybrid. */
1333
+ #define DUK_F_BYTEORDER 3
1334
+ #else
1335
+ /* byte order is big endian but cannot determine IEEE double word order */
1336
+ #endif /* float word order */
1337
+ #else
1338
+ /* cannot determine byte order */
1339
+ #endif /* integer byte order */
1340
+ #endif /* !defined(DUK_F_BYTEORDER) */
1341
+
1342
+ /* GCC and Clang provide endianness defines as built-in predefines, with
1343
+ * leading and trailing double underscores (e.g. __BYTE_ORDER__). See
1344
+ * output of "make gccpredefs" and "make clangpredefs". Clang doesn't
1345
+ * seem to provide __FLOAT_WORD_ORDER__.
1346
+ * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
1347
+ */
1348
+ #if !defined(DUK_F_BYTEORDER) && defined(__BYTE_ORDER__)
1349
+ #if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1350
+ /* Integer little endian */
1351
+ #if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
1352
+ (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1353
+ #define DUK_F_BYTEORDER 1
1354
+ #elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
1355
+ (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
1356
+ #define DUK_F_BYTEORDER 2
1357
+ #elif !defined(__FLOAT_WORD_ORDER__)
1358
+ /* Float word order not known, assume not a hybrid. */
1359
+ #define DUK_F_BYTEORDER 1
1360
+ #else
1361
+ /* byte order is little endian but cannot determine IEEE double word order */
1362
+ #endif /* float word order */
1363
+ #elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1364
+ /* Integer big endian */
1365
+ #if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
1366
+ (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
1367
+ #define DUK_F_BYTEORDER 3
1368
+ #elif !defined(__FLOAT_WORD_ORDER__)
1369
+ /* Float word order not known, assume not a hybrid. */
1370
+ #define DUK_F_BYTEORDER 3
1371
+ #else
1372
+ /* byte order is big endian but cannot determine IEEE double word order */
1373
+ #endif /* float word order */
1374
+ #else
1375
+ /* cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit
1376
+ * integer ordering and is not relevant
1377
+ */
1378
+ #endif /* integer byte order */
1379
+ #endif /* !defined(DUK_F_BYTEORDER) && defined(__BYTE_ORDER__) */
1380
+
1381
+ /* Atari ST TOS */
1382
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_TOS)
1383
+ #define DUK_F_BYTEORDER 3
1384
+ #endif
1385
+
1386
+ /* AmigaOS on M68k */
1387
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_AMIGAOS)
1388
+ #if defined(DUK_F_M68K)
1389
+ #define DUK_F_BYTEORDER 3
1390
+ #endif
1391
+ #endif
1392
+
1393
+ /* On Windows, assume we're little endian. Even Itanium which has a
1394
+ * configurable endianness runs little endian in Windows.
1395
+ */
1396
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_WINDOWS)
1397
+ /* XXX: verify that Windows on ARM is little endian for floating point
1398
+ * values too.
1399
+ */
1400
+ #define DUK_F_BYTEORDER 1
1401
+ #endif /* Windows */
1402
+
1403
+ /* Crossbridge should work with the standard byteorder #ifdefs. It doesn't
1404
+ * provide _FLOAT_WORD_ORDER but the standard approach now covers that case
1405
+ * too. This has been left here just in case.
1406
+ */
1407
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_FLASHPLAYER)
1408
+ #define DUK_F_BYTEORDER 1
1409
+ #endif
1410
+
1411
+ /* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__:
1412
+ * $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian
1413
+ * 67:#define __LITTLEENDIAN__ 1
1414
+ * $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian
1415
+ * 81:#define __BIGENDIAN__ 1
1416
+ * $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian
1417
+ * 70:#define __LITTLEENDIAN__ 1
1418
+ */
1419
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_QNX)
1420
+ /* XXX: ARM hybrid? */
1421
+ #if defined(__LITTLEENDIAN__)
1422
+ #define DUK_F_BYTEORDER 1
1423
+ #elif defined(__BIGENDIAN__)
1424
+ #define DUK_F_BYTEORDER 3
1425
+ #endif
1426
+ #endif
1427
+
1428
+ /* Bruce's C Compiler (BCC), assume we're on x86. */
1429
+ #if !defined(DUK_F_BYTEORDER) && defined(DUK_F_BCC)
1430
+ #define DUK_F_BYTEORDER 1
1431
+ #endif
1432
+
1433
+ /* Check whether or not byte order detection worked based on the intermediate
1434
+ * define, and define final values. If detection failed, #error out.
1435
+ */
1436
+ #if defined(DUK_F_BYTEORDER)
1437
+ #if (DUK_F_BYTEORDER == 1)
1438
+ #define DUK_USE_INTEGER_LE
1439
+ #define DUK_USE_DOUBLE_LE
1440
+ #elif (DUK_F_BYTEORDER == 2)
1441
+ #define DUK_USE_INTEGER_LE /* integer endianness is little on purpose */
1442
+ #define DUK_USE_DOUBLE_ME
1443
+ #elif (DUK_F_BYTEORDER == 3)
1444
+ #define DUK_USE_INTEGER_BE
1445
+ #define DUK_USE_DOUBLE_BE
1446
+ #else
1447
+ #error unsupported: byte order detection failed (internal error, should not happen)
1448
+ #endif /* byte order */
1449
+ #else
1450
+ #error unsupported: byte order detection failed
1451
+ #endif /* defined(DUK_F_BYTEORDER) */
1452
+
1453
+ /*
1454
+ * Check whether or not a packed duk_tval representation is possible.
1455
+ * What's basically required is that pointers are 32-bit values
1456
+ * (sizeof(void *) == 4). Best effort check, not always accurate.
1457
+ * If guess goes wrong, crashes may result; self tests also verify
1458
+ * the guess.
1459
+ */
1460
+
1461
+ #undef DUK_USE_PACKED_TVAL_POSSIBLE
1462
+
1463
+ /* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */
1464
+ #if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_HAVE_INTTYPES) && defined(DUK_UINTPTR_MAX)
1465
+ #if (DUK_UINTPTR_MAX <= 0xffffffffUL)
1466
+ #define DUK_USE_PACKED_TVAL_POSSIBLE
1467
+ #endif
1468
+ #endif
1469
+
1470
+ /* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */
1471
+ #if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)
1472
+ #if (DUK_UINTPTR_MAX <= 0xffffffffUL)
1473
+ #define DUK_USE_PACKED_TVAL_POSSIBLE
1474
+ #endif
1475
+ #endif
1476
+
1477
+ /* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */
1478
+ #if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED)
1479
+ #if DUK_SIZE_MAX <= 0xffffffffUL
1480
+ #define DUK_USE_PACKED_TVAL_POSSIBLE
1481
+ #endif
1482
+ #endif
1483
+
1484
+ /* M68K: packed always possible */
1485
+ #if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_M68K)
1486
+ #define DUK_USE_PACKED_TVAL_POSSIBLE
1487
+ #endif
1488
+
1489
+ /* With Emscripten, force unpacked duk_tval just to be safe, as it seems to
1490
+ * break at least on Firefox (probably IEEE double arithmetic is not 100%
1491
+ * supported, especially for NaNs).
1492
+ */
1493
+ #if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_EMSCRIPTEN)
1494
+ #undef DUK_USE_PACKED_TVAL_POSSIBLE
1495
+ #endif
1496
+
1497
+ /* Microsoft Visual Studio 2010 on x64 fails the above rules and tries to
1498
+ * use a packed type. Force unpacked on x64 in general.
1499
+ */
1500
+ #if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_X64)
1501
+ #undef DUK_USE_PACKED_TVAL_POSSIBLE
1502
+ #endif
1503
+
1504
+ /* GCC/clang inaccurate math would break compliance and probably duk_tval,
1505
+ * so refuse to compile. Relax this if -ffast-math is tested to work.
1506
+ */
1507
+ #if defined(__FAST_MATH__)
1508
+ #error __FAST_MATH__ defined, refusing to compile
1509
+ #endif
1510
+
1511
+ /*
1512
+ * Detection of double constants and math related functions. Availability
1513
+ * of constants and math functions is a significant porting concern.
1514
+ *
1515
+ * INFINITY/HUGE_VAL is problematic on GCC-3.3: it causes an overflow warning
1516
+ * and there is no pragma in GCC-3.3 to disable it. Using __builtin_inf()
1517
+ * avoids this problem for some reason.
1518
+ */
1519
+
1520
+ #define DUK_DOUBLE_2TO32 4294967296.0
1521
+ #define DUK_DOUBLE_2TO31 2147483648.0
1522
+
1523
+ #undef DUK_USE_COMPUTED_INFINITY
1524
+ #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600)
1525
+ /* GCC older than 4.6: avoid overflow warnings related to using INFINITY */
1526
+ #define DUK_DOUBLE_INFINITY (__builtin_inf())
1527
+ #elif defined(INFINITY)
1528
+ #define DUK_DOUBLE_INFINITY ((double) INFINITY)
1529
+ #elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC)
1530
+ #define DUK_DOUBLE_INFINITY (1.0 / 0.0)
1531
+ #else
1532
+ /* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.
1533
+ * Use a computed infinity (initialized when a heap is created at the
1534
+ * latest).
1535
+ */
1536
+ extern double duk_computed_infinity;
1537
+ #define DUK_USE_COMPUTED_INFINITY
1538
+ #define DUK_DOUBLE_INFINITY duk_computed_infinity
1539
+ #endif
1540
+
1541
+ #undef DUK_USE_COMPUTED_NAN
1542
+ #if defined(NAN)
1543
+ #define DUK_DOUBLE_NAN NAN
1544
+ #elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC)
1545
+ #define DUK_DOUBLE_NAN (0.0 / 0.0)
1546
+ #else
1547
+ /* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.
1548
+ * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.
1549
+ * Use a computed NaN (initialized when a heap is created at the
1550
+ * latest).
1551
+ */
1552
+ extern double duk_computed_nan;
1553
+ #define DUK_USE_COMPUTED_NAN
1554
+ #define DUK_DOUBLE_NAN duk_computed_nan
1555
+ #endif
1556
+
1557
+ /* Many platforms are missing fpclassify() and friends, so use replacements
1558
+ * if necessary. The replacement constants (FP_NAN etc) can be anything but
1559
+ * match Linux constants now.
1560
+ */
1561
+ #undef DUK_USE_REPL_FPCLASSIFY
1562
+ #undef DUK_USE_REPL_SIGNBIT
1563
+ #undef DUK_USE_REPL_ISFINITE
1564
+ #undef DUK_USE_REPL_ISNAN
1565
+ #undef DUK_USE_REPL_ISINF
1566
+
1567
+ /* Complex condition broken into separate parts. */
1568
+ #undef DUK_F_USE_REPL_ALL
1569
+ #if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \
1570
+ defined(FP_SUBNORMAL) && defined(FP_NORMAL))
1571
+ /* Missing some obvious constants. */
1572
+ #define DUK_F_USE_REPL_ALL
1573
+ #elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)
1574
+ /* VBCC is missing the built-ins even in C99 mode (perhaps a header issue) */
1575
+ #define DUK_F_USE_REPL_ALL
1576
+ #elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)
1577
+ /* Placeholder fix for (detection is wider than necessary):
1578
+ * http://llvm.org/bugs/show_bug.cgi?id=17788
1579
+ */
1580
+ #define DUK_F_USE_REPL_ALL
1581
+ #elif defined(DUK_F_UCLIBC)
1582
+ /* At least some uclibc versions have broken floating point math. For
1583
+ * example, fpclassify() can incorrectly classify certain NaN formats.
1584
+ * To be safe, use replacements.
1585
+ */
1586
+ #define DUK_F_USE_REPL_ALL
1587
+ #endif
1588
+
1589
+ #if defined(DUK_F_USE_REPL_ALL)
1590
+ #define DUK_USE_REPL_FPCLASSIFY
1591
+ #define DUK_USE_REPL_SIGNBIT
1592
+ #define DUK_USE_REPL_ISFINITE
1593
+ #define DUK_USE_REPL_ISNAN
1594
+ #define DUK_USE_REPL_ISINF
1595
+ #define DUK_FPCLASSIFY duk_repl_fpclassify
1596
+ #define DUK_SIGNBIT duk_repl_signbit
1597
+ #define DUK_ISFINITE duk_repl_isfinite
1598
+ #define DUK_ISNAN duk_repl_isnan
1599
+ #define DUK_ISINF duk_repl_isinf
1600
+ #define DUK_FP_NAN 0
1601
+ #define DUK_FP_INFINITE 1
1602
+ #define DUK_FP_ZERO 2
1603
+ #define DUK_FP_SUBNORMAL 3
1604
+ #define DUK_FP_NORMAL 4
1605
+ #else
1606
+ #define DUK_FPCLASSIFY fpclassify
1607
+ #define DUK_SIGNBIT signbit
1608
+ #define DUK_ISFINITE isfinite
1609
+ #define DUK_ISNAN isnan
1610
+ #define DUK_ISINF isinf
1611
+ #define DUK_FP_NAN FP_NAN
1612
+ #define DUK_FP_INFINITE FP_INFINITE
1613
+ #define DUK_FP_ZERO FP_ZERO
1614
+ #define DUK_FP_SUBNORMAL FP_SUBNORMAL
1615
+ #define DUK_FP_NORMAL FP_NORMAL
1616
+ #endif
1617
+
1618
+ #if defined(DUK_F_USE_REPL_ALL)
1619
+ #undef DUK_F_USE_REPL_ALL
1620
+ #endif
1621
+
1622
+ /* Some math functions are C99 only. This is also an issue with some
1623
+ * embedded environments using uclibc where uclibc has been configured
1624
+ * not to provide some functions. For now, use replacements whenever
1625
+ * using uclibc.
1626
+ */
1627
+ #undef DUK_USE_MATH_FMIN
1628
+ #undef DUK_USE_MATH_FMAX
1629
+ #undef DUK_USE_MATH_ROUND
1630
+ #if defined(DUK_F_UCLIBC)
1631
+ /* uclibc may be missing these */
1632
+ #elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)
1633
+ /* vbcc + AmigaOS may be missing these */
1634
+ #elif !defined(DUK_F_C99) && !defined(DUK_F_CPP11)
1635
+ /* build is not C99 or C++11, play it safe */
1636
+ #else
1637
+ /* C99 or C++11, no known issues */
1638
+ #define DUK_USE_MATH_FMIN
1639
+ #define DUK_USE_MATH_FMAX
1640
+ #define DUK_USE_MATH_ROUND
1641
+ #endif
1642
+
1643
+ /* These functions don't currently need replacement but are wrapped for
1644
+ * completeness. Because these are used as function pointers, they need
1645
+ * to be defined as concrete C functions (not macros).
1646
+ */
1647
+ #define DUK_FABS fabs
1648
+ #define DUK_FMIN fmin
1649
+ #define DUK_FMAX fmax
1650
+ #define DUK_FLOOR floor
1651
+ #define DUK_CEIL ceil
1652
+ #define DUK_FMOD fmod
1653
+ #define DUK_POW pow
1654
+ #define DUK_ACOS acos
1655
+ #define DUK_ASIN asin
1656
+ #define DUK_ATAN atan
1657
+ #define DUK_ATAN2 atan2
1658
+ #define DUK_SIN sin
1659
+ #define DUK_COS cos
1660
+ #define DUK_TAN tan
1661
+ #define DUK_EXP exp
1662
+ #define DUK_LOG log
1663
+ #define DUK_SQRT sqrt
1664
+
1665
+ /* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,
1666
+ * see test-bug-netbsd-math-pow.js. Use NetBSD specific workaround.
1667
+ * (This might be a wider problem; if so, generalize the define name.)
1668
+ */
1669
+ #undef DUK_USE_POW_NETBSD_WORKAROUND
1670
+ #if defined(DUK_F_NETBSD)
1671
+ #define DUK_USE_POW_NETBSD_WORKAROUND
1672
+ #endif
1673
+
1674
+ /* Rely as little as possible on compiler behavior for NaN comparison,
1675
+ * signed zero handling, etc. Currently never activated but may be needed
1676
+ * for broken compilers.
1677
+ */
1678
+ #undef DUK_USE_PARANOID_MATH
1679
+
1680
+ /* There was a curious bug where test-bi-date-canceling.js would fail e.g.
1681
+ * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99. Some date computations
1682
+ * using doubles would be optimized which then broke some corner case tests.
1683
+ * The problem goes away by adding 'volatile' to the datetime computations.
1684
+ * Not sure what the actual triggering conditions are, but using this on
1685
+ * non-C99 systems solves the known issues and has relatively little cost
1686
+ * on other platforms. See bugs/issue-2e9d9c2d761dabaf8136c0897b91a270d1a47147.yaml.
1687
+ */
1688
+ #undef DUK_USE_PARANOID_DATE_COMPUTATION
1689
+ #if !defined(DUK_F_C99)
1690
+ #define DUK_USE_PARANOID_DATE_COMPUTATION
1691
+ #endif
1692
+
1693
+ /*
1694
+ * ANSI C string/memory function wrapper defines to allow easier workarounds.
1695
+ * Also convenience macros like DUK_MEMZERO which may be mapped to existing
1696
+ * platform function to zero memory (like the deprecated bzero).
1697
+ *
1698
+ * For instance, some platforms don't support zero-size memcpy correctly,
1699
+ * some arcane uclibc versions have a buggy memcpy (but working memmove)
1700
+ * and so on. Such broken platforms can be dealt with here.
1701
+ *
1702
+ * NOTE: ANSI C (various versions) and some implementations require that the
1703
+ * pointer arguments to memset(), memcpy(), and memmove() be valid values
1704
+ * even when byte size is 0 (even a NULL pointer is considered invalid in
1705
+ * this context). Zero-size operations as such are allowed, as long as their
1706
+ * pointer arguments point to a valid memory area. The DUK_MEMSET(),
1707
+ * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.:
1708
+ * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be
1709
+ * allowed. If these are not fulfilled, a macro wrapper is needed.
1710
+ *
1711
+ * http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0
1712
+ * http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html
1713
+ *
1714
+ * Not sure what's the required behavior when a pointer points just past the
1715
+ * end of a buffer, which often happens in practice (e.g. zero size memmoves).
1716
+ * For example, if allocation size is 3, the following pointer would not
1717
+ * technically point to a valid memory byte:
1718
+ *
1719
+ * <-- alloc -->
1720
+ * | 0 | 1 | 2 | .....
1721
+ * ^-- p=3, points after last valid byte (2)
1722
+ *
1723
+ * If this is a practical issue, wrappers are again needed.
1724
+ */
1725
+
1726
+ typedef FILE duk_file;
1727
+ #define DUK_STDIN stdin
1728
+ #define DUK_STDOUT stdout
1729
+ #define DUK_STDERR stderr
1730
+
1731
+ /* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h
1732
+ * (which is unfortunately named).
1733
+ */
1734
+ #define DUK_ANSI_MALLOC malloc
1735
+ #define DUK_ANSI_REALLOC realloc
1736
+ #define DUK_ANSI_CALLOC calloc
1737
+ #define DUK_ANSI_FREE free
1738
+
1739
+ /* Old uclibcs have a broken memcpy so use memmove instead (this is overly
1740
+ * wide now on purpose):
1741
+ * http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html
1742
+ */
1743
+ #if defined(DUK_F_UCLIBC)
1744
+ #define DUK_MEMCPY memmove
1745
+ #else
1746
+ #define DUK_MEMCPY memcpy
1747
+ #endif
1748
+
1749
+ #define DUK_MEMMOVE memmove
1750
+ #define DUK_MEMCMP memcmp
1751
+ #define DUK_MEMSET memset
1752
+ #define DUK_STRLEN strlen
1753
+ #define DUK_STRCMP strcmp
1754
+ #define DUK_STRNCMP strncmp
1755
+ #define DUK_PRINTF printf
1756
+ #define DUK_FPRINTF fprintf
1757
+ #define DUK_SPRINTF sprintf
1758
+
1759
+ #if defined(DUK_F_MSVC)
1760
+ /* _snprintf() does NOT NUL terminate on truncation, but Duktape code never
1761
+ * assumes that.
1762
+ * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
1763
+ */
1764
+ #define DUK_SNPRINTF _snprintf
1765
+ #else
1766
+ #define DUK_SNPRINTF snprintf
1767
+ #endif
1768
+
1769
+ #define DUK_VSPRINTF vsprintf
1770
+
1771
+ #if defined(DUK_F_MSVC)
1772
+ #if (_MSC_VER < 1600)
1773
+ /* Older MSVC version are missing vsnprintf() but have _vsnprintf(). */
1774
+ #define DUK_VSNPRINTF _vsnprintf
1775
+ #else
1776
+ #define DUK_VSNPRINTF vsnprintf
1777
+ #endif
1778
+ #else
1779
+ #define DUK_VSNPRINTF vsnprintf
1780
+ #endif /* DUK_F_MSVC */
1781
+
1782
+ #define DUK_SSCANF sscanf
1783
+ #define DUK_VSSCANF vsscanf
1784
+ #define DUK_FOPEN fopen
1785
+ #define DUK_FCLOSE fclose
1786
+ #define DUK_FREAD fread
1787
+ #define DUK_FWRITE fwrite
1788
+ #define DUK_FSEEK fseek
1789
+ #define DUK_FTELL ftell
1790
+ #define DUK_FFLUSH fflush
1791
+ #define DUK_FPUTC fputc
1792
+
1793
+ #define DUK_MEMZERO(p,n) \
1794
+ DUK_MEMSET((p), 0, (n))
1795
+
1796
+ /*
1797
+ * Avoiding platform function pointers.
1798
+ *
1799
+ * On some platforms built-in functions may be implemented as macros or
1800
+ * inline functions, so they can't be necessarily addressed by function
1801
+ * pointers. This is certainly the case with some platform "polyfills"
1802
+ * which provide missing C99/C++11 functions through macros, and may be
1803
+ * the case with VS2013 (see GH-17).
1804
+ */
1805
+
1806
+ /* This is now the default: the cost in footprint is negligible. */
1807
+ #define DUK_USE_AVOID_PLATFORM_FUNCPTRS
1808
+
1809
+ /*
1810
+ * Vararg macro wrappers. We need va_copy() which is defined in C99 / C++11,
1811
+ * so an awkward replacement is needed for pre-C99 / pre-C++11 environments.
1812
+ * This will quite likely need portability hacks for some non-C99 environments.
1813
+ */
1814
+
1815
+ #if defined(DUK_F_C99) || defined(DUK_F_CPP11)
1816
+ /* C99 / C++11 and above: rely on va_copy() which is required.
1817
+ * Omit parenthesis on macro right side on purpose to minimize differences
1818
+ * to direct use.
1819
+ */
1820
+ #define DUK_VA_COPY(dest,src) va_copy(dest,src)
1821
+ #elif defined(DUK_F_GCC) || defined(DUK_F_CLANG)
1822
+ /* GCC: assume we have __va_copy() in non-C99 mode, which should be correct
1823
+ * for even quite old GCC versions. Clang matches GCC behavior.
1824
+ */
1825
+ #define DUK_VA_COPY(dest,src) __va_copy(dest,src)
1826
+ #else
1827
+ /* Pre-C99: va_list type is implementation dependent. This replacement
1828
+ * assumes it is a plain value so that a simple assignment will work.
1829
+ * This is not the case on all platforms (it may be a single-array element,
1830
+ * for instance).
1831
+ */
1832
+ #define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0)
1833
+ #endif
1834
+
1835
+ /*
1836
+ * Miscellaneous ANSI C or other platform wrappers.
1837
+ */
1838
+
1839
+ #define DUK_ABORT abort
1840
+ #define DUK_EXIT exit
1841
+ #define DUK_SETJMP setjmp
1842
+ #define DUK_LONGJMP longjmp
1843
+
1844
+ /*
1845
+ * Macro hackery to convert e.g. __LINE__ to a string without formatting,
1846
+ * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string
1847
+ */
1848
+
1849
+ #define DUK_F_STRINGIFY_HELPER(x) #x
1850
+ #define DUK_MACRO_STRINGIFY(x) DUK_F_STRINGIFY_HELPER(x)
1851
+
1852
+ /*
1853
+ * Cause segfault macro.
1854
+ *
1855
+ * This is optionally used by panic handling to cause the program to segfault
1856
+ * (instead of e.g. abort()) on panic. Valgrind will then indicate the C
1857
+ * call stack leading to the panic.
1858
+ */
1859
+
1860
+ #define DUK_CAUSE_SEGFAULT() do { \
1861
+ *((duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; \
1862
+ } while (0)
1863
+
1864
+ /*
1865
+ * Macro for suppressing warnings for potentially unreferenced variables.
1866
+ * The variables can be actually unreferenced or unreferenced in some
1867
+ * specific cases only; for instance, if a variable is only debug printed,
1868
+ * it is unreferenced when debug printing is disabled.
1869
+ *
1870
+ * (Introduced here because it's potentially compiler specific.)
1871
+ */
1872
+
1873
+ #define DUK_UNREF(x) do { \
1874
+ (void) (x); \
1875
+ } while (0)
1876
+
1877
+ /*
1878
+ * DUK_NORETURN: macro for declaring a 'noreturn' function.
1879
+ * Unfortunately the noreturn declaration may appear in various
1880
+ * places of a function declaration, so the solution is to wrap
1881
+ * the entire declaration inside the macro. Compiler support
1882
+ * for using a noreturn declaration on function pointers varies;
1883
+ * this macro must only be used for actual function declarations.
1884
+ *
1885
+ * http://gcc.gnu.org/onlinedocs/gcc-4.3.2//gcc/Function-Attributes.html
1886
+ * http://clang.llvm.org/docs/LanguageExtensions.html
1887
+ */
1888
+
1889
+ #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L)
1890
+ /* since gcc-2.5 */
1891
+ #define DUK_NORETURN(decl) decl __attribute__((noreturn))
1892
+ #elif defined(__clang__)
1893
+ /* syntax same as gcc */
1894
+ #define DUK_NORETURN(decl) decl __attribute__((noreturn))
1895
+ #elif defined(DUK_F_MSVC)
1896
+ /* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */
1897
+ #define DUK_NORETURN(decl) __declspec(noreturn) decl
1898
+ #else
1899
+ /* Don't know how to declare a noreturn function, so don't do it; this
1900
+ * may cause some spurious compilation warnings (e.g. "variable used
1901
+ * uninitialized").
1902
+ */
1903
+ #define DUK_NORETURN(decl) decl
1904
+ #endif
1905
+
1906
+ /*
1907
+ * Macro for stating that a certain line cannot be reached.
1908
+ *
1909
+ * http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Other-Builtins.html#Other-Builtins
1910
+ * http://clang.llvm.org/docs/LanguageExtensions.html
1911
+ */
1912
+
1913
+ #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)
1914
+ /* since gcc-4.5 */
1915
+ #define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0)
1916
+ #elif defined(__clang__) && defined(__has_builtin)
1917
+ #if __has_builtin(__builtin_unreachable)
1918
+ /* same as gcc */
1919
+ #define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0)
1920
+ #endif
1921
+ #else
1922
+ /* unknown */
1923
+ #endif
1924
+
1925
+ #if !defined(DUK_UNREACHABLE)
1926
+ /* Don't know how to declare unreachable point, so don't do it; this
1927
+ * may cause some spurious compilation warnings (e.g. "variable used
1928
+ * uninitialized").
1929
+ */
1930
+ #define DUK_UNREACHABLE() /* unreachable */
1931
+ #endif
1932
+
1933
+ /*
1934
+ * Likely and unlikely branches. Using these is not at all a clear cut case,
1935
+ * so the selection is a two-step process: (1) DUK_USE_BRANCH_HINTS is set
1936
+ * if the architecture, compiler etc make it useful to use the hints, and (2)
1937
+ * a separate check determines how to do them.
1938
+ *
1939
+ * These macros expect the argument to be a relational expression with an
1940
+ * integer value. If used with pointers, you should use an explicit check
1941
+ * like:
1942
+ *
1943
+ * if (DUK_LIKELY(ptr != NULL)) { ... }
1944
+ *
1945
+ * instead of:
1946
+ *
1947
+ * if (DUK_LIKELY(ptr)) { ... }
1948
+ *
1949
+ * http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html (__builtin_expect)
1950
+ */
1951
+
1952
+ /* pretty much a placeholder now */
1953
+ #if defined(DUK_F_GCC)
1954
+ #define DUK_USE_BRANCH_HINTS
1955
+ #elif defined(DUK_F_CLANG)
1956
+ #define DUK_USE_BRANCH_HINTS
1957
+ #else
1958
+ #undef DUK_USE_BRANCH_HINTS
1959
+ #endif
1960
+
1961
+ #if defined(DUK_USE_BRANCH_HINTS)
1962
+ #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERISON >= 40500L)
1963
+ /* GCC: test not very accurate; enable only in relatively recent builds
1964
+ * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)
1965
+ */
1966
+ #define DUK_LIKELY(x) __builtin_expect((x), 1)
1967
+ #define DUK_UNLIKELY(x) __builtin_expect((x), 0)
1968
+ #elif defined(DUK_F_CLANG)
1969
+ #define DUK_LIKELY(x) __builtin_expect((x), 1)
1970
+ #define DUK_UNLIKELY(x) __builtin_expect((x), 0)
1971
+ #endif
1972
+ #endif /* DUK_USE_BRANCH_HINTS */
1973
+
1974
+ #if !defined(DUK_LIKELY)
1975
+ #define DUK_LIKELY(x) (x)
1976
+ #endif
1977
+ #if !defined(DUK_UNLIKELY)
1978
+ #define DUK_UNLIKELY(x) (x)
1979
+ #endif
1980
+
1981
+ /*
1982
+ * __FILE__, __LINE__, __func__ are wrapped. Especially __func__ is a
1983
+ * problem because it is not available even in some compilers which try
1984
+ * to be C99 compatible (e.g. VBCC with -c99 option).
1985
+ */
1986
+
1987
+ #define DUK_FILE_MACRO __FILE__
1988
+
1989
+ #define DUK_LINE_MACRO __LINE__
1990
+
1991
+ #if !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC)
1992
+ #define DUK_FUNC_MACRO __func__
1993
+ #else
1994
+ #define DUK_FUNC_MACRO "unknown"
1995
+ #endif
1996
+
1997
+ /*
1998
+ * Architecture string, human readable value exposed in Duktape.env
1999
+ */
2000
+
2001
+ #if defined(DUK_F_X86)
2002
+ #define DUK_USE_ARCH_STRING "x86"
2003
+ #elif defined(DUK_F_X32)
2004
+ #define DUK_USE_ARCH_STRING "x32"
2005
+ #elif defined(DUK_F_X64)
2006
+ #define DUK_USE_ARCH_STRING "x64"
2007
+ #elif defined(DUK_F_ARM)
2008
+ #define DUK_USE_ARCH_STRING "arm"
2009
+ #elif defined(DUK_F_MIPS)
2010
+ #define DUK_USE_ARCH_STRING "mips"
2011
+ #elif defined(DUK_F_M68K)
2012
+ #define DUK_USE_ARCH_STRING "m68k"
2013
+ #elif defined(DUK_F_FLASHPLAYER)
2014
+ #define DUK_USE_ARCH_STRING "flashplayer"
2015
+ #elif defined(DUK_F_EMSCRIPTEN)
2016
+ #define DUK_USE_ARCH_STRING "emscripten"
2017
+ #else
2018
+ #define DUK_USE_ARCH_STRING "unknown"
2019
+ #endif
2020
+
2021
+ /*
2022
+ * Tagged type representation (duk_tval)
2023
+ */
2024
+
2025
+ #undef DUK_USE_PACKED_TVAL
2026
+ #undef DUK_USE_FULL_TVAL
2027
+
2028
+ #if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && !defined(DUK_OPT_NO_PACKED_TVAL)
2029
+ #define DUK_USE_PACKED_TVAL
2030
+ #undef DUK_USE_FULL_TVAL
2031
+ #endif
2032
+
2033
+ /*
2034
+ * Memory management options
2035
+ */
2036
+
2037
+ #define DUK_USE_REFERENCE_COUNTING
2038
+ #define DUK_USE_DOUBLE_LINKED_HEAP
2039
+ #define DUK_USE_MARK_AND_SWEEP
2040
+ #define DUK_USE_MS_STRINGTABLE_RESIZE
2041
+ #undef DUK_USE_GC_TORTURE
2042
+
2043
+ #if defined(DUK_OPT_NO_REFERENCE_COUNTING)
2044
+ #undef DUK_USE_REFERENCE_COUNTING
2045
+ #undef DUK_USE_DOUBLE_LINKED_HEAP
2046
+ /* XXX: undef DUK_USE_MS_STRINGTABLE_RESIZE as it is more expensive
2047
+ * with more frequent mark-and-sweeps?
2048
+ */
2049
+ #endif
2050
+
2051
+ #if defined(DUK_OPT_NO_MARK_AND_SWEEP)
2052
+ #undef DUK_USE_MARK_AND_SWEEP
2053
+ #endif
2054
+
2055
+ #if defined(DUK_USE_MARK_AND_SWEEP)
2056
+ #define DUK_USE_VOLUNTARY_GC
2057
+ #if defined(DUK_OPT_NO_VOLUNTARY_GC)
2058
+ #undef DUK_USE_VOLUNTARY_GC
2059
+ #endif
2060
+ #endif
2061
+
2062
+ #if !defined(DUK_USE_MARK_AND_SWEEP) && !defined(DUK_USE_REFERENCE_COUNTING)
2063
+ #error must have either mark-and-sweep or reference counting enabled
2064
+ #endif
2065
+
2066
+ #if defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE)
2067
+ #undef DUK_USE_MS_STRINGTABLE_RESIZE
2068
+ #endif
2069
+
2070
+ #if defined(DUK_OPT_GC_TORTURE)
2071
+ #define DUK_USE_GC_TORTURE
2072
+ #endif
2073
+
2074
+ /*
2075
+ * Error handling options
2076
+ */
2077
+
2078
+ #define DUK_USE_AUGMENT_ERROR_CREATE
2079
+ #define DUK_USE_AUGMENT_ERROR_THROW
2080
+ #define DUK_USE_TRACEBACKS
2081
+ #define DUK_USE_ERRCREATE
2082
+ #define DUK_USE_ERRTHROW
2083
+
2084
+ #define DUK_USE_VERBOSE_ERRORS
2085
+
2086
+ #if defined(DUK_OPT_NO_AUGMENT_ERRORS)
2087
+ #undef DUK_USE_AUGMENT_ERROR_CREATE
2088
+ #undef DUK_USE_AUGMENT_ERROR_THROW
2089
+ #undef DUK_USE_TRACEBACKS
2090
+ #undef DUK_USE_ERRCREATE
2091
+ #undef DUK_USE_ERRTHROW
2092
+ #elif defined(DUK_OPT_NO_TRACEBACKS)
2093
+ #undef DUK_USE_TRACEBACKS
2094
+ #endif
2095
+
2096
+ #if defined(DUK_OPT_NO_VERBOSE_ERRORS)
2097
+ #undef DUK_USE_VERBOSE_ERRORS
2098
+ #endif
2099
+
2100
+ #if defined(DUK_USE_TRACEBACKS)
2101
+ #if defined(DUK_OPT_TRACEBACK_DEPTH)
2102
+ #define DUK_USE_TRACEBACK_DEPTH DUK_OPT_TRACEBACK_DEPTH
2103
+ #else
2104
+ #define DUK_USE_TRACEBACK_DEPTH 10
2105
+ #endif
2106
+ #endif
2107
+
2108
+ /* Include messages in executor internal errors. */
2109
+ #define DUK_USE_VERBOSE_EXECUTOR_ERRORS
2110
+
2111
+ /*
2112
+ * Execution and debugger options
2113
+ */
2114
+
2115
+ #define DUK_USE_INTERRUPT_COUNTER
2116
+ #if defined(DUK_OPT_NO_INTERRUPT_COUNTER)
2117
+ #undef DUK_USE_INTERRUPT_COUNTER
2118
+ #endif
2119
+
2120
+ /* For opcodes with indirect indices, check final index against stack size.
2121
+ * This should not be necessary because the compiler is trusted, and we don't
2122
+ * bound check non-indirect indices either.
2123
+ */
2124
+ #undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK
2125
+ #if defined(DUK_OPT_DEBUG) || defined(DUK_OPT_ASSERTIONS)
2126
+ /* Enabled with debug/assertions just so that any issues can be caught. */
2127
+ #define DUK_USE_EXEC_INDIRECT_BOUND_CHECK
2128
+ #endif
2129
+
2130
+ /*
2131
+ * Debug printing and assertion options
2132
+ */
2133
+
2134
+ #undef DUK_USE_DEBUG
2135
+ #undef DUK_USE_DPRINT
2136
+ #undef DUK_USE_DDPRINT
2137
+ #undef DUK_USE_DDDPRINT
2138
+ #undef DUK_USE_DPRINT_RDTSC
2139
+ #undef DUK_USE_ASSERTIONS
2140
+
2141
+ /* Global debug enable. Compile must be clean on C99 regardless of whether or
2142
+ * not debugging is enabled. On non-C99 platforms compile should be clean with
2143
+ * debugging disabled but may produce warnings with debugging enabled (related
2144
+ * to debug macro hackery and such).
2145
+ */
2146
+ #if defined(DUK_OPT_DEBUG)
2147
+ #define DUK_USE_DEBUG
2148
+ #endif
2149
+
2150
+ #if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DPRINT)
2151
+ #define DUK_USE_DPRINT
2152
+ #endif
2153
+ #if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DDPRINT)
2154
+ #define DUK_USE_DDPRINT
2155
+ #endif
2156
+ #if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DDDPRINT)
2157
+ #define DUK_USE_DDDPRINT
2158
+ #endif
2159
+
2160
+ #undef DUK_USE_DPRINT_COLORS
2161
+ #if defined(DUK_OPT_DPRINT_COLORS)
2162
+ #define DUK_USE_DPRINT_COLORS
2163
+ #endif
2164
+
2165
+ #if defined(DUK_RDTSC_AVAILABLE) && defined(DUK_OPT_DPRINT_RDTSC)
2166
+ #define DUK_USE_DPRINT_RDTSC
2167
+ #else
2168
+ #undef DUK_USE_DPRINT_RDTSC
2169
+ #endif
2170
+
2171
+ #if defined(DUK_OPT_ASSERTIONS)
2172
+ #define DUK_USE_ASSERTIONS
2173
+ #endif
2174
+
2175
+ /* The static buffer for debug printing is quite large by default, so there
2176
+ * is an option to shrink it manually for constrained builds.
2177
+ */
2178
+ #if defined(DUK_OPT_DEBUG_BUFSIZE)
2179
+ #define DUK_USE_DEBUG_BUFSIZE DUK_OPT_DEBUG_BUFSIZE
2180
+ #else
2181
+ #define DUK_USE_DEBUG_BUFSIZE 65536L
2182
+ #endif
2183
+
2184
+ /*
2185
+ * Ecmascript features / compliance options
2186
+ */
2187
+
2188
+ #if defined(DUK_F_BCC)
2189
+ /* Math built-in is stubbed out on BCC to allow compiler torture testing. */
2190
+ #else
2191
+ #define DUK_USE_MATH_BUILTIN
2192
+ #endif
2193
+
2194
+ #define DUK_USE_REGEXP_SUPPORT
2195
+ #if defined(DUK_OPT_NO_REGEXP_SUPPORT)
2196
+ #undef DUK_USE_REGEXP_SUPPORT
2197
+ #endif
2198
+
2199
+ #undef DUK_USE_STRICT_UTF8_SOURCE
2200
+ #if defined(DUK_OPT_STRICT_UTF8_SOURCE)
2201
+ #define DUK_USE_STRICT_UTF8_SOURCE
2202
+ #endif
2203
+
2204
+ #define DUK_USE_OCTAL_SUPPORT
2205
+ #if defined(DUK_OPT_NO_OCTAL_SUPPORT)
2206
+ #undef DUK_USE_OCTAL_SUPPORT
2207
+ #endif
2208
+
2209
+ #define DUK_USE_SOURCE_NONBMP
2210
+ #if defined(DUK_OPT_NO_SOURCE_NONBMP)
2211
+ #undef DUK_USE_SOURCE_NONBMP
2212
+ #endif
2213
+
2214
+ #define DUK_USE_BROWSER_LIKE
2215
+ #if defined(DUK_OPT_NO_BROWSER_LIKE)
2216
+ #undef DUK_USE_BROWSER_LIKE
2217
+ #endif
2218
+
2219
+ /* E5/E5.1 Section B features. */
2220
+ #define DUK_USE_SECTION_B
2221
+ #if defined(DUK_OPT_NO_SECTION_B)
2222
+ #undef DUK_USE_SECTION_B
2223
+ #endif
2224
+
2225
+ /* Non-standard regexp parsing features. */
2226
+ #define DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE
2227
+
2228
+ /* Treat function statements (function declarations outside top level of
2229
+ * Program or FunctionBody) same as normal function declarations. This is
2230
+ * also V8 behavior. See test-dev-func-decl-outside-top.js.
2231
+ */
2232
+ #define DUK_USE_NONSTD_FUNC_STMT
2233
+ #if defined(DUK_OPT_NO_NONSTD_FUNC_STMT)
2234
+ #undef DUK_USE_NONSTD_FUNC_STMT
2235
+ #endif
2236
+
2237
+ /* Array.prototype.splice() non-standard but real world compatible behavior
2238
+ * when deleteCount is omitted.
2239
+ */
2240
+ #define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT
2241
+ #if defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT)
2242
+ #undef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT
2243
+ #endif
2244
+
2245
+ /* Non-standard 'caller' property for function instances, see
2246
+ * test-bi-function-nonstd-caller-prop.js.
2247
+ */
2248
+ #undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
2249
+ #if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY)
2250
+ #define DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
2251
+ #endif
2252
+
2253
+ /* Non-standard Object.prototype.__proto__ (ES6 draft), see
2254
+ * test-bi-object-proto-__proto__.js.
2255
+ */
2256
+ #define DUK_USE_ES6_OBJECT_PROTO_PROPERTY
2257
+ #if defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY)
2258
+ #undef DUK_USE_ES6_OBJECT_PROTO_PROPERTY
2259
+ #endif
2260
+
2261
+ /* Non-standard Object.setPrototypeOf (ES6 draft), see
2262
+ * test-bi-object-setprototypeof.js.
2263
+ */
2264
+ #define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF
2265
+ #if defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF)
2266
+ #undef DUK_USE_ES6_OBJECT_SETPROTOTYPEOF
2267
+ #endif
2268
+
2269
+ /* ES6 Proxy object (subset for now). */
2270
+ #define DUK_USE_ES6_PROXY
2271
+ #if defined(DUK_OPT_NO_ES6_PROXY)
2272
+ #undef DUK_USE_ES6_PROXY
2273
+ #endif
2274
+
2275
+ /* Record pc-to-line information. */
2276
+ #define DUK_USE_PC2LINE
2277
+ #if defined(DUK_OPT_NO_PC2LINE)
2278
+ #undef DUK_USE_PC2LINE
2279
+ #endif
2280
+
2281
+ /* Non-standard function 'source' property. */
2282
+ #undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY
2283
+ #if defined(DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY)
2284
+ #define DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY
2285
+ #endif
2286
+
2287
+ /* CommonJS modules */
2288
+ #define DUK_USE_COMMONJS_MODULES
2289
+ #if defined(DUK_OPT_NO_COMMONJS_MODULES)
2290
+ #undef DUK_USE_COMMONJS_MODULES
2291
+ #endif
2292
+
2293
+ /* Additional key argument to setter/getter calls when triggered by property
2294
+ * accesses.
2295
+ */
2296
+
2297
+ #define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT
2298
+ #define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT
2299
+ #if defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT)
2300
+ #undef DUK_USE_NONSTD_GETTER_KEY_ARGUMENT
2301
+ #undef DUK_USE_NONSTD_SETTER_KEY_ARGUMENT
2302
+ #endif
2303
+
2304
+ /*
2305
+ * Tailcalls
2306
+ */
2307
+
2308
+ /* Tailcalls are enabled by default. The non-standard function 'caller'
2309
+ * property feature conflicts with tailcalls quite severely so tailcalls
2310
+ * are disabled if the 'caller' property is enabled.
2311
+ */
2312
+ #define DUK_USE_TAILCALL
2313
+ #if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
2314
+ #undef DUK_USE_TAILCALL
2315
+ #endif
2316
+
2317
+ /*
2318
+ * Deep vs. shallow stack.
2319
+ *
2320
+ * Some embedded platforms have very shallow stack (e.g. 64kB); default to
2321
+ * a shallow stack on unknown platforms or known embedded platforms.
2322
+ */
2323
+
2324
+ #if defined(DUK_F_LINUX) || defined(DUK_F_BSD) || defined(DUK_F_WINDOWS) || \
2325
+ defined(DUK_OPT_DEEP_C_STACK)
2326
+ #define DUK_USE_DEEP_C_STACK
2327
+ #else
2328
+ #undef DUK_USE_DEEP_C_STACK
2329
+ #endif
2330
+
2331
+ /*
2332
+ * Ecmascript compiler
2333
+ */
2334
+
2335
+ /* Ensure final bytecode never exceeds a certain byte size and never uses
2336
+ * line numbers above a certain limit. This ensures that there is no need
2337
+ * to deal with unbounded ranges in e.g. pc2line data structures. For now,
2338
+ * limits are set so that signed 32-bit values can represent line number
2339
+ * and byte offset with room to spare.
2340
+ */
2341
+ #define DUK_USE_ESBC_LIMITS
2342
+ #define DUK_USE_ESBC_MAX_LINENUMBER 0x7fff0000L
2343
+ #define DUK_USE_ESBC_MAX_BYTES 0x7fff0000L
2344
+
2345
+ /*
2346
+ * User panic handler, panic exit behavior for default panic handler
2347
+ */
2348
+
2349
+ #undef DUK_USE_PANIC_HANDLER
2350
+ #if defined(DUK_OPT_PANIC_HANDLER)
2351
+ #define DUK_USE_PANIC_HANDLER(code,msg) DUK_OPT_PANIC_HANDLER((code),(msg))
2352
+ #endif
2353
+
2354
+ #undef DUK_USE_PANIC_ABORT
2355
+ #undef DUK_USE_PANIC_EXIT
2356
+ #undef DUK_USE_PANIC_SEGFAULT
2357
+
2358
+ #if defined(DUK_OPT_SEGFAULT_ON_PANIC)
2359
+ #define DUK_USE_PANIC_SEGFAULT
2360
+ #else
2361
+ #define DUK_USE_PANIC_ABORT
2362
+ #endif
2363
+
2364
+ /*
2365
+ * File I/O support. This is now used in a few API calls to e.g. push
2366
+ * a string from file contents or eval a file. For portability it must
2367
+ * be possible to disable I/O altogether.
2368
+ */
2369
+
2370
+ #undef DUK_USE_FILE_IO
2371
+ #if !defined(DUK_OPT_NO_FILE_IO)
2372
+ #define DUK_USE_FILE_IO
2373
+ #endif
2374
+
2375
+ /*
2376
+ * Optional run-time self tests executed when a heap is created. Some
2377
+ * platform/compiler issues cannot be determined at compile time. One
2378
+ * particular example is the bug described in misc/clang_aliasing.c.
2379
+ */
2380
+
2381
+ #undef DUK_USE_SELF_TESTS
2382
+ #if defined(DUK_OPT_SELF_TESTS)
2383
+ #define DUK_USE_SELF_TESTS
2384
+ #endif
2385
+
2386
+ /* Double aliasing testcase fails when Emscripten-generated code is run
2387
+ * on Firefox. This is not fatal because it only affects packed duk_tval
2388
+ * which we avoid with Emscripten.
2389
+ */
2390
+ #undef DUK_USE_NO_DOUBLE_ALIASING_SELFTEST
2391
+ #if defined(DUK_F_EMSCRIPTEN)
2392
+ #define DUK_USE_NO_DOUBLE_ALIASING_SELFTEST
2393
+ #endif
2394
+
2395
+ /*
2396
+ * Codecs
2397
+ */
2398
+
2399
+ #define DUK_USE_JX
2400
+ #if defined(DUK_OPT_NO_JX)
2401
+ #undef DUK_USE_JX
2402
+ #endif
2403
+
2404
+ #define DUK_USE_JC
2405
+ #if defined(DUK_OPT_NO_JC)
2406
+ #undef DUK_USE_JC
2407
+ #endif
2408
+
2409
+ /*
2410
+ * InitJS code
2411
+ */
2412
+
2413
+ /* Always use the built-in InitJS code for now. */
2414
+ #define DUK_USE_BUILTIN_INITJS
2415
+
2416
+ /* User provided InitJS. */
2417
+ #undef DUK_USE_USER_INITJS
2418
+ #if defined(DUK_OPT_USER_INITJS)
2419
+ #define DUK_USE_USER_INITJS (DUK_OPT_USER_INITJS)
2420
+ #endif
2421
+
2422
+ /*
2423
+ * Miscellaneous
2424
+ */
2425
+
2426
+ #define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS
2427
+ #undef DUK_USE_EXPLICIT_NULL_INIT
2428
+
2429
+ #if !defined(DUK_USE_PACKED_TVAL)
2430
+ #define DUK_USE_EXPLICIT_NULL_INIT
2431
+ #endif
2432
+
2433
+ #define DUK_USE_ZERO_BUFFER_DATA
2434
+ #if defined(DUK_OPT_NO_ZERO_BUFFER_DATA)
2435
+ #undef DUK_USE_ZERO_BUFFER_DATA
2436
+ #endif
2437
+
2438
+ #if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__))
2439
+ #define DUK_USE_VARIADIC_MACROS
2440
+ #else
2441
+ #undef DUK_USE_VARIADIC_MACROS
2442
+ #endif
2443
+
2444
+ /*
2445
+ * Variable size array initialization.
2446
+ *
2447
+ * Variable size array at the end of a structure is nonportable.
2448
+ * There are three alternatives:
2449
+ *
2450
+ * 1) C99 (flexible array member): char buf[]
2451
+ * 2) Compiler specific (e.g. GCC): char buf[0]
2452
+ * 3) Portable but wastes memory / complicates allocation: char buf[1]
2453
+ */
2454
+
2455
+ /* XXX: Currently unused, only hbuffer.h needed this at some point. */
2456
+ #undef DUK_USE_FLEX_C99
2457
+ #undef DUK_USE_FLEX_ZEROSIZE
2458
+ #undef DUK_USE_FLEX_ONESIZE
2459
+ #if defined(DUK_F_C99)
2460
+ #define DUK_USE_FLEX_C99
2461
+ #elif defined(__GNUC__)
2462
+ #define DUK_USE_FLEX_ZEROSIZE
2463
+ #else
2464
+ #define DUK_USE_FLEX_ONESIZE
2465
+ #endif
2466
+
2467
+ /*
2468
+ * GCC pragmas
2469
+ */
2470
+
2471
+ /* XXX: GCC pragma inside a function fails in some earlier GCC versions (e.g. gcc 4.5).
2472
+ * This is very approximate but allows clean builds for development right now.
2473
+ */
2474
+ /* http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html */
2475
+ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)
2476
+ #define DUK_USE_GCC_PRAGMAS
2477
+ #else
2478
+ #undef DUK_USE_GCC_PRAGMAS
2479
+ #endif
2480
+
2481
+ /*
2482
+ * User declarations
2483
+ */
2484
+
2485
+ #if defined(DUK_OPT_DECLARE)
2486
+ #define DUK_USE_USER_DECLARE() DUK_OPT_DECLARE
2487
+ #else
2488
+ #define DUK_USE_USER_DECLARE() /* no user declarations */
2489
+ #endif
2490
+
2491
+ /*
2492
+ * Alternative customization header
2493
+ *
2494
+ * If you want to modify the final DUK_USE_xxx flags directly (without
2495
+ * using the available DUK_OPT_Xxx flags), define DUK_OPT_HAVE_CUSTOM_H
2496
+ * and tweak the final flags there.
2497
+ */
2498
+
2499
+ #if defined(DUK_OPT_HAVE_CUSTOM_H)
2500
+ #include "duk_custom.h"
2501
+ #endif
2502
+
2503
+ #endif /* DUK_FEATURES_H_INCLUDED */
2504
+
2505
+ /*
2506
+ * BEGIN PUBLIC API
2507
+ */
2508
+
2509
+ #ifndef DUK_API_PUBLIC_H_INCLUDED
2510
+ #define DUK_API_PUBLIC_H_INCLUDED
2511
+
2512
+ /*
2513
+ * Avoid C++ name mangling
2514
+ */
2515
+
2516
+ #ifdef __cplusplus
2517
+ extern "C" {
2518
+ #endif
2519
+
2520
+ /*
2521
+ * Some defines forwarded from feature detection
2522
+ */
2523
+
2524
+ #undef DUK_API_VARIADIC_MACROS
2525
+ #ifdef DUK_USE_VARIADIC_MACROS
2526
+ #define DUK_API_VARIADIC_MACROS
2527
+ #endif
2528
+
2529
+ #define DUK_API_NORETURN(decl) DUK_NORETURN(decl)
2530
+
2531
+ /*
2532
+ * Public API specific typedefs
2533
+ *
2534
+ * (duk_context *) maps directly to internal type (duk_hthread *).
2535
+ * Currently only primitive typedefs have a '_t' suffix.
2536
+ *
2537
+ * Many types are wrapped by Duktape for portability to rare platforms
2538
+ * where e.g. 'int' is a 16-bit type. See practical typing discussion
2539
+ * in Duktape web documentation.
2540
+ */
2541
+
2542
+ struct duk_memory_functions;
2543
+ struct duk_function_list_entry;
2544
+ struct duk_number_list_entry;
2545
+
2546
+ typedef void duk_context;
2547
+ typedef struct duk_memory_functions duk_memory_functions;
2548
+ typedef struct duk_function_list_entry duk_function_list_entry;
2549
+ typedef struct duk_number_list_entry duk_number_list_entry;
2550
+
2551
+ typedef duk_ret_t (*duk_c_function)(duk_context *ctx);
2552
+ typedef void *(*duk_alloc_function) (void *udata, duk_size_t size);
2553
+ typedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size);
2554
+ typedef void (*duk_free_function) (void *udata, void *ptr);
2555
+ typedef void (*duk_fatal_function) (duk_context *ctx, duk_errcode_t code, const char *msg);
2556
+ typedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint);
2557
+ typedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint);
2558
+ typedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx);
2559
+
2560
+ struct duk_memory_functions {
2561
+ duk_alloc_function alloc;
2562
+ duk_realloc_function realloc;
2563
+ duk_free_function free;
2564
+ void *udata;
2565
+ };
2566
+
2567
+ struct duk_function_list_entry {
2568
+ const char *key;
2569
+ duk_c_function value;
2570
+ duk_int_t nargs;
2571
+ };
2572
+
2573
+ struct duk_number_list_entry {
2574
+ const char *key;
2575
+ duk_double_t value;
2576
+ };
2577
+
2578
+ /*
2579
+ * Constants
2580
+ */
2581
+
2582
+ /* Duktape version, (major * 10000) + (minor * 100) + patch. Allows C code
2583
+ * to #ifdef against Duktape API version. The same value is also available
2584
+ * to Ecmascript code in Duktape.version. Unofficial development snapshots
2585
+ * have 99 for patch level (e.g. 0.10.99 would be a development version
2586
+ * after 0.10.0 but before the next official release).
2587
+ */
2588
+ #define DUK_VERSION 1100L
2589
+
2590
+ /* Used to represent invalid index; if caller uses this without checking,
2591
+ * this index will map to a non-existent stack entry. Also used in some
2592
+ * API calls as a marker to denote "no value".
2593
+ */
2594
+ #define DUK_INVALID_INDEX INT_MIN
2595
+
2596
+ /* Indicates that a native function does not have a fixed number of args,
2597
+ * and the argument stack should not be capped/extended at all.
2598
+ */
2599
+ #define DUK_VARARGS ((duk_int_t) (-1))
2600
+
2601
+ /* Number of value stack entries (in addition to actual call arguments)
2602
+ * guaranteed to be allocated on entry to a Duktape/C function.
2603
+ */
2604
+ #define DUK_API_ENTRY_STACK 64
2605
+
2606
+ /* Value types, used by e.g. duk_get_type() */
2607
+ #define DUK_TYPE_NONE 0 /* no value, e.g. invalid index */
2608
+ #define DUK_TYPE_UNDEFINED 1 /* Ecmascript undefined */
2609
+ #define DUK_TYPE_NULL 2 /* Ecmascript null */
2610
+ #define DUK_TYPE_BOOLEAN 3 /* Ecmascript boolean: 0 or 1 */
2611
+ #define DUK_TYPE_NUMBER 4 /* Ecmascript number: double */
2612
+ #define DUK_TYPE_STRING 5 /* Ecmascript string: CESU-8 / extended UTF-8 encoded */
2613
+ #define DUK_TYPE_OBJECT 6 /* Ecmascript object: includes objects, arrays, functions, threads */
2614
+ #define DUK_TYPE_BUFFER 7 /* fixed or dynamic, garbage collected byte buffer */
2615
+ #define DUK_TYPE_POINTER 8 /* raw void pointer */
2616
+
2617
+ /* Value mask types, used by e.g. duk_get_type_mask() */
2618
+ #define DUK_TYPE_MASK_NONE (1 << DUK_TYPE_NONE)
2619
+ #define DUK_TYPE_MASK_UNDEFINED (1 << DUK_TYPE_UNDEFINED)
2620
+ #define DUK_TYPE_MASK_NULL (1 << DUK_TYPE_NULL)
2621
+ #define DUK_TYPE_MASK_BOOLEAN (1 << DUK_TYPE_BOOLEAN)
2622
+ #define DUK_TYPE_MASK_NUMBER (1 << DUK_TYPE_NUMBER)
2623
+ #define DUK_TYPE_MASK_STRING (1 << DUK_TYPE_STRING)
2624
+ #define DUK_TYPE_MASK_OBJECT (1 << DUK_TYPE_OBJECT)
2625
+ #define DUK_TYPE_MASK_BUFFER (1 << DUK_TYPE_BUFFER)
2626
+ #define DUK_TYPE_MASK_POINTER (1 << DUK_TYPE_POINTER)
2627
+ #define DUK_TYPE_MASK_THROW (1 << 10) /* internal flag value: throw if mask doesn't match */
2628
+
2629
+ /* Coercion hints */
2630
+ #define DUK_HINT_NONE 0 /* prefer number, unless input is a Date, in which
2631
+ * case prefer string (E5 Section 8.12.8)
2632
+ */
2633
+ #define DUK_HINT_STRING 1 /* prefer string */
2634
+ #define DUK_HINT_NUMBER 2 /* prefer number */
2635
+
2636
+ /* Enumeration flags for duk_enum() */
2637
+ #define DUK_ENUM_INCLUDE_NONENUMERABLE (1 << 0) /* enumerate non-numerable properties in addition to enumerable */
2638
+ #define DUK_ENUM_INCLUDE_INTERNAL (1 << 1) /* enumerate internal properties (regardless of enumerability) */
2639
+ #define DUK_ENUM_OWN_PROPERTIES_ONLY (1 << 2) /* don't walk prototype chain, only check own properties */
2640
+ #define DUK_ENUM_ARRAY_INDICES_ONLY (1 << 3) /* only enumerate array indices */
2641
+ #define DUK_ENUM_SORT_ARRAY_INDICES (1 << 4) /* sort array indices, use with DUK_ENUM_ARRAY_INDICES_ONLY */
2642
+ #define DUK_ENUM_NO_PROXY_BEHAVIOR (1 << 5) /* enumerate a proxy object itself without invoking proxy behavior */
2643
+
2644
+ /* Compilation flags for duk_compile() and duk_eval() */
2645
+ #define DUK_COMPILE_EVAL (1 << 0) /* compile eval code (instead of program) */
2646
+ #define DUK_COMPILE_FUNCTION (1 << 1) /* compile function code (instead of program) */
2647
+ #define DUK_COMPILE_STRICT (1 << 2) /* use strict (outer) context for program, eval, or function */
2648
+ #define DUK_COMPILE_SAFE (1 << 3) /* (internal) catch compilation errors */
2649
+ #define DUK_COMPILE_NORESULT (1 << 4) /* (internal) omit eval result */
2650
+ #define DUK_COMPILE_NOSOURCE (1 << 5) /* (internal) no source string on stack */
2651
+ #define DUK_COMPILE_STRLEN (1 << 6) /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */
2652
+
2653
+ /* Flags for duk_push_thread_raw() */
2654
+ #define DUK_THREAD_NEW_GLOBAL_ENV (1 << 0) /* create a new global environment */
2655
+
2656
+ /* Duktape specific error codes */
2657
+ #define DUK_ERR_UNIMPLEMENTED_ERROR 50 /* UnimplementedError */
2658
+ #define DUK_ERR_UNSUPPORTED_ERROR 51 /* UnsupportedError */
2659
+ #define DUK_ERR_INTERNAL_ERROR 52 /* InternalError */
2660
+ #define DUK_ERR_ALLOC_ERROR 53 /* AllocError */
2661
+ #define DUK_ERR_ASSERTION_ERROR 54 /* AssertionError */
2662
+ #define DUK_ERR_API_ERROR 55 /* APIError */
2663
+ #define DUK_ERR_UNCAUGHT_ERROR 56 /* UncaughtError */
2664
+
2665
+ /* Ecmascript E5 specification error codes */
2666
+ #define DUK_ERR_ERROR 100 /* Error */
2667
+ #define DUK_ERR_EVAL_ERROR 101 /* EvalError */
2668
+ #define DUK_ERR_RANGE_ERROR 102 /* RangeError */
2669
+ #define DUK_ERR_REFERENCE_ERROR 103 /* ReferenceError */
2670
+ #define DUK_ERR_SYNTAX_ERROR 104 /* SyntaxError */
2671
+ #define DUK_ERR_TYPE_ERROR 105 /* TypeError */
2672
+ #define DUK_ERR_URI_ERROR 106 /* URIError */
2673
+
2674
+ /* Return codes for C functions (shortcut for throwing an error) */
2675
+ #define DUK_RET_UNIMPLEMENTED_ERROR (-DUK_ERR_UNIMPLEMENTED_ERROR)
2676
+ #define DUK_RET_UNSUPPORTED_ERROR (-DUK_ERR_UNSUPPORTED_ERROR)
2677
+ #define DUK_RET_INTERNAL_ERROR (-DUK_ERR_INTERNAL_ERROR)
2678
+ #define DUK_RET_ALLOC_ERROR (-DUK_ERR_ALLOC_ERROR)
2679
+ #define DUK_RET_ASSERTION_ERROR (-DUK_ERR_ASSERTION_ERROR)
2680
+ #define DUK_RET_API_ERROR (-DUK_ERR_API_ERROR)
2681
+ #define DUK_RET_UNCAUGHT_ERROR (-DUK_ERR_UNCAUGHT_ERROR)
2682
+ #define DUK_RET_ERROR (-DUK_ERR_ERROR)
2683
+ #define DUK_RET_EVAL_ERROR (-DUK_ERR_EVAL_ERROR)
2684
+ #define DUK_RET_RANGE_ERROR (-DUK_ERR_RANGE_ERROR)
2685
+ #define DUK_RET_REFERENCE_ERROR (-DUK_ERR_REFERENCE_ERROR)
2686
+ #define DUK_RET_SYNTAX_ERROR (-DUK_ERR_SYNTAX_ERROR)
2687
+ #define DUK_RET_TYPE_ERROR (-DUK_ERR_TYPE_ERROR)
2688
+ #define DUK_RET_URI_ERROR (-DUK_ERR_URI_ERROR)
2689
+
2690
+ /* Return codes for protected calls (duk_safe_call(), duk_pcall()). */
2691
+ #define DUK_EXEC_SUCCESS 0
2692
+ #define DUK_EXEC_ERROR 1
2693
+
2694
+ /* Log levels */
2695
+ #define DUK_LOG_TRACE 0
2696
+ #define DUK_LOG_DEBUG 1
2697
+ #define DUK_LOG_INFO 2
2698
+ #define DUK_LOG_WARN 3
2699
+ #define DUK_LOG_ERROR 4
2700
+ #define DUK_LOG_FATAL 5
2701
+
2702
+ /*
2703
+ * If no variadic macros, __FILE__ and __LINE__ are passed through globals
2704
+ * which is ugly and not thread safe.
2705
+ */
2706
+
2707
+ #ifndef DUK_API_VARIADIC_MACROS
2708
+ extern const char *duk_api_global_filename;
2709
+ extern duk_int_t duk_api_global_line;
2710
+ #endif
2711
+
2712
+ /*
2713
+ * Context management
2714
+ */
2715
+
2716
+ duk_context *duk_create_heap(duk_alloc_function alloc_func,
2717
+ duk_realloc_function realloc_func,
2718
+ duk_free_function free_func,
2719
+ void *alloc_udata,
2720
+ duk_fatal_function fatal_handler);
2721
+ void duk_destroy_heap(duk_context *ctx);
2722
+
2723
+ #define duk_create_heap_default() \
2724
+ duk_create_heap(NULL, NULL, NULL, NULL, NULL)
2725
+
2726
+ /*
2727
+ * Memory management
2728
+ *
2729
+ * Raw functions have no side effects (cannot trigger GC).
2730
+ */
2731
+
2732
+ void *duk_alloc_raw(duk_context *ctx, duk_size_t size);
2733
+ void duk_free_raw(duk_context *ctx, void *ptr);
2734
+ void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size);
2735
+ void *duk_alloc(duk_context *ctx, duk_size_t size);
2736
+ void duk_free(duk_context *ctx, void *ptr);
2737
+ void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size);
2738
+ void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs);
2739
+ void duk_gc(duk_context *ctx, duk_uint_t flags);
2740
+
2741
+ /*
2742
+ * Error handling
2743
+ */
2744
+
2745
+ DUK_API_NORETURN(void duk_throw(duk_context *ctx));
2746
+
2747
+ DUK_API_NORETURN(void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...));
2748
+ #ifdef DUK_API_VARIADIC_MACROS
2749
+ #define duk_error(ctx,err_code,...) \
2750
+ duk_error_raw((ctx), (duk_errcode_t) (err_code), __FILE__, (duk_int_t) __LINE__, __VA_ARGS__)
2751
+ #else
2752
+ DUK_API_NORETURN(void duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...));
2753
+ #define duk_error \
2754
+ duk_api_global_filename = __FILE__, \
2755
+ duk_api_global_line = (duk_int_t) __LINE__, \
2756
+ duk_error_stash /* arguments follow */
2757
+ #endif
2758
+
2759
+ DUK_API_NORETURN(void duk_fatal(duk_context *ctx, duk_errcode_t err_code, const char *err_msg));
2760
+
2761
+ /*
2762
+ * Other state related functions
2763
+ */
2764
+
2765
+ duk_bool_t duk_is_strict_call(duk_context *ctx);
2766
+ duk_bool_t duk_is_constructor_call(duk_context *ctx);
2767
+ duk_int_t duk_get_magic(duk_context *ctx);
2768
+
2769
+ /*
2770
+ * Stack management
2771
+ */
2772
+
2773
+ duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t index);
2774
+ duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index);
2775
+ duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t index);
2776
+ void duk_require_valid_index(duk_context *ctx, duk_idx_t index);
2777
+
2778
+ duk_idx_t duk_get_top(duk_context *ctx);
2779
+ void duk_set_top(duk_context *ctx, duk_idx_t index);
2780
+ duk_idx_t duk_get_top_index(duk_context *ctx);
2781
+ duk_idx_t duk_require_top_index(duk_context *ctx);
2782
+
2783
+ /* Although extra/top could be an unsigned type here, using a signed type
2784
+ * makes the API more robust to calling code calculation errors or corner
2785
+ * cases (where caller might occasionally come up with negative values).
2786
+ * Negative values are treated as zero, which is better than casting them
2787
+ * to a large unsigned number. (This principle is used elsewhere in the
2788
+ * API too.)
2789
+ */
2790
+ duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra);
2791
+ void duk_require_stack(duk_context *ctx, duk_idx_t extra);
2792
+ duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top);
2793
+ void duk_require_stack_top(duk_context *ctx, duk_idx_t top);
2794
+
2795
+ /*
2796
+ * Stack manipulation (other than push/pop)
2797
+ */
2798
+
2799
+ void duk_swap(duk_context *ctx, duk_idx_t index1, duk_idx_t index2);
2800
+ void duk_swap_top(duk_context *ctx, duk_idx_t index);
2801
+ void duk_dup(duk_context *ctx, duk_idx_t from_index);
2802
+ void duk_dup_top(duk_context *ctx);
2803
+ void duk_insert(duk_context *ctx, duk_idx_t to_index);
2804
+ void duk_replace(duk_context *ctx, duk_idx_t to_index);
2805
+ void duk_copy(duk_context *ctx, duk_idx_t from_index, duk_idx_t to_index);
2806
+ void duk_remove(duk_context *ctx, duk_idx_t index);
2807
+ /* FIXME: undocumented */
2808
+ void duk_xmove(duk_context *from_ctx, duk_context *to_ctx, duk_idx_t count);
2809
+
2810
+ /*
2811
+ * Push operations
2812
+ *
2813
+ * Push functions return the absolute (relative to bottom of frame)
2814
+ * position of the pushed value for convenience.
2815
+ *
2816
+ * Note: duk_dup() is technically a push.
2817
+ */
2818
+
2819
+ void duk_push_undefined(duk_context *ctx);
2820
+ void duk_push_null(duk_context *ctx);
2821
+ void duk_push_boolean(duk_context *ctx, duk_bool_t val);
2822
+ void duk_push_true(duk_context *ctx);
2823
+ void duk_push_false(duk_context *ctx);
2824
+ void duk_push_number(duk_context *ctx, duk_double_t val);
2825
+ void duk_push_nan(duk_context *ctx);
2826
+ void duk_push_int(duk_context *ctx, duk_int_t val);
2827
+ void duk_push_uint(duk_context *ctx, duk_uint_t val);
2828
+ const char *duk_push_string(duk_context *ctx, const char *str);
2829
+ const char *duk_push_string_file(duk_context *ctx, const char *path);
2830
+ const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);
2831
+ void duk_push_pointer(duk_context *ctx, void *p);
2832
+ const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);
2833
+ const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);
2834
+
2835
+ void duk_push_this(duk_context *ctx);
2836
+ void duk_push_current_function(duk_context *ctx);
2837
+ void duk_push_current_thread(duk_context *ctx);
2838
+ void duk_push_global_object(duk_context *ctx);
2839
+ void duk_push_heap_stash(duk_context *ctx);
2840
+ void duk_push_global_stash(duk_context *ctx);
2841
+ void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx);
2842
+
2843
+ duk_idx_t duk_push_object(duk_context *ctx);
2844
+ duk_idx_t duk_push_array(duk_context *ctx);
2845
+ duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);
2846
+ duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);
2847
+
2848
+ #define duk_push_thread(ctx) \
2849
+ duk_push_thread_raw((ctx), 0 /*flags*/)
2850
+
2851
+ #define duk_push_thread_new_globalenv(ctx) \
2852
+ duk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/)
2853
+
2854
+ duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...);
2855
+ #ifdef DUK_API_VARIADIC_MACROS
2856
+ #define duk_push_error_object(ctx,err_code,...) \
2857
+ duk_push_error_object_raw((ctx),(err_code),__FILE__,__LINE__,__VA_ARGS__)
2858
+ #else
2859
+ duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...);
2860
+ #define duk_push_error_object \
2861
+ duk_api_global_filename = __FILE__, \
2862
+ duk_api_global_line = __LINE__, \
2863
+ duk_push_error_object_stash /* arguments follow */
2864
+ #endif
2865
+
2866
+ void *duk_push_buffer(duk_context *ctx, duk_size_t size, duk_bool_t dynamic);
2867
+ void *duk_push_fixed_buffer(duk_context *ctx, duk_size_t size);
2868
+ void *duk_push_dynamic_buffer(duk_context *ctx, duk_size_t size);
2869
+
2870
+ /*
2871
+ * Pop operations
2872
+ */
2873
+
2874
+ void duk_pop(duk_context *ctx);
2875
+ void duk_pop_n(duk_context *ctx, duk_idx_t count);
2876
+ void duk_pop_2(duk_context *ctx);
2877
+ void duk_pop_3(duk_context *ctx);
2878
+
2879
+ /*
2880
+ * Type checks
2881
+ *
2882
+ * duk_is_none(), which would indicate whether index it outside of stack,
2883
+ * is not needed; duk_is_valid_index() gives the same information.
2884
+ */
2885
+
2886
+ /* FIXME: a duk_small_int_t suffices to represent type and type mask (at least now). */
2887
+ duk_int_t duk_get_type(duk_context *ctx, duk_idx_t index);
2888
+ duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t index, duk_int_t type);
2889
+ duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t index);
2890
+ duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t index, duk_uint_t mask);
2891
+
2892
+ duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index);
2893
+ duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t index);
2894
+ duk_bool_t duk_is_null_or_undefined(duk_context *ctx, duk_idx_t index);
2895
+ duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t index);
2896
+ duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t index);
2897
+ duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t index);
2898
+ duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index);
2899
+ duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t index);
2900
+ duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t index);
2901
+ duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t index);
2902
+
2903
+ duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t index);
2904
+ duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t index);
2905
+ duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t index);
2906
+ duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t index);
2907
+ duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t index);
2908
+ duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t index);
2909
+
2910
+ duk_bool_t duk_is_callable(duk_context *ctx, duk_idx_t index);
2911
+ duk_bool_t duk_is_dynamic(duk_context *ctx, duk_idx_t index);
2912
+ duk_bool_t duk_is_fixed(duk_context *ctx, duk_idx_t index);
2913
+
2914
+ duk_bool_t duk_is_primitive(duk_context *ctx, duk_idx_t index);
2915
+ #define duk_is_object_coercible(ctx,index) \
2916
+ duk_check_type_mask((ctx), (index), DUK_TYPE_MASK_BOOLEAN | \
2917
+ DUK_TYPE_MASK_NUMBER | \
2918
+ DUK_TYPE_MASK_STRING | \
2919
+ DUK_TYPE_MASK_OBJECT | \
2920
+ DUK_TYPE_MASK_BUFFER | \
2921
+ DUK_TYPE_MASK_POINTER)
2922
+
2923
+ /*
2924
+ * Get operations: no coercion, returns default value for invalid
2925
+ * indices and invalid value types.
2926
+ *
2927
+ * duk_get_undefined() and duk_get_null() would be pointless and
2928
+ * are not included.
2929
+ */
2930
+
2931
+ duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t index);
2932
+ duk_double_t duk_get_number(duk_context *ctx, duk_idx_t index);
2933
+ duk_int_t duk_get_int(duk_context *ctx, duk_idx_t index);
2934
+ duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t index);
2935
+ const char *duk_get_string(duk_context *ctx, duk_idx_t index);
2936
+ const char *duk_get_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len);
2937
+ void *duk_get_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size);
2938
+ void *duk_get_pointer(duk_context *ctx, duk_idx_t index);
2939
+ duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t index);
2940
+ duk_context *duk_get_context(duk_context *ctx, duk_idx_t index);
2941
+ duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index);
2942
+
2943
+ /*
2944
+ * Require operations: no coercion, throw error if index or type
2945
+ * is incorrect. No defaulting.
2946
+ */
2947
+
2948
+ #define duk_require_type_mask(ctx,index,mask) \
2949
+ ((void) duk_check_type_mask((ctx), (index), (mask) | DUK_TYPE_MASK_THROW))
2950
+
2951
+ void duk_require_undefined(duk_context *ctx, duk_idx_t index);
2952
+ void duk_require_null(duk_context *ctx, duk_idx_t index);
2953
+ duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t index);
2954
+ duk_double_t duk_require_number(duk_context *ctx, duk_idx_t index);
2955
+ duk_int_t duk_require_int(duk_context *ctx, duk_idx_t index);
2956
+ duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t index);
2957
+ const char *duk_require_string(duk_context *ctx, duk_idx_t index);
2958
+ const char *duk_require_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len);
2959
+ void *duk_require_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size);
2960
+ void *duk_require_pointer(duk_context *ctx, duk_idx_t index);
2961
+ duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t index);
2962
+ duk_context *duk_require_context(duk_context *ctx, duk_idx_t index);
2963
+
2964
+ #define duk_require_object_coercible(ctx,index) \
2965
+ ((void) duk_check_type_mask((ctx), (index), DUK_TYPE_MASK_BOOLEAN | \
2966
+ DUK_TYPE_MASK_NUMBER | \
2967
+ DUK_TYPE_MASK_STRING | \
2968
+ DUK_TYPE_MASK_OBJECT | \
2969
+ DUK_TYPE_MASK_BUFFER | \
2970
+ DUK_TYPE_MASK_POINTER | \
2971
+ DUK_TYPE_MASK_THROW))
2972
+
2973
+ /*
2974
+ * Coercion operations: in-place coercion, return coerced value where
2975
+ * applicable. If index is invalid, throw error. Some coercions may
2976
+ * throw an expected error (e.g. from a toString() or valueOf() call)
2977
+ * or an internal error (e.g. from out of memory).
2978
+ */
2979
+
2980
+ void duk_to_undefined(duk_context *ctx, duk_idx_t index);
2981
+ void duk_to_null(duk_context *ctx, duk_idx_t index);
2982
+ duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t index);
2983
+ duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index);
2984
+ duk_int_t duk_to_int(duk_context *ctx, duk_idx_t index);
2985
+ duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t index);
2986
+ duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t index);
2987
+ duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t index);
2988
+ duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t index);
2989
+ const char *duk_to_string(duk_context *ctx, duk_idx_t index);
2990
+ const char *duk_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len);
2991
+ void *duk_to_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size);
2992
+ void *duk_to_fixed_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size);
2993
+ void *duk_to_dynamic_buffer(duk_context *ctx, duk_idx_t index, duk_size_t *out_size);
2994
+ void *duk_to_pointer(duk_context *ctx, duk_idx_t index);
2995
+ void duk_to_object(duk_context *ctx, duk_idx_t index);
2996
+ void duk_to_defaultvalue(duk_context *ctx, duk_idx_t index, duk_int_t hint); /* FIXME: small int? */
2997
+ void duk_to_primitive(duk_context *ctx, duk_idx_t index, duk_int_t hint); /* FIXME: small int? */
2998
+
2999
+ /* safe variants of a few coercion operations */
3000
+ const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t index, duk_size_t *out_len);
3001
+ #define duk_safe_to_string(ctx,index) \
3002
+ duk_safe_to_lstring((ctx), (index), NULL)
3003
+
3004
+ /*
3005
+ * Misc conversion
3006
+ */
3007
+
3008
+ const char *duk_base64_encode(duk_context *ctx, duk_idx_t index);
3009
+ void duk_base64_decode(duk_context *ctx, duk_idx_t index);
3010
+ const char *duk_hex_encode(duk_context *ctx, duk_idx_t index);
3011
+ void duk_hex_decode(duk_context *ctx, duk_idx_t index);
3012
+ const char *duk_json_encode(duk_context *ctx, duk_idx_t index);
3013
+ void duk_json_decode(duk_context *ctx, duk_idx_t index);
3014
+
3015
+ /*
3016
+ * Buffer
3017
+ */
3018
+
3019
+ void *duk_resize_buffer(duk_context *ctx, duk_idx_t index, duk_size_t new_size);
3020
+
3021
+ /*
3022
+ * Property access
3023
+ *
3024
+ * The basic function assumes key is on stack. The _string variant takes
3025
+ * a C string as a property name, while the _index variant takes an array
3026
+ * index as a property name (e.g. 123 is equivalent to the key "123").
3027
+ */
3028
+
3029
+ duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_index);
3030
+ duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key);
3031
+ duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index);
3032
+ duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_index);
3033
+ duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key);
3034
+ duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index);
3035
+ duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index);
3036
+ duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key);
3037
+ duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index);
3038
+ duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_index);
3039
+ duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key);
3040
+ duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index);
3041
+
3042
+ duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);
3043
+
3044
+ /*
3045
+ * Module helpers: put multiple function or constant properties
3046
+ */
3047
+
3048
+ void duk_put_function_list(duk_context *ctx, duk_idx_t obj_index, const duk_function_list_entry *funcs);
3049
+ void duk_put_number_list(duk_context *ctx, duk_idx_t obj_index, const duk_number_list_entry *numbers);
3050
+
3051
+ /*
3052
+ * Variable access
3053
+ */
3054
+
3055
+ /* FIXME: incomplete, not usable now */
3056
+ void duk_get_var(duk_context *ctx);
3057
+ void duk_put_var(duk_context *ctx);
3058
+ duk_bool_t duk_del_var(duk_context *ctx);
3059
+ duk_bool_t duk_has_var(duk_context *ctx);
3060
+
3061
+ /*
3062
+ * Object operations
3063
+ */
3064
+
3065
+ void duk_compact(duk_context *ctx, duk_idx_t obj_index);
3066
+ void duk_enum(duk_context *ctx, duk_idx_t obj_index, duk_uint_t enum_flags);
3067
+ duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_index, duk_bool_t get_value);
3068
+
3069
+ /*
3070
+ * String manipulation
3071
+ */
3072
+
3073
+ void duk_concat(duk_context *ctx, duk_idx_t count);
3074
+ void duk_join(duk_context *ctx, duk_idx_t count);
3075
+ void duk_decode_string(duk_context *ctx, duk_idx_t index, duk_decode_char_function callback, void *udata);
3076
+ void duk_map_string(duk_context *ctx, duk_idx_t index, duk_map_char_function callback, void *udata);
3077
+ void duk_substring(duk_context *ctx, duk_idx_t index, duk_size_t start_char_offset, duk_size_t end_char_offset);
3078
+ void duk_trim(duk_context *ctx, duk_idx_t index);
3079
+ duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t index, duk_size_t char_offset);
3080
+
3081
+ /*
3082
+ * Ecmascript operators
3083
+ */
3084
+
3085
+ duk_bool_t duk_equals(duk_context *ctx, duk_idx_t index1, duk_idx_t index2);
3086
+ duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t index1, duk_idx_t index2);
3087
+
3088
+ /*
3089
+ * Function (method) calls
3090
+ */
3091
+
3092
+ void duk_call(duk_context *ctx, duk_idx_t nargs);
3093
+ void duk_call_method(duk_context *ctx, duk_idx_t nargs);
3094
+ void duk_call_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t nargs);
3095
+ duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs);
3096
+ duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs);
3097
+ duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t nargs);
3098
+ void duk_new(duk_context *ctx, duk_idx_t nargs);
3099
+ duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets);
3100
+
3101
+ /*
3102
+ * Thread management
3103
+ */
3104
+
3105
+ /* There are currently no native functions to yield/resume, due to the internal
3106
+ * limitations on coroutine handling. These will be added later.
3107
+ */
3108
+
3109
+ /*
3110
+ * Compilation and evaluation
3111
+ */
3112
+
3113
+ duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);
3114
+ duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);
3115
+
3116
+ /* plain */
3117
+ #define duk_eval(ctx) \
3118
+ ((void) duk_push_string((ctx), __FILE__), \
3119
+ (void) duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL))
3120
+
3121
+ #define duk_eval_noresult(ctx) \
3122
+ ((void) duk_push_string((ctx), __FILE__), \
3123
+ (void) duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT))
3124
+
3125
+ #define duk_peval(ctx) \
3126
+ ((void) duk_push_string((ctx), __FILE__), \
3127
+ duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE))
3128
+
3129
+ #define duk_peval_noresult(ctx) \
3130
+ ((void) duk_push_string((ctx), __FILE__), \
3131
+ duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT))
3132
+
3133
+ #define duk_compile(ctx,flags) \
3134
+ ((void) duk_compile_raw((ctx), NULL, 0, (flags)))
3135
+
3136
+ #define duk_pcompile(ctx,flags) \
3137
+ (duk_compile_raw((ctx), NULL, 0, (flags) | DUK_COMPILE_SAFE))
3138
+
3139
+ /* string */
3140
+ #define duk_eval_string(ctx,src) \
3141
+ ((void) duk_push_string((ctx), __FILE__), \
3142
+ (void) duk_eval_raw((ctx), (src), 0, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3143
+
3144
+ #define duk_eval_string_noresult(ctx,src) \
3145
+ ((void) duk_push_string((ctx), __FILE__), \
3146
+ (void) duk_eval_raw((ctx), (src), 0, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT))
3147
+
3148
+ #define duk_peval_string(ctx,src) \
3149
+ ((void) duk_push_string((ctx), __FILE__), \
3150
+ duk_eval_raw((ctx), (src), 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3151
+
3152
+ #define duk_peval_string_noresult(ctx,src) \
3153
+ ((void) duk_push_string((ctx), __FILE__), \
3154
+ duk_eval_raw((ctx), (src), 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT))
3155
+
3156
+ #define duk_compile_string(ctx,flags,src) \
3157
+ ((void) duk_push_string((ctx), __FILE__), \
3158
+ (void) duk_compile_raw((ctx), (src), 0, (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3159
+
3160
+ #define duk_compile_string_filename(ctx,flags,src) \
3161
+ ((void) duk_compile_raw((ctx), (src), 0, (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3162
+
3163
+ #define duk_pcompile_string(ctx,flags,src) \
3164
+ ((void) duk_push_string((ctx), __FILE__), \
3165
+ duk_compile_raw((ctx), (src), 0, (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3166
+
3167
+ #define duk_pcompile_string_filename(ctx,flags,src) \
3168
+ (duk_compile_raw((ctx), (src), 0, (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))
3169
+
3170
+ /* lstring */
3171
+ #define duk_eval_lstring(ctx,buf,len) \
3172
+ ((void) duk_push_string((ctx), __FILE__), \
3173
+ (void) duk_eval_raw((ctx), buf, len, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE))
3174
+
3175
+ #define duk_eval_lstring_noresult(ctx,buf,len) \
3176
+ ((void) duk_push_string((ctx), __FILE__), \
3177
+ (void) duk_eval_raw((ctx), buf, len, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT))
3178
+
3179
+ #define duk_peval_lstring(ctx,buf,len) \
3180
+ ((void) duk_push_string((ctx), __FILE__), \
3181
+ duk_eval_raw((ctx), buf, len, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE))
3182
+
3183
+ #define duk_peval_lstring_noresult(ctx,buf,len) \
3184
+ ((void) duk_push_string((ctx), __FILE__), \
3185
+ duk_eval_raw((ctx), buf, len, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT))
3186
+
3187
+ #define duk_compile_lstring(ctx,flags,buf,len) \
3188
+ ((void) duk_push_string((ctx), __FILE__), \
3189
+ (void) duk_compile_raw((ctx), buf, len, (flags) | DUK_COMPILE_NOSOURCE))
3190
+
3191
+ #define duk_compile_lstring_filename(ctx,flags,buf,len) \
3192
+ ((void) duk_compile_raw((ctx), buf, len, (flags) | DUK_COMPILE_NOSOURCE))
3193
+
3194
+ #define duk_pcompile_lstring(ctx,flags,buf,len) \
3195
+ ((void) duk_push_string((ctx), __FILE__), \
3196
+ duk_compile_raw((ctx), buf, len, (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))
3197
+
3198
+ #define duk_pcompile_lstring_filename(ctx,flags,buf,len) \
3199
+ (duk_compile_raw((ctx), buf, len, (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))
3200
+
3201
+ /* file */
3202
+ #define duk_eval_file(ctx,path) \
3203
+ ((void) duk_push_string_file((ctx), (path)), \
3204
+ (void) duk_push_string((ctx), (path)), \
3205
+ (void) duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL))
3206
+
3207
+ #define duk_eval_file_noresult(ctx,path) \
3208
+ ((void) duk_push_string_file((ctx), (path)), \
3209
+ (void) duk_push_string((ctx), (path)), \
3210
+ (void) duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT))
3211
+
3212
+ #define duk_peval_file(ctx,path) \
3213
+ ((void) duk_push_string_file((ctx), (path)), \
3214
+ (void) duk_push_string((ctx), (path)), \
3215
+ duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE))
3216
+
3217
+ #define duk_peval_file_noresult(ctx,path) \
3218
+ ((void) duk_push_string_file((ctx), (path)), \
3219
+ (void) duk_push_string((ctx), (path)), \
3220
+ duk_eval_raw((ctx), NULL, 0, DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT))
3221
+
3222
+ #define duk_compile_file(ctx,flags,path) \
3223
+ ((void) duk_push_string_file((ctx), (path)), \
3224
+ (void) duk_push_string((ctx), (path)), \
3225
+ (void) duk_compile_raw((ctx), NULL, 0, (flags)))
3226
+
3227
+ #define duk_pcompile_file(ctx,flags,path) \
3228
+ ((void) duk_push_string_file((ctx), (path)), \
3229
+ (void) duk_push_string((ctx), (path)), \
3230
+ duk_compile_raw((ctx), NULL, 0, (flags) | DUK_COMPILE_SAFE))
3231
+
3232
+ /*
3233
+ * Logging
3234
+ */
3235
+
3236
+ /* FIXME: here a small integer type would be proper */
3237
+ void duk_log(duk_context *ctx, duk_int_t level, const char *fmt, ...);
3238
+
3239
+ /*
3240
+ * Debugging
3241
+ */
3242
+
3243
+ void duk_push_context_dump(duk_context *ctx);
3244
+
3245
+ #if defined(DUK_USE_FILE_IO)
3246
+ /* internal use */
3247
+ #define duk_dump_context_filehandle(ctx,fh) \
3248
+ do { \
3249
+ duk_push_context_dump((ctx)); \
3250
+ fprintf(stdout, "%s\n", duk_safe_to_string(ctx, -1)); \
3251
+ duk_pop(ctx); \
3252
+ } while (0)
3253
+
3254
+ /* external use */
3255
+ #define duk_dump_context_stdout(ctx) \
3256
+ duk_dump_context_filehandle(ctx,stdout)
3257
+ #define duk_dump_context_stderr(ctx) \
3258
+ duk_dump_context_filehandle(ctx,stderr)
3259
+ #else /* DUK_USE_FILE_IO */
3260
+ #define duk_dump_context_stdout(ctx) do {} while (0)
3261
+ #define duk_dump_context_stderr(ctx) do {} while (0)
3262
+ #endif /* DUK_USE_FILE_IO */
3263
+
3264
+ /*
3265
+ * C++ name mangling
3266
+ */
3267
+
3268
+ #ifdef __cplusplus
3269
+ /* end 'extern "C"' wrapper */
3270
+ }
3271
+ #endif
3272
+
3273
+ #endif /* DUK_API_PUBLIC_H_INCLUDED */
3274
+
3275
+ /*
3276
+ * END PUBLIC API
3277
+ */
3278
+
3279
+ /*
3280
+ * Sanity check for the final effective internal defines. This file also
3281
+ * double checks user tweaks made by an optional duk_custom.h header.
3282
+ */
3283
+
3284
+ #ifndef DUK_FEATURES_SANITY_H_INCLUDED
3285
+ #define DUK_FEATURES_SANITY_H_INCLUDED
3286
+
3287
+ /*
3288
+ * Deprecated feature options.
3289
+ *
3290
+ * Catch so that user more easily notices and updates build.
3291
+ */
3292
+
3293
+ #if defined(DUK_OPT_NO_FUNC_STMT)
3294
+ #error DUK_OPT_NO_FUNC_STMT is deprecated, use DUK_OPT_NO_NONSTD_FUNC_STMT
3295
+ #endif
3296
+
3297
+ #if defined(DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY)
3298
+ #error DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY is deprecated, use DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY
3299
+ #endif
3300
+
3301
+ #if defined(DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY)
3302
+ #error DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY is deprecated, use DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY
3303
+ #endif
3304
+
3305
+ #if defined(DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT)
3306
+ #error DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT is deprecated, use DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT
3307
+ #endif
3308
+
3309
+ #if defined(DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY)
3310
+ #error DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY is deprecated, use DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY
3311
+ #endif
3312
+
3313
+ #if defined(DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF)
3314
+ #error DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF is deprecated, use DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF
3315
+ #endif
3316
+
3317
+ #if defined(DUK_OPT_NO_JSONX)
3318
+ #error DUK_OPT_NO_JSONX is deprecated, use DUK_OPT_NO_JX
3319
+ #endif
3320
+
3321
+ #if defined(DUK_OPT_NO_JSONC)
3322
+ #error DUK_OPT_NO_JSONC is deprecated, use DUK_OPT_NO_JC
3323
+ #endif
3324
+
3325
+ /*
3326
+ * Debug print consistency
3327
+ */
3328
+
3329
+ #if defined(DUK_USE_DPRINT) && !defined(DUK_USE_DEBUG)
3330
+ #error DUK_USE_DPRINT without DUK_USE_DEBUG
3331
+ #endif
3332
+
3333
+ #if defined(DUK_USE_DDPRINT) && !defined(DUK_USE_DEBUG)
3334
+ #error DUK_USE_DDPRINT without DUK_USE_DEBUG
3335
+ #endif
3336
+
3337
+ #if defined(DUK_USE_DDDPRINT) && !defined(DUK_USE_DEBUG)
3338
+ #error DUK_USE_DDDPRINT without DUK_USE_DEBUG
3339
+ #endif
3340
+
3341
+ /*
3342
+ * Garbage collection consistency
3343
+ */
3344
+
3345
+ #if defined(DUK_USE_REFERENCE_COUNTING) && !defined(DUK_USE_DOUBLE_LINKED_HEAP)
3346
+ #error DUK_USE_REFERENCE_COUNTING defined without DUK_USE_DOUBLE_LINKED_HEAP
3347
+ #endif
3348
+
3349
+ #if defined(DUK_USE_GC_TORTURE) && !defined(DUK_USE_MARK_AND_SWEEP)
3350
+ #error DUK_USE_GC_TORTURE defined without DUK_USE_MARK_AND_SWEEP
3351
+ #endif
3352
+
3353
+ #endif /* DUK_FEATURES_SANITY_H_INCLUDED */
3354
+
3355
+ /*
3356
+ * Union to access IEEE double memory representation, indexes for double
3357
+ * memory representation, and some macros for double manipulation.
3358
+ *
3359
+ * Also used by packed duk_tval. Use a union for bit manipulation to
3360
+ * minimize aliasing issues in practice. The C99 standard does not
3361
+ * guarantee that this should work, but it's a very widely supported
3362
+ * practice for low level manipulation.
3363
+ *
3364
+ * IEEE double format summary:
3365
+ *
3366
+ * seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
3367
+ * A B C D E F G H
3368
+ *
3369
+ * s sign bit
3370
+ * eee... exponent field
3371
+ * fff... fraction
3372
+ *
3373
+ * See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.
3374
+ *
3375
+ * NaNs are represented as exponent 0x7ff and mantissa != 0. The NaN is a
3376
+ * signaling NaN when the highest bit of the mantissa is zero, and a quiet
3377
+ * NaN when the highest bit is set.
3378
+ *
3379
+ * At least three memory layouts are relevant here:
3380
+ *
3381
+ * A B C D E F G H Big endian (e.g. 68k) DUK_USE_DOUBLE_BE
3382
+ * H G F E D C B A Little endian (e.g. x86) DUK_USE_DOUBLE_LE
3383
+ * D C B A H G F E Mixed/cross endian (e.g. ARM) DUK_USE_DOUBLE_ME
3384
+ *
3385
+ * ARM is a special case: ARM double values are in mixed/cross endian
3386
+ * format while ARM duk_uint64_t values are in standard little endian
3387
+ * format (H G F E D C B A). When a double is read as a duk_uint64_t
3388
+ * from memory, the register will contain the (logical) value
3389
+ * E F G H A B C D. This requires some special handling below.
3390
+ *
3391
+ * Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to
3392
+ * the logical (big endian) order:
3393
+ *
3394
+ * byte order duk_uint8_t duk_uint16_t duk_uint32_t
3395
+ * BE 01234567 0123 01
3396
+ * LE 76543210 3210 10
3397
+ * ME (ARM) 32107654 1032 01
3398
+ *
3399
+ * Some processors may alter NaN values in a floating point load+store.
3400
+ * For instance, on X86 a FLD + FSTP may convert a signaling NaN to a
3401
+ * quiet one. This is catastrophic when NaN space is used in packed
3402
+ * duk_tval values. See: misc/clang_aliasing.c.
3403
+ */
3404
+
3405
+ #ifndef DUK_DBLUNION_H_INCLUDED
3406
+ #define DUK_DBLUNION_H_INCLUDED
3407
+
3408
+ /*
3409
+ * Union for accessing double parts, also serves as packed duk_tval
3410
+ */
3411
+
3412
+ union duk_double_union {
3413
+ double d;
3414
+ #ifdef DUK_USE_64BIT_OPS
3415
+ duk_uint64_t ull[1];
3416
+ #endif
3417
+ duk_uint32_t ui[2];
3418
+ duk_uint16_t us[4];
3419
+ duk_uint8_t uc[8];
3420
+ #ifdef DUK_USE_PACKED_TVAL_POSSIBLE
3421
+ void *vp[2]; /* used by packed duk_tval, assumes sizeof(void *) == 4 */
3422
+ #endif
3423
+ };
3424
+
3425
+ typedef union duk_double_union duk_double_union;
3426
+
3427
+ /*
3428
+ * Indexes of various types with respect to big endian (logical) layout
3429
+ */
3430
+
3431
+ #if defined(DUK_USE_DOUBLE_LE)
3432
+ #ifdef DUK_USE_64BIT_OPS
3433
+ #define DUK_DBL_IDX_ULL0 0
3434
+ #endif
3435
+ #define DUK_DBL_IDX_UI0 1
3436
+ #define DUK_DBL_IDX_UI1 0
3437
+ #define DUK_DBL_IDX_US0 3
3438
+ #define DUK_DBL_IDX_US1 2
3439
+ #define DUK_DBL_IDX_US2 1
3440
+ #define DUK_DBL_IDX_US3 0
3441
+ #define DUK_DBL_IDX_UC0 7
3442
+ #define DUK_DBL_IDX_UC1 6
3443
+ #define DUK_DBL_IDX_UC2 5
3444
+ #define DUK_DBL_IDX_UC3 4
3445
+ #define DUK_DBL_IDX_UC4 3
3446
+ #define DUK_DBL_IDX_UC5 2
3447
+ #define DUK_DBL_IDX_UC6 1
3448
+ #define DUK_DBL_IDX_UC7 0
3449
+ #define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
3450
+ #define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
3451
+ #elif defined(DUK_USE_DOUBLE_BE)
3452
+ #ifdef DUK_USE_64BIT_OPS
3453
+ #define DUK_DBL_IDX_ULL0 0
3454
+ #endif
3455
+ #define DUK_DBL_IDX_UI0 0
3456
+ #define DUK_DBL_IDX_UI1 1
3457
+ #define DUK_DBL_IDX_US0 0
3458
+ #define DUK_DBL_IDX_US1 1
3459
+ #define DUK_DBL_IDX_US2 2
3460
+ #define DUK_DBL_IDX_US3 3
3461
+ #define DUK_DBL_IDX_UC0 0
3462
+ #define DUK_DBL_IDX_UC1 1
3463
+ #define DUK_DBL_IDX_UC2 2
3464
+ #define DUK_DBL_IDX_UC3 3
3465
+ #define DUK_DBL_IDX_UC4 4
3466
+ #define DUK_DBL_IDX_UC5 5
3467
+ #define DUK_DBL_IDX_UC6 6
3468
+ #define DUK_DBL_IDX_UC7 7
3469
+ #define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
3470
+ #define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
3471
+ #elif defined(DUK_USE_DOUBLE_ME)
3472
+ #ifdef DUK_USE_64BIT_OPS
3473
+ #define DUK_DBL_IDX_ULL0 0 /* not directly applicable, byte order differs from a double */
3474
+ #endif
3475
+ #define DUK_DBL_IDX_UI0 0
3476
+ #define DUK_DBL_IDX_UI1 1
3477
+ #define DUK_DBL_IDX_US0 1
3478
+ #define DUK_DBL_IDX_US1 0
3479
+ #define DUK_DBL_IDX_US2 3
3480
+ #define DUK_DBL_IDX_US3 2
3481
+ #define DUK_DBL_IDX_UC0 3
3482
+ #define DUK_DBL_IDX_UC1 2
3483
+ #define DUK_DBL_IDX_UC2 1
3484
+ #define DUK_DBL_IDX_UC3 0
3485
+ #define DUK_DBL_IDX_UC4 7
3486
+ #define DUK_DBL_IDX_UC5 6
3487
+ #define DUK_DBL_IDX_UC6 5
3488
+ #define DUK_DBL_IDX_UC7 4
3489
+ #define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
3490
+ #define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
3491
+ #else
3492
+ #error internal error
3493
+ #endif
3494
+
3495
+ /*
3496
+ * Helper macros for reading/writing memory representation parts, used
3497
+ * by duk_numconv.c and duk_tval.h.
3498
+ */
3499
+
3500
+ #define DUK_DBLUNION_SET_DOUBLE(u,v) do { \
3501
+ (u)->d = (v); \
3502
+ } while (0)
3503
+
3504
+ #define DUK_DBLUNION_SET_HIGH32(u,v) do { \
3505
+ (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \
3506
+ } while (0)
3507
+
3508
+ #ifdef DUK_USE_64BIT_OPS
3509
+ #ifdef DUK_USE_DOUBLE_ME
3510
+ #define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
3511
+ (u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \
3512
+ } while (0)
3513
+ #else
3514
+ #define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
3515
+ (u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \
3516
+ } while (0)
3517
+ #endif
3518
+ #else /* DUK_USE_64BIT_OPS */
3519
+ #define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
3520
+ (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \
3521
+ (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \
3522
+ } while (0)
3523
+ #endif /* DUK_USE_64BIT_OPS */
3524
+
3525
+ #define DUK_DBLUNION_SET_LOW32(u,v) do { \
3526
+ (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \
3527
+ } while (0)
3528
+
3529
+ #define DUK_DBLUNION_GET_DOUBLE(u) ((u)->d)
3530
+ #define DUK_DBLUNION_GET_HIGH32(u) ((u)->ui[DUK_DBL_IDX_UI0])
3531
+ #define DUK_DBLUNION_GET_LOW32(u) ((u)->ui[DUK_DBL_IDX_UI1])
3532
+
3533
+ /*
3534
+ * Double NaN manipulation macros related to NaN normalization needed when
3535
+ * using the packed duk_tval representation. NaN normalization is necessary
3536
+ * to keep double values compatible with the duk_tval format.
3537
+ *
3538
+ * When packed duk_tval is used, the NaN space is used to store pointers
3539
+ * and other tagged values in addition to NaNs. Actual NaNs are normalized
3540
+ * to a specific format. The macros below are used by the implementation
3541
+ * to check and normalize NaN values when they might be created. The macros
3542
+ * are essentially NOPs when the non-packed duk_tval representation is used.
3543
+ *
3544
+ * A FULL check is exact and checks all bits. A NOTFULL check is used by
3545
+ * the packed duk_tval and works correctly for all NaNs except those that
3546
+ * begin with 0x7ff0. Since the 'normalized NaN' values used with packed
3547
+ * duk_tval begin with 0x7ff8, the partial check is reliable when packed
3548
+ * duk_tval is used.
3549
+ *
3550
+ * The ME variant below is specifically for ARM byte order, which has the
3551
+ * feature that while doubles have a mixed byte order (32107654), unsigned
3552
+ * long long values has a little endian byte order (76543210). When writing
3553
+ * a logical double value through a ULL pointer, the 32-bit words need to be
3554
+ * swapped; hence the #ifdefs below for ULL writes with DUK_USE_DOUBLE_ME.
3555
+ * This is not full ARM support but suffices for some environments.
3556
+ */
3557
+
3558
+ #ifdef DUK_USE_64BIT_OPS
3559
+ #ifdef DUK_USE_DOUBLE_ME
3560
+ #define DUK__DBLUNION_SET_NAN_FULL(u) do { \
3561
+ (u)->ull[DUK_DBL_IDX_ULL0] = 0x000000007ff80000ULL; \
3562
+ } while (0)
3563
+ #else
3564
+ #define DUK__DBLUNION_SET_NAN_FULL(u) do { \
3565
+ (u)->ull[DUK_DBL_IDX_ULL0] = 0x7ff8000000000000ULL; \
3566
+ } while (0)
3567
+ #endif
3568
+ #else /* DUK_USE_64BIT_OPS */
3569
+ #define DUK__DBLUNION_SET_NAN_FULL(u) do { \
3570
+ (u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \
3571
+ (u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \
3572
+ } while (0)
3573
+ #endif /* DUK_USE_64BIT_OPS */
3574
+
3575
+ #define DUK__DBLUNION_SET_NAN_NOTFULL(u) do { \
3576
+ (u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \
3577
+ } while (0)
3578
+
3579
+ #ifdef DUK_USE_64BIT_OPS
3580
+ #ifdef DUK_USE_DOUBLE_ME
3581
+ #define DUK__DBLUNION_IS_NAN_FULL(u) \
3582
+ /* E == 0x7ff, F != 0 => NaN */ \
3583
+ ((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \
3584
+ ((((u)->ull[DUK_DBL_IDX_ULL0]) & 0xffffffff000fffffULL) != 0))
3585
+ #else
3586
+ #define DUK__DBLUNION_IS_NAN_FULL(u) \
3587
+ /* E == 0x7ff, F != 0 => NaN */ \
3588
+ ((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \
3589
+ ((((u)->ull[DUK_DBL_IDX_ULL0]) & 0x000fffffffffffffULL) != 0))
3590
+ #endif
3591
+ #else /* DUK_USE_64BIT_OPS */
3592
+ #define DUK__DBLUNION_IS_NAN_FULL(u) \
3593
+ /* E == 0x7ff, F != 0 => NaN */ \
3594
+ ((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \
3595
+ (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \
3596
+ (u)->ui[DUK_DBL_IDX_UI1] != 0))
3597
+ #endif /* DUK_USE_64BIT_OPS */
3598
+
3599
+ #define DUK__DBLUNION_IS_NAN_NOTFULL(u) \
3600
+ /* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \
3601
+ ((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \
3602
+ (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))
3603
+
3604
+ #ifdef DUK_USE_64BIT_OPS
3605
+ #ifdef DUK_USE_DOUBLE_ME
3606
+ #define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
3607
+ ((u)->ull[DUK_DBL_IDX_ULL0] == 0x000000007ff80000ULL)
3608
+ #else
3609
+ #define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
3610
+ ((u)->ull[DUK_DBL_IDX_ULL0] == 0x7ff8000000000000ULL)
3611
+ #endif
3612
+ #else /* DUK_USE_64BIT_OPS */
3613
+ #define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
3614
+ (((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \
3615
+ ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
3616
+ #endif /* DUK_USE_64BIT_OPS */
3617
+
3618
+ #define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \
3619
+ /* E == 0x7ff, F == 8 => normalized NaN */ \
3620
+ ((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)
3621
+
3622
+ #define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u) do { \
3623
+ if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
3624
+ DUK__DBLUNION_SET_NAN_FULL((u)); \
3625
+ } \
3626
+ } while (0)
3627
+
3628
+ #define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) do { \
3629
+ if (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \
3630
+ DUK__DBLUNION_SET_NAN_NOTFULL((u)); \
3631
+ } \
3632
+ } while (0)
3633
+
3634
+ /* Concrete macros for NaN handling used by the implementation internals.
3635
+ * Chosen so that they match the duk_tval representation: with a packed
3636
+ * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval
3637
+ * these are essentially NOPs.
3638
+ */
3639
+
3640
+ #if defined(DUK_USE_PACKED_TVAL)
3641
+ #if defined(DUK_USE_FULL_TVAL)
3642
+ #define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))
3643
+ #define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u))
3644
+ #define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))
3645
+ #define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d))
3646
+ #else
3647
+ #define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))
3648
+ #define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u))
3649
+ #define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))
3650
+ #define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_NOTFULL((d))
3651
+ #endif
3652
+ #define DUK_DBLUNION_IS_NORMALIZED(u) \
3653
+ (!DUK_DBLUNION_IS_NAN((u)) || /* either not a NaN */ \
3654
+ DUK_DBLUNION_IS_NORMALIZED_NAN((u))) /* or is a normalized NaN */
3655
+ #else /* DUK_USE_PACKED_TVAL */
3656
+ #define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) /* nop: no need to normalize */
3657
+ #define DUK_DBLUNION_IS_NAN(u) (DUK_ISNAN((u)->d))
3658
+ #define DUK_DBLUNION_IS_NORMALIZED_NAN(u) (DUK_ISNAN((u)->d))
3659
+ #define DUK_DBLUNION_IS_NORMALIZED(u) 1 /* all doubles are considered normalized */
3660
+ #define DUK_DBLUNION_SET_NAN(u) do { \
3661
+ /* in non-packed representation we don't care about which NaN is used */ \
3662
+ (u)->d = DUK_DOUBLE_NAN; \
3663
+ } while (0)
3664
+ #endif /* DUK_USE_PACKED_TVAL */
3665
+
3666
+ #endif /* DUK_DBLUNION_H_INCLUDED */
3667
+
3668
+ #endif /* DUKTAPE_H_INCLUDED */