Browse Source

Merge pull request #1099 from svaarala/fix-cygwin-math-issues

Fix a few math issues on Cygwin (MinGW)
pull/1102/head
Sami Vaarala 8 years ago
committed by GitHub
parent
commit
23bd6e7142
  1. 21
      Makefile
  2. 3
      RELEASES.rst
  3. 8
      config/config-options/DUK_USE_ATAN2_WORKAROUNDS.yaml
  4. 1
      config/config-options/DUK_USE_POW_NETBSD_WORKAROUND.yaml
  5. 9
      config/config-options/DUK_USE_POW_WORKAROUNDS.yaml
  6. 19
      config/header-snippets/platform_fillins.h.in
  7. 3
      doc/release-notes-v2-0.rst
  8. 33
      src-input/duk_bi_math.c
  9. 1
      src-input/duk_js.h
  10. 77
      src-input/duk_js_arith.c
  11. 10
      src-input/duk_js_executor.c
  12. 75
      tests/ecmascript/test-bug-mingw-math-issues.js
  13. 2
      util/makeduk_base.yaml
  14. 2
      util/makeduk_debug.yaml

21
Makefile

@ -59,13 +59,20 @@ DUKTAPE_CMDLINE_SOURCES = \
examples/alloc-logging/duk_alloc_logging.c \ examples/alloc-logging/duk_alloc_logging.c \
examples/alloc-torture/duk_alloc_torture.c \ examples/alloc-torture/duk_alloc_torture.c \
examples/alloc-hybrid/duk_alloc_hybrid.c \ examples/alloc-hybrid/duk_alloc_hybrid.c \
examples/debug-trans-socket/duk_trans_socket_unix.c \
extras/print-alert/duk_print_alert.c \ extras/print-alert/duk_print_alert.c \
extras/console/duk_console.c \ extras/console/duk_console.c \
extras/logging/duk_logging.c \ extras/logging/duk_logging.c \
extras/module-duktape/duk_module_duktape.c extras/module-duktape/duk_module_duktape.c
LINENOISE_SOURCES = \ ifdef SYSTEMROOT # Windows
linenoise/linenoise.c DUKTAPE_CMDLINE_SOURCES += examples/debug-trans-socket/duk_trans_socket_windows.c
else
DUKTAPE_CMDLINE_SOURCES += examples/debug-trans-socket/duk_trans_socket_unix.c
endif
ifdef SYSTEMROOT # Windows
LINENOISE_SOURCES =
else
LINENOISE_SOURCES = linenoise/linenoise.c
endif
# Configure.py options for a few configuration profiles needed. # Configure.py options for a few configuration profiles needed.
CONFIGOPTS_NONDEBUG=--option-file util/makeduk_base.yaml CONFIGOPTS_NONDEBUG=--option-file util/makeduk_base.yaml
@ -90,7 +97,11 @@ CCOPTS_SHARED += -DDUK_CMDLINE_PRINTALERT_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_CONSOLE_SUPPORT CCOPTS_SHARED += -DDUK_CMDLINE_CONSOLE_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_LOGGING_SUPPORT CCOPTS_SHARED += -DDUK_CMDLINE_LOGGING_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_MODULE_SUPPORT CCOPTS_SHARED += -DDUK_CMDLINE_MODULE_SUPPORT
ifdef SYSTEMROOT # Windows
# Skip fancy (linenoise)
else
CCOPTS_SHARED += -DDUK_CMDLINE_FANCY CCOPTS_SHARED += -DDUK_CMDLINE_FANCY
endif
CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_LOGGING CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_LOGGING
CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_TORTURE CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_TORTURE
CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_HYBRID CCOPTS_SHARED += -DDUK_CMDLINE_ALLOC_HYBRID
@ -140,7 +151,11 @@ CCOPTS_AJDUK += -UDUK_CMDLINE_FANCY -DDUK_CMDLINE_AJSHEAP -D_POSIX_C_SOURCE=2008
CCOPTS_AJDUK += -UDUK_CMDLINE_LOGGING_SUPPORT # extras/logger init writes to Duktape.Logger, problem with ROM build CCOPTS_AJDUK += -UDUK_CMDLINE_LOGGING_SUPPORT # extras/logger init writes to Duktape.Logger, problem with ROM build
CCOPTS_AJDUK += -UDUK_CMDLINE_MODULE_SUPPORT # extras/module-duktape init writes to Duktape.Logger, problem with ROM build CCOPTS_AJDUK += -UDUK_CMDLINE_MODULE_SUPPORT # extras/module-duktape init writes to Duktape.Logger, problem with ROM build
ifdef SYSTEMROOT # Windows
CCLIBS = -lm -lws2_32
else
CCLIBS = -lm CCLIBS = -lm
endif
# Emscripten options: # Emscripten options:
# - --memory-init-file 0 to avoid a separate memory init file (this is # - --memory-init-file 0 to avoid a separate memory init file (this is

