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 */