gopkg.in/olebedev/go-duktape.v1@v1.0.0-20151008052556-e2ae92f01e4a/duktape.h (about)

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