3
RELEASES.rst

@ -2033,6 +2033,9 @@ Planned
* Fix Cygwin warning about shadowed 'accept' variable (GH-1098) * Fix Cygwin warning about shadowed 'accept' variable (GH-1098)
* Fix Cygwin/MinGW math issues related to pow2() and atan2() semantics
(GH-1099)
* Fix two-argument Math function (like Math.atan2()) argument coercion * Fix two-argument Math function (like Math.atan2()) argument coercion
order; the order was not guaranteed but specification requires left-to-right order; the order was not guaranteed but specification requires left-to-right
ordering (GH-943) ordering (GH-943)

8
config/config-options/DUK_USE_ATAN2_WORKAROUNDS.yaml

@ -0,0 +1,8 @@
define: DUK_USE_ATAN2_WORKAROUNDS
introduced: 2.0.0
default: false
tags:
- portability
description: >
Enable workarounds to common atan2() semantics issues. At least Cygwin/MinGW
has such issues, see test-bug-mingw-math-issues.js.

1
config/config-options/DUK_USE_POW_NETBSD_WORKAROUND.yaml

@ -1,5 +1,6 @@
define: DUK_USE_POW_NETBSD_WORKAROUND define: DUK_USE_POW_NETBSD_WORKAROUND
introduced: 1.0.0 introduced: 1.0.0
removed: 2.0.0
default: false default: false
tags: tags:
- portability - portability

9
config/config-options/DUK_USE_POW_WORKAROUNDS.yaml

@ -0,0 +1,9 @@
define: DUK_USE_POW_WORKAROUNDS
introduced: 2.0.0
default: false
tags:
- portability
description: >
Enable workarounds to common pow() semantics issues. At least NetBSD
6.0 x86 and Cygwin/MinGW have such issues, see test-bug-netbsd-math-pow.js
and test-bug-mingw-math-issues.js.

19
config/header-snippets/platform_fillins.h.in

@ -279,12 +279,21 @@
#endif /* DUK_F_C99 */ #endif /* DUK_F_C99 */
/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics, /* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,
* see test-bug-netbsd-math-pow.js. Use NetBSD specific workaround. * see test-bug-netbsd-math-pow.js. MinGW has similar (but different)
* (This might be a wider problem; if so, generalize the define name.) * issues, see test-bug-mingw-math-issues.js. Enable pow() workarounds
* for these targets.
*/ */
#undef DUK_USE_POW_NETBSD_WORKAROUND #undef DUK_USE_POW_WORKAROUNDS
#if defined(DUK_F_NETBSD) #if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW)
#define DUK_USE_POW_NETBSD_WORKAROUND #define DUK_USE_POW_WORKAROUNDS
#endif
/* Similar workarounds for atan2() semantics issues. MinGW issues are
* documented in test-bug-mingw-math-issues.js.
*/
#undef DUK_USE_ATAN2_WORKAROUNDS
#if defined(DUK_F_MINGW)
#define DUK_USE_ATAN2_WORKAROUNDS
#endif #endif
/* Rely as little as possible on compiler behavior for NaN comparison, /* Rely as little as possible on compiler behavior for NaN comparison,

3
doc/release-notes-v2-0.rst

@ -1030,6 +1030,9 @@ Other incompatible changes
is the same as "\u00078", "\8" and "\9" are accepted as literal "8" and "9" is the same as "\u00078", "\8" and "\9" are accepted as literal "8" and "9"
(even in strict mode). (even in strict mode).
* The NetBSD pow() workaround option ``DUK_USE_POW_NETBSD_WORKAROUND`` has been
generalized and renamed to ``DUK_USE_POW_WORKAROUNDS``.
Known issues Known issues
============ ============

33
src-input/duk_bi_math.c

@ -225,7 +225,34 @@ DUK_LOCAL double duk__sqrt(double x) {
DUK_LOCAL double duk__tan(double x) { DUK_LOCAL double duk__tan(double x) {
return DUK_TAN(x); return DUK_TAN(x);
} }
DUK_LOCAL double duk__atan2(double x, double y) { DUK_LOCAL double duk__atan2_fixed(double x, double y) {
#if defined(DUK_USE_ATAN2_WORKAROUNDS)
/* Specific fixes to common atan2() implementation issues:
* - test-bug-mingw-math-issues.js
*/
if (DUK_ISINF(x) && DUK_ISINF(y)) {
if (DUK_SIGNBIT(x)) {
if (DUK_SIGNBIT(y)) {
return -2.356194490192345;
} else {
return -0.7853981633974483;
}
} else {
if (DUK_SIGNBIT(y)) {
return 2.356194490192345;
} else {
return 0.7853981633974483;
}
}
}
#else
/* Some ISO C assumptions. */
DUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == 0.7853981633974483);
DUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == -0.7853981633974483);
DUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == 2.356194490192345);
DUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == -2.356194490192345);
#endif
return DUK_ATAN2(x, y); return DUK_ATAN2(x, y);
} }
#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */ #endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
@ -278,10 +305,10 @@ DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {
/* order must match constants in genbuiltins.py */ /* order must match constants in genbuiltins.py */
DUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = { DUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {
#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS) #if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)
duk__atan2, duk__atan2_fixed,
duk_js_arith_pow duk_js_arith_pow
#else #else
DUK_ATAN2, duk__atan2_fixed,
duk_js_arith_pow duk_js_arith_pow
#endif #endif
}; };

1
src-input/duk_js.h

@ -43,6 +43,7 @@ DUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);
/* arithmetic */ /* arithmetic */
DUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y); DUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y);
DUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y);
#define duk_js_equals(thr,tv_x,tv_y) \ #define duk_js_equals(thr,tv_x,tv_y) \
duk_js_equals_helper((thr), (tv_x), (tv_y), 0) duk_js_equals_helper((thr), (tv_x), (tv_y), 0)

77
src-input/duk_js_arith.c

