diff options
Diffstat (limited to 'javascript/duktape/duk_config.h')
-rw-r--r-- | javascript/duktape/duk_config.h | 3882 |
1 files changed, 2143 insertions, 1739 deletions
diff --git a/javascript/duktape/duk_config.h b/javascript/duktape/duk_config.h index adf275432..f6ee91cdd 100644 --- a/javascript/duktape/duk_config.h +++ b/javascript/duktape/duk_config.h @@ -1,163 +1,105 @@ /* - * Determine platform features, select feature selection defines - * (e.g. _XOPEN_SOURCE), include system headers, and define DUK_USE_xxx - * defines which are (only) checked in Duktape internal code for - * activated features. Duktape feature selection is based on automatic - * feature detection, user supplied DUK_OPT_xxx defines, and optionally - * a "duk_custom.h" user header (if DUK_OPT_HAVE_CUSTOM_H is defined). + * duk_config.h configuration header generated by genconfig.py. * - * When compiling Duktape, DUK_COMPILING_DUKTAPE is set, and this file - * is included before any system headers are included. Feature selection - * defines (e.g. _XOPEN_SOURCE) are defined here before any system headers - * are included (which is a requirement for system headers to work correctly). - * This file is responsible for including all system headers and contains - * all platform dependent cruft in general. When compiling user code, - * DUK_COMPILING_DUKTAPE is not defined, and we must avoid e.g. defining - * unnecessary feature selection defines. + * Git commit: b7b1c5fd2d1d4550140d57e05a7b32f540082bfa + * Git describe: v1.3.0-383-gb7b1c5f + * Git branch: duk-config-improvements * - * The general order of handling: - * - Compiler feature detection (require no includes) - * - Intermediate platform detection (-> easier platform defines) - * - Platform detection, system includes, byte order detection, etc - * - ANSI C wrappers (e.g. DUK_MEMCMP), wrappers for constants, etc - * - DUK_USE_xxx defines are resolved based on input defines - * - Duktape Date provider settings - * - Final sanity checks + * Supported platforms: + * - Mac OSX, iPhone, Darwin + * - OpenBSD + * - Generic BSD + * - Atari ST TOS + * - AmigaOS + * - Windows + * - Flashplayer (Crossbridge) + * - QNX + * - TI-Nspire + * - Emscripten + * - Linux + * - Solaris + * - Generic POSIX + * - Cygwin + * - Generic UNIX + * - Generic fallback * - * DUK_F_xxx are internal feature detection macros which should not be - * used outside this header. + * Supported architectures: + * - x86 + * - x64 + * - x32 + * - ARM 32-bit + * - ARM 64-bit + * - MIPS 32-bit + * - MIPS 64-bit + * - PowerPC 32-bit + * - PowerPC 64-bit + * - SPARC 32-bit + * - SPARC 64-bit + * - SuperH + * - Motorola 68k + * - Emscripten + * - Generic * - * Useful resources: + * Supported compilers: + * - Clang + * - GCC + * - MSVC + * - Emscripten + * - TinyC + * - VBCC + * - Bruce's C compiler + * - Generic * - * http://sourceforge.net/p/predef/wiki/Home/ - * http://sourceforge.net/p/predef/wiki/Architectures/ - * http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor - * http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types - * - * Preprocessor defines available in a particular GCC: - * - * gcc -dM -E - </dev/null # http://www.brain-dump.org/blog/entry/107 */ -#ifndef DUK_CONFIG_H_INCLUDED +#if !defined(DUK_CONFIG_H_INCLUDED) #define DUK_CONFIG_H_INCLUDED /* - * Compiler features - */ - -#undef DUK_F_C99 -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -#define DUK_F_C99 -#endif - -#undef DUK_F_CPP -#if defined(__cplusplus) -#define DUK_F_CPP -#endif - -#undef DUK_F_CPP11 -#if defined(__cplusplus) && (__cplusplus >= 201103L) -#define DUK_F_CPP11 -#endif - -/* - * Provides the duk_rdtsc() inline function (if available), limited to - * GCC C99. - * - * See: http://www.mcs.anl.gov/~kazutomo/rdtsc.html + * Intermediate helper defines */ -/* XXX: more accurate detection of what gcc versions work; more inline - * asm versions for other compilers. - */ -#if defined(__GNUC__) && defined(__i386__) && defined(DUK_F_C99) && \ - !defined(__cplusplus) /* unsigned long long not standard */ -static __inline__ unsigned long long duk_rdtsc(void) { - unsigned long long int x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; -} -#define DUK_USE_RDTSC() duk_rdtsc() -#elif defined(__GNUC__) && defined(__x86_64__) && defined(DUK_F_C99) && \ - !defined(__cplusplus) /* unsigned long long not standard */ -static __inline__ unsigned long long duk_rdtsc(void) { - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); -} -#define DUK_USE_RDTSC() duk_rdtsc() +/* DLL build detection */ +#if defined(DUK_OPT_DLL_BUILD) +#define DUK_F_DLL_BUILD +#elif defined(DUK_OPT_NO_DLL_BUILD) +#undef DUK_F_DLL_BUILD #else -/* not available */ -#undef DUK_USE_RDTSC +/* not configured for DLL build */ +#undef DUK_F_DLL_BUILD #endif -/* - * Intermediate platform, architecture, and compiler detection. These are - * hopelessly intertwined - e.g. architecture defines depend on compiler etc. - * - * Provide easier defines for platforms and compilers which are often tricky - * or verbose to detect. The intent is not to provide intermediate defines for - * all features; only if existing feature defines are inconvenient. - */ - -/* Intel x86 (32-bit) */ -#if defined(i386) || defined(__i386) || defined(__i386__) || \ - defined(__i486__) || defined(__i586__) || defined(__i686__) || \ - defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \ - defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) -#define DUK_F_X86 +/* Apple OSX, iOS */ +#if defined(__APPLE__) +#define DUK_F_APPLE #endif -/* AMD64 (64-bit) */ -#if defined(__amd64__) || defined(__amd64) || \ - defined(__x86_64__) || defined(__x86_64) || \ - defined(_M_X64) || defined(_M_AMD64) -#define DUK_F_X64 +/* OpenBSD */ +#if defined(__OpenBSD__) || defined(__OpenBSD) +#define DUK_F_OPENBSD #endif -/* X32: 64-bit with 32-bit pointers (allows packed tvals). X32 support is - * not very mature yet. - * - * https://sites.google.com/site/x32abi/ - */ -#if defined(DUK_F_X64) && \ - (defined(_ILP32) || defined(__ILP32__)) -#define DUK_F_X32 -/* define only one of: DUK_F_X86, DUK_F_X32, or DUK_F_X64 */ -#undef DUK_F_X64 -#undef DUK_F_X86 +/* NetBSD */ +#if defined(__NetBSD__) || defined(__NetBSD) +#define DUK_F_NETBSD #endif -/* ARM */ -#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) -#define DUK_F_ARM +/* FreeBSD */ +#if defined(__FreeBSD__) || defined(__FreeBSD) +#define DUK_F_FREEBSD #endif -/* MIPS */ -/* Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */ -#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \ - defined(_R3000) || defined(_R4000) || defined(_R5900) || \ - defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \ - defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \ - defined(__mips) || defined(__MIPS__) -#define DUK_F_MIPS -#if defined(__LP64__) || defined(__mips64) || defined(__mips64__) || \ - defined(__mips_n64) -#define DUK_F_MIPS64 -#else -#define DUK_F_MIPS32 -#endif +/* BSD variant */ +#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \ + defined(__bsdi__) || defined(__DragonFly__) +#define DUK_F_BSD #endif -/* SuperH */ -#if defined(__sh__) || \ - defined(__sh1__) || defined(__SH1__) || \ - defined(__sh2__) || defined(__SH2__) || \ - defined(__sh3__) || defined(__SH3__) || \ - defined(__sh4__) || defined(__SH4__) || \ - defined(__sh5__) || defined(__SH5__) -#define DUK_F_SUPERH +/* Atari ST TOS. __TOS__ defined by PureC. No platform define in VBCC + * apparently, so to use with VBCC user must define __TOS__ manually. + */ +#if defined(__TOS__) +#define DUK_F_TOS #endif /* Motorola 68K. Not defined by VBCC, so user must define one of these @@ -167,40 +109,77 @@ static __inline__ unsigned long long duk_rdtsc(void) { #define DUK_F_M68K #endif +/* AmigaOS. Neither AMIGA nor __amigaos__ is defined on VBCC, so user must + * define 'AMIGA' manually when using VBCC. + */ +#if defined(AMIGA) || defined(__amigaos__) +#define DUK_F_AMIGAOS +#endif + /* PowerPC */ #if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__) #define DUK_F_PPC -#if defined(__PPC64__) +#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64) #define DUK_F_PPC64 #else #define DUK_F_PPC32 #endif #endif +/* Windows, both 32-bit and 64-bit */ +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) +#define DUK_F_WINDOWS +#if defined(_WIN64) || defined(WIN64) +#define DUK_F_WIN64 +#else +#define DUK_F_WIN32 +#endif +#endif + +/* Flash player (e.g. Crossbridge) */ +#if defined(__FLASHPLAYER__) +#define DUK_F_FLASHPLAYER +#endif + +/* QNX */ +#if defined(__QNX__) +#define DUK_F_QNX +#endif + +/* TI-Nspire (using Ndless) */ +#if defined(_TINSPIRE) +#define DUK_F_TINSPIRE +#endif + +/* Emscripten (provided explicitly by user), improve if possible */ +#if defined(EMSCRIPTEN) +#define DUK_F_EMSCRIPTEN +#endif + +/* BCC (Bruce's C compiler): this is a "torture target" for compilation */ +#if defined(__BCC__) || defined(__BCC_VERSION__) +#define DUK_F_BCC +#endif + /* Linux */ #if defined(__linux) || defined(__linux__) || defined(linux) #define DUK_F_LINUX #endif -/* FreeBSD */ -#if defined(__FreeBSD__) || defined(__FreeBSD) -#define DUK_F_FREEBSD -#endif - -/* NetBSD */ -#if defined(__NetBSD__) || defined(__NetBSD) -#define DUK_F_NETBSD +/* illumos / Solaris */ +#if defined(__sun) && defined(__SVR4) +#define DUK_F_SUN #endif -/* OpenBSD */ -#if defined(__OpenBSD__) || defined(__OpenBSD) -#define DUK_F_OPENBSD +/* POSIX */ +#if defined(__posix) +#define DUK_F_POSIX #endif -/* BSD variant */ -#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \ - defined(__bsdi__) || defined(__DragonFly__) -#define DUK_F_BSD +/* Cygwin */ +#if defined(__CYGWIN__) +#define DUK_F_CYGWIN #endif /* Generic Unix (includes Cygwin) */ @@ -209,58 +188,111 @@ static __inline__ unsigned long long duk_rdtsc(void) { #define DUK_F_UNIX #endif -/* Cygwin */ -#if defined(__CYGWIN__) -#define DUK_F_CYGWIN +/* stdint.h not available */ +#if defined(DUK_F_WINDOWS) && defined(_MSC_VER) +#if (_MSC_VER < 1700) +/* VS2012+ has stdint.h, < VS2012 does not (but it's available for download). */ +#define DUK_F_NO_STDINT_H +#endif +#endif +#if !defined(DUK_F_NO_STDINT_H) && (defined(DUK_F_TOS) || defined(DUK_F_BCC)) +#define DUK_F_NO_STDINT_H #endif -/* Windows (32-bit or above) */ -#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \ - defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) -#define DUK_F_WINDOWS +/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers), + * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32. + * https://sites.google.com/site/x32abi/ + */ +#if defined(__amd64__) || defined(__amd64) || \ + defined(__x86_64__) || defined(__x86_64) || \ + defined(_M_X64) || defined(_M_AMD64) +#if defined(__ILP32__) || defined(_ILP32) +#define DUK_F_X32 +#else +#define DUK_F_X64 +#endif +#elif defined(i386) || defined(__i386) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || defined(__i686__) || \ + defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \ + defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) +#if defined(__LP64__) || defined(_LP64) +/* This should not really happen, but would indicate x64. */ +#define DUK_F_X64 +#else +#define DUK_F_X86 +#endif #endif -#if defined(__APPLE__) -#define DUK_F_APPLE +/* ARM */ +#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) +#define DUK_F_ARM +#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) +#define DUK_F_ARM64 +#else +#define DUK_F_ARM32 +#endif #endif -/* Atari ST TOS. __TOS__ defined by PureC (which doesn't work as a target now - * because int is 16-bit, to be fixed). No platform define in VBCC apparently, - * so to use with VBCC, user must define '__TOS__' manually. - */ -#if defined(__TOS__) -#define DUK_F_TOS +/* MIPS. Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */ +#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \ + defined(_R3000) || defined(_R4000) || defined(_R5900) || \ + defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \ + defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \ + defined(__mips) || defined(__MIPS__) +#define DUK_F_MIPS +#if defined(__LP64__) || defined(_LP64) || defined(__mips64) || \ + defined(__mips64__) || defined(__mips_n64) +#define DUK_F_MIPS64 +#else +#define DUK_F_MIPS32 +#endif #endif -/* AmigaOS. Neither AMIGA nor __amigaos__ is defined on VBCC, so user must - * define 'AMIGA' manually. - */ -#if defined(AMIGA) || defined(__amigaos__) -#define DUK_F_AMIGAOS +/* SPARC */ +#if defined(sparc) || defined(__sparc) || defined(__sparc__) +#define DUK_F_SPARC +#if defined(__LP64__) || defined(_LP64) +#define DUK_F_SPARC64 +#else +#define DUK_F_SPARC32 +#endif #endif -/* Flash player (e.g. Crossbridge) */ -#if defined(__FLASHPLAYER__) -#define DUK_F_FLASHPLAYER +/* SuperH */ +#if defined(__sh__) || \ + defined(__sh1__) || defined(__SH1__) || \ + defined(__sh2__) || defined(__SH2__) || \ + defined(__sh3__) || defined(__SH3__) || \ + defined(__sh4__) || defined(__SH4__) || \ + defined(__sh5__) || defined(__SH5__) +#define DUK_F_SUPERH #endif -/* Emscripten (provided explicitly by user), improve if possible */ -#if defined(EMSCRIPTEN) -#define DUK_F_EMSCRIPTEN +/* Clang */ +#if defined(__clang__) +#define DUK_F_CLANG #endif -/* QNX */ -#if defined(__QNX__) -#define DUK_F_QNX +/* C++ */ +#undef DUK_F_CPP +#if defined(__cplusplus) +#define DUK_F_CPP #endif -/* TI-Nspire (using Ndless) */ -#if defined(_TINSPIRE) -#define DUK_F_TINSPIRE +/* C99 or above */ +#undef DUK_F_C99 +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define DUK_F_C99 +#endif + +/* C++11 or above */ +#undef DUK_F_CPP11 +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#define DUK_F_CPP11 #endif -/* GCC and GCC version convenience define. */ -#if defined(__GNUC__) +/* GCC. Clang also defines __GNUC__ so don't detect GCC if using Clang. */ +#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG) #define DUK_F_GCC #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) /* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */ @@ -270,16 +302,9 @@ static __inline__ unsigned long long duk_rdtsc(void) { #endif #endif -/* Clang */ -#if defined(__clang__) -#define DUK_F_CLANG -/* It seems clang also defines __GNUC__, so undo the GCC detection. */ -#if defined(DUK_F_GCC) -#undef DUK_F_GCC -#endif -#if defined(DUK_F_GCC_VERSION) -#undef DUK_F_GCC_VERSION -#endif +/* MinGW. Also GCC flags (DUK_F_GCC) are enabled now. */ +#if defined(__MINGW32__) || defined(__MINGW64__) +#define DUK_F_MINGW #endif /* MSVC */ @@ -298,105 +323,25 @@ static __inline__ unsigned long long duk_rdtsc(void) { #endif #endif /* _MSC_VER */ -/* MinGW */ -#if defined(__MINGW32__) || defined(__MINGW64__) -/* NOTE: Also GCC flags are detected (DUK_F_GCC etc). */ -#define DUK_F_MINGW -#endif - -/* BCC (Bruce's C compiler): this is a "torture target" for compilation */ -#if defined(__BCC__) || defined(__BCC_VERSION__) -#define DUK_F_BCC +/* TinyC */ +#if defined(__TINYC__) +/* http://bellard.org/tcc/tcc-doc.html#SEC9 */ +#define DUK_F_TINYC #endif +/* VBCC */ #if defined(__VBCC__) #define DUK_F_VBCC #endif -/* - * Platform detection, system includes, Date provider selection. - * - * Feature selection (e.g. _XOPEN_SOURCE) must happen before any system - * headers are included. This header should avoid providing any feature - * selection defines when compiling user code (only when compiling Duktape - * itself). If a feature selection option is required for user code to - * compile correctly (e.g. it is needed for type detection), it should - * probably be -checked- here, not defined here. - * - * Date provider selection seems a bit out-of-place here, but since - * the date headers and provider functions are heavily platform - * specific, there's little point in duplicating the platform if-else - * ladder. All platform specific Date provider functions are in - * duk_bi_date.c; here we provide appropriate #defines to enable them, - * and include all the necessary system headers so that duk_bi_date.c - * compiles. Date "providers" are: - * - * NOW = getting current time (required) - * TZO = getting local time offset (required) - * PRS = parse datetime (optional) - * FMT = format datetime (optional) - * - * There's a lot of duplication here, unfortunately, because many - * platforms have similar (but not identical) headers, Date providers, - * etc. The duplication could be removed by more complicated nested - * #ifdefs, but it would then be more difficult to make fixes which - * affect only a specific platform. - * - * XXX: add a way to provide custom functions to provide the critical - * primitives; this would be convenient when porting to unknown platforms - * (rather than muck with Duktape internals). - */ - -#if defined(DUK_COMPILING_DUKTAPE) && \ - (defined(DUK_F_LINUX) || defined(DUK_F_EMSCRIPTEN)) -/* A more recent Emscripten (2014-05) seems to lack "linux" environment - * defines, so check for Emscripten explicitly. - */ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200809L -#endif -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* e.g. getdate_r */ -#endif -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE /* e.g. strptime */ -#endif -#endif - -#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE) -/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */ -#define _XOPEN_SOURCE 600 -#define _POSIX_C_SOURCE 200112L +/* uclibc */ +#if defined(__UCLIBC__) +#define DUK_F_UCLIBC #endif -#undef DUK_F_MSVC_CRT_SECURE -#if defined(DUK_F_WINDOWS) && defined(_MSC_VER) -/* http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx - * http://msdn.microsoft.com/en-us/library/wd3wzwts.aspx - * Seem to be available since VS2005. - */ -#if (_MSC_VER >= 1400) -/* VS2005+, secure CRT functions are preferred. Windows Store applications - * (and probably others) should use these. - */ -#define DUK_F_MSVC_CRT_SECURE -#endif -#if (_MSC_VER < 1700) -/* VS2012+ has stdint.h, < VS2012 does not (but it's available for download). */ -#define DUK_F_NO_STDINT_H -#endif -/* Initial fix: disable secure CRT related warnings when compiling Duktape - * itself (must be defined before including Windows headers). Don't define - * for user code including duktape.h. +/* + * Platform autodetection */ -#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS -#endif -#endif /* DUK_F_WINDOWS && _MSC_VER */ - -#if defined(DUK_F_TOS) || defined(DUK_F_BCC) -#define DUK_F_NO_STDINT_H -#endif /* Workaround for older C++ compilers before including <inttypes.h>, * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366 @@ -408,19 +353,35 @@ static __inline__ unsigned long long duk_rdtsc(void) { #define __STDC_CONSTANT_MACROS #endif -#if defined(__APPLE__) -/* Mac OSX, iPhone, Darwin */ +#if defined(DUK_F_APPLE) +/* --- Mac OSX, iPhone, Darwin --- */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <TargetConditionals.h> #include <architecture/byte_order.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> + +/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */ +#if TARGET_IPHONE_SIMULATOR +#define DUK_USE_OS_STRING "iphone-sim" +#elif TARGET_OS_IPHONE +#define DUK_USE_OS_STRING "iphone" +#elif TARGET_OS_MAC +#define DUK_USE_OS_STRING "ios" +#else +#define DUK_USE_OS_STRING "ios-unknown" +#endif + +/* Use _setjmp() on Apple by default, see GH-55. */ +#define DUK_USE_UNDERSCORE_SETJMP +#define DUK_SETJMP(jb) _setjmp((jb)) +#define DUK_LONGJMP(jb) _longjmp((jb), 1) #elif defined(DUK_F_OPENBSD) +/* --- OpenBSD --- */ /* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R @@ -428,45 +389,52 @@ static __inline__ unsigned long long duk_rdtsc(void) { #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> #include <sys/endian.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> + +#define DUK_USE_OS_STRING "openbsd" #elif defined(DUK_F_BSD) -/* other BSD */ +/* --- Generic BSD --- */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> #include <sys/endian.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> + +#define DUK_USE_OS_STRING "bsd" #elif defined(DUK_F_TOS) -/* Atari ST TOS */ +/* --- Atari ST TOS --- */ #define DUK_USE_DATE_NOW_TIME #define DUK_USE_DATE_TZO_GMTIME /* no parsing (not an error) */ #define DUK_USE_DATE_FMT_STRFTIME -#include <limits.h> #include <time.h> + +#define DUK_USE_OS_STRING "tos" + +/* TOS on M68K is always big endian. */ +#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K) +#define DUK_USE_BYTEORDER 3 +#endif #elif defined(DUK_F_AMIGAOS) +/* --- AmigaOS --- */ #if defined(DUK_F_M68K) /* AmigaOS on M68k */ #define DUK_USE_DATE_NOW_TIME #define DUK_USE_DATE_TZO_GMTIME /* no parsing (not an error) */ #define DUK_USE_DATE_FMT_STRFTIME -#include <limits.h> #include <time.h> #elif defined(DUK_F_PPC) #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME -#include <limits.h> #include <time.h> #ifndef UINTPTR_MAX #define UINTPTR_MAX UINT_MAX @@ -474,7 +442,23 @@ static __inline__ unsigned long long duk_rdtsc(void) { #else #error AmigaOS but not M68K/PPC, not supported now #endif + +#define DUK_USE_OS_STRING "amigaos" + +/* AmigaOS on M68K or PPC is always big endian. */ +#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC)) +#define DUK_USE_BYTEORDER 3 +#endif #elif defined(DUK_F_WINDOWS) +/* --- Windows --- */ +/* Initial fix: disable secure CRT related warnings when compiling Duktape + * itself (must be defined before including Windows headers). Don't define + * for user code including duktape.h. + */ +#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + /* Windows 32-bit and 64-bit are currently the same. */ /* MSVC does not have sys/param.h */ #define DUK_USE_DATE_NOW_WINDOWS @@ -484,133 +468,802 @@ static __inline__ unsigned long long duk_rdtsc(void) { * the ISO 8601 standard format. */ #if defined(DUK_COMPILING_DUKTAPE) +/* Only include when compiling Duktape to avoid polluting application build + * with a lot of unnecessary defines. + */ #include <windows.h> #endif -#include <limits.h> + +#define DUK_USE_OS_STRING "windows" + +/* On Windows, assume we're little endian. Even Itanium which has a + * configurable endianness runs little endian in Windows. + */ +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif #elif defined(DUK_F_FLASHPLAYER) -/* Crossbridge */ +/* --- Flashplayer (Crossbridge) --- */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <endian.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> + +#define DUK_USE_OS_STRING "flashplayer" + +#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER) +#define DUK_USE_BYTEORDER 1 +#endif #elif defined(DUK_F_QNX) +/* --- QNX --- */ +#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE) +/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */ +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L +#endif + #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> + +#define DUK_USE_OS_STRING "qnx" #elif defined(DUK_F_TINSPIRE) +/* --- TI-Nspire --- */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> -#elif defined(DUK_F_LINUX) + +#define DUK_USE_OS_STRING "tinspire" +#elif defined(DUK_F_EMSCRIPTEN) +/* --- Emscripten --- */ +#if defined(DUK_COMPILING_DUKTAPE) +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* e.g. getdate_r */ +#endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif +#endif /* DUK_COMPILING_DUKTAPE */ + +#include <sys/types.h> +#if defined(DUK_F_BCC) +/* no endian.h */ +#else +#include <endian.h> +#endif /* DUK_F_BCC */ +#include <sys/param.h> +#include <sys/time.h> +#include <time.h> +#include <stdint.h> + #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "emscripten" +#elif defined(DUK_F_LINUX) +/* --- Linux --- */ +#if defined(DUK_COMPILING_DUKTAPE) +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* e.g. getdate_r */ +#endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE /* e.g. strptime */ +#endif +#endif /* DUK_COMPILING_DUKTAPE */ + #include <sys/types.h> #if defined(DUK_F_BCC) -/* no endian.h */ +/* no endian.h or stdint.h */ #else #include <endian.h> +#include <stdint.h> #endif /* DUK_F_BCC */ -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> -#elif defined(__posix) -/* POSIX */ + #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R #define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME + +#define DUK_USE_OS_STRING "linux" +#elif defined(DUK_F_SUN) +/* --- Solaris --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME + #include <sys/types.h> -#include <endian.h> -#include <limits.h> +#include <ast/endian.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> -#elif defined(DUK_F_CYGWIN) -/* Cygwin -- don't use strptime() for now */ + +#define DUK_USE_OS_STRING "solaris" +#elif defined(DUK_F_POSIX) +/* --- Generic POSIX --- */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> #include <endian.h> -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> -#else -/* Other UNIX, hopefully others */ + +#define DUK_USE_OS_STRING "posix" +#elif defined(DUK_F_CYGWIN) +/* --- Cygwin --- */ +/* don't use strptime() for now */ #define DUK_USE_DATE_NOW_GETTIMEOFDAY #define DUK_USE_DATE_TZO_GMTIME_R -#define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_FMT_STRFTIME #include <sys/types.h> -#if defined(DUK_F_BCC) -/* no endian.h */ -#else #include <endian.h> -#endif /* DUK_F_BCC */ -#include <limits.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> -#endif -/* Shared includes */ +#define DUK_USE_UNDERSCORE_SETJMP +#define DUK_SETJMP(jb) _setjmp((jb)) +#define DUK_LONGJMP(jb) _longjmp((jb), 1) + +#define DUK_USE_OS_STRING "windows" +#elif defined(DUK_F_UNIX) +/* --- Generic UNIX --- */ +#define DUK_USE_DATE_NOW_GETTIMEOFDAY +#define DUK_USE_DATE_TZO_GMTIME_R +#define DUK_USE_DATE_PRS_STRPTIME +#define DUK_USE_DATE_FMT_STRFTIME +#include <time.h> +#include <sys/time.h> +#define DUK_USE_OS_STRING "unknown" +#else +/* --- Generic fallback --- */ +/* The most portable current time provider is time(), but it only has a + * one second resolution. + */ +#define DUK_USE_DATE_NOW_TIME + +/* The most portable way to figure out local time offset is gmtime(), + * but it's not thread safe so use with caution. + */ +#define DUK_USE_DATE_TZO_GMTIME + +/* Avoid custom date parsing and formatting for portability. */ +#undef DUK_USE_DATE_PRS_STRPTIME +#undef DUK_USE_DATE_FMT_STRFTIME + +/* Rely on C89 headers only; time.h must be here. */ +#include <time.h> + +#define DUK_USE_OS_STRING "unknown" +#endif /* autodetect platform */ + +/* Shared includes: C89 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> /* varargs */ #include <setjmp.h> #include <stddef.h> /* e.g. ptrdiff_t */ +#include <math.h> +#include <limits.h> + +/* date.h is omitted, and included per platform */ + +/* Shared includes: stdint.h is C99 */ #if defined(DUK_F_NO_STDINT_H) /* stdint.h not available */ #else -/* Technically C99 (C++11) but found in many systems. Note the workaround - * above for some C++ compilers (__STDC_LIMIT_MACROS etc). +/* Technically C99 (C++11) but found in many systems. On some systems + * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before + * including stdint.h (see above). */ #include <stdint.h> #endif -#include <math.h> -#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \ - !defined(DUK_F_BCC) -/* ULL / LL preprocessor constants should be avoided because they're not - * always available. With suitable options, some compilers will support - * 64-bit integer types but won't support ULL / LL preprocessor constants. - * Assume C99/C++11 environments have these. However, BCC is nominally - * C99 but doesn't support these constants. +/* + * Architecture autodetection + */ + +#if defined(DUK_F_X86) +/* --- x86 --- */ +#define DUK_USE_ARCH_STRING "x86" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +/* XXX: This is technically not guaranteed because it's possible to configure + * an x86 to require aligned accesses with Alignment Check (AC) flag. */ -#define DUK_F_ULL_CONSTS +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 1 #endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_X64) +/* --- x64 --- */ +#define DUK_USE_ARCH_STRING "x64" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +/* XXX: This is technically not guaranteed because it's possible to configure + * an x86 to require aligned accesses with Alignment Check (AC) flag. + */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 1 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_X32) +/* --- x32 --- */ +#define DUK_USE_ARCH_STRING "x32" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +/* XXX: This is technically not guaranteed because it's possible to configure + * an x86 to require aligned accesses with Alignment Check (AC) flag. + */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 1 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_ARM32) +/* --- ARM 32-bit --- */ +#define DUK_USE_ARCH_STRING "arm32" +/* Byte order varies, so rely on autodetect. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 4 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_ARM64) +/* --- ARM 64-bit --- */ +#define DUK_USE_ARCH_STRING "arm64" +/* Byte order varies, so rely on autodetect. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_MIPS32) +/* --- MIPS 32-bit --- */ +#define DUK_USE_ARCH_STRING "mips32" +/* MIPS byte order varies so rely on autodetection. */ +/* Based on 'make checkalign' there are no alignment requirements on + * Linux MIPS except for doubles, which need align by 4. Alignment + * requirements vary based on target though. + */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 4 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_MIPS64) +/* --- MIPS 64-bit --- */ +#define DUK_USE_ARCH_STRING "mips64" +/* MIPS byte order varies so rely on autodetection. */ +/* Good default is a bit arbitrary because alignment requirements + * depend on target. See https://github.com/svaarala/duktape/issues/102. + */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_PPC32) +/* --- PowerPC 32-bit --- */ +#define DUK_USE_ARCH_STRING "ppc32" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_PPC64) +/* --- PowerPC 64-bit --- */ +#define DUK_USE_ARCH_STRING "ppc64" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_SPARC32) +/* --- SPARC 32-bit --- */ +#define DUK_USE_ARCH_STRING "sparc32" +/* SPARC byte order varies so rely on autodetection. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_SPARC64) +/* --- SPARC 64-bit --- */ +#define DUK_USE_ARCH_STRING "sparc64" +/* SPARC byte order varies so rely on autodetection. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_SUPERH) +/* --- SuperH --- */ +#define DUK_USE_ARCH_STRING "sh" +/* Byte order varies, rely on autodetection. */ +/* Based on 'make checkalign' there are no alignment requirements on + * Linux SH4, but align by 4 is probably a good basic default. + */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 4 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_M68K) +/* --- Motorola 68k --- */ +#define DUK_USE_ARCH_STRING "m68k" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 3 +#endif +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#define DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#elif defined(DUK_F_EMSCRIPTEN) +/* --- Emscripten --- */ +#define DUK_USE_ARCH_STRING "emscripten" +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 +#endif +#undef DUK_USE_PACKED_TVAL +#define DUK_F_PACKED_TVAL_PROVIDED +#else +/* --- Generic --- */ +/* These are necessary wild guesses. */ +#define DUK_USE_ARCH_STRING "generic" +/* Rely on autodetection for byte order, alignment, and packed tval. */ +#endif /* autodetect architecture */ /* - * Detection for specific libc variants (like uclibc) and other libc specific - * features. Potentially depends on the #includes above. + * Compiler autodetection */ -#if defined(__UCLIBC__) -#define DUK_F_UCLIBC +#if defined(DUK_F_CLANG) +/* --- Clang --- */ +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +/* C99 / C++11 and above: rely on va_copy() which is required. */ +#define DUK_VA_COPY(dest,src) va_copy(dest,src) +#else +/* Clang: assume we have __va_copy() in non-C99 mode. */ +#define DUK_VA_COPY(dest,src) __va_copy(dest,src) #endif +#define DUK_NORETURN(decl) decl __attribute__((noreturn)) + +#if defined(__clang__) && defined(__has_builtin) +#if __has_builtin(__builtin_unreachable) +#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while (0) +#endif +#endif + +#define DUK_USE_BRANCH_HINTS +#define DUK_LIKELY(x) __builtin_expect((x), 1) +#define DUK_UNLIKELY(x) __builtin_expect((x), 0) + +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_NOINLINE __attribute__((noinline)) +#define DUK_INLINE inline +#define DUK_ALWAYS_INLINE inline __attribute__((always_inline)) +#endif + +#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS) +/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're + * compiling Duktape or the application. + */ +#if defined(DUK_COMPILING_DUKTAPE) +#define DUK_EXTERNAL_DECL extern __declspec(dllexport) +#define DUK_EXTERNAL __declspec(dllexport) +#else +#define DUK_EXTERNAL_DECL extern __declspec(dllimport) +#define DUK_EXTERNAL should_not_happen +#endif +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL extern +#define DUK_INTERNAL /*empty*/ +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static + +#else +#define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern +#define DUK_EXTERNAL __attribute__ ((visibility("default"))) +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static +#endif + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "clang" +#else +#define DUK_USE_COMPILER_STRING "clang" +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_USE_VARIADIC_MACROS +#endif + +#undef DUK_USE_FLEX_C99 +#undef DUK_USE_FLEX_ZEROSIZE +#undef DUK_USE_FLEX_ONESIZE +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE +#endif + +#undef DUK_USE_GCC_PRAGMAS +#define DUK_USE_PACK_CLANG_ATTR +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_GCC) +/* --- GCC --- */ +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +/* C99 / C++11 and above: rely on va_copy() which is required. */ +#define DUK_VA_COPY(dest,src) va_copy(dest,src) +#else +/* GCC: assume we have __va_copy() in non-C99 mode. */ +#define DUK_VA_COPY(dest,src) __va_copy(dest,src) +#endif + +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) +/* since gcc-2.5 */ +#define DUK_NORETURN(decl) decl __attribute__((noreturn)) +#endif + +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) +/* since gcc-4.5 */ +#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while (0) +#endif + +#define DUK_USE_BRANCH_HINTS +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) +/* GCC: test not very accurate; enable only in relatively recent builds + * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html) + */ +#define DUK_LIKELY(x) __builtin_expect((x), 1) +#define DUK_UNLIKELY(x) __builtin_expect((x), 0) +#endif + +#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \ + defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101) +#define DUK_NOINLINE __attribute__((noinline)) +#define DUK_INLINE inline +#define DUK_ALWAYS_INLINE inline __attribute__((always_inline)) +#endif + +#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS) +/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're + * compiling Duktape or the application. + */ +#if defined(DUK_COMPILING_DUKTAPE) +#define DUK_EXTERNAL_DECL extern __declspec(dllexport) +#define DUK_EXTERNAL __declspec(dllexport) +#else +#define DUK_EXTERNAL_DECL extern __declspec(dllimport) +#define DUK_EXTERNAL should_not_happen +#endif +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL extern +#define DUK_INTERNAL /*empty*/ +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static + +#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000) +#define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern +#define DUK_EXTERNAL __attribute__ ((visibility("default"))) +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static +#endif + +#if defined(DUK_F_MINGW) +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "mingw++" +#else +#define DUK_USE_COMPILER_STRING "mingw" +#endif +#else +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "g++" +#else +#define DUK_USE_COMPILER_STRING "gcc" +#endif +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__)) +#define DUK_USE_VARIADIC_MACROS +#endif + +#undef DUK_USE_FLEX_C99 +#undef DUK_USE_FLEX_ZEROSIZE +#undef DUK_USE_FLEX_ONESIZE +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE +#endif + +#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600) +#define DUK_USE_GCC_PRAGMAS +#else +#undef DUK_USE_GCC_PRAGMAS +#endif + +#define DUK_USE_PACK_GCC_ATTR +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_MSVC) +/* --- MSVC --- */ +/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */ +#define DUK_NORETURN(decl) __declspec(noreturn) decl + +/* XXX: DUK_UNREACHABLE for msvc? */ + +#undef DUK_USE_BRANCH_HINTS + +/* XXX: DUK_LIKELY, DUK_UNLIKELY for msvc? */ +/* XXX: DUK_NOINLINE, DUK_INLINE, DUK_ALWAYS_INLINE for msvc? */ + +#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS) +/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're + * compiling Duktape or the application. + */ +#if defined(DUK_COMPILING_DUKTAPE) +#define DUK_EXTERNAL_DECL extern __declspec(dllexport) +#define DUK_EXTERNAL __declspec(dllexport) +#else +#define DUK_EXTERNAL_DECL extern __declspec(dllimport) +#define DUK_EXTERNAL should_not_happen +#endif +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL extern +#define DUK_INTERNAL /*empty*/ +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static + +#endif + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "msvc++" +#else +#define DUK_USE_COMPILER_STRING "msvc" +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) +#define DUK_USE_VARIADIC_MACROS +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +/* VS2005+ should have variadic macros even when they're not C99. */ +#define DUK_USE_VARIADIC_MACROS +#endif + +#undef DUK_USE_FLEX_C99 +#undef DUK_USE_FLEX_ZEROSIZE +#undef DUK_USE_FLEX_ONESIZE +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE +#endif + +#undef DUK_USE_GCC_PRAGMAS + +#define DUK_USE_PACK_MSVC_PRAGMA + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#define DUK_SNPRINTF snprintf +#define DUK_VSNPRINTF vsnprintf +#else +/* (v)snprintf() is missing before MSVC 2015. Note that _(v)snprintf() does + * NOT NUL terminate on truncation, but Duktape code never assumes that. + * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 + */ +#define DUK_SNPRINTF _snprintf +#define DUK_VSNPRINTF _vsnprintf +#endif +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_EMSCRIPTEN) +/* --- Emscripten --- */ +#define DUK_NORETURN(decl) decl __attribute__((noreturn)) + +#if defined(__clang__) && defined(__has_builtin) +#if __has_builtin(__builtin_unreachable) +#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while (0) +#endif +#endif + +#define DUK_USE_BRANCH_HINTS +#define DUK_LIKELY(x) __builtin_expect((x), 1) +#define DUK_UNLIKELY(x) __builtin_expect((x), 0) + +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_NOINLINE __attribute__((noinline)) +#define DUK_INLINE inline +#define DUK_ALWAYS_INLINE inline __attribute__((always_inline)) +#endif + +#define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern +#define DUK_EXTERNAL __attribute__ ((visibility("default"))) +#if defined(DUK_SINGLE_FILE) +#define DUK_INTERNAL_DECL static +#define DUK_INTERNAL static +#else +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) +#endif +#define DUK_LOCAL_DECL static +#define DUK_LOCAL static + +#define DUK_USE_COMPILER_STRING "emscripten" + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_USE_VARIADIC_MACROS +#endif + +#undef DUK_USE_FLEX_C99 +#undef DUK_USE_FLEX_ZEROSIZE +#undef DUK_USE_FLEX_ONESIZE +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 +#else +#define DUK_USE_FLEX_ZEROSIZE +#endif + +#undef DUK_USE_GCC_PRAGMAS +#define DUK_USE_PACK_CLANG_ATTR +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_TINYC) +/* --- TinyC --- */ +#undef DUK_USE_BRANCH_HINTS + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "tinyc++" +#else +#define DUK_USE_COMPILER_STRING "tinyc" +#endif + +/* http://bellard.org/tcc/tcc-doc.html#SEC7 */ +#define DUK_USE_VARIADIC_MACROS + +/* Most portable, wastes space */ +#define DUK_USE_FLEX_ONESIZE + +/* Most portable, potentially wastes space */ +#define DUK_USE_PACK_DUMMY_MEMBER +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_VBCC) +/* --- VBCC --- */ +#undef DUK_USE_BRANCH_HINTS + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "vbcc-c++" +#else +#define DUK_USE_COMPILER_STRING "vbcc" +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_USE_VARIADIC_MACROS +#endif + +#define DUK_USE_FLEX_ZEROSIZE +#define DUK_USE_PACK_DUMMY_MEMBER +#define DUK_F_VARIADIC_MACROS_PROVIDED +#elif defined(DUK_F_BCC) +/* --- Bruce's C compiler --- */ +#undef DUK_USE_BRANCH_HINTS + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "bcc++" +#else +#define DUK_USE_COMPILER_STRING "bcc" +#endif + +/* XXX */ +#undef DUK_USE_VARIADIC_MACROS + +/* Most portable, wastes space */ +#define DUK_USE_FLEX_ONESIZE + +/* Most portable, potentially wastes space */ +#define DUK_USE_PACK_DUMMY_MEMBER + +/* BCC, assume we're on x86. */ +#if !defined(DUK_USE_BYTEORDER) +#define DUK_USE_BYTEORDER 1 +#endif +#define DUK_F_VARIADIC_MACROS_PROVIDED +#else +/* --- Generic --- */ +#undef DUK_USE_BRANCH_HINTS + +#if defined(DUK_F_CPP) +#define DUK_USE_COMPILER_STRING "generic-c++" +#else +#define DUK_USE_COMPILER_STRING "generic" +#endif + +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_USE_VARIADIC_MACROS +#endif + +/* Most portable, wastes space */ +#define DUK_USE_FLEX_ONESIZE + +/* Most portable, potentially wastes space */ +#define DUK_USE_PACK_DUMMY_MEMBER +#define DUK_F_VARIADIC_MACROS_PROVIDED +#endif /* autodetect compiler */ + /* * Wrapper typedefs and constants for integer types, also sanity check types. * @@ -654,10 +1307,11 @@ static __inline__ unsigned long long duk_rdtsc(void) { #error cannot check complement of two #endif -/* Pointer size determination based on architecture. - * XXX: unsure about BCC correctness. +/* Pointer size determination based on __WORDSIZE or architecture when + * that's not available. */ #if defined(DUK_F_X86) || defined(DUK_F_X32) || \ + defined(DUK_F_M68K) || defined(DUK_F_PPC32) || \ defined(DUK_F_BCC) || \ (defined(__WORDSIZE) && (__WORDSIZE == 32)) #define DUK_F_32BIT_PTRS @@ -1154,11 +1808,9 @@ typedef double duk_double_t; /* Type for public API calls. */ typedef struct duk_hthread duk_context; -/* - * Check whether we should use 64-bit integers - */ - -/* Quite incomplete now. Use 64-bit types if detected (C99 or other detection) +/* Check whether we should use 64-bit integers or not. + * + * Quite incomplete now. Use 64-bit types if detected (C99 or other detection) * unless they are known to be unreliable. For instance, 64-bit types are * available on VBCC but seem to misbehave. */ @@ -1169,383 +1821,160 @@ typedef struct duk_hthread duk_context; #endif /* - * Alignment requirement and support for unaligned accesses - * - * Assume unaligned accesses are not supported unless specifically allowed - * in the target platform. Some platforms may support unaligned accesses - * but alignment to 4 or 8 may still be desirable. + * Fill-ins for platform, architecture, and compiler */ -#undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE -#undef DUK_USE_ALIGN_BY - -#if defined(DUK_F_EMSCRIPTEN) -/* Required on at least some targets, so use whenever Emscripten used, - * regardless of compilation target. - */ -#define DUK_USE_ALIGN_BY 8 -#elif defined(DUK_F_ARM) -#define DUK_USE_ALIGN_BY 4 -#elif defined(DUK_F_MIPS32) -/* Based on 'make checkalign' there are no alignment requirements on - * Linux MIPS except for doubles, which need align by 4. Alignment - * requirements vary based on target though. - */ -#define DUK_USE_ALIGN_BY 4 -#elif defined(DUK_F_MIPS64) -/* Good default is a bit arbitrary because alignment requirements - * depend on target. See https://github.com/svaarala/duktape/issues/102. - */ -#define DUK_USE_ALIGN_BY 8 -#elif defined(DUK_F_SUPERH) -/* Based on 'make checkalign' there are no alignment requirements on - * Linux SH4, but align by 4 is probably a good basic default. - */ -#define DUK_USE_ALIGN_BY 4 -#elif defined(DUK_F_X86) || defined(DUK_F_X32) || defined(DUK_F_X64) || \ - defined(DUK_F_BCC) -/* XXX: This is technically not guaranteed because it's possible to configure - * an x86 to require aligned accesses with Alignment Check (AC) flag. - */ -#define DUK_USE_ALIGN_BY 1 -#define DUK_USE_UNALIGNED_ACCESSES_POSSIBLE -#else -/* Unknown, use safe default */ -#define DUK_USE_ALIGN_BY 8 +#if !defined(DUK_SETJMP) +#define DUK_USE_SETJMP +#define DUK_SETJMP(jb) setjmp((jb)) +#define DUK_LONGJMP(jb) longjmp((jb), 1) #endif -/* User forced alignment to 4 or 8. */ -#if defined(DUK_OPT_FORCE_ALIGN) -#undef DUK_USE_ALIGN_BY -#undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE -#if (DUK_OPT_FORCE_ALIGN == 4) -#define DUK_USE_ALIGN_BY 4 -#elif (DUK_OPT_FORCE_ALIGN == 8) -#define DUK_USE_ALIGN_BY 8 -#else -#error invalid DUK_OPT_FORCE_ALIGN value +typedef FILE duk_file; +#if !defined(DUK_STDIN) +#define DUK_STDIN stdin #endif +#if !defined(DUK_STDOUT) +#define DUK_STDOUT stdout +#endif +#if !defined(DUK_STDERR) +#define DUK_STDERR stderr #endif -/* Compiler specific hackery needed to force struct size to match aligment, - * see e.g. duk_hbuffer.h. - * - * http://stackoverflow.com/questions/11130109/c-struct-size-alignment - * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment +/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h + * (which is unfortunately named). May sometimes need replacement, e.g. + * some compilers don't handle zero length or NULL correctly in realloc(). */ -#if defined(DUK_F_MSVC) -#define DUK_USE_PACK_MSVC_PRAGMA -#elif defined(DUK_F_GCC) -#define DUK_USE_PACK_GCC_ATTR -#elif defined(DUK_F_CLANG) -#define DUK_USE_PACK_CLANG_ATTR -#else -#define DUK_USE_PACK_DUMMY_MEMBER +#if !defined(DUK_ANSI_MALLOC) +#define DUK_ANSI_MALLOC malloc #endif - -#ifdef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE -#define DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS -#else -#undef DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS +#if !defined(DUK_ANSI_REALLOC) +#define DUK_ANSI_REALLOC realloc #endif - -/* Object property allocation layout has implications for memory and code - * footprint and generated code size/speed. The best layout also depends - * on whether the platform has alignment requirements or benefits from - * having mostly aligned accesses. - */ -#undef DUK_USE_HOBJECT_LAYOUT_1 -#undef DUK_USE_HOBJECT_LAYOUT_2 -#undef DUK_USE_HOBJECT_LAYOUT_3 -#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) && (DUK_USE_ALIGN_BY == 1) -/* On platforms without any alignment issues, layout 1 is preferable - * because it compiles to slightly less code and provides direct access - * to property keys. - */ -#define DUK_USE_HOBJECT_LAYOUT_1 -#else -/* On other platforms use layout 2, which requires some padding but - * is a bit more natural than layout 3 in ordering the entries. Layout - * 3 is currently not used. - */ -#define DUK_USE_HOBJECT_LAYOUT_2 +#if !defined(DUK_ANSI_CALLOC) +#define DUK_ANSI_CALLOC calloc +#endif +#if !defined(DUK_ANSI_FREE) +#define DUK_ANSI_FREE free #endif -/* - * Byte order and double memory layout detection +/* ANSI C (various versions) and some implementations require that the + * pointer arguments to memset(), memcpy(), and memmove() be valid values + * even when byte size is 0 (even a NULL pointer is considered invalid in + * this context). Zero-size operations as such are allowed, as long as their + * pointer arguments point to a valid memory area. The DUK_MEMSET(), + * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.: + * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be + * allowed. If these are not fulfilled, a macro wrapper is needed. * - * Endianness detection is a major portability hassle because the macros - * and headers are not standardized. There's even variance across UNIX - * platforms. Even with "standard" headers, details like underscore count - * varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used - * (Crossbridge has a single underscore, for instance). + * http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0 + * http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html * - * The checks below are structured with this in mind: several approaches are - * used, and at the end we check if any of them worked. This allows generic - * approaches to be tried first, and platform/compiler specific hacks tried - * last. As a last resort, the user can force a specific endianness, as it's - * not likely that automatic detection will work on the most exotic platforms. + * Not sure what's the required behavior when a pointer points just past the + * end of a buffer, which often happens in practice (e.g. zero size memmoves). + * For example, if allocation size is 3, the following pointer would not + * technically point to a valid memory byte: * - * Duktape supports little and big endian machines. There's also support - * for a hybrid used by some ARM machines where integers are little endian - * but IEEE double values use a mixed order (12345678 -> 43218765). This - * byte order for doubles is referred to as "mixed endian". - */ - -#undef DUK_F_BYTEORDER -#undef DUK_USE_BYTEORDER_FORCED - -/* DUK_F_BYTEORDER is set as an intermediate value when detection - * succeeds, to one of: - * 1 = little endian - * 2 = mixed (arm hybrid) endian - * 3 = big endian + * <-- alloc --> + * | 0 | 1 | 2 | ..... + * ^-- p=3, points after last valid byte (2) */ - -/* For custom platforms allow user to define byteorder explicitly. - * Since endianness headers are not standardized, this is a useful - * workaround for custom platforms for which endianness detection - * is not directly supported. Perhaps custom hardware is used and - * user cannot submit upstream patches. +#if !defined(DUK_MEMCPY) +#if defined(DUK_F_UCLIBC) +/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide + * now on purpose): http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html */ -#if defined(DUK_OPT_FORCE_BYTEORDER) -#if (DUK_OPT_FORCE_BYTEORDER == 1) -#define DUK_F_BYTEORDER 1 -#elif (DUK_OPT_FORCE_BYTEORDER == 2) -#define DUK_F_BYTEORDER 2 -#elif (DUK_OPT_FORCE_BYTEORDER == 3) -#define DUK_F_BYTEORDER 3 +#define DUK_MEMCPY memmove #else -#error invalid DUK_OPT_FORCE_BYTEORDER value +#define DUK_MEMCPY memcpy #endif -#define DUK_USE_BYTEORDER_FORCED -#endif /* DUK_OPT_FORCE_BYTEORDER */ - -/* More or less standard endianness predefines provided by header files. - * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER - * will be big endian, see: http://lists.mysql.com/internals/443. - */ -#if !defined(DUK_F_BYTEORDER) -#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \ - defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \ - defined(__LITTLE_ENDIAN__) -/* Integer little endian */ -#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \ - defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN) -#define DUK_F_BYTEORDER 1 -#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \ - defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN) -#define DUK_F_BYTEORDER 2 -#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER) -/* Float word order not known, assume not a hybrid. */ -#define DUK_F_BYTEORDER 1 -#else -/* byte order is little endian but cannot determine IEEE double word order */ -#endif /* float word order */ -#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \ - defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \ - defined(__BIG_ENDIAN__) -/* Integer big endian */ -#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \ - defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN) -#define DUK_F_BYTEORDER 3 -#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER) -/* Float word order not known, assume not a hybrid. */ -#define DUK_F_BYTEORDER 3 -#else -/* byte order is big endian but cannot determine IEEE double word order */ -#endif /* float word order */ -#else -/* cannot determine byte order */ -#endif /* integer byte order */ -#endif /* !defined(DUK_F_BYTEORDER) */ - -/* GCC and Clang provide endianness defines as built-in predefines, with - * leading and trailing double underscores (e.g. __BYTE_ORDER__). See - * output of "make gccpredefs" and "make clangpredefs". Clang doesn't - * seem to provide __FLOAT_WORD_ORDER__. - * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html - */ -#if !defined(DUK_F_BYTEORDER) && defined(__BYTE_ORDER__) -#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -/* Integer little endian */ -#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ - (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define DUK_F_BYTEORDER 1 -#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ - (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) -#define DUK_F_BYTEORDER 2 -#elif !defined(__FLOAT_WORD_ORDER__) -/* Float word order not known, assume not a hybrid. */ -#define DUK_F_BYTEORDER 1 -#else -/* byte order is little endian but cannot determine IEEE double word order */ -#endif /* float word order */ -#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -/* Integer big endian */ -#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ - (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) -#define DUK_F_BYTEORDER 3 -#elif !defined(__FLOAT_WORD_ORDER__) -/* Float word order not known, assume not a hybrid. */ -#define DUK_F_BYTEORDER 3 -#else -/* byte order is big endian but cannot determine IEEE double word order */ -#endif /* float word order */ -#else -/* cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit - * integer ordering and is not relevant - */ -#endif /* integer byte order */ -#endif /* !defined(DUK_F_BYTEORDER) && defined(__BYTE_ORDER__) */ - -/* Atari ST TOS */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_TOS) -#define DUK_F_BYTEORDER 3 #endif - -/* AmigaOS on M68K or PPC */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_AMIGAOS) -#if defined(DUK_F_M68K) || defined(DUK_F_PPC) -#define DUK_F_BYTEORDER 3 +#if !defined(DUK_MEMMOVE) +#define DUK_MEMMOVE memmove #endif +#if !defined(DUK_MEMCMP) +#define DUK_MEMCMP memcmp #endif - -/* On Windows, assume we're little endian. Even Itanium which has a - * configurable endianness runs little endian in Windows. - */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_WINDOWS) -/* XXX: verify that Windows on ARM is little endian for floating point - * values too. - */ -#define DUK_F_BYTEORDER 1 -#endif /* Windows */ - -/* Crossbridge should work with the standard byteorder #ifdefs. It doesn't - * provide _FLOAT_WORD_ORDER but the standard approach now covers that case - * too. This has been left here just in case. - */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_FLASHPLAYER) -#define DUK_F_BYTEORDER 1 +#if !defined(DUK_MEMSET) +#define DUK_MEMSET memset #endif - -/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__: - * $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian - * 67:#define __LITTLEENDIAN__ 1 - * $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian - * 81:#define __BIGENDIAN__ 1 - * $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian - * 70:#define __LITTLEENDIAN__ 1 - */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_QNX) -/* XXX: ARM hybrid? */ -#if defined(__LITTLEENDIAN__) -#define DUK_F_BYTEORDER 1 -#elif defined(__BIGENDIAN__) -#define DUK_F_BYTEORDER 3 +#if !defined(DUK_STRLEN) +#define DUK_STRLEN strlen #endif +#if !defined(DUK_STRCMP) +#define DUK_STRCMP strcmp #endif - -/* Bruce's C Compiler (BCC), assume we're on x86. */ -#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_BCC) -#define DUK_F_BYTEORDER 1 +#if !defined(DUK_STRNCMP) +#define DUK_STRNCMP strncmp #endif - -/* Check whether or not byte order detection worked based on the intermediate - * define, and define final values. If detection failed, #error out. - */ -#if defined(DUK_F_BYTEORDER) -#if (DUK_F_BYTEORDER == 1) -#define DUK_USE_INTEGER_LE -#define DUK_USE_DOUBLE_LE -#elif (DUK_F_BYTEORDER == 2) -#define DUK_USE_INTEGER_LE /* integer endianness is little on purpose */ -#define DUK_USE_DOUBLE_ME -#elif (DUK_F_BYTEORDER == 3) -#define DUK_USE_INTEGER_BE -#define DUK_USE_DOUBLE_BE -#else -#error unsupported: byte order detection failed (internal error, should not happen) -#endif /* byte order */ -#else -#error unsupported: byte order detection failed -#endif /* defined(DUK_F_BYTEORDER) */ - -/* - * Check whether or not a packed duk_tval representation is possible. - * What's basically required is that pointers are 32-bit values - * (sizeof(void *) == 4). Best effort check, not always accurate. - * If guess goes wrong, crashes may result; self tests also verify - * the guess. - */ - -#undef DUK_USE_PACKED_TVAL_POSSIBLE - -/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */ -#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_HAVE_INTTYPES) && defined(DUK_UINTPTR_MAX) -#if (DUK_UINTPTR_MAX <= 0xffffffffUL) -#define DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_PRINTF) +#define DUK_PRINTF printf #endif +#if !defined(DUK_FPRINTF) +#define DUK_FPRINTF fprintf #endif - -/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */ -#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED) -#if (DUK_UINTPTR_MAX <= 0xffffffffUL) -#define DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_SPRINTF) +#define DUK_SPRINTF sprintf #endif +#if !defined(DUK_SNPRINTF) +/* snprintf() is technically not part of C89 but usually available. */ +#define DUK_SNPRINTF snprintf #endif - -/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */ -#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED) -#if DUK_SIZE_MAX <= 0xffffffffUL -#define DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_VSPRINTF) +#define DUK_VSPRINTF vsprintf #endif +#if !defined(DUK_VSNPRINTF) +/* vsnprintf() is technically not part of C89 but usually available. */ +#define DUK_VSNPRINTF vsnprintf #endif - -/* M68K: packed always possible */ -#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_M68K) -#define DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_SSCANF) +#define DUK_SSCANF sscanf #endif - -/* PPC32: packed always possible */ -#if !defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_PPC32) -#define DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_VSSCANF) +#define DUK_VSSCANF vsscanf #endif - -/* With Emscripten, force unpacked duk_tval just to be safe, as it seems to - * break at least on Firefox (probably IEEE double arithmetic is not 100% - * supported, especially for NaNs). - */ -#if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_EMSCRIPTEN) -#undef DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_FOPEN) +#define DUK_FOPEN fopen #endif - -/* Microsoft Visual Studio 2010 on x64 fails the above rules and tries to - * use a packed type. Force unpacked on x64 in general. - */ -#if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && defined(DUK_F_X64) -#undef DUK_USE_PACKED_TVAL_POSSIBLE +#if !defined(DUK_FCLOSE) +#define DUK_FCLOSE fclose #endif - -/* GCC/clang inaccurate math would break compliance and probably duk_tval, - * so refuse to compile. Relax this if -ffast-math is tested to work. - */ -#if defined(__FAST_MATH__) -#error __FAST_MATH__ defined, refusing to compile +#if !defined(DUK_FREAD) +#define DUK_FREAD fread +#endif +#if !defined(DUK_FWRITE) +#define DUK_FWRITE fwrite +#endif +#if !defined(DUK_FSEEK) +#define DUK_FSEEK fseek +#endif +#if !defined(DUK_FTELL) +#define DUK_FTELL ftell +#endif +#if !defined(DUK_FFLUSH) +#define DUK_FFLUSH fflush +#endif +#if !defined(DUK_FPUTC) +#define DUK_FPUTC fputc +#endif +#if !defined(DUK_MEMZERO) +#define DUK_MEMZERO(p,n) DUK_MEMSET((p), 0, (n)) +#endif +#if !defined(DUK_ABORT) +#define DUK_ABORT abort +#endif +#if !defined(DUK_EXIT) +#define DUK_EXIT exit #endif -/* - * Detection of double constants and math related functions. Availability - * of constants and math functions is a significant porting concern. - * - * INFINITY/HUGE_VAL is problematic on GCC-3.3: it causes an overflow warning - * and there is no pragma in GCC-3.3 to disable it. Using __builtin_inf() - * avoids this problem for some reason. - */ - +#if !defined(DUK_DOUBLE_2TO32) #define DUK_DOUBLE_2TO32 4294967296.0 +#endif +#if !defined(DUK_DOUBLE_2TO31) #define DUK_DOUBLE_2TO31 2147483648.0 +#endif +#if !defined(DUK_DOUBLE_INFINITY) #undef DUK_USE_COMPUTED_INFINITY #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600) /* GCC older than 4.6: avoid overflow warnings related to using INFINITY */ @@ -1559,11 +1988,12 @@ typedef struct duk_hthread duk_context; * Use a computed infinity (initialized when a heap is created at the * latest). */ -extern double duk_computed_infinity; #define DUK_USE_COMPUTED_INFINITY #define DUK_DOUBLE_INFINITY duk_computed_infinity #endif +#endif +#if !defined(DUK_DOUBLE_NAN) #undef DUK_USE_COMPUTED_NAN #if defined(NAN) #define DUK_DOUBLE_NAN NAN @@ -1575,10 +2005,10 @@ extern double duk_computed_infinity; * Use a computed NaN (initialized when a heap is created at the * latest). */ -extern double duk_computed_nan; #define DUK_USE_COMPUTED_NAN #define DUK_DOUBLE_NAN duk_computed_nan #endif +#endif /* Many platforms are missing fpclassify() and friends, so use replacements * if necessary. The replacement constants (FP_NAN etc) can be anything but @@ -1670,23 +2100,57 @@ extern double duk_computed_nan; * completeness. Because these are used as function pointers, they need * to be defined as concrete C functions (not macros). */ +#if !defined(DUK_FABS) #define DUK_FABS fabs +#endif +#if !defined(DUK_FMIN) #define DUK_FMIN fmin +#endif +#if !defined(DUK_FMAX) #define DUK_FMAX fmax +#endif +#if !defined(DUK_FLOOR) #define DUK_FLOOR floor +#endif +#if !defined(DUK_CEIL) #define DUK_CEIL ceil +#endif +#if !defined(DUK_FMOD) #define DUK_FMOD fmod +#endif +#if !defined(DUK_POW) #define DUK_POW pow +#endif +#if !defined(DUK_ACOS) #define DUK_ACOS acos +#endif +#if !defined(DUK_ASIN) #define DUK_ASIN asin +#endif +#if !defined(DUK_ATAN) #define DUK_ATAN atan +#endif +#if !defined(DUK_ATAN2) #define DUK_ATAN2 atan2 +#endif +#if !defined(DUK_SIN) #define DUK_SIN sin +#endif +#if !defined(DUK_COS) #define DUK_COS cos +#endif +#if !defined(DUK_TAN) #define DUK_TAN tan +#endif +#if !defined(DUK_EXP) #define DUK_EXP exp +#endif +#if !defined(DUK_LOG) #define DUK_LOG log +#endif +#if !defined(DUK_SQRT) #define DUK_SQRT sqrt +#endif /* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics, * see test-bug-netbsd-math-pow.js. Use NetBSD specific workaround. @@ -1709,7 +2173,7 @@ extern double duk_computed_nan; * The problem goes away by adding 'volatile' to the datetime computations. * Not sure what the actual triggering conditions are, but using this on * non-C99 systems solves the known issues and has relatively little cost - * on other platforms. See bugs/issue-2e9d9c2d761dabaf8136c0897b91a270d1a47147.yaml. + * on other platforms. */ #undef DUK_USE_PARANOID_DATE_COMPUTATION #if !defined(DUK_F_C99) @@ -1717,125 +2181,182 @@ extern double duk_computed_nan; #endif /* - * ANSI C string/memory function wrapper defines to allow easier workarounds. - * Also convenience macros like DUK_MEMZERO which may be mapped to existing - * platform function to zero memory (like the deprecated bzero). - * - * For instance, some platforms don't support zero-size memcpy correctly, - * some arcane uclibc versions have a buggy memcpy (but working memmove) - * and so on. Such broken platforms can be dealt with here. - * - * NOTE: ANSI C (various versions) and some implementations require that the - * pointer arguments to memset(), memcpy(), and memmove() be valid values - * even when byte size is 0 (even a NULL pointer is considered invalid in - * this context). Zero-size operations as such are allowed, as long as their - * pointer arguments point to a valid memory area. The DUK_MEMSET(), - * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.: - * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be - * allowed. If these are not fulfilled, a macro wrapper is needed. - * - * http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0 - * http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html + * Byte order and double memory layout detection * - * Not sure what's the required behavior when a pointer points just past the - * end of a buffer, which often happens in practice (e.g. zero size memmoves). - * For example, if allocation size is 3, the following pointer would not - * technically point to a valid memory byte: + * Endianness detection is a major portability hassle because the macros + * and headers are not standardized. There's even variance across UNIX + * platforms. Even with "standard" headers, details like underscore count + * varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used + * (Crossbridge has a single underscore, for instance). * - * <-- alloc --> - * | 0 | 1 | 2 | ..... - * ^-- p=3, points after last valid byte (2) + * The checks below are structured with this in mind: several approaches are + * used, and at the end we check if any of them worked. This allows generic + * approaches to be tried first, and platform/compiler specific hacks tried + * last. As a last resort, the user can force a specific endianness, as it's + * not likely that automatic detection will work on the most exotic platforms. * - * If this is a practical issue, wrappers are again needed. - */ - -typedef FILE duk_file; -#define DUK_STDIN stdin -#define DUK_STDOUT stdout -#define DUK_STDERR stderr - -/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h - * (which is unfortunately named). + * Duktape supports little and big endian machines. There's also support + * for a hybrid used by some ARM machines where integers are little endian + * but IEEE double values use a mixed order (12345678 -> 43218765). This + * byte order for doubles is referred to as "mixed endian". */ -#define DUK_ANSI_MALLOC malloc -#define DUK_ANSI_REALLOC realloc -#define DUK_ANSI_CALLOC calloc -#define DUK_ANSI_FREE free -/* Old uclibcs have a broken memcpy so use memmove instead (this is overly - * wide now on purpose): - * http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html +/* For custom platforms allow user to define byteorder explicitly. + * Since endianness headers are not standardized, this is a useful + * workaround for custom platforms for which endianness detection + * is not directly supported. Perhaps custom hardware is used and + * user cannot submit upstream patches. */ -#if defined(DUK_F_UCLIBC) -#define DUK_MEMCPY memmove +#if defined(DUK_OPT_FORCE_BYTEORDER) +#undef DUK_USE_BYTEORDER +#if (DUK_OPT_FORCE_BYTEORDER == 1) +#define DUK_USE_BYTEORDER 1 +#elif (DUK_OPT_FORCE_BYTEORDER == 2) +#define DUK_USE_BYTEORDER 2 +#elif (DUK_OPT_FORCE_BYTEORDER == 3) +#define DUK_USE_BYTEORDER 3 #else -#define DUK_MEMCPY memcpy +#error invalid DUK_OPT_FORCE_BYTEORDER value #endif +#endif /* DUK_OPT_FORCE_BYTEORDER */ -#define DUK_MEMMOVE memmove -#define DUK_MEMCMP memcmp -#define DUK_MEMSET memset -#define DUK_STRLEN strlen -#define DUK_STRCMP strcmp -#define DUK_STRNCMP strncmp -#define DUK_PRINTF printf -#define DUK_FPRINTF fprintf -#define DUK_SPRINTF sprintf +/* GCC and Clang provide endianness defines as built-in predefines, with + * leading and trailing double underscores (e.g. __BYTE_ORDER__). See + * output of "make gccpredefs" and "make clangpredefs". Clang doesn't + * seem to provide __FLOAT_WORD_ORDER__; assume not mixed endian for clang. + * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html + */ +#if !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) +#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define DUK_USE_BYTEORDER 1 +#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) +#define DUK_USE_BYTEORDER 2 +#elif !defined(__FLOAT_WORD_ORDER__) +/* Float word order not known, assume not a hybrid. */ +#define DUK_USE_BYTEORDER 1 +#else +/* Byte order is little endian but cannot determine IEEE double word order. */ +#endif /* float word order */ +#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) +#define DUK_USE_BYTEORDER 3 +#elif !defined(__FLOAT_WORD_ORDER__) +/* Float word order not known, assume not a hybrid. */ +#define DUK_USE_BYTEORDER 3 +#else +/* Byte order is big endian but cannot determine IEEE double word order. */ +#endif /* float word order */ +#else +/* Cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit + * integer ordering and is not relevant. + */ +#endif /* integer byte order */ +#endif /* !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) */ -#if defined(DUK_F_MSVC) -/* _snprintf() does NOT NUL terminate on truncation, but Duktape code never - * assumes that. - * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 +/* More or less standard endianness predefines provided by header files. + * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER + * will be big endian, see: http://lists.mysql.com/internals/443. + * On some platforms some defines may be present with an empty value which + * causes comparisons to fail: https://github.com/svaarala/duktape/issues/453. */ -#define DUK_SNPRINTF _snprintf +#if !defined(DUK_USE_BYTEORDER) +#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \ + defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \ + defined(__LITTLE_ENDIAN__) +#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \ + defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN) +#define DUK_USE_BYTEORDER 1 +#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \ + defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN) +#define DUK_USE_BYTEORDER 2 +#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER) +/* Float word order not known, assume not a hybrid. */ +#define DUK_USE_BYTEORDER 1 #else -#define DUK_SNPRINTF snprintf +/* Byte order is little endian but cannot determine IEEE double word order. */ +#endif /* float word order */ +#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \ + defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \ + defined(__BIG_ENDIAN__) +#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \ + defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN) +#define DUK_USE_BYTEORDER 3 +#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER) +/* Float word order not known, assume not a hybrid. */ +#define DUK_USE_BYTEORDER 3 +#else +/* Byte order is big endian but cannot determine IEEE double word order. */ +#endif /* float word order */ +#else +/* Cannot determine byte order. */ +#endif /* integer byte order */ +#endif /* !defined(DUK_USE_BYTEORDER) */ + +/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__: + * $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian + * 67:#define __LITTLEENDIAN__ 1 + * $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian + * 81:#define __BIGENDIAN__ 1 + * $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian + * 70:#define __LITTLEENDIAN__ 1 + */ +#if !defined(DUK_USE_BYTEORDER) +#if defined(__LITTLEENDIAN__) +#define DUK_USE_BYTEORDER 1 +#elif defined(__BIGENDIAN__) +#define DUK_USE_BYTEORDER 3 +#endif #endif -#define DUK_VSPRINTF vsprintf +/* + * Alignment requirement and support for unaligned accesses + * + * Assume unaligned accesses are not supported unless specifically allowed + * in the target platform. Some platforms may support unaligned accesses + * but alignment to 4 or 8 may still be desirable. + */ -#if defined(DUK_F_MSVC) -#if (_MSC_VER < 1600) -/* Older MSVC version are missing vsnprintf() but have _vsnprintf(). */ -#define DUK_VSNPRINTF _vsnprintf -#else -#define DUK_VSNPRINTF vsnprintf +/* If not provided, use safe default for alignment. */ +#if !defined(DUK_USE_ALIGN_BY) +#define DUK_USE_ALIGN_BY 8 #endif -#else -#define DUK_VSNPRINTF vsnprintf -#endif /* DUK_F_MSVC */ -#define DUK_SSCANF sscanf -#define DUK_VSSCANF vsscanf -#define DUK_FOPEN fopen -#define DUK_FCLOSE fclose -#define DUK_FREAD fread -#define DUK_FWRITE fwrite -#define DUK_FSEEK fseek -#define DUK_FTELL ftell -#define DUK_FFLUSH fflush -#define DUK_FPUTC fputc - -#define DUK_MEMZERO(p,n) \ - DUK_MEMSET((p), 0, (n)) +/* User forced alignment to 4 or 8. */ +#if defined(DUK_OPT_FORCE_ALIGN) +#undef DUK_USE_ALIGN_BY +#if (DUK_OPT_FORCE_ALIGN == 4) +#define DUK_USE_ALIGN_BY 4 +#elif (DUK_OPT_FORCE_ALIGN == 8) +#define DUK_USE_ALIGN_BY 8 +#else +#error invalid DUK_OPT_FORCE_ALIGN value +#endif +#endif -/* - * Vararg macro wrappers. We need va_copy() which is defined in C99 / C++11, - * so an awkward replacement is needed for pre-C99 / pre-C++11 environments. - * This will quite likely need portability hacks for some non-C99 environments. +/* Compiler specific hackery needed to force struct size to match aligment, + * see e.g. duk_hbuffer.h. + * + * http://stackoverflow.com/questions/11130109/c-struct-size-alignment + * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment */ +#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \ + defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER)) +#define DUK_USE_PACK_DUMMY_MEMBER +#endif +#if !defined(DUK_VA_COPY) +/* We need va_copy() which is defined in C99 / C++11, so an awkward + * replacement is needed for pre-C99 / pre-C++11 environments. This + * will quite likely need portability hacks for some non-C99 + * environments. + */ #if defined(DUK_F_C99) || defined(DUK_F_CPP11) /* C99 / C++11 and above: rely on va_copy() which is required. * Omit parenthesis on macro right side on purpose to minimize differences * to direct use. */ #define DUK_VA_COPY(dest,src) va_copy(dest,src) -#elif defined(DUK_F_GCC) || defined(DUK_F_CLANG) -/* GCC: assume we have __va_copy() in non-C99 mode, which should be correct - * for even quite old GCC versions. Clang matches GCC behavior. - */ -#define DUK_VA_COPY(dest,src) __va_copy(dest,src) #else /* Pre-C99: va_list type is implementation dependent. This replacement * assumes it is a plain value so that a simple assignment will work. @@ -1844,156 +2365,48 @@ typedef FILE duk_file; */ #define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0) #endif +#endif -/* - * Miscellaneous ANSI C or other platform wrappers. - */ - -#define DUK_ABORT abort -#define DUK_EXIT exit - -/* - * Avoiding platform function pointers. - * - * On some platforms built-in functions may be implemented as macros or - * inline functions, so they can't be necessarily addressed by function - * pointers. This is certainly the case with some platform "polyfills" - * which provide missing C99/C++11 functions through macros, and may be - * the case with VS2013 (see GH-17). - */ - -/* This is now the default: the cost in footprint is negligible. */ -#define DUK_USE_AVOID_PLATFORM_FUNCPTRS - -/* - * Macro hackery to convert e.g. __LINE__ to a string without formatting, - * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string - */ - -#define DUK_F_STRINGIFY_HELPER(x) #x -#define DUK_MACRO_STRINGIFY(x) DUK_F_STRINGIFY_HELPER(x) - -/* - * Cause segfault macro. - * - * This is optionally used by panic handling to cause the program to segfault - * (instead of e.g. abort()) on panic. Valgrind will then indicate the C - * call stack leading to the panic. - */ - -#define DUK_CAUSE_SEGFAULT() do { \ - *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; \ - } while (0) - -/* - * Macro for suppressing warnings for potentially unreferenced variables. - * The variables can be actually unreferenced or unreferenced in some - * specific cases only; for instance, if a variable is only debug printed, - * it is unreferenced when debug printing is disabled. - * - * (Introduced here because it's potentially compiler specific.) - */ - -#define DUK_UNREF(x) do { \ - (void) (x); \ - } while (0) - -/* - * DUK_NORETURN: macro for declaring a 'noreturn' function. - * Unfortunately the noreturn declaration may appear in various - * places of a function declaration, so the solution is to wrap - * the entire declaration inside the macro. Compiler support - * for using a noreturn declaration on function pointers varies; - * this macro must only be used for actual function declarations. - * - * http://gcc.gnu.org/onlinedocs/gcc-4.3.2//gcc/Function-Attributes.html - * http://clang.llvm.org/docs/LanguageExtensions.html +#if !defined(DUK_MACRO_STRINGIFY) +/* Macro hackery to convert e.g. __LINE__ to a string without formatting, + * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string */ +#define DUK_MACRO_STRINGIFY_HELPER(x) #x +#define DUK_MACRO_STRINGIFY(x) DUK_MACRO_STRINGIFY_HELPER(x) +#endif -#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) -/* since gcc-2.5 */ -#define DUK_NORETURN(decl) decl __attribute__((noreturn)) -#elif defined(__clang__) -/* syntax same as gcc */ -#define DUK_NORETURN(decl) decl __attribute__((noreturn)) -#elif defined(DUK_F_MSVC) -/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */ -#define DUK_NORETURN(decl) __declspec(noreturn) decl -#else -/* Don't know how to declare a noreturn function, so don't do it; this - * may cause some spurious compilation warnings (e.g. "variable used - * uninitialized"). +#if !defined(DUK_CAUSE_SEGFAULT) +/* This is optionally used by panic handling to cause the program to segfault + * (instead of e.g. abort()) on panic. Valgrind will then indicate the C + * call stack leading to the panic. */ -#define DUK_NORETURN(decl) decl +#define DUK_CAUSE_SEGFAULT() do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0) #endif - -/* - * Macro for stating that a certain line cannot be reached. - * - * http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Other-Builtins.html#Other-Builtins - * http://clang.llvm.org/docs/LanguageExtensions.html +#if !defined(DUK_UNREF) +/* Macro for suppressing warnings for potentially unreferenced variables. + * The variables can be actually unreferenced or unreferenced in some + * specific cases only; for instance, if a variable is only debug printed, + * it is unreferenced when debug printing is disabled. */ - -#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) -/* since gcc-4.5 */ -#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0) -#elif defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_unreachable) -/* same as gcc */ -#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0) +#define DUK_UNREF(x) do { (void) (x); } while (0) #endif -#else -/* unknown */ +#if !defined(DUK_NORETURN) +#define DUK_NORETURN(decl) decl #endif - #if !defined(DUK_UNREACHABLE) /* Don't know how to declare unreachable point, so don't do it; this * may cause some spurious compilation warnings (e.g. "variable used * uninitialized"). */ -#define DUK_UNREACHABLE() /* unreachable */ +#define DUK_UNREACHABLE() do { } while (0) #endif - -/* - * Likely and unlikely branches. Using these is not at all a clear cut case, - * so the selection is a two-step process: (1) DUK_USE_BRANCH_HINTS is set - * if the architecture, compiler etc make it useful to use the hints, and (2) - * a separate check determines how to do them. - * - * These macros expect the argument to be a relational expression with an - * integer value. If used with pointers, you should use an explicit check - * like: - * - * if (DUK_LIKELY(ptr != NULL)) { ... } - * - * instead of: - * - * if (DUK_LIKELY(ptr)) { ... } - * - * http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html (__builtin_expect) - */ - -/* pretty much a placeholder now */ -#if defined(DUK_F_GCC) -#define DUK_USE_BRANCH_HINTS -#elif defined(DUK_F_CLANG) -#define DUK_USE_BRANCH_HINTS -#else -#undef DUK_USE_BRANCH_HINTS -#endif - -#if defined(DUK_USE_BRANCH_HINTS) -#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L) -/* GCC: test not very accurate; enable only in relatively recent builds - * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html) +#if !defined(DUK_LOSE_CONST) +/* Convert any input pointer into a "void *", losing a const qualifier. + * This is not fully portable because casting through duk_uintptr_t may + * not work on all architectures (e.g. those with long, segmented pointers). */ -#define DUK_LIKELY(x) __builtin_expect((x), 1) -#define DUK_UNLIKELY(x) __builtin_expect((x), 0) -#elif defined(DUK_F_CLANG) -#define DUK_LIKELY(x) __builtin_expect((x), 1) -#define DUK_UNLIKELY(x) __builtin_expect((x), 0) +#define DUK_LOSE_CONST(src) ((void *) (duk_uintptr_t) (src)) #endif -#endif /* DUK_USE_BRANCH_HINTS */ #if !defined(DUK_LIKELY) #define DUK_LIKELY(x) (x) @@ -2002,1041 +2415,957 @@ typedef FILE duk_file; #define DUK_UNLIKELY(x) (x) #endif -/* - * Function inlining control - * - * DUK_NOINLINE: avoid inlining a function. - * DUK_INLINE: suggest inlining a function. - * DUK_ALWAYS_INLINE: force inlining for critical functions. - * - * Apply to function definition only (not declaration). - */ - -#if defined(DUK_F_CLANG) && (defined(DUK_F_C99) || defined(DUK_F_CPP11)) -#define DUK_NOINLINE __attribute__((noinline)) -#define DUK_INLINE inline -#define DUK_ALWAYS_INLINE inline __attribute__((always_inline)) -#elif defined(DUK_F_GCC) && defined(DUK_F_GCC_VERSION) && (defined(DUK_F_C99) || defined(DUK_F_CPP11)) -#if (DUK_F_GCC_VERSION >= 30101) -#define DUK_NOINLINE __attribute__((noinline)) -#define DUK_INLINE inline -#define DUK_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif -#endif - #if !defined(DUK_NOINLINE) #define DUK_NOINLINE /*nop*/ -#define DUK_INLINE /*nop*/ -#define DUK_ALWAYS_INLINE /*nop*/ #endif - -/* Temporary workaround for GH-323: avoid inlining control when - * compiling from multiple sources, as it causes compiler trouble. - */ -#if !defined(DUK_SINGLE_FILE) -#undef DUK_NOINLINE -#undef DUK_INLINE -#undef DUK_ALWAYS_INLINE -#define DUK_NOINLINE /*nop*/ +#if !defined(DUK_INLINE) #define DUK_INLINE /*nop*/ +#endif +#if !defined(DUK_ALWAYS_INLINE) #define DUK_ALWAYS_INLINE /*nop*/ #endif -/* - * Symbol visibility macros - * - * To avoid C++ declaration issues (see GH-63): - * - * - Don't use DUK_LOCAL_DECL for local -data symbols- so that you don't - * end up with both a "static" declaration and a definition. - * - * - Wrap any DUK_INTERNAL_DECL with a '#if !defined(DUK_SINGLE_FILE)' - * so that the internal declarations (which would map to "static" in - * a single file distribution) get dropped. - */ - -/* XXX: user override for these? user override for just using the default visibility macros? */ -/* XXX: separate macros for function and data may be necessary at some point. */ - -#if defined(DUK_F_GCC_VERSION) -#if (DUK_F_GCC_VERSION >= 40000) && !(defined(DUK_F_MINGW) || defined(DUK_F_CYGWIN)) -/* Might work on earlier versions too but limit to GCC 4+. - * MinGW should use Windows specific __declspec or no visibility attributes at all, - * otherwise: "warning: visibility attribute not supported in this configuration; ignored". - * Same applies to Cygwin GCC. - */ -#define DUK_F_GCC_SYMBOL_VISIBILITY -#endif -#endif -#if defined(DUK_F_CLANG) && !defined(DUK_F_GCC_SYMBOL_VISIBILITY) -#define DUK_F_GCC_SYMBOL_VISIBILITY +#if !defined(DUK_EXTERNAL_DECL) +#define DUK_EXTERNAL_DECL extern #endif -#if defined(DUK_OPT_DLL_BUILD) && defined(_WIN32) && (defined(_MSC_VER) || defined(__GNUC__)) -/* __declspec(dllexport) and __declspec(dllimport) only for Windows DLL build. - * MSVC: any minimum version? - * MinGW: no minimum version, even gcc-2.95.3 supported dllimport/dllexport. -*/ -#define DUK_F_MSVC_DLL_SYMBOL_VISIBILITY +#if !defined(DUK_EXTERNAL) +#define DUK_EXTERNAL /*empty*/ #endif - -#if defined(DUK_F_GCC_SYMBOL_VISIBILITY) -/* GCC 4+ visibility attributes. */ -#define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern -#define DUK_EXTERNAL __attribute__ ((visibility("default"))) +#if !defined(DUK_INTERNAL_DECL) #if defined(DUK_SINGLE_FILE) #define DUK_INTERNAL_DECL static -#define DUK_INTERNAL static #else -#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern -#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) +#define DUK_INTERNAL_DECL extern #endif -#elif defined(DUK_F_MSVC_DLL_SYMBOL_VISIBILITY) -/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're - * compiling Duktape or the application. - */ -#if defined(DUK_COMPILING_DUKTAPE) -#define DUK_EXTERNAL_DECL extern __declspec(dllexport) -#define DUK_EXTERNAL __declspec(dllexport) -#else -#define DUK_EXTERNAL_DECL extern __declspec(dllimport) -#define DUK_EXTERNAL should_not_happen #endif +#if !defined(DUK_INTERNAL) #if defined(DUK_SINGLE_FILE) -#define DUK_INTERNAL_DECL static #define DUK_INTERNAL static #else -#define DUK_INTERNAL_DECL extern #define DUK_INTERNAL /*empty*/ #endif -#else -/* Default visibility. */ -#define DUK_EXTERNAL_DECL extern -#define DUK_EXTERNAL /*empty*/ -#if defined(DUK_SINGLE_FILE) -#define DUK_INTERNAL_DECL static -#define DUK_INTERNAL static -#else /* DUK_SINGLE_FILE */ -#define DUK_INTERNAL_DECL extern -#define DUK_INTERNAL /*empty*/ #endif -#endif - -/* For now, these are shared. */ +#if !defined(DUK_LOCAL_DECL) #define DUK_LOCAL_DECL static +#endif +#if !defined(DUK_LOCAL) #define DUK_LOCAL static +#endif -/* - * __FILE__, __LINE__, __func__ are wrapped. Especially __func__ is a - * problem because it is not available even in some compilers which try - * to be C99 compatible (e.g. VBCC with -c99 option). - */ - +#if !defined(DUK_FILE_MACRO) #define DUK_FILE_MACRO __FILE__ - +#endif +#if !defined(DUK_LINE_MACRO) #define DUK_LINE_MACRO __LINE__ - -#if !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) +#endif +#if !defined(DUK_FUNC_MACRO) +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) #define DUK_FUNC_MACRO __func__ +#elif defined(__FUNCTION__) +#define DUK_FUNC_MACRO __FUNCTION__ #else #define DUK_FUNC_MACRO "unknown" #endif +#endif -/* - * Byteswap macros - * - * These are here so that inline assembly or other platform functions can be - * used if available. - */ - +#if !defined(DUK_BSWAP32) #define DUK_BSWAP32(x) \ ((((duk_uint32_t) (x)) >> 24) | \ ((((duk_uint32_t) (x)) >> 8) & 0xff00UL) | \ ((((duk_uint32_t) (x)) << 8) & 0xff0000UL) | \ (((duk_uint32_t) (x)) << 24)) - +#endif +#if !defined(DUK_BSWAP16) #define DUK_BSWAP16(x) \ ((duk_uint16_t) (x) >> 8) | \ ((duk_uint16_t) (x) << 8) - -/* - * Architecture string, human readable value exposed in Duktape.env - */ - -#if defined(DUK_F_X86) -#define DUK_USE_ARCH_STRING "x86" -#elif defined(DUK_F_X32) -#define DUK_USE_ARCH_STRING "x32" -#elif defined(DUK_F_X64) -#define DUK_USE_ARCH_STRING "x64" -#elif defined(DUK_F_ARM) -#define DUK_USE_ARCH_STRING "arm" -#elif defined(DUK_F_MIPS32) -#define DUK_USE_ARCH_STRING "mips32" -#elif defined(DUK_F_MIPS64) -#define DUK_USE_ARCH_STRING "mips64" -#elif defined(DUK_F_SUPERH) -#define DUK_USE_ARCH_STRING "sh" -#elif defined(DUK_F_PPC) -#define DUK_USE_ARCH_STRING "ppc" -#elif defined(DUK_F_M68K) -#define DUK_USE_ARCH_STRING "m68k" -#elif defined(DUK_F_FLASHPLAYER) -#define DUK_USE_ARCH_STRING "flashplayer" -#elif defined(DUK_F_EMSCRIPTEN) -#define DUK_USE_ARCH_STRING "emscripten" -#else -#define DUK_USE_ARCH_STRING "unknown" #endif -/* - * OS string, human readable value exposed in Duktape.env - */ +/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */ +#if !defined(DUK_F_VARIADIC_MACROS_PROVIDED) +#undef DUK_USE_VARIADIC_MACROS +#if defined(DUK_F_C99) || defined(DUK_F_CPP11) +#define DUK_USE_VARIADIC_MACROS +#endif +#endif -#if defined(DUK_F_LINUX) -#define DUK_USE_OS_STRING "linux" -#elif defined(__APPLE__) -/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */ -#if TARGET_IPHONE_SIMULATOR -#define DUK_USE_OS_STRING "iphone-sim" -#elif TARGET_OS_IPHONE -#define DUK_USE_OS_STRING "iphone" -#elif TARGET_OS_MAC -#define DUK_USE_OS_STRING "ios" +#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || defined(DUK_USE_FLEX_ONESIZE)) +#if defined(DUK_F_C99) +#define DUK_USE_FLEX_C99 #else -#define DUK_USE_OS_STRING "ios-unknown" +#define DUK_USE_FLEX_ZEROSIZE /* Not standard but common enough */ #endif -#elif defined(DUK_F_FREEBSD) -#define DUK_USE_OS_STRING "freebsd" -#elif defined(DUK_F_OPENBSD) -#define DUK_USE_OS_STRING "openbsd" -#elif defined(DUK_F_NETBSD) -#define DUK_USE_OS_STRING "netbsd" -#elif defined(DUK_F_BSD) -#define DUK_USE_OS_STRING "bsd" -#elif defined(DUK_F_UNIX) -#define DUK_USE_OS_STRING "unix" -#elif defined(DUK_F_WINDOWS) -#define DUK_USE_OS_STRING "windows" -#elif defined(DUK_F_TOS) -#define DUK_USE_OS_STRING "tos" -#elif defined(DUK_F_AMIGAOS) -#define DUK_USE_OS_STRING "amigaos" -#elif defined(DUK_F_QNX) -#define DUK_USE_OS_STRING "qnx" -#elif defined(DUK_F_TINSPIRE) -#define DUK_USE_OS_STRING "tinspire" -#else -#define DUK_USE_OS_STRING "unknown" #endif -/* - * Compiler string, human readable value exposed in Duktape.env - */ - -#if defined(DUK_F_MINGW) -#define DUK_USE_COMPILER_STRING "mingw" -#elif defined(DUK_F_GCC) -#if defined(DUK_F_CPP) -#define DUK_USE_COMPILER_STRING "g++" -#else -#define DUK_USE_COMPILER_STRING "gcc" +#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \ + defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER)) +#define DUK_USE_PACK_DUMMY_MEMBER #endif -#elif defined(DUK_F_CLANG) -#define DUK_USE_COMPILER_STRING "clang" -#elif defined(DUK_F_MSVC) -#define DUK_USE_COMPILER_STRING "msvc" -#elif defined(DUK_F_VBCC) -#define DUK_USE_COMPILER_STRING "vbcc" -#else -#define DUK_USE_COMPILER_STRING "unknown" + +#if 0 /* not defined by default */ +#undef DUK_USE_GCC_PRAGMAS #endif -/* - * Target info string +/* Workaround for GH-323: avoid inlining control when compiling from + * multiple sources, as it causes compiler portability trouble. */ - -#if defined(DUK_OPT_TARGET_INFO) -#define DUK_USE_TARGET_INFO DUK_OPT_TARGET_INFO -#else -#define DUK_USE_TARGET_INFO "unknown" +#if !defined(DUK_SINGLE_FILE) +#undef DUK_NOINLINE +#undef DUK_INLINE +#undef DUK_ALWAYS_INLINE +#define DUK_NOINLINE /*nop*/ +#define DUK_INLINE /*nop*/ +#define DUK_ALWAYS_INLINE /*nop*/ #endif /* - * Long control transfer, setjmp/longjmp or alternatives - * - * Signal mask is not saved (when that can be communicated to the platform) + * Check whether or not a packed duk_tval representation is possible. + * What's basically required is that pointers are 32-bit values + * (sizeof(void *) == 4). Best effort check, not always accurate. + * If guess goes wrong, crashes may result; self tests also verify + * the guess. */ -/* dummy non-zero value to be used as an argument for longjmp(), see man longjmp */ -#define DUK_LONGJMP_DUMMY_VALUE 1 +/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */ +#if !defined(DUK_F_PACKED_TVAL_PROVIDED) +#undef DUK_F_PACKED_TVAL_POSSIBLE -#if defined(DUK_OPT_SETJMP) -#define DUK_USE_SETJMP -#elif defined(DUK_OPT_UNDERSCORE_SETJMP) -#define DUK_USE_UNDERSCORE_SETJMP -#elif defined(DUK_OPT_SIGSETJMP) -#define DUK_USE_SIGSETJMP -#elif defined(__APPLE__) -/* Use _setjmp() on Apple by default, see GH-55. */ -#define DUK_USE_UNDERSCORE_SETJMP -#else -/* The most portable default is setjmp(). */ -#define DUK_USE_SETJMP +/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */ +#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) +#if (DUK_UINTPTR_MAX <= 0xffffffffUL) +#define DUK_F_PACKED_TVAL_POSSIBLE +#endif #endif -#if defined(DUK_USE_UNDERSCORE_SETJMP) -#define DUK_SETJMP(jb) _setjmp((jb)) -#define DUK_LONGJMP(jb) _longjmp((jb), DUK_LONGJMP_DUMMY_VALUE) -#elif defined(DUK_USE_SIGSETJMP) -#define DUK_SETJMP(jb) sigsetjmp((jb), 0 /*savesigs*/) -#define DUK_LONGJMP(jb) siglongjmp((jb), DUK_LONGJMP_DUMMY_VALUE) -#elif defined(DUK_USE_SETJMP) -#define DUK_SETJMP(jb) setjmp((jb)) -#define DUK_LONGJMP(jb) longjmp((jb), DUK_LONGJMP_DUMMY_VALUE) -#else -#error internal error +/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */ +#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED) +#if (DUK_UINTPTR_MAX <= 0xffffffffUL) +#define DUK_F_PACKED_TVAL_POSSIBLE +#endif #endif -/* - * Speed/size and other performance options - */ +/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */ +#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED) +#if (DUK_SIZE_MAX <= 0xffffffffUL) +#define DUK_F_PACKED_TVAL_POSSIBLE +#endif +#endif -/* Use fast ("inline") refcount operations instead of calling out to helpers - * by default. The difference in binary size is small (~1kB on x64). - */ -#define DUK_USE_FAST_REFCOUNT_DEFAULT +#undef DUK_USE_PACKED_TVAL +#if defined(DUK_F_PACKED_TVAL_POSSIBLE) +#define DUK_USE_PACKED_TVAL +#endif -/* Assert for valstack space but don't check for it in non-assert build. - * Valstack overruns (writing beyond checked space) is memory unsafe and - * potentially a segfault. Produces a smaller and faster binary. - * (In practice the speed difference is small with -O3 so default to - * safer behavior for now.) - */ -#undef DUK_USE_VALSTACK_UNSAFE +#undef DUK_F_PACKED_TVAL_POSSIBLE +#endif /* DUK_F_PACKED_TVAL_PROVIDED */ -/* Catch-all flag which can be used to choose between variant algorithms - * where a speed-size tradeoff exists (e.g. lookup tables). When it really - * matters, specific use flags may be appropriate. +/* Feature option forcing. */ +#if defined(DUK_OPT_NO_PACKED_TVAL) +#undef DUK_USE_PACKED_TVAL +#elif defined(DUK_OPT_PACKED_TVAL) +#undef DUK_USE_PACKED_TVAL +#define DUK_USE_PACKED_TVAL +#endif +/* Object property allocation layout has implications for memory and code + * footprint and generated code size/speed. The best layout also depends + * on whether the platform has alignment requirements or benefits from + * having mostly aligned accesses. */ -#undef DUK_USE_PREFER_SIZE - -/* Use a sliding window for lexer; slightly larger footprint, slightly faster. */ -#define DUK_USE_LEXER_SLIDING_WINDOW +#undef DUK_USE_HOBJECT_LAYOUT_1 +#undef DUK_USE_HOBJECT_LAYOUT_2 +#undef DUK_USE_HOBJECT_LAYOUT_3 +#if (DUK_USE_ALIGN_BY == 1) +/* On platforms without any alignment issues, layout 1 is preferable + * because it compiles to slightly less code and provides direct access + * to property keys. + */ +#define DUK_USE_HOBJECT_LAYOUT_1 +#else +/* On other platforms use layout 2, which requires some padding but + * is a bit more natural than layout 3 in ordering the entries. Layout + * 3 is currently not used. + */ +#define DUK_USE_HOBJECT_LAYOUT_2 +#endif -/* Transparent JSON.stringify() fastpath. */ -#undef DUK_USE_JSON_STRINGIFY_FASTPATH -#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH) -#define DUK_USE_JSON_STRINGIFY_FASTPATH +/* GCC/clang inaccurate math would break compliance and probably duk_tval, + * so refuse to compile. Relax this if -ffast-math is tested to work. + */ +#if defined(__FAST_MATH__) +#error __FAST_MATH__ defined, refusing to compile #endif /* - * Tagged type representation (duk_tval) + * Feature option handling */ -#undef DUK_USE_PACKED_TVAL -#undef DUK_USE_FULL_TVAL - -#if defined(DUK_USE_PACKED_TVAL_POSSIBLE) && !defined(DUK_OPT_NO_PACKED_TVAL) -#define DUK_USE_PACKED_TVAL +#if !defined(DUK_USE_ALIGN_BY) +#if defined(DUK_OPT_FORCE_ALIGN) +#define DUK_USE_ALIGN_BY DUK_OPT_FORCE_ALIGN +#else +#define DUK_USE_ALIGN_BY 8 +#endif #endif -/* Support for 48-bit signed integer duk_tval with transparent semantics. */ -#undef DUK_USE_FASTINT -#if defined(DUK_OPT_FASTINT) -#if !defined(DUK_F_HAVE_64BIT) -#error DUK_OPT_FASTINT requires 64-bit integer type support at the moment +#if defined(DUK_OPT_ASSERTIONS) +#define DUK_USE_ASSERTIONS +#elif defined(DUK_OPT_NO_ASSERTIONS) +#undef DUK_USE_ASSERTIONS +#else +#undef DUK_USE_ASSERTIONS #endif -#define DUK_USE_FASTINT + +#if defined(DUK_OPT_AUGMENT_ERRORS) +#define DUK_USE_AUGMENT_ERROR_CREATE +#elif defined(DUK_OPT_NO_AUGMENT_ERRORS) +#undef DUK_USE_AUGMENT_ERROR_CREATE +#else +#define DUK_USE_AUGMENT_ERROR_CREATE #endif -/* - * Memory management options - */ +#if defined(DUK_OPT_AUGMENT_ERRORS) +#define DUK_USE_AUGMENT_ERROR_THROW +#elif defined(DUK_OPT_NO_AUGMENT_ERRORS) +#undef DUK_USE_AUGMENT_ERROR_THROW +#else +#define DUK_USE_AUGMENT_ERROR_THROW +#endif -#define DUK_USE_REFERENCE_COUNTING -#define DUK_USE_DOUBLE_LINKED_HEAP -#define DUK_USE_MARK_AND_SWEEP -#define DUK_USE_MS_STRINGTABLE_RESIZE +#if defined(DUK_OPT_BROWSER_LIKE) +#define DUK_USE_BROWSER_LIKE +#elif defined(DUK_OPT_NO_BROWSER_LIKE) +#undef DUK_USE_BROWSER_LIKE +#else +#define DUK_USE_BROWSER_LIKE +#endif -#if defined(DUK_OPT_NO_REFERENCE_COUNTING) -#undef DUK_USE_REFERENCE_COUNTING -#undef DUK_USE_DOUBLE_LINKED_HEAP -/* XXX: undef DUK_USE_MS_STRINGTABLE_RESIZE as it is more expensive - * with more frequent mark-and-sweeps? - */ +#if defined(DUK_OPT_BUFFEROBJECT_SUPPORT) +#define DUK_USE_BUFFEROBJECT_SUPPORT +#elif defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT) +#undef DUK_USE_BUFFEROBJECT_SUPPORT +#else +#define DUK_USE_BUFFEROBJECT_SUPPORT #endif -#if defined(DUK_OPT_NO_MARK_AND_SWEEP) -#undef DUK_USE_MARK_AND_SWEEP +#if defined(DUK_OPT_BUFLEN16) +#define DUK_USE_BUFLEN16 +#elif defined(DUK_OPT_NO_BUFLEN16) +#undef DUK_USE_BUFLEN16 +#else +#undef DUK_USE_BUFLEN16 #endif -#if defined(DUK_USE_MARK_AND_SWEEP) -#define DUK_USE_VOLUNTARY_GC -#if defined(DUK_OPT_NO_VOLUNTARY_GC) -#undef DUK_USE_VOLUNTARY_GC +#if defined(DUK_OPT_BYTECODE_DUMP_SUPPORT) +#define DUK_USE_BYTECODE_DUMP_SUPPORT +#elif defined(DUK_OPT_NO_BYTECODE_DUMP_SUPPORT) +#undef DUK_USE_BYTECODE_DUMP_SUPPORT +#else +#define DUK_USE_BYTECODE_DUMP_SUPPORT #endif + +#if defined(DUK_OPT_COMMONJS_MODULES) +#define DUK_USE_COMMONJS_MODULES +#elif defined(DUK_OPT_NO_COMMONJS_MODULES) +#undef DUK_USE_COMMONJS_MODULES +#else +#define DUK_USE_COMMONJS_MODULES #endif -#if !defined(DUK_USE_MARK_AND_SWEEP) && !defined(DUK_USE_REFERENCE_COUNTING) -#error must have either mark-and-sweep or reference counting enabled +#if defined(DUK_OPT_DATAPTR16) +#define DUK_USE_DATAPTR16 +#elif defined(DUK_OPT_NO_DATAPTR16) +#undef DUK_USE_DATAPTR16 +#else +#undef DUK_USE_DATAPTR16 #endif -#if defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE) -#undef DUK_USE_MS_STRINGTABLE_RESIZE +#if defined(DUK_OPT_DATAPTR_DEC16) +#define DUK_USE_DATAPTR_DEC16(udata,ptr) DUK_OPT_DATAPTR_DEC16((udata),(ptr)) +#else +#undef DUK_USE_DATAPTR_DEC16 #endif -#undef DUK_USE_GC_TORTURE -#if defined(DUK_OPT_GC_TORTURE) -#define DUK_USE_GC_TORTURE +#if defined(DUK_OPT_DATAPTR_ENC16) +#define DUK_USE_DATAPTR_ENC16(udata,ptr) DUK_OPT_DATAPTR_ENC16((udata),(ptr)) +#else +#undef DUK_USE_DATAPTR_ENC16 #endif -/* - * String table options - */ +#if defined(DUK_OPT_DDDPRINT) +#define DUK_USE_DDDPRINT +#elif defined(DUK_OPT_NO_DDDPRINT) +#undef DUK_USE_DDDPRINT +#else +#undef DUK_USE_DDDPRINT +#endif -#if defined(DUK_OPT_STRTAB_CHAIN) && defined(DUK_OPT_STRTAB_CHAIN_SIZE) -/* Low memory algorithm: separate chaining using arrays, fixed size hash */ -#define DUK_USE_STRTAB_CHAIN -#define DUK_USE_STRTAB_CHAIN_SIZE DUK_OPT_STRTAB_CHAIN_SIZE +#if defined(DUK_OPT_DDPRINT) +#define DUK_USE_DDPRINT +#elif defined(DUK_OPT_NO_DDPRINT) +#undef DUK_USE_DDPRINT #else -/* Default algorithm: open addressing (probing) */ -#define DUK_USE_STRTAB_PROBE +#undef DUK_USE_DDPRINT #endif -/* - * Error handling options - */ +#if defined(DUK_OPT_DEBUG) +#define DUK_USE_DEBUG +#elif defined(DUK_OPT_NO_DEBUG) +#undef DUK_USE_DEBUG +#else +#undef DUK_USE_DEBUG +#endif -#define DUK_USE_AUGMENT_ERROR_CREATE -#define DUK_USE_AUGMENT_ERROR_THROW -#define DUK_USE_TRACEBACKS -#define DUK_USE_ERRCREATE -#define DUK_USE_ERRTHROW +#if defined(DUK_OPT_DEBUGGER_DUMPHEAP) +#define DUK_USE_DEBUGGER_DUMPHEAP +#elif defined(DUK_OPT_NO_DEBUGGER_DUMPHEAP) +#undef DUK_USE_DEBUGGER_DUMPHEAP +#else +#undef DUK_USE_DEBUGGER_DUMPHEAP +#endif -#define DUK_USE_VERBOSE_ERRORS +#if defined(DUK_OPT_DEBUGGER_FWD_LOGGING) +#define DUK_USE_DEBUGGER_FWD_LOGGING +#elif defined(DUK_OPT_NO_DEBUGGER_FWD_LOGGING) +#undef DUK_USE_DEBUGGER_FWD_LOGGING +#else +#undef DUK_USE_DEBUGGER_FWD_LOGGING +#endif -#if defined(DUK_OPT_NO_AUGMENT_ERRORS) -#undef DUK_USE_AUGMENT_ERROR_CREATE -#undef DUK_USE_AUGMENT_ERROR_THROW -#undef DUK_USE_TRACEBACKS -#undef DUK_USE_ERRCREATE -#undef DUK_USE_ERRTHROW -#elif defined(DUK_OPT_NO_TRACEBACKS) -#undef DUK_USE_TRACEBACKS +#if defined(DUK_OPT_DEBUGGER_FWD_PRINTALERT) +#define DUK_USE_DEBUGGER_FWD_PRINTALERT +#elif defined(DUK_OPT_NO_DEBUGGER_FWD_PRINTALERT) +#undef DUK_USE_DEBUGGER_FWD_PRINTALERT +#else +#undef DUK_USE_DEBUGGER_FWD_PRINTALERT #endif -#if defined(DUK_OPT_NO_VERBOSE_ERRORS) -#undef DUK_USE_VERBOSE_ERRORS +#if defined(DUK_OPT_DEBUGGER_PAUSE_UNCAUGHT) +#define DUK_USE_DEBUGGER_PAUSE_UNCAUGHT +#elif defined(DUK_OPT_NO_DEBUGGER_PAUSE_UNCAUGHT) +#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT +#else +#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT #endif -#if defined(DUK_USE_TRACEBACKS) -#if defined(DUK_OPT_TRACEBACK_DEPTH) -#define DUK_USE_TRACEBACK_DEPTH DUK_OPT_TRACEBACK_DEPTH +#if defined(DUK_OPT_DEBUGGER_SUPPORT) +#define DUK_USE_DEBUGGER_SUPPORT +#elif defined(DUK_OPT_NO_DEBUGGER_SUPPORT) +#undef DUK_USE_DEBUGGER_SUPPORT #else -#define DUK_USE_TRACEBACK_DEPTH 10 +#undef DUK_USE_DEBUGGER_SUPPORT #endif + +#if defined(DUK_OPT_DEBUGGER_THROW_NOTIFY) +#define DUK_USE_DEBUGGER_THROW_NOTIFY +#elif defined(DUK_OPT_NO_DEBUGGER_THROW_NOTIFY) +#undef DUK_USE_DEBUGGER_THROW_NOTIFY +#else +#undef DUK_USE_DEBUGGER_THROW_NOTIFY #endif -/* Include messages in executor internal errors. */ -#define DUK_USE_VERBOSE_EXECUTOR_ERRORS +#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE) +#define DUK_USE_DEBUGGER_TRANSPORT_TORTURE +#elif defined(DUK_OPT_NO_DEBUGGER_TRANSPORT_TORTURE) +#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE +#else +#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE +#endif -/* - * Execution and debugger options - */ +#if defined(DUK_OPT_DEBUG_BUFSIZE) +#define DUK_USE_DEBUG_BUFSIZE DUK_OPT_DEBUG_BUFSIZE +#else +#define DUK_USE_DEBUG_BUFSIZE 65536L +#endif -#undef DUK_USE_INTERRUPT_COUNTER -#if defined(DUK_OPT_INTERRUPT_COUNTER) -#define DUK_USE_INTERRUPT_COUNTER +#if defined(DUK_OPT_REFERENCE_COUNTING) +#define DUK_USE_DOUBLE_LINKED_HEAP +#elif defined(DUK_OPT_NO_REFERENCE_COUNTING) +#undef DUK_USE_DOUBLE_LINKED_HEAP +#else +#define DUK_USE_DOUBLE_LINKED_HEAP #endif -#undef DUK_USE_EXEC_TIMEOUT_CHECK -#if defined(DUK_OPT_EXEC_TIMEOUT_CHECK) -#define DUK_USE_EXEC_TIMEOUT_CHECK(udata) DUK_OPT_EXEC_TIMEOUT_CHECK((udata)) +#if defined(DUK_OPT_DPRINT) +#define DUK_USE_DPRINT +#elif defined(DUK_OPT_NO_DPRINT) +#undef DUK_USE_DPRINT +#else +#undef DUK_USE_DPRINT #endif -#undef DUK_USE_DEBUGGER_SUPPORT -#if defined(DUK_OPT_DEBUGGER_SUPPORT) -#define DUK_USE_DEBUGGER_SUPPORT +#if defined(DUK_OPT_DPRINT_COLORS) +#define DUK_USE_DPRINT_COLORS +#elif defined(DUK_OPT_NO_DPRINT_COLORS) +#undef DUK_USE_DPRINT_COLORS +#else +#undef DUK_USE_DPRINT_COLORS #endif -#undef DUK_USE_DEBUGGER_FWD_PRINTALERT -#if defined(DUK_OPT_DEBUGGER_SUPPORT) && defined(DUK_OPT_DEBUGGER_FWD_PRINTALERT) -#define DUK_USE_DEBUGGER_FWD_PRINTALERT +#if defined(DUK_OPT_DPRINT_RDTSC) +#define DUK_USE_DPRINT_RDTSC +#elif defined(DUK_OPT_NO_DPRINT_RDTSC) +#undef DUK_USE_DPRINT_RDTSC +#else +#undef DUK_USE_DPRINT_RDTSC #endif -#undef DUK_USE_DEBUGGER_FWD_LOGGING -#if defined(DUK_OPT_DEBUGGER_SUPPORT) && defined(DUK_OPT_DEBUGGER_FWD_LOGGING) -#define DUK_USE_DEBUGGER_FWD_LOGGING +#if defined(DUK_OPT_AUGMENT_ERRORS) +#define DUK_USE_ERRCREATE +#elif defined(DUK_OPT_NO_AUGMENT_ERRORS) +#undef DUK_USE_ERRCREATE +#else +#define DUK_USE_ERRCREATE #endif -/* DumpHeap is optional because it's not always needed and has a relatively - * large footprint. - */ -#undef DUK_USE_DEBUGGER_DUMPHEAP -#if defined(DUK_OPT_DEBUGGER_DUMPHEAP) -#define DUK_USE_DEBUGGER_DUMPHEAP +#if defined(DUK_OPT_AUGMENT_ERRORS) +#define DUK_USE_ERRTHROW +#elif defined(DUK_OPT_NO_AUGMENT_ERRORS) +#undef DUK_USE_ERRTHROW +#else +#define DUK_USE_ERRTHROW #endif -#define DUK_USE_DEBUGGER_THROW_NOTIFY -#if defined(DUK_OPT_NO_DEBUGGER_THROW_NOTIFY) -#undef DUK_USE_DEBUGGER_THROW_NOTIFY +#if defined(DUK_OPT_ES6_OBJECT_PROTO_PROPERTY) +#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY +#elif defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY) +#undef DUK_USE_ES6_OBJECT_PROTO_PROPERTY +#else +#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY #endif -#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT -#if defined(DUK_OPT_DEBUGGER_PAUSE_UNCAUGHT) -#define DUK_USE_DEBUGGER_PAUSE_UNCAUGHT +#if defined(DUK_OPT_ES6_OBJECT_SETPROTOTYPEOF) +#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF +#elif defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF) +#undef DUK_USE_ES6_OBJECT_SETPROTOTYPEOF +#else +#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF #endif -/* Debugger transport read/write torture. */ -#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE -#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE) -#define DUK_USE_DEBUGGER_TRANSPORT_TORTURE +#if defined(DUK_OPT_ES6_PROXY) +#define DUK_USE_ES6_PROXY +#elif defined(DUK_OPT_NO_ES6_PROXY) +#undef DUK_USE_ES6_PROXY +#else +#define DUK_USE_ES6_PROXY #endif -/* For opcodes with indirect indices, check final index against stack size. - * This should not be necessary because the compiler is trusted, and we don't - * bound check non-indirect indices either. - */ #undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK #if defined(DUK_OPT_DEBUG) || defined(DUK_OPT_ASSERTIONS) /* Enabled with debug/assertions just so that any issues can be caught. */ #define DUK_USE_EXEC_INDIRECT_BOUND_CHECK #endif -/* - * Debug printing and assertion options - */ +#undef DUK_USE_EXEC_TIMEOUT_CHECK +#if defined(DUK_OPT_EXEC_TIMEOUT_CHECK) +#define DUK_USE_EXEC_TIMEOUT_CHECK(udata) DUK_OPT_EXEC_TIMEOUT_CHECK((udata)) +#endif -#undef DUK_USE_DEBUG -#undef DUK_USE_DPRINT -#undef DUK_USE_DDPRINT -#undef DUK_USE_DDDPRINT -#undef DUK_USE_DPRINT_RDTSC -#undef DUK_USE_ASSERTIONS +#undef DUK_USE_EXTSTR_FREE +#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_FREE) +#define DUK_USE_EXTSTR_FREE(udata,ptr) DUK_OPT_EXTSTR_FREE((udata), (ptr)) +#endif -/* Global debug enable. Compile must be clean on C99 regardless of whether or - * not debugging is enabled. On non-C99 platforms compile should be clean with - * debugging disabled but may produce warnings with debugging enabled (related - * to debug macro hackery and such). - */ -#if defined(DUK_OPT_DEBUG) -#define DUK_USE_DEBUG +#undef DUK_USE_EXTSTR_INTERN_CHECK +#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_INTERN_CHECK) +#define DUK_USE_EXTSTR_INTERN_CHECK(udata,ptr,len) DUK_OPT_EXTSTR_INTERN_CHECK((udata), (ptr), (len)) #endif -#if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DPRINT) -#define DUK_USE_DPRINT +/* Support for 48-bit signed integer duk_tval with transparent semantics. */ +#undef DUK_USE_FASTINT +#if defined(DUK_OPT_FASTINT) +#if !defined(DUK_F_HAVE_64BIT) +#error DUK_OPT_FASTINT requires 64-bit integer type support at the moment #endif -#if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DDPRINT) -#define DUK_USE_DDPRINT +#define DUK_USE_FASTINT #endif -#if defined(DUK_OPT_DEBUG) && defined(DUK_OPT_DDDPRINT) -#define DUK_USE_DDDPRINT + +#if defined(DUK_OPT_FILE_IO) +#define DUK_USE_FILE_IO +#elif defined(DUK_OPT_NO_FILE_IO) +#undef DUK_USE_FILE_IO +#else +#define DUK_USE_FILE_IO #endif -#undef DUK_USE_DPRINT_COLORS -#if defined(DUK_OPT_DPRINT_COLORS) -#define DUK_USE_DPRINT_COLORS +#if defined(DUK_OPT_FUNCPTR16) +#define DUK_USE_FUNCPTR16 +#elif defined(DUK_OPT_NO_FUNCPTR16) +#undef DUK_USE_FUNCPTR16 +#else +#undef DUK_USE_FUNCPTR16 #endif -#if defined(DUK_USE_RDTSC) && defined(DUK_OPT_DPRINT_RDTSC) -#define DUK_USE_DPRINT_RDTSC +#if defined(DUK_OPT_FUNCPTR_DEC16) +#define DUK_USE_FUNCPTR_DEC16(udata,ptr) DUK_OPT_FUNCPTR_DEC16((udata),(ptr)) #else -#undef DUK_USE_DPRINT_RDTSC +#undef DUK_USE_FUNCPTR_DEC16 #endif -#if defined(DUK_OPT_ASSERTIONS) -#define DUK_USE_ASSERTIONS +#if defined(DUK_OPT_FUNCPTR_ENC16) +#define DUK_USE_FUNCPTR_ENC16(udata,ptr) DUK_OPT_FUNCPTR_ENC16((udata),(ptr)) +#else +#undef DUK_USE_FUNCPTR_ENC16 #endif -/* The static buffer for debug printing is quite large by default, so there - * is an option to shrink it manually for constrained builds. - */ -#if defined(DUK_OPT_DEBUG_BUFSIZE) -#define DUK_USE_DEBUG_BUFSIZE DUK_OPT_DEBUG_BUFSIZE +#if defined(DUK_OPT_GC_TORTURE) +#define DUK_USE_GC_TORTURE +#elif defined(DUK_OPT_NO_GC_TORTURE) +#undef DUK_USE_GC_TORTURE #else -#define DUK_USE_DEBUG_BUFSIZE 65536L +#undef DUK_USE_GC_TORTURE #endif -/* - * Ecmascript features / compliance options - */ +#if defined(DUK_OPT_HEAPPTR16) +#define DUK_USE_HEAPPTR16 +#elif defined(DUK_OPT_NO_HEAPPTR16) +#undef DUK_USE_HEAPPTR16 +#else +#undef DUK_USE_HEAPPTR16 +#endif -#if defined(DUK_F_BCC) -/* Math built-in is stubbed out on BCC to allow compiler torture testing. */ +#if defined(DUK_OPT_HEAPPTR_DEC16) +#define DUK_USE_HEAPPTR_DEC16(udata,ptr) DUK_OPT_HEAPPTR_DEC16((udata),(ptr)) #else -#define DUK_USE_MATH_BUILTIN +#undef DUK_USE_HEAPPTR_DEC16 #endif -#define DUK_USE_STRICT_DECL -#if defined(DUK_OPT_NO_STRICT_DECL) -#undef DUK_USE_STRICT_DECL +#if defined(DUK_OPT_HEAPPTR_ENC16) +#define DUK_USE_HEAPPTR_ENC16(udata,ptr) DUK_OPT_HEAPPTR_ENC16((udata),(ptr)) +#else +#undef DUK_USE_HEAPPTR_ENC16 #endif -#define DUK_USE_REGEXP_SUPPORT -#if defined(DUK_OPT_NO_REGEXP_SUPPORT) -#undef DUK_USE_REGEXP_SUPPORT +/* For now, hash part is dropped if and only if 16-bit object fields are used. */ +#define DUK_USE_HOBJECT_HASH_PART +#if defined(DUK_OPT_OBJSIZES16) +#undef DUK_USE_HOBJECT_HASH_PART #endif -#undef DUK_USE_STRICT_UTF8_SOURCE -#if defined(DUK_OPT_STRICT_UTF8_SOURCE) -#define DUK_USE_STRICT_UTF8_SOURCE +#if defined(DUK_OPT_EXTERNAL_STRINGS) +#define DUK_USE_HSTRING_EXTDATA +#elif defined(DUK_OPT_NO_EXTERNAL_STRINGS) +#undef DUK_USE_HSTRING_EXTDATA +#else +#undef DUK_USE_HSTRING_EXTDATA #endif -#define DUK_USE_OCTAL_SUPPORT -#if defined(DUK_OPT_NO_OCTAL_SUPPORT) -#undef DUK_USE_OCTAL_SUPPORT +#if defined(DUK_OPT_INTERRUPT_COUNTER) +#define DUK_USE_INTERRUPT_COUNTER +#elif defined(DUK_OPT_NO_INTERRUPT_COUNTER) +#undef DUK_USE_INTERRUPT_COUNTER +#else +#undef DUK_USE_INTERRUPT_COUNTER #endif -#define DUK_USE_SOURCE_NONBMP -#if defined(DUK_OPT_NO_SOURCE_NONBMP) -#undef DUK_USE_SOURCE_NONBMP +#if defined(DUK_OPT_JC) +#define DUK_USE_JC +#elif defined(DUK_OPT_NO_JC) +#undef DUK_USE_JC +#else +#define DUK_USE_JC #endif -#define DUK_USE_BROWSER_LIKE -#if defined(DUK_OPT_NO_BROWSER_LIKE) -#undef DUK_USE_BROWSER_LIKE +#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH) +#define DUK_USE_JSON_STRINGIFY_FASTPATH +#elif defined(DUK_OPT_NO_JSON_STRINGIFY_FASTPATH) +#undef DUK_USE_JSON_STRINGIFY_FASTPATH +#else +#undef DUK_USE_JSON_STRINGIFY_FASTPATH #endif -/* E5/E5.1 Section B features. */ -#define DUK_USE_SECTION_B -#if defined(DUK_OPT_NO_SECTION_B) -#undef DUK_USE_SECTION_B +#if defined(DUK_OPT_JX) +#define DUK_USE_JX +#elif defined(DUK_OPT_NO_JX) +#undef DUK_USE_JX +#else +#define DUK_USE_JX #endif -/* Non-standard regexp parsing features. */ -#define DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE +#if defined(DUK_OPT_LIGHTFUNC_BUILTINS) +#define DUK_USE_LIGHTFUNC_BUILTINS +#elif defined(DUK_OPT_NO_LIGHTFUNC_BUILTINS) +#undef DUK_USE_LIGHTFUNC_BUILTINS +#else +#undef DUK_USE_LIGHTFUNC_BUILTINS +#endif -/* Treat function statements (function declarations outside top level of - * Program or FunctionBody) same as normal function declarations. This is - * also V8 behavior. See test-dev-func-decl-outside-top.js. - */ -#define DUK_USE_NONSTD_FUNC_STMT -#if defined(DUK_OPT_NO_NONSTD_FUNC_STMT) -#undef DUK_USE_NONSTD_FUNC_STMT +#if defined(DUK_OPT_MARK_AND_SWEEP) +#define DUK_USE_MARK_AND_SWEEP +#elif defined(DUK_OPT_NO_MARK_AND_SWEEP) +#undef DUK_USE_MARK_AND_SWEEP +#else +#define DUK_USE_MARK_AND_SWEEP #endif -/* Array.prototype.splice() non-standard but real world compatible behavior - * when deleteCount is omitted. - */ -#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT -#if defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT) -#undef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT +#if defined(DUK_OPT_MS_STRINGTABLE_RESIZE) +#define DUK_USE_MS_STRINGTABLE_RESIZE +#elif defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE) +#undef DUK_USE_MS_STRINGTABLE_RESIZE +#else +#define DUK_USE_MS_STRINGTABLE_RESIZE #endif -/* Array.prototype.concat() non-standard but real world compatible behavior - * for non-existent trailing elements. - */ +#if defined(DUK_OPT_NONSTD_ARRAY_CONCAT_TRAILER) #define DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER -#if defined(DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER) +#elif defined(DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER) #undef DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER +#else +#define DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER #endif -/* Array.prototype.map() non-standard but real world compatible behavior - * for non-existent trailing elements. - */ +#if defined(DUK_OPT_NONSTD_ARRAY_MAP_TRAILER) #define DUK_USE_NONSTD_ARRAY_MAP_TRAILER -#if defined(DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER) +#elif defined(DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER) #undef DUK_USE_NONSTD_ARRAY_MAP_TRAILER +#else +#define DUK_USE_NONSTD_ARRAY_MAP_TRAILER #endif -/* Non-standard 'caller' property for function instances, see - * test-bi-function-nonstd-caller-prop.js. - */ -#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY -#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY) -#define DUK_USE_NONSTD_FUNC_CALLER_PROPERTY -#endif - -/* Non-standard Object.prototype.__proto__ (ES6), see - * test-bi-object-proto-__proto__.js. - */ -#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY -#if defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY) -#undef DUK_USE_ES6_OBJECT_PROTO_PROPERTY -#endif - -/* Non-standard Object.setPrototypeOf (ES6), see - * test-bi-object-setprototypeof.js. - */ -#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF -#if defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF) -#undef DUK_USE_ES6_OBJECT_SETPROTOTYPEOF -#endif - -/* ES6 Proxy object (subset for now). */ -#define DUK_USE_ES6_PROXY -#if defined(DUK_OPT_NO_ES6_PROXY) -#undef DUK_USE_ES6_PROXY +#if defined(DUK_OPT_NONSTD_ARRAY_SPLICE_DELCOUNT) +#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT +#elif defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT) +#undef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT +#else +#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT #endif -/* Record pc-to-line information. */ -#define DUK_USE_PC2LINE -#if defined(DUK_OPT_NO_PC2LINE) -#undef DUK_USE_PC2LINE +#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY) +#define DUK_USE_NONSTD_FUNC_CALLER_PROPERTY +#elif defined(DUK_OPT_NO_NONSTD_FUNC_CALLER_PROPERTY) +#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY +#else +#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY #endif -/* Non-standard function 'source' property. */ -#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY #if defined(DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY) #define DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY +#elif defined(DUK_OPT_NO_NONSTD_FUNC_SOURCE_PROPERTY) +#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY +#else +#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY #endif -/* CommonJS modules */ -#define DUK_USE_COMMONJS_MODULES -#if defined(DUK_OPT_NO_COMMONJS_MODULES) -#undef DUK_USE_COMMONJS_MODULES +#if defined(DUK_OPT_NONSTD_FUNC_STMT) +#define DUK_USE_NONSTD_FUNC_STMT +#elif defined(DUK_OPT_NO_NONSTD_FUNC_STMT) +#undef DUK_USE_NONSTD_FUNC_STMT +#else +#define DUK_USE_NONSTD_FUNC_STMT #endif -/* Additional key argument to setter/getter calls when triggered by property - * accesses. - */ - +#if defined(DUK_OPT_NONSTD_ACCESSOR_KEY_ARGUMENT) #define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT -#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT -#if defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT) +#elif defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT) #undef DUK_USE_NONSTD_GETTER_KEY_ARGUMENT -#undef DUK_USE_NONSTD_SETTER_KEY_ARGUMENT +#else +#define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT #endif -/* JSON escaping of U+2028 and U+2029. - */ - +#if defined(DUK_OPT_NONSTD_JSON_ESC_U2028_U2029) #define DUK_USE_NONSTD_JSON_ESC_U2028_U2029 -#if defined(DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029) +#elif defined(DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029) #undef DUK_USE_NONSTD_JSON_ESC_U2028_U2029 +#else +#define DUK_USE_NONSTD_JSON_ESC_U2028_U2029 #endif -/* Allow 32-bit codepoints in String.fromCharCode. */ -#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT -#if defined(DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT) -#undef DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT +#if defined(DUK_OPT_NONSTD_REGEXP_DOLLAR_ESCAPE) +#define DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE +#elif defined(DUK_OPT_NO_NONSTD_REGEXP_DOLLAR_ESCAPE) +#undef DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE +#else +#define DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE #endif -/* Non-standard array fast path write behavior: when writing to numeric - * indexes of an Array instance, assume Array.prototype doesn't have - * conflicting properties (e.g. a non-writable property "7"). - */ -#define DUK_USE_NONSTD_ARRAY_WRITE -#if defined(DUK_OPT_NO_NONSTD_ARRAY_WRITE) -#undef DUK_USE_NONSTD_ARRAY_WRITE +#if defined(DUK_OPT_NONSTD_ACCESSOR_KEY_ARGUMENT) +#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT +#elif defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT) +#undef DUK_USE_NONSTD_SETTER_KEY_ARGUMENT +#else +#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT #endif -/* Node.js Buffer and Khronos/ES6 typed array support. */ -#define DUK_USE_BUFFEROBJECT_SUPPORT -#if defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT) -#undef DUK_USE_BUFFEROBJECT_SUPPORT +#if defined(DUK_OPT_NONSTD_STRING_FROMCHARCODE_32BIT) +#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT +#elif defined(DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT) +#undef DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT +#else +#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT #endif -/* - * Optional C API options - */ - -#define DUK_USE_BYTECODE_DUMP_SUPPORT -#if defined(DUK_OPT_NO_BYTECODE_DUMP_SUPPORT) -#undef DUK_USE_BYTECODE_DUMP_SUPPORT +#if defined(DUK_OPT_OBJSIZES16) +#define DUK_USE_OBJSIZES16 +#elif defined(DUK_OPT_NO_OBJSIZES16) +#undef DUK_USE_OBJSIZES16 +#else +#undef DUK_USE_OBJSIZES16 #endif -/* - * Tailcalls - */ - -/* Tailcalls are enabled by default. The non-standard function 'caller' - * property feature conflicts with tailcalls quite severely so tailcalls - * are disabled if the 'caller' property is enabled. - */ -#define DUK_USE_TAILCALL -#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) -#undef DUK_USE_TAILCALL +#if defined(DUK_OPT_OCTAL_SUPPORT) +#define DUK_USE_OCTAL_SUPPORT +#elif defined(DUK_OPT_NO_OCTAL_SUPPORT) +#undef DUK_USE_OCTAL_SUPPORT +#else +#define DUK_USE_OCTAL_SUPPORT #endif -/* - * Ecmascript compiler - */ - -/* Ensure final bytecode never exceeds a certain byte size and never uses - * line numbers above a certain limit. This ensures that there is no need - * to deal with unbounded ranges in e.g. pc2line data structures. For now, - * limits are set so that signed 32-bit values can represent line number - * and byte offset with room to spare. - */ -#define DUK_USE_ESBC_LIMITS -#define DUK_USE_ESBC_MAX_LINENUMBER 0x7fff0000L -#define DUK_USE_ESBC_MAX_BYTES 0x7fff0000L - -#undef DUK_USE_SHUFFLE_TORTURE -#if defined(DUK_OPT_SHUFFLE_TORTURE) -#define DUK_USE_SHUFFLE_TORTURE +#if defined(DUK_OPT_PACKED_TVAL) +#define DUK_USE_PACKED_TVAL +#elif defined(DUK_OPT_NO_PACKED_TVAL) +#undef DUK_USE_PACKED_TVAL +#else +#undef DUK_USE_PACKED_TVAL #endif -/* - * User panic handler, panic exit behavior for default panic handler - */ +#undef DUK_USE_PANIC_ABORT +#if !defined(DUK_OPT_SEGFAULT_ON_PANIC) +#define DUK_USE_PANIC_ABORT +#endif #undef DUK_USE_PANIC_HANDLER #if defined(DUK_OPT_PANIC_HANDLER) #define DUK_USE_PANIC_HANDLER(code,msg) DUK_OPT_PANIC_HANDLER((code),(msg)) #endif -#undef DUK_USE_PANIC_ABORT -#undef DUK_USE_PANIC_EXIT #undef DUK_USE_PANIC_SEGFAULT - #if defined(DUK_OPT_SEGFAULT_ON_PANIC) #define DUK_USE_PANIC_SEGFAULT -#else -#define DUK_USE_PANIC_ABORT #endif -/* - * File I/O support. This is now used in a few API calls to e.g. push - * a string from file contents or eval a file. For portability it must - * be possible to disable I/O altogether. - */ - -#undef DUK_USE_FILE_IO -#if !defined(DUK_OPT_NO_FILE_IO) -#define DUK_USE_FILE_IO +#if defined(DUK_OPT_PARANOID_ERRORS) +#define DUK_USE_PARANOID_ERRORS +#elif defined(DUK_OPT_NO_PARANOID_ERRORS) +#undef DUK_USE_PARANOID_ERRORS +#else +#undef DUK_USE_PARANOID_ERRORS #endif -/* - * Optional run-time self tests executed when a heap is created. Some - * platform/compiler issues cannot be determined at compile time. One - * particular example is the bug described in misc/clang_aliasing.c. - */ - -#undef DUK_USE_SELF_TESTS -#if defined(DUK_OPT_SELF_TESTS) -#define DUK_USE_SELF_TESTS +#if defined(DUK_OPT_PC2LINE) +#define DUK_USE_PC2LINE +#elif defined(DUK_OPT_NO_PC2LINE) +#undef DUK_USE_PC2LINE +#else +#define DUK_USE_PC2LINE #endif -/* Double aliasing testcase fails when Emscripten-generated code is run - * on Firefox. This is not fatal because it only affects packed duk_tval - * which we avoid with Emscripten. - */ -#undef DUK_USE_NO_DOUBLE_ALIASING_SELFTEST -#if defined(DUK_F_EMSCRIPTEN) -#define DUK_USE_NO_DOUBLE_ALIASING_SELFTEST +#if defined(DUK_OPT_REFCOUNT16) +#define DUK_USE_REFCOUNT16 +#elif defined(DUK_OPT_NO_REFCOUNT16) +#undef DUK_USE_REFCOUNT16 +#else +#undef DUK_USE_REFCOUNT16 #endif -/* - * Codecs - */ - -#define DUK_USE_JX -#if defined(DUK_OPT_NO_JX) -#undef DUK_USE_JX +#if defined(DUK_OPT_REFERENCE_COUNTING) +#define DUK_USE_REFERENCE_COUNTING +#elif defined(DUK_OPT_NO_REFERENCE_COUNTING) +#undef DUK_USE_REFERENCE_COUNTING +#else +#define DUK_USE_REFERENCE_COUNTING #endif -#define DUK_USE_JC -#if defined(DUK_OPT_NO_JC) -#undef DUK_USE_JC +#if defined(DUK_OPT_REGEXP_CANON_WORKAROUND) +#define DUK_USE_REGEXP_CANON_WORKAROUND +#elif defined(DUK_OPT_NO_REGEXP_CANON_WORKAROUND) +#undef DUK_USE_REGEXP_CANON_WORKAROUND +#else +#undef DUK_USE_REGEXP_CANON_WORKAROUND #endif -/* - * InitJS code - */ - -/* Always use the built-in InitJS code for now. */ -#define DUK_USE_BUILTIN_INITJS - -/* User provided InitJS. */ -#undef DUK_USE_USER_INITJS -#if defined(DUK_OPT_USER_INITJS) -#define DUK_USE_USER_INITJS (DUK_OPT_USER_INITJS) +#if defined(DUK_OPT_REGEXP_SUPPORT) +#define DUK_USE_REGEXP_SUPPORT +#elif defined(DUK_OPT_NO_REGEXP_SUPPORT) +#undef DUK_USE_REGEXP_SUPPORT +#else +#define DUK_USE_REGEXP_SUPPORT #endif -/* - * External string data support - * - * Allow duk_hstrings to store data also behind an external pointer (see - * duk_hstring_external). This increases code size slightly but is useful - * in low memory environments where memory is more limited than flash. - */ - -#undef DUK_USE_HSTRING_EXTDATA -#if defined(DUK_OPT_EXTERNAL_STRINGS) -#define DUK_USE_HSTRING_EXTDATA +#if defined(DUK_OPT_SECTION_B) +#define DUK_USE_SECTION_B +#elif defined(DUK_OPT_NO_SECTION_B) +#undef DUK_USE_SECTION_B +#else +#define DUK_USE_SECTION_B #endif -#undef DUK_USE_EXTSTR_INTERN_CHECK -#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_INTERN_CHECK) -#define DUK_USE_EXTSTR_INTERN_CHECK(udata,ptr,len) DUK_OPT_EXTSTR_INTERN_CHECK((udata), (ptr), (len)) +#if defined(DUK_OPT_SELF_TESTS) +#define DUK_USE_SELF_TESTS +#elif defined(DUK_OPT_NO_SELF_TESTS) +#undef DUK_USE_SELF_TESTS +#else +#undef DUK_USE_SELF_TESTS #endif -#undef DUK_USE_EXTSTR_FREE -#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_FREE) -#define DUK_USE_EXTSTR_FREE(udata,ptr) DUK_OPT_EXTSTR_FREE((udata), (ptr)) +#if defined(DUK_OPT_SETJMP) +#define DUK_USE_SETJMP +#elif defined(DUK_OPT_NO_SETJMP) +#undef DUK_USE_SETJMP +#else +#define DUK_USE_SETJMP #endif -/* - * Lightweight functions - */ - -/* Force built-ins to use lightfunc function pointers when possible. This - * makes the built-in functions non-compliant with respect to their property - * values and such, but is very useful in low memory environments (can save - * around 14kB of initial RAM footprint). - */ -#undef DUK_USE_LIGHTFUNC_BUILTINS -#if defined(DUK_OPT_LIGHTFUNC_BUILTINS) -#define DUK_USE_LIGHTFUNC_BUILTINS +#if defined(DUK_OPT_SHUFFLE_TORTURE) +#define DUK_USE_SHUFFLE_TORTURE +#elif defined(DUK_OPT_NO_SHUFFLE_TORTURE) +#undef DUK_USE_SHUFFLE_TORTURE +#else +#undef DUK_USE_SHUFFLE_TORTURE #endif -/* - * Pointer compression and 16-bit header fields for low memory environments - */ - -#undef DUK_USE_HEAPPTR16 -#undef DUK_USE_HEAPPTR_ENC16 -#undef DUK_USE_HEAPPTR_DEC16 -#if defined(DUK_OPT_HEAPPTR16) && defined(DUK_OPT_HEAPPTR_ENC16) && defined(DUK_OPT_HEAPPTR_DEC16) -#define DUK_USE_HEAPPTR16 -#define DUK_USE_HEAPPTR_ENC16(udata,ptr) DUK_OPT_HEAPPTR_ENC16((udata),(ptr)) -#define DUK_USE_HEAPPTR_DEC16(udata,ptr) DUK_OPT_HEAPPTR_DEC16((udata),(ptr)) +#if defined(DUK_OPT_SIGSETJMP) +#define DUK_USE_SIGSETJMP +#elif defined(DUK_OPT_NO_SIGSETJMP) +#undef DUK_USE_SIGSETJMP +#else +#undef DUK_USE_SIGSETJMP #endif -#undef DUK_USE_DATAPTR16 -#undef DUK_USE_DATAPTR_ENC16 -#undef DUK_USE_DATAPTR_DEC16 -#if defined(DUK_OPT_DATAPTR16) && defined(DUK_OPT_DATAPTR_ENC16) && defined(DUK_OPT_DATAPTR_DEC16) -#define DUK_USE_DATAPTR16 -#define DUK_USE_DATAPTR_ENC16(udata,ptr) DUK_OPT_DATAPTR_ENC16((udata),(ptr)) -#define DUK_USE_DATAPTR_DEC16(udata,ptr) DUK_OPT_DATAPTR_DEC16((udata),(ptr)) +#if defined(DUK_OPT_SOURCE_NONBMP) +#define DUK_USE_SOURCE_NONBMP +#elif defined(DUK_OPT_NO_SOURCE_NONBMP) +#undef DUK_USE_SOURCE_NONBMP +#else +#define DUK_USE_SOURCE_NONBMP #endif -#undef DUK_USE_FUNCPTR16 -#undef DUK_USE_FUNCPTR_ENC16 -#undef DUK_USE_FUNCPTR_DEC16 -#if defined(DUK_OPT_FUNCPTR16) && defined(DUK_OPT_FUNCPTR_ENC16) && defined(DUK_OPT_FUNCPTR_DEC16) -#define DUK_USE_FUNCPTR16 -#define DUK_USE_FUNCPTR_ENC16(udata,ptr) DUK_OPT_FUNCPTR_ENC16((udata),(ptr)) -#define DUK_USE_FUNCPTR_DEC16(udata,ptr) DUK_OPT_FUNCPTR_DEC16((udata),(ptr)) +#if defined(DUK_OPT_STRHASH16) +#define DUK_USE_STRHASH16 +#elif defined(DUK_OPT_NO_STRHASH16) +#undef DUK_USE_STRHASH16 +#else +#undef DUK_USE_STRHASH16 #endif -#undef DUK_USE_REFCOUNT16 -#if defined(DUK_OPT_REFCOUNT16) -#define DUK_USE_REFCOUNT16 +#if defined(DUK_OPT_STRICT_DECL) +#define DUK_USE_STRICT_DECL +#elif defined(DUK_OPT_NO_STRICT_DECL) +#undef DUK_USE_STRICT_DECL +#else +#define DUK_USE_STRICT_DECL #endif -#undef DUK_USE_STRHASH16 -#if defined(DUK_OPT_STRHASH16) -#define DUK_USE_STRHASH16 +#if defined(DUK_OPT_STRICT_UTF8_SOURCE) +#define DUK_USE_STRICT_UTF8_SOURCE +#elif defined(DUK_OPT_NO_STRICT_UTF8_SOURCE) +#undef DUK_USE_STRICT_UTF8_SOURCE +#else +#undef DUK_USE_STRICT_UTF8_SOURCE #endif -#undef DUK_USE_STRLEN16 #if defined(DUK_OPT_STRLEN16) #define DUK_USE_STRLEN16 +#elif defined(DUK_OPT_NO_STRLEN16) +#undef DUK_USE_STRLEN16 +#else +#undef DUK_USE_STRLEN16 #endif -#undef DUK_USE_BUFLEN16 -#if defined(DUK_OPT_BUFLEN16) -#define DUK_USE_BUFLEN16 +#undef DUK_USE_STRTAB_CHAIN +#if defined(DUK_OPT_STRTAB_CHAIN) && defined(DUK_OPT_STRTAB_CHAIN_SIZE) +#define DUK_USE_STRTAB_CHAIN #endif -#undef DUK_USE_OBJSIZES16 -#if defined(DUK_OPT_OBJSIZES16) -#define DUK_USE_OBJSIZES16 +#undef DUK_USE_STRTAB_CHAIN_SIZE +#if defined(DUK_OPT_STRTAB_CHAIN) && defined(DUK_OPT_STRTAB_CHAIN_SIZE) +/* Low memory algorithm: separate chaining using arrays, fixed size hash */ +#define DUK_USE_STRTAB_CHAIN_SIZE DUK_OPT_STRTAB_CHAIN_SIZE #endif -/* For now, hash part is dropped if and only if 16-bit object fields are used. */ -#define DUK_USE_HOBJECT_HASH_PART -#if defined(DUK_USE_OBJSIZES16) -#undef DUK_USE_HOBJECT_HASH_PART +#undef DUK_USE_STRTAB_PROBE +#if !(defined(DUK_OPT_STRTAB_CHAIN) && defined(DUK_OPT_STRTAB_CHAIN_SIZE)) +#define DUK_USE_STRTAB_PROBE #endif -/* - * Miscellaneous - */ - -/* Convenience define: 32-bit pointers. 32-bit platforms are an important - * footprint optimization target, and this define allows e.g. struct sizes - * to be organized for compactness. - */ -#undef DUK_USE_32BIT_PTRS -#if defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED) -#if DUK_UINTPTR_MAX <= 0xffffffffUL -#define DUK_USE_32BIT_PTRS -#endif +#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY) +#undef DUK_USE_TAILCALL +#else +#define DUK_USE_TAILCALL #endif -#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS -#undef DUK_USE_EXPLICIT_NULL_INIT - -#define DUK_USE_ZERO_BUFFER_DATA -#if defined(DUK_OPT_NO_ZERO_BUFFER_DATA) -#undef DUK_USE_ZERO_BUFFER_DATA +#if defined(DUK_OPT_TARGET_INFO) +#define DUK_USE_TARGET_INFO DUK_OPT_TARGET_INFO +#else +#define DUK_USE_TARGET_INFO "unknown" #endif -#undef DUK_USE_VARIADIC_MACROS -#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__)) -#define DUK_USE_VARIADIC_MACROS -#endif -#if defined(_MSC_VER) && !defined(DUK_USE_VARIADIC_MACROS) -#if (_MSC_VER >= 1400) -/* VS2005+ should have variadic macros even when they're not C99. */ -#define DUK_USE_VARIADIC_MACROS +#if defined(DUK_OPT_NO_AUGMENT_ERRORS) +#undef DUK_USE_TRACEBACKS +#elif defined(DUK_OPT_NO_TRACEBACKS) +#undef DUK_USE_TRACEBACKS +#else +#define DUK_USE_TRACEBACKS #endif + +#if defined(DUK_OPT_TRACEBACK_DEPTH) +#define DUK_USE_TRACEBACK_DEPTH DUK_OPT_TRACEBACK_DEPTH +#else +#define DUK_USE_TRACEBACK_DEPTH 10 #endif -/* - * Variable size array initialization. - * - * Variable size array at the end of a structure is nonportable. - * There are three alternatives: - * - * 1) C99 (flexible array member): char buf[] - * 2) Compiler specific (e.g. GCC): char buf[0] - * 3) Portable but wastes memory / complicates allocation: char buf[1] - */ +#if defined(DUK_OPT_UNDERSCORE_SETJMP) +#define DUK_USE_UNDERSCORE_SETJMP +#elif defined(DUK_OPT_NO_UNDERSCORE_SETJMP) +#undef DUK_USE_UNDERSCORE_SETJMP +#else +#undef DUK_USE_UNDERSCORE_SETJMP +#endif -/* XXX: Currently unused, only hbuffer.h needed this at some point. */ -#undef DUK_USE_FLEX_C99 -#undef DUK_USE_FLEX_ZEROSIZE -#undef DUK_USE_FLEX_ONESIZE -#if defined(DUK_F_C99) -#define DUK_USE_FLEX_C99 -#elif defined(__GNUC__) -#define DUK_USE_FLEX_ZEROSIZE +#if defined(DUK_OPT_DECLARE) +#define DUK_USE_USER_DECLARE() DUK_OPT_DECLARE #else -#define DUK_USE_FLEX_ONESIZE +#define DUK_USE_USER_DECLARE() /* no user declarations */ #endif -/* - * GCC pragmas - */ +/* User provided InitJS. */ +#undef DUK_USE_USER_INITJS +#if defined(DUK_OPT_USER_INITJS) +#define DUK_USE_USER_INITJS (DUK_OPT_USER_INITJS) +#endif -/* XXX: GCC pragma inside a function fails in some earlier GCC versions (e.g. gcc 4.5). - * This is very approximate but allows clean builds for development right now. - */ -/* http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6) -#define DUK_USE_GCC_PRAGMAS +#if defined(DUK_OPT_VERBOSE_ERRORS) +#define DUK_USE_VERBOSE_ERRORS +#elif defined(DUK_OPT_NO_VERBOSE_ERRORS) +#undef DUK_USE_VERBOSE_ERRORS #else -#undef DUK_USE_GCC_PRAGMAS +#define DUK_USE_VERBOSE_ERRORS #endif -/* - * User declarations - */ +#if defined(DUK_OPT_VOLUNTARY_GC) +#define DUK_USE_VOLUNTARY_GC +#elif defined(DUK_OPT_NO_VOLUNTARY_GC) +#undef DUK_USE_VOLUNTARY_GC +#else +#define DUK_USE_VOLUNTARY_GC +#endif -#if defined(DUK_OPT_DECLARE) -#define DUK_USE_USER_DECLARE() DUK_OPT_DECLARE +#if defined(DUK_OPT_ZERO_BUFFER_DATA) +#define DUK_USE_ZERO_BUFFER_DATA +#elif defined(DUK_OPT_NO_ZERO_BUFFER_DATA) +#undef DUK_USE_ZERO_BUFFER_DATA #else -#define DUK_USE_USER_DECLARE() /* no user declarations */ +#define DUK_USE_ZERO_BUFFER_DATA #endif /* * Autogenerated defaults */ +#define DUK_USE_AVOID_PLATFORM_FUNCPTRS +#define DUK_USE_BASE64_FASTPATH +#define DUK_USE_BUILTIN_INITJS #define DUK_USE_COMPILER_RECLIMIT 2500 #undef DUK_USE_DATE_FORMAT_STRING #undef DUK_USE_DATE_GET_LOCAL_TZOFFSET #undef DUK_USE_DATE_GET_NOW #undef DUK_USE_DATE_PARSE_STRING #undef DUK_USE_DATE_PRS_GETDATE +#define DUK_USE_ESBC_LIMITS +#define DUK_USE_ESBC_MAX_BYTES 2147418112L +#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L #undef DUK_USE_EXEC_FUN_LOCAL -#undef DUK_USE_INTEGER_ME +#undef DUK_USE_EXPLICIT_NULL_INIT +#define DUK_USE_FAST_REFCOUNT_DEFAULT +#define DUK_USE_HEX_FASTPATH #undef DUK_USE_INTERRUPT_DEBUG_FIXUP #define DUK_USE_JSON_DECNUMBER_FASTPATH #define DUK_USE_JSON_DECSTRING_FASTPATH @@ -3044,12 +3373,21 @@ typedef FILE duk_file; #define DUK_USE_JSON_EATWHITE_FASTPATH #define DUK_USE_JSON_ENC_RECLIMIT 1000 #define DUK_USE_JSON_QUOTESTRING_FASTPATH +#define DUK_USE_LEXER_SLIDING_WINDOW #undef DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE #define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256 +#define DUK_USE_MATH_BUILTIN #define DUK_USE_NATIVE_CALL_RECLIMIT 1000 +#undef DUK_USE_PANIC_EXIT +#undef DUK_USE_PREFER_SIZE +#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS #undef DUK_USE_REFZERO_FINALIZER_TORTURE #define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000 #define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000 +#undef DUK_USE_STRHASH_DENSE +#define DUK_USE_STRHASH_SKIP_SHIFT 5 +#undef DUK_USE_VALSTACK_UNSAFE +#define DUK_USE_VERBOSE_EXECUTOR_ERRORS /* * Alternative customization header @@ -3084,13 +3422,10 @@ typedef FILE duk_file; #if defined(DUK_USE_DATE_GET_NOW) /* External provider already defined. */ #elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY) -DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(duk_context *ctx); #define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_gettimeofday((ctx)) #elif defined(DUK_USE_DATE_NOW_TIME) -DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(duk_context *ctx); #define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_time((ctx)) #elif defined(DUK_USE_DATE_NOW_WINDOWS) -DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx); #define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows((ctx)) #else #error no provider for DUK_USE_DATE_GET_NOW() @@ -3099,10 +3434,8 @@ DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx); #if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET) /* External provider already defined. */ #elif defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME) -DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d); #define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) duk_bi_date_get_local_tzoffset_gmtime((d)) #elif defined(DUK_USE_DATE_TZO_WINDOWS) -DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d); #define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d) duk_bi_date_get_local_tzoffset_windows((d)) #else #error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET() @@ -3111,10 +3444,8 @@ DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t #if defined(DUK_USE_DATE_PARSE_STRING) /* External provider already defined. */ #elif defined(DUK_USE_DATE_PRS_STRPTIME) -DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, const char *str); #define DUK_USE_DATE_PARSE_STRING(ctx,str) duk_bi_date_parse_string_strptime((ctx), (str)) #elif defined(DUK_USE_DATE_PRS_GETDATE) -DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const char *str); #define DUK_USE_DATE_PARSE_STRING(ctx,str) duk_bi_date_parse_string_getdate((ctx), (str)) #else /* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */ @@ -3123,7 +3454,6 @@ DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, #if defined(DUK_USE_DATE_FORMAT_STRING) /* External provider already defined. */ #elif defined(DUK_USE_DATE_FMT_STRFTIME) -DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags); #define DUK_USE_DATE_FORMAT_STRING(ctx,parts,tzoffset,flags) \ duk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags)) #else @@ -3133,109 +3463,183 @@ DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, #endif /* DUK_COMPILING_DUKTAPE */ /* - * Sanity check for the final effective internal defines. Also - * double checks user tweaks made by an optional duk_custom.h header. - */ - -/* - * Deprecated feature options. - * - * Catch so that user more easily notices and updates build. + * Checks for config option consistency (DUK_USE_xxx) */ -#if defined(DUK_OPT_NO_FUNC_STMT) -#error DUK_OPT_NO_FUNC_STMT is deprecated, use DUK_OPT_NO_NONSTD_FUNC_STMT +#if defined(DUK_USE_32BIT_PTRS) +#error unsupported config option used (option has been removed): DUK_USE_32BIT_PTRS #endif - -#if defined(DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY) -#error DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY is deprecated, use DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY +#if defined(DUK_USE_ALIGN_4) +#error unsupported config option used (option has been removed): DUK_USE_ALIGN_4 #endif - -#if defined(DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY) -#error DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY is deprecated, use DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY +#if defined(DUK_USE_ALIGN_8) +#error unsupported config option used (option has been removed): DUK_USE_ALIGN_8 #endif - -#if defined(DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT) -#error DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT is deprecated, use DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT +#if defined(DUK_USE_BYTEORDER_FORCED) +#error unsupported config option used (option has been removed): DUK_USE_BYTEORDER_FORCED #endif - -#if defined(DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY) -#error DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY is deprecated, use DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY +#if defined(DUK_USE_DATAPTR_DEC16) && !defined(DUK_USE_DATAPTR16) +#error config option DUK_USE_DATAPTR_DEC16 requires option DUK_USE_DATAPTR16 (which is missing) #endif - -#if defined(DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF) -#error DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF is deprecated, use DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF +#if defined(DUK_USE_DATAPTR_ENC16) && !defined(DUK_USE_DATAPTR16) +#error config option DUK_USE_DATAPTR_ENC16 requires option DUK_USE_DATAPTR16 (which is missing) #endif - -#if defined(DUK_OPT_NO_JSONX) -#error DUK_OPT_NO_JSONX is deprecated, use DUK_OPT_NO_JX +#if defined(DUK_USE_DEBUGGER_DUMPHEAP) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_DUMPHEAP requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) #endif - -#if defined(DUK_OPT_NO_JSONC) -#error DUK_OPT_NO_JSONC is deprecated, use DUK_OPT_NO_JC +#if defined(DUK_USE_DEBUGGER_FWD_LOGGING) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_FWD_LOGGING requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) +#endif +#if defined(DUK_USE_DEBUGGER_FWD_PRINTALERT) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_FWD_PRINTALERT requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) +#endif +#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_PAUSE_UNCAUGHT requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) +#endif +#if defined(DUK_USE_DEBUGGER_SUPPORT) && !defined(DUK_USE_INTERRUPT_COUNTER) +#error config option DUK_USE_DEBUGGER_SUPPORT requires option DUK_USE_INTERRUPT_COUNTER (which is missing) +#endif +#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_THROW_NOTIFY requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) +#endif +#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE) && !defined(DUK_USE_DEBUGGER_SUPPORT) +#error config option DUK_USE_DEBUGGER_TRANSPORT_TORTURE requires option DUK_USE_DEBUGGER_SUPPORT (which is missing) +#endif +#if defined(DUK_USE_DEEP_C_STACK) +#error unsupported config option used (option has been removed): DUK_USE_DEEP_C_STACK +#endif +#if defined(DUK_USE_DOUBLE_BE) +#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_BE +#endif +#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_LE) +#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_LE (which is also defined) +#endif +#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_ME) +#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_ME (which is also defined) +#endif +#if defined(DUK_USE_DOUBLE_LE) +#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_LE +#endif +#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_BE) +#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_BE (which is also defined) +#endif +#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_ME) +#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_ME (which is also defined) +#endif +#if defined(DUK_USE_DOUBLE_ME) +#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_ME +#endif +#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_LE) +#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_LE (which is also defined) +#endif +#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_BE) +#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_BE (which is also defined) #endif - -/* - * Debug print consistency - */ - #if defined(DUK_USE_DPRINT) && !defined(DUK_USE_DEBUG) -#error DUK_USE_DPRINT without DUK_USE_DEBUG +#error config option DUK_USE_DPRINT requires option DUK_USE_DEBUG (which is missing) #endif - -#if defined(DUK_USE_DDPRINT) && !defined(DUK_USE_DEBUG) -#error DUK_USE_DDPRINT without DUK_USE_DEBUG +#if defined(DUK_USE_ESBC_MAX_BYTES) && !defined(DUK_USE_ESBC_LIMITS) +#error config option DUK_USE_ESBC_MAX_BYTES requires option DUK_USE_ESBC_LIMITS (which is missing) #endif - -#if defined(DUK_USE_DDDPRINT) && !defined(DUK_USE_DEBUG) -#error DUK_USE_DDDPRINT without DUK_USE_DEBUG +#if defined(DUK_USE_ESBC_MAX_LINENUMBER) && !defined(DUK_USE_ESBC_LIMITS) +#error config option DUK_USE_ESBC_MAX_LINENUMBER requires option DUK_USE_ESBC_LIMITS (which is missing) +#endif +#if defined(DUK_USE_EXEC_TIMEOUT_CHECK) && !defined(DUK_USE_INTERRUPT_COUNTER) +#error config option DUK_USE_EXEC_TIMEOUT_CHECK requires option DUK_USE_INTERRUPT_COUNTER (which is missing) +#endif +#if defined(DUK_USE_EXTSTR_FREE) && !defined(DUK_USE_HSTRING_EXTDATA) +#error config option DUK_USE_EXTSTR_FREE requires option DUK_USE_HSTRING_EXTDATA (which is missing) +#endif +#if defined(DUK_USE_EXTSTR_INTERN_CHECK) && !defined(DUK_USE_HSTRING_EXTDATA) +#error config option DUK_USE_EXTSTR_INTERN_CHECK requires option DUK_USE_HSTRING_EXTDATA (which is missing) +#endif +#if defined(DUK_USE_FULL_TVAL) +#error unsupported config option used (option has been removed): DUK_USE_FULL_TVAL +#endif +#if defined(DUK_USE_FUNCPTR_DEC16) && !defined(DUK_USE_FUNCPTR16) +#error config option DUK_USE_FUNCPTR_DEC16 requires option DUK_USE_FUNCPTR16 (which is missing) +#endif +#if defined(DUK_USE_FUNCPTR_ENC16) && !defined(DUK_USE_FUNCPTR16) +#error config option DUK_USE_FUNCPTR_ENC16 requires option DUK_USE_FUNCPTR16 (which is missing) +#endif +#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS) +#error unsupported config option used (option has been removed): DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS #endif - #if defined(DUK_USE_HEAPPTR16) && defined(DUK_USE_DEBUG) -/* Debug code doesn't have access to 'heap' so it cannot decode pointers. */ -#error debug printing cannot currently be used with heap pointer compression +#error config option DUK_USE_HEAPPTR16 conflicts with option DUK_USE_DEBUG (which is also defined) #endif - -/* - * Debugger consistency - */ - -#if defined(DUK_USE_DEBUGGER_SUPPORT) -#if !defined(DUK_USE_INTERRUPT_COUNTER) -#error DUK_USE_INTERRUPT_COUNTER is needed when debugger support is enabled +#if defined(DUK_USE_HEAPPTR_DEC16) && !defined(DUK_USE_HEAPPTR16) +#error config option DUK_USE_HEAPPTR_DEC16 requires option DUK_USE_HEAPPTR16 (which is missing) #endif -#if !defined(DUK_USE_PC2LINE) -#error DUK_USE_PC2LINE is needed when debugger support is enabled +#if defined(DUK_USE_HEAPPTR_ENC16) && !defined(DUK_USE_HEAPPTR16) +#error config option DUK_USE_HEAPPTR_ENC16 requires option DUK_USE_HEAPPTR16 (which is missing) #endif +#if defined(DUK_USE_INTEGER_BE) +#error unsupported config option used (option has been removed): DUK_USE_INTEGER_BE #endif - -/* - * Garbage collection consistency - */ - -#if defined(DUK_USE_REFERENCE_COUNTING) && !defined(DUK_USE_DOUBLE_LINKED_HEAP) -#error DUK_USE_REFERENCE_COUNTING defined without DUK_USE_DOUBLE_LINKED_HEAP +#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_LE) +#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_LE (which is also defined) #endif - -#if defined(DUK_USE_GC_TORTURE) && !defined(DUK_USE_MARK_AND_SWEEP) -#error DUK_USE_GC_TORTURE defined without DUK_USE_MARK_AND_SWEEP +#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_ME) +#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_ME (which is also defined) #endif - -/* - * Low memory feature consistency - */ - -#if defined(DUK_USE_OBJSIZES16) -#if defined(DUK_USE_HOBJECT_HASH_PART) -#error DUK_USE_OBJSIZES16 assumes DUK_USE_HOBJECT_HASH_PART is not defined +#if defined(DUK_USE_INTEGER_LE) +#error unsupported config option used (option has been removed): DUK_USE_INTEGER_LE #endif +#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_BE) +#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_BE (which is also defined) #endif - -#if defined(DUK_USE_STRTAB_CHAIN) && defined(DUK_USE_STRTAB_PROBE) -#error both DUK_USE_STRTAB_CHAIN and DUK_USE_STRTAB_PROBE defined +#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_ME) +#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_ME (which is also defined) +#endif +#if defined(DUK_USE_INTEGER_ME) +#error unsupported config option used (option has been removed): DUK_USE_INTEGER_ME +#endif +#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_LE) +#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_LE (which is also defined) +#endif +#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_BE) +#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_BE (which is also defined) +#endif +#if defined(DUK_USE_NO_DOUBLE_ALIASING_SELFTEST) +#error unsupported config option used (option has been removed): DUK_USE_NO_DOUBLE_ALIASING_SELFTEST #endif -#if !defined(DUK_USE_STRTAB_CHAIN) && !defined(DUK_USE_STRTAB_PROBE) -#error neither DUK_USE_STRTAB_CHAIN nor DUK_USE_STRTAB_PROBE is defined +#if defined(DUK_USE_PACKED_TVAL_POSSIBLE) +#error unsupported config option used (option has been removed): DUK_USE_PACKED_TVAL_POSSIBLE #endif +#if defined(DUK_USE_RDTSC) +#error unsupported config option used (option has been removed): DUK_USE_RDTSC +#endif +#if defined(DUK_USE_STRTAB_CHAIN_SIZE) && !defined(DUK_USE_STRTAB_CHAIN) +#error config option DUK_USE_STRTAB_CHAIN_SIZE requires option DUK_USE_STRTAB_CHAIN (which is missing) +#endif +#if defined(DUK_USE_TAILCALL) && defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY) +#error config option DUK_USE_TAILCALL conflicts with option DUK_USE_NONSTD_FUNC_CALLER_PROPERTY (which is also defined) +#endif +#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) +#error unsupported config option used (option has been removed): DUK_USE_UNALIGNED_ACCESSES_POSSIBLE +#endif + +/* + * Convert DUK_USE_BYTEORDER, from whatever source, into currently used + * internal defines. If detection failed, #error out. + */ + +#if defined(DUK_USE_BYTEORDER) +#if (DUK_USE_BYTEORDER == 1) +#define DUK_USE_INTEGER_LE +#define DUK_USE_DOUBLE_LE +#elif (DUK_USE_BYTEORDER == 2) +#define DUK_USE_INTEGER_LE /* integer endianness is little on purpose */ +#define DUK_USE_DOUBLE_ME +#elif (DUK_USE_BYTEORDER == 3) +#define DUK_USE_INTEGER_BE +#define DUK_USE_DOUBLE_BE +#else +#error unsupported: byte order invalid +#endif /* byte order */ +#else +#error unsupported: byte order detection failed +#endif /* defined(DUK_USE_BYTEORDER) */ #endif /* DUK_CONFIG_H_INCLUDED */ |