diff options
| author | Ashvith Shetty <ashvith@noreply.codeberg.org> | 2026-01-13 17:07:18 +0530 |
|---|---|---|
| committer | Efraim Flashner <efraim@flashner.co.il> | 2026-01-14 13:04:25 +0200 |
| commit | 89e8c55f2b9e0d4f679561b96016b552a74e9534 (patch) | |
| tree | 674189a35bc10edd4b430718a5cd1ab20ed8aeed | |
| parent | 93e81e1c9612145b87234e7692e79128b377bdc3 (diff) | |
gnu: quickjs-ng: Resolve build issue with x86-32 platform.
* gnu/packages/javascript.scm (quickjs-ng):
[source]: Add quickjs-ng-64-bits-precision-on-i686.patch and
quickjs-ng-fix-atomics.pause-on-32-bit.patch patches.
[arguments]<#:tests?>: Enable them.
* quickjs-ng-64-bits-precision-on-i686.patch,
* gnu/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch: New
files.
* gnu/local.mk (dist_patch_DATA): Add them.
Change-Id: I94be4c85725c9fe7780c1b2e2186411719051b56
Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
| -rw-r--r-- | gnu/local.mk | 2 | ||||
| -rw-r--r-- | gnu/packages/javascript.scm | 10 | ||||
| -rw-r--r-- | gnu/packages/patches/quickjs-ng-64-bits-precision-on-i686.patch | 211 | ||||
| -rw-r--r-- | gnu/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch | 26 |
4 files changed, 244 insertions, 5 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index b273dae61c1..5d130aa7ced 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -2224,6 +2224,8 @@ dist_patch_DATA = \ %D%/packages/patches/qtbase-5-use-TZDIR.patch \ %D%/packages/patches/qtscript-disable-tests.patch \ %D%/packages/patches/quagga-reproducible-build.patch \ + %D%/packages/patches/quickjs-ng-64-bits-precision-on-i686.patch \ + %D%/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch \ %D%/packages/patches/quilt-grep-compat.patch \ %D%/packages/patches/qmk-firmware-fix-hacker-dvorak.patch \ %D%/packages/patches/qtwayland-dont-recreate-callbacks.patch \ diff --git a/gnu/packages/javascript.scm b/gnu/packages/javascript.scm index 20ae6d7d3f1..e89cdf855e3 100644 --- a/gnu/packages/javascript.scm +++ b/gnu/packages/javascript.scm @@ -958,13 +958,13 @@ wrappers.") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 - (base32 "0mfk32zvvh6c9a9plp6ad07888g795lhdmal3jyaclyn2k5iig9i")))) + (base32 "0mfk32zvvh6c9a9plp6ad07888g795lhdmal3jyaclyn2k5iig9i")) + ;; Remove these patches on next release as they will be included. + (patches (search-patches + "quickjs-ng-64-bits-precision-on-i686.patch" + "quickjs-ng-fix-atomics.pause-on-32-bit.patch")))) (arguments (list - ;; Data model is ILP32 in 32bit, LP64 in 64bit - ;; https://docs.oracle.com/cd/E19620-01/805-3024/lp64-1/index.html - #:tests? (and (not (%current-target-system)) - (target-64bit?)) #:configure-flags #~(list "-DBUILD_SHARED_LIBS:BOOL=TRUE" "-DQJS_BUILD_EXAMPLES:BOOL=FALSE" diff --git a/gnu/packages/patches/quickjs-ng-64-bits-precision-on-i686.patch b/gnu/packages/patches/quickjs-ng-64-bits-precision-on-i686.patch new file mode 100644 index 00000000000..637a40f7145 --- /dev/null +++ b/gnu/packages/patches/quickjs-ng-64-bits-precision-on-i686.patch @@ -0,0 +1,211 @@ +From bd4ee689a854252665fd607758f078d930fbc4c8 Mon Sep 17 00:00:00 2001 +From: Ben Noordhuis <info@bnoordhuis.nl> +Date: Fri, 21 Nov 2025 11:56:28 +0100 +Subject: [PATCH] Fix JS number rounding on x87 (#1244) + +Disable 80-bits extended precision, use standard 64-bits precision. +The extra precision affects rounding and is user-observable, meaning +it causes test262 tests to fail. + +The rounding mode is a per-CPU (or, more accurately, per-FPU) property, +and since quickjs is often used as a library, take care to tweak the FPU +control word before sensitive operations, and restore it afterwards. + +Only affects x87. SSE is IEEE-754 conforming. + +Fixes: https://github.com/quickjs-ng/quickjs/issues/1236 +--- + .github/workflows/ci.yml | 4 ++-- + cutils.h | 19 +++++++++++++++++++ + quickjs.c | 34 +++++++++++++++++++++++++++++----- + 3 files changed, 50 insertions(+), 7 deletions(-) + +diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml +index d1efee1b9..c722b517d 100644 +--- a/.github/workflows/ci.yml ++++ b/.github/workflows/ci.yml +@@ -58,7 +58,7 @@ jobs: + - { os: ubuntu-latest, configType: asan+ubsan, runTest262: true } + - { os: ubuntu-latest, configType: msan } + - { os: ubuntu-latest, configType: tcc } +- - { os: ubuntu-latest, arch: x86 } ++ - { os: ubuntu-latest, arch: x86, runTest262: true } + - { os: ubuntu-latest, arch: riscv64 } + - { os: ubuntu-latest, arch: s390x } + +@@ -97,7 +97,7 @@ jobs: + uses: jirutka/setup-alpine@v1 + with: + arch: ${{ matrix.config.arch }} +- packages: "build-base make cmake" ++ packages: "build-base make cmake git" + + - name: uname + run: uname -a +diff --git a/cutils.h b/cutils.h +index 5129c3cb2..f5d2a8bce 100644 +--- a/cutils.h ++++ b/cutils.h +@@ -634,6 +634,25 @@ int js_thread_join(js_thread_t thrd); + + #endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */ + ++// JS requires strict rounding behavior. Turn on 64-bits double precision ++// and disable x87 80-bits extended precision for intermediate floating-point ++// results. 0x300 is extended precision, 0x200 is double precision. ++// Note that `*&cw` in the asm constraints looks redundant but isn't. ++#if defined(__i386__) && !defined(_MSC_VER) ++#define JS_X87_FPCW_SAVE_AND_ADJUST(cw) \ ++ unsigned short cw; \ ++ __asm__ __volatile__("fnstcw %0" : "=m"(*&cw)); \ ++ do { \ ++ unsigned short t = 0x200 | (cw & ~0x300); \ ++ __asm__ __volatile__("fldcw %0" : /*empty*/ : "m"(*&t)); \ ++ } while (0) ++#define JS_X87_FPCW_RESTORE(cw) \ ++ __asm__ __volatile__("fldcw %0" : /*empty*/ : "m"(*&cw)) ++#else ++#define JS_X87_FPCW_SAVE_AND_ADJUST(cw) ++#define JS_X87_FPCW_RESTORE(cw) ++#endif ++ + #ifdef __cplusplus + } /* extern "C" { */ + #endif +diff --git a/quickjs.c b/quickjs.c +index 3970bb247..7900c5e3d 100644 +--- a/quickjs.c ++++ b/quickjs.c +@@ -13395,12 +13395,17 @@ static int js_is_array(JSContext *ctx, JSValueConst val) + + static double js_math_pow(double a, double b) + { ++ double d; ++ + if (unlikely(!isfinite(b)) && fabs(a) == 1) { + /* not compatible with IEEE 754 */ +- return NAN; ++ d = NAN; + } else { +- return pow(a, b); ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); ++ d = pow(a, b); ++ JS_X87_FPCW_RESTORE(fpcw); + } ++ return d; + } + + JSValue JS_NewBigInt64(JSContext *ctx, int64_t v) +@@ -13820,11 +13825,15 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s + } + break; + case OP_div: ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number((double)v1 / (double)v2); ++ JS_X87_FPCW_RESTORE(fpcw); + return 0; + case OP_mod: + if (v1 < 0 || v2 <= 0) { ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number(fmod(v1, v2)); ++ JS_X87_FPCW_RESTORE(fpcw); + return 0; + } else { + v = (int64_t)v1 % (int64_t)v2; +@@ -13888,6 +13897,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s + if (JS_ToFloat64Free(ctx, &d2, op2)) + goto exception; + handle_float64: ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + switch(op) { + case OP_sub: + dr = d1 - d2; +@@ -13907,6 +13917,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s + default: + abort(); + } ++ JS_X87_FPCW_RESTORE(fpcw); + sp[-2] = js_float64(dr); + } + return 0; +@@ -14023,7 +14034,9 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) + } + if (JS_ToFloat64Free(ctx, &d2, op2)) + goto exception; ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(d1 + d2); ++ JS_X87_FPCW_RESTORE(fpcw); + } + return 0; + exception: +@@ -17998,8 +18011,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(JS_VALUE_GET_FLOAT64(op1) + + JS_VALUE_GET_FLOAT64(op2)); ++ JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else { + add_slow: +@@ -18066,8 +18081,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(JS_VALUE_GET_FLOAT64(op1) - + JS_VALUE_GET_FLOAT64(op2)); ++ JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else { + goto binary_arith_slow; +@@ -18098,7 +18115,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + d = JS_VALUE_GET_FLOAT64(op1) * JS_VALUE_GET_FLOAT64(op2); ++ JS_X87_FPCW_RESTORE(fpcw); + mul_fp_res: + sp[-2] = js_float64(d); + sp--; +@@ -52277,7 +52296,9 @@ static double set_date_fields(double fields[minimum_length(7)], int is_local) { + int yi, mi, i; + int64_t days; + volatile double temp; /* enforce evaluation order */ ++ double d = NAN; + ++ JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + /* emulate 21.4.1.15 MakeDay ( year, month, date ) */ + y = fields[0]; + m = fields[1]; +@@ -52287,7 +52308,7 @@ static double set_date_fields(double fields[minimum_length(7)], int is_local) { + if (mn < 0) + mn += 12; + if (ym < -271821 || ym > 275760) +- return NAN; ++ goto out; + + yi = ym; + mi = mn; +@@ -52319,14 +52340,17 @@ static double set_date_fields(double fields[minimum_length(7)], int is_local) { + /* emulate 21.4.1.16 MakeDate ( day, time ) */ + tv = (temp = day * 86400000) + time; /* prevent generation of FMA */ + if (!isfinite(tv)) +- return NAN; ++ goto out; + + /* adjust for local time and clip */ + if (is_local) { + int64_t ti = tv < INT64_MIN ? INT64_MIN : tv >= 0x1p63 ? INT64_MAX : (int64_t)tv; + tv += getTimezoneOffset(ti) * 60000; + } +- return time_clip(tv); ++ d = time_clip(tv); ++out: ++ JS_X87_FPCW_RESTORE(fpcw); ++ return d; + } + + static JSValue get_date_field(JSContext *ctx, JSValueConst this_val, diff --git a/gnu/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch b/gnu/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch new file mode 100644 index 00000000000..005414e1252 --- /dev/null +++ b/gnu/packages/patches/quickjs-ng-fix-atomics.pause-on-32-bit.patch @@ -0,0 +1,26 @@ +From c211485e6f6c9fcd0ea9f5aa1943f8c95fdd186b Mon Sep 17 00:00:00 2001 +From: Ben Noordhuis <info@bnoordhuis.nl> +Date: Sun, 9 Nov 2025 21:28:14 +0100 +Subject: [PATCH] Fix Atomics.pause on 32 bits platforms + +Use JS_VALUE_GET_NORM_TAG to get the type tag, not JS_VALUE_GET_TAG. +The latter doesn't work correctly with NaN boxing. + +Refs: https://github.com/quickjs-ng/quickjs/issues/986#issuecomment-3508547332 +--- + quickjs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/quickjs.c b/quickjs.c +index 4fb9f95b7..3970bb247 100644 +--- a/quickjs.c ++++ b/quickjs.c +@@ -57112,7 +57112,7 @@ static JSValue js_atomics_pause(JSContext *ctx, JSValueConst this_obj, + double d; + + if (argc > 0) { +- switch (JS_VALUE_GET_TAG(argv[0])) { ++ switch (JS_VALUE_GET_NORM_TAG(argv[0])) { + case JS_TAG_FLOAT64: // accepted if and only if fraction == 0.0 + d = JS_VALUE_GET_FLOAT64(argv[0]); + if (isfinite(d)) |