@ -4,6 +4,58 @@
#include "duk_internal.h" #include "duk_internal.h"
/* Ecmascript modulus ('%') does not match IEEE 754 "remainder" operation
* (implemented by remainder() in C99) but does seem to match ANSI C fmod().
* Compare E5 Section 11.5.3 and "man fmod".
*/
DUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {
#if defined(DUK_USE_POW_WORKAROUNDS)
/* Specific fixes to common fmod() implementation issues:
* - test-bug-mingw-math-issues.js
*/
if (DUK_ISINF(d2)) {
if (DUK_ISINF(d1)) {
return DUK_DOUBLE_NAN;
} else {
return d1;
}
} else if (d1 == 0.0) {
/* d1 +/-0 is returned as is (preserving sign) except when
* d2 is zero or NaN.
*/
if (d2 == 0.0 || DUK_ISNAN(d2)) {
return DUK_DOUBLE_NAN;
} else {
return d1;
}
}
#else
/* Some ISO C assumptions. */
DUK_ASSERT(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY) == 1.0);
DUK_ASSERT(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY) == -1.0);
DUK_ASSERT(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY) == 1.0);
DUK_ASSERT(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY) == -1.0);
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));
DUK_ASSERT(DUK_FMOD(0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0);
DUK_ASSERT(DUK_FMOD(-0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0);
DUK_ASSERT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);
DUK_ASSERT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0);
DUK_ASSERT(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);
DUK_ASSERT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0);
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN)));
DUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN)));
#endif
return (duk_double_t) DUK_FMOD((double) d1, (double) d2);
}
/* Shared helper for Math.pow() and exponentiation operator. */ /* Shared helper for Math.pow() and exponentiation operator. */
DUK_INTERNAL double duk_js_arith_pow(double x, double y) { DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
/* The ANSI C pow() semantics differ from Ecmascript. /* The ANSI C pow() semantics differ from Ecmascript.
@ -24,10 +76,11 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
if (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) { if (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {
goto ret_nan; goto ret_nan;
} }
#if defined(DUK_USE_POW_NETBSD_WORKAROUND)
/* See test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least) does not #if defined(DUK_USE_POW_WORKAROUNDS)
* correctly handle some cases where x=+/-0. Specific fixes to these /* Specific fixes to common pow() implementation issues:
* here. * - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least)
* - test-bug-mingw-math-issues.js
*/ */
cx = (duk_small_int_t) DUK_FPCLASSIFY(x); cx = (duk_small_int_t) DUK_FPCLASSIFY(x);
if (cx == DUK_FP_ZERO && y < 0.0) { if (cx == DUK_FP_ZERO && y < 0.0) {
@ -42,7 +95,7 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
} else { } else {
/* Math.pow(-0,y) where y<0 should be: /* Math.pow(-0,y) where y<0 should be:
* - -Infinity if y<0 and an odd integer * - -Infinity if y<0 and an odd integer
* - Infinity otherwise * - Infinity if y<0 but not an odd integer
* NetBSD pow() returns -Infinity for all finite y<0. The * NetBSD pow() returns -Infinity for all finite y<0. The
* if-clause also catches y == -Infinity (which works even * if-clause also catches y == -Infinity (which works even
* without the fix). * without the fix).
@ -61,8 +114,22 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
return DUK_DOUBLE_INFINITY; return DUK_DOUBLE_INFINITY;
} }
} }
} else if (cx == DUK_FP_NAN) {
if (y == 0.0) {
/* NaN ** +/- 0 should always be 1, but is NaN on
* at least some Cygwin/MinGW versions.
*/
return 1.0;
}
} }
#else
/* Some ISO C assumptions. */
DUK_ASSERT(DUK_POW(DUK_DOUBLE_NAN, 0.0) == 1.0);
DUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);
DUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);
DUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0);
#endif #endif
return DUK_POW(x, y); return DUK_POW(x, y);
ret_nan: ret_nan:

10
src-input/duk_js_executor.c

@ -73,15 +73,7 @@ DUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, d
*/ */
DUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) { DUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {
/* return (duk_double_t) duk_js_arith_mod((double) d1, (double) d2);
* Ecmascript modulus ('%') does not match IEEE 754 "remainder"
* operation (implemented by remainder() in C99) but does seem
* to match ANSI C fmod().
*
* Compare E5 Section 11.5.3 and "man fmod".
*/
return (duk_double_t) DUK_FMOD((double) d1, (double) d2);
} }
#if defined(DUK_USE_ES7_EXP_OPERATOR) #if defined(DUK_USE_ES7_EXP_OPERATOR)

75
tests/ecmascript/test-bug-mingw-math-issues.js

@ -0,0 +1,75 @@
/*
* Some MinGW math issues
*
* https://github.com/svaarala/duktape/pull/1099
*/
/*@include util-number.js@*/
/*===
1
1
-1e+100
-1e+100
NaN
NaN
NaN
NaN
0
-0
0
-0
0
-0
0
-0
NaN
NaN
NaN
NaN
NaN
NaN
0.7853981633974483
2.356194490192345
-0.7853981633974483
-2.356194490192345
1
1
===*/
function test() {
printExact((0/0) ** 0);
printExact((0/0) ** -0);
printExact((-1e100) % (1/0)); // return 1st arg if modulus is +/- inf
printExact((-1e100) % (-1/0));
printExact((1/0) % (1/0)); // but if 1st arg is +/- inf (and modulus +/- inf), return NaN
printExact((1/0) % (-1/0));
printExact((-1/0) % (1/0));
printExact((-1/0) % (-1/0));
printExact(0 % 1); // preserve zero and its sign, even for inf
printExact(-0 % 1);
printExact(0 % -1);
printExact(-0 % -1);
printExact(0 % (1/0));
printExact(-0 % (1/0));
printExact(0 % (-1/0));
printExact(-0 % (-1/0));
printExact(0 % (0/0)); // ... but if modulus is NaN or 0, result is NaN
printExact(-0 % (0/0));
printExact(0 % 0);
printExact(-0 % 0);
printExact(0 % -0);
printExact(-0 % -0);
printExact(Math.atan2(1/0, 1/0));
printExact(Math.atan2(1/0, -1/0));
printExact(Math.atan2(-1/0, 1/0));
printExact(Math.atan2(-1/0, -1/0));
printExact(Math.pow(0/0, 0));
printExact(Math.pow(0/0, -0));
}
try {
test();
} catch (e) {
print(e.stack || e);
}

2
util/makeduk_base.yaml

@ -8,7 +8,7 @@
DUK_USE_TARGET_INFO: "\"duk command built from Duktape repo\"" DUK_USE_TARGET_INFO: "\"duk command built from Duktape repo\""
DUK_USE_FATAL_HANDLER: DUK_USE_FATAL_HANDLER:
verbatim: "#define DUK_USE_FATAL_HANDLER(udata,msg) do { const char *fatal_msg = (msg); fprintf(stderr, \"*** FATAL ERROR: %s\\n\", fatal_msg ? fatal_msg : \"no message\"); *((volatile unsigned int *) 0) = (unsigned int) 0xdeadbeefUL; abort(); } while(0)" verbatim: "#define DUK_USE_FATAL_HANDLER(udata,msg) do { const char *fatal_msg = (msg); fprintf(stderr, \"*** FATAL ERROR: %s\\n\", fatal_msg ? fatal_msg : \"no message\"); fflush(stderr); *((volatile unsigned int *) 0) = (unsigned int) 0xdeadbeefUL; abort(); } while(0)"
DUK_USE_SELF_TESTS: true DUK_USE_SELF_TESTS: true
#DUK_USE_ASSERTIONS: true #DUK_USE_ASSERTIONS: true

2
util/makeduk_debug.yaml

@ -5,5 +5,5 @@ DUK_USE_DEBUG: true
DUK_USE_DEBUG_LEVEL: 0 DUK_USE_DEBUG_LEVEL: 0
#DUK_USE_DEBUG_LEVEL: 1 #DUK_USE_DEBUG_LEVEL: 1
DUK_USE_DEBUG_WRITE: DUK_USE_DEBUG_WRITE:
verbatim: "#define DUK_USE_DEBUG_WRITE(level,file,line,func,msg) do {fprintf(stderr, \"D%ld %s:%ld (%s): %s\\n\", (long) (level), (file), (long) (line), (func), (msg));} while(0)" verbatim: "#define DUK_USE_DEBUG_WRITE(level,file,line,func,msg) do {fprintf(stderr, \"D%ld %s:%ld (%s): %s\\n\", (long) (level), (file), (long) (line), (func), (msg)); fflush(stderr);} while(0)"
DUK_USE_ASSERTIONS: true DUK_USE_ASSERTIONS: true

Loading…
Cancel
Save