From 3c8872ffb60688776043e96854702c018857b230 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 18 Aug 2026 13:46:57 -0700 Subject: [PATCH] Mark WASM_BIGINT as deprecated With the minimum Safari version bumped to 15 in #27542, WebAssembly BigInt integration (`WASM_BIGINT`) is now standard and enabled by default across all supported engines. The only remaining use case for disabling it is internally for `WASM2JS` (`-sWASM=0`). Users should no longer set `-sWASM_BIGINT` directly, so mark `WASM_BIGINT` as deprecated. --- ChangeLog.md | 3 +++ .../tools_reference/settings_reference.rst | 3 +++ src/settings.js | 1 + test/decorators.py | 18 ------------------ test/test_browser.py | 15 ++++++--------- test/test_core.py | 13 +------------ test/test_jslib.py | 6 +++--- test/test_other.py | 19 +++++++++++-------- tools/settings.py | 1 + 9 files changed, 29 insertions(+), 50 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index c371f965dc355..4d0a2b1adc5a8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -33,6 +33,9 @@ See docs/process.md for more on how version tagging works. disabling of `WASM_BIGINT` itself should only be needed under `-sWASM=0` (where it is automatically disabled). (#27568) - The `SOCKET_WEBRTC` setting was removed (#27367) +- `WASM_BIGINT` was deprecated. BigInt integration is standard and enabled by + default across all supported engines; it should now only ever be disabled + implicitly when targeting JavaScript via `-sWASM=0`. (#27558) 6.0.7 - 08/17/26 ---------------- diff --git a/site/source/docs/tools_reference/settings_reference.rst b/site/source/docs/tools_reference/settings_reference.rst index 3e24d226373bf..aaccc9b8823b2 100644 --- a/site/source/docs/tools_reference/settings_reference.rst +++ b/site/source/docs/tools_reference/settings_reference.rst @@ -2139,6 +2139,8 @@ WebAssembly integration with JavaScript BigInt. When enabled we don't need to legalize i64s into pairs of i32s, as the wasm VM will use a BigInt where an i64 is used. +.. note:: This setting is deprecated + Default value: true .. _emit_producers_section: @@ -3521,6 +3523,7 @@ these settings please open a bug (or reply to one of the existing bugs). - ``RUNTIME_LINKED_LIBS``: you can simply list the libraries directly on the commandline now - ``CLOSURE_WARNINGS``: use -Wclosure/-Wno-closure instead + - ``WASM_BIGINT``: no longer needed. Should only ever be implicitly disabled by -sWASM=0 - ``ASYNCIFY_EXPORTS``: please use JSPI_EXPORTS instead - ``LINKABLE``: under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262) - ``EXPORT_EXCEPTION_HANDLING_HELPERS``: getExceptionMessage is exported anyway when ASSERTIONS or EXCEPTION_STACK_TRACES is set, which are set by default at -O0. At -O1 or above, you can export it separately by -sEXPORTED_RUNTIME_METHODS=getExceptionMessage,decrementExceptionRefcount. diff --git a/src/settings.js b/src/settings.js index c9797396ed36f..8101b4662c3d8 100644 --- a/src/settings.js +++ b/src/settings.js @@ -1490,6 +1490,7 @@ var DYNCALLS = false; // legalize i64s into pairs of i32s, as the wasm VM will use a BigInt where an // i64 is used. // [link] +// [deprecated] var WASM_BIGINT = true; // WebAssembly defines a "producers section" which compilers and tools can diff --git a/test/decorators.py b/test/decorators.py index b422fe7f9add6..823f6f3d33749 100644 --- a/test/decorators.py +++ b/test/decorators.py @@ -416,24 +416,6 @@ def metafunc(self, with_minimal_runtime, *args, **kwargs): return metafunc -def also_without_bigint(func): - assert callable(func) - - @wraps(func) - def metafunc(self, no_bigint, *args, **kwargs): - if DEBUG: - print('parameterize:no_bigint=%s' % no_bigint) - if no_bigint: - if self.get_setting('WASM_BIGINT') is not None: - self.skipTest('redundant in bigint test config') - self.set_setting('WASM_BIGINT', 0) - return func(self, *args, **kwargs) - - parameterize(metafunc, {'': (False,), - 'no_bigint': (True,)}) - return metafunc - - def also_with_wasm64(func): assert callable(func) diff --git a/test/test_browser.py b/test/test_browser.py index 9faccdfdc8456..b5381bd96f07b 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -3203,8 +3203,6 @@ def test_cocos2d_hello(self): 'asyncify': (['-sASYNCIFY'],), 'asyncify_minimal_runtime': (['-sMINIMAL_RUNTIME', '-sASYNCIFY'],), 'jspi': (['-sJSPI'],), - 'jspi_wasm_bigint': (['-sJSPI', '-sWASM_BIGINT'],), - 'jspi_wasm_bigint_minimal_runtime': (['-sMINIMAL_RUNTIME', '-sJSPI', '-sWASM_BIGINT'],), }) def test_async(self, opt, args): if is_jspi(args) and not is_chrome(): @@ -3873,8 +3871,8 @@ def test_pthread_printf(self, args): def test_pthread_iostream(self): self.btest_exit('pthread/test_pthread_iostream.cpp', cflags=['-O3', '-pthread', '-sPTHREAD_POOL_SIZE']) - def test_pthread_unistd_io_bigint(self): - self.btest_exit('unistd/io.c', cflags=['-pthread', '-sPROXY_TO_PTHREAD', '-sWASM_BIGINT']) + def test_pthread_unistd_io(self): + self.btest_exit('unistd/io.c', cflags=['-pthread', '-sPROXY_TO_PTHREAD']) # Test that the main thread is able to use pthread_set/getspecific. @also_with_wasm2js @@ -5264,17 +5262,16 @@ def test_dlmalloc_3gb(self): self.set_setting('MAXIMUM_MEMORY', '4GB') self.btest_exit('alloc_3gb.c', cflags=['-sMALLOC=dlmalloc', '-sALLOW_MEMORY_GROWTH=1']) + # under wasm2js we disable BigInt support which affects the ABI + @also_with_wasm2js @parameterized({ # the fetch backend works even on the main thread: we proxy to a background # thread and busy-wait # this test requires one thread per fetch backend, so updates to the test # will require bumping this - 'main_thread': (['-sPTHREAD_POOL_SIZE=5'],), + '': (['-sPTHREAD_POOL_SIZE=5'],), # using proxy_to_pthread also works, of course 'proxy_to_pthread': (['-sPROXY_TO_PTHREAD', '-DPROXYING'],), - # using BigInt support affects the ABI, and should not break things. (this - # could be tested on either thread; do the main thread for simplicity) - 'bigint': (['-sPTHREAD_POOL_SIZE=5', '-sWASM_BIGINT'],), }) def test_wasmfs_fetch_backend_threaded(self, args): create_file('data.dat', 'hello, fetch') @@ -5290,10 +5287,10 @@ def test_wasmfs_fetch_backend_threaded(self, args): '--js-library', test_file('wasmfs/wasmfs_fetch.js')] + args) @no_firefox('no OPFS support yet') + @also_with_wasm2js @parameterized({ '': (['-pthread', '-sPROXY_TO_PTHREAD'],), 'jspi': (['-sJSPI'],), - 'jspi_wasm_bigint': (['-sJSPI', '-sWASM_BIGINT'],), 'asyncify': (['-sASYNCIFY=1'],), }) @no_safari('TODO: Fails with abort:Assertion failed: err == 0') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15) diff --git a/test/test_core.py b/test/test_core.py index 19bd5633fff4e..110dacf458821 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -48,7 +48,6 @@ also_with_pthreads, also_with_standalone_wasm, also_with_wasmfs, - also_without_bigint, can_do_standalone, crossplatform, disabled, @@ -2080,7 +2079,7 @@ def test_em_js(self, args, force_c): @no_wasm2js('test depends on WASM_BIGINT which is not compatible with wasm2js') def test_em_js_i64(self): expected = 'emcc: error: using 64-bit arguments in EM_JS function without WASM_BIGINT is not yet fully supported: `foo`' - self.assert_fail([EMCC, '-Werror', '-sWASM_BIGINT=0', test_file('core/test_em_js_i64.c')], expected) + self.assert_fail([EMCC, '-Werror', '-sWASM=0', test_file('core/test_em_js_i64.c')], expected) self.do_core_test('test_em_js_i64.c') def test_em_js_address_taken(self): @@ -4419,7 +4418,6 @@ def test_dylink_i64_b(self): ''', 'other says -1311768467750121224.\nmy fp says: 43.\nmy second fp says: 43.', force_c=True) @with_dylink_reversed - @also_without_bigint def test_dylink_i64_c(self): self.dylink_test(r''' #include @@ -4471,7 +4469,6 @@ def test_dylink_i64_c(self): EMSCRIPTEN_KEEPALIVE int64_t function_ret_64(int32_t i, int32_t j, int32_t k); ''', force_c=True) - @also_without_bigint @parameterized({ '': (False,), 'rtld_local': (True,), @@ -5728,7 +5725,6 @@ def test_readdir(self): self.cflags += ['-DWASMFS_NODERAWFS'] self.do_runf_out_file('dirent/test_readdir.c') - @also_without_bigint def test_readdir_empty(self): self.do_runf_out_file('dirent/test_readdir_empty.c') @@ -5782,7 +5778,6 @@ def test_fcntl_open(self): self.skipTest('noderawfs fails here under non-linux') self.do_runf_out_file('fcntl/test_fcntl_open.c') - @also_without_bigint def test_fcntl_misc(self): if self.get_setting('WASMFS'): self.cflags += ['-sFORCE_FILESYSTEM'] @@ -5860,7 +5855,6 @@ def test_utf8(self): self.do_runf('core/test_utf8.c', 'done\n') @with_both_text_decoder - @also_without_bigint def test_utf8_bench(self): self.cflags += ['--embed-file', test_file('test_utf8_bench.txt') + '@/utf8_corpus.txt'] self.do_runf('test_utf8_bench.c', 'done\n') @@ -6304,7 +6298,6 @@ def test_unistd_symlink_on_nodefs(self): # Calling readlink() on a non-link gives error 22 EINVAL on Unix, but simply error 0 OK on Windows. self.do_runf_out_file('unistd/symlink_on_nodefs.c', cflags=['-lnodefs.js']) - @also_without_bigint @also_with_nodefs def test_unistd_io(self): if self.get_setting('WASMFS'): @@ -7269,7 +7262,6 @@ def test_dyncall_ptr_handling(self): def test_dyncall_pointers(self, args): self.do_core_test('test_dyncall_pointers.c', cflags=args) - @also_without_bigint @no_modularize_instance('uses Module object directly') def test_getValue_setValue(self): # these used to be exported, but no longer are by default @@ -7704,7 +7696,6 @@ def test_embind_float_constants(self): def test_embind_negative_constants(self): self.do_runf_out_file('embind/test_negative_constants.cpp', cflags=['-lembind']) - @also_without_bigint def test_embind_unsigned(self): self.do_runf_out_file('embind/test_unsigned.cpp', cflags=['-lembind']) @@ -8242,7 +8233,6 @@ def test_modularize_closure_pre(self): @no_wasm2js('symbol names look different wasm2js backtraces') @no_modularize_instance('assumes .js output filename') - @also_without_bigint @no_bun('https://github.com/emscripten-core/emscripten/issues/26197') def test_emscripten_log(self): self.cflags += ['-g', '-DRUN_FROM_JS_SHELL', '-Wno-deprecated-pragma'] @@ -9788,7 +9778,6 @@ def test_pipe_select(self, args): def test_pipe_pollhup(self): self.do_runf('core/test_pipe_pollhup.c', 'done\n') - @also_without_bigint def test_jslib_i64_params(self): # Tests the defineI64Param and receiveI64ParamAsI53 helpers that are # used to receive i64 argument in syscalls. diff --git a/test/test_jslib.py b/test/test_jslib.py index 4f0236404e71b..4d210d4716e8e 100644 --- a/test/test_jslib.py +++ b/test/test_jslib.py @@ -6,7 +6,7 @@ from subprocess import PIPE from common import RunnerCore, copy_asset, create_file, read_file, test_file -from decorators import also_with_wasm64, also_without_bigint, parameterized, requires_node_25 +from decorators import also_with_wasm2js, also_with_wasm64, parameterized, requires_node_25 from tools.shared import EMCC from tools.utils import delete_file @@ -375,7 +375,7 @@ def test_jslib_invalid_decorator(self): "lib.js: Decorator (jslibfunc__export) has wrong type. Expected 'boolean' not 'string'") @also_with_wasm64 - @also_without_bigint + @also_with_wasm2js def test_jslib_i53abi(self): create_file('lib.js', r''' addToLibrary({ @@ -597,7 +597,7 @@ def test_jslib_include(self): self.assert_fail([EMCC, test_file('hello_world.c'), '--js-library', 'foo.js'], 'foo.js:5: file not found: inc.js') @also_with_wasm64 - @also_without_bigint + @also_with_wasm2js @parameterized({ '': ([],), 'closure': (['--closure=1'],), diff --git a/test/test_other.py b/test/test_other.py index 3de75e6cc1c67..d116ed31ead93 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -71,7 +71,6 @@ also_with_wasm2js, also_with_wasm64, also_with_wasmfs, - also_without_bigint, crossplatform, disabled, flaky, @@ -7961,6 +7960,7 @@ def test_EM_ASM_i64(self): def test_EM_ASM_i64_nobigint(self): self.set_setting('WASM_BIGINT', 0) + self.cflags.append('-Wno-error=deprecated') self.do_runf('other/test_em_asm_i64.cpp', 'Invalid character 106("j") in readEmAsmArgs!', assert_returncode=NON_ZERO) def test_eval_ctor_ordering(self): @@ -9471,9 +9471,9 @@ def test_full_js_library_except(self): @crossplatform @parameterized({ '': ([],), - # bigint support is interesting to test here because it changes which + # wasm2js support is interesting to test here because it changes which # binaryen tools get run, which can affect how debug info is kept around - 'nobigint': (['-sWASM_BIGINT=0'],), + 'wasm2js': (['-sWASM=0'],), 'pthread': (['-pthread', '-Wno-experimental'],), 'pthread_offscreen': (['-pthread', '-Wno-experimental', '-sOFFSCREEN_FRAMEBUFFER'],), 'wasmfs': (['-sWASMFS'],), @@ -9482,6 +9482,12 @@ def test_full_js_library_except(self): }) def test_closure_full_js_library(self, args): # Test for closure errors and warnings in the entire JS library. + # Enable as many features as possible in order to maximise + # the amount of library code we include here. + if '-sWASM=0' in args: + args += ['-sEXPORT_ALL'] + else: + args += ['-sMAIN_MODULE'] self.build('hello_world.c', cflags=[ '--closure=1', '--minify=0', @@ -9492,9 +9498,6 @@ def test_closure_full_js_library(self, args): '-sAUTO_JS_LIBRARIES', '-sINCLUDE_FULL_LIBRARY', '-sOFFSCREEN_FRAMEBUFFER', - # Enable as many features as possible in order to maximise - # the amount of library code we include here. - '-sMAIN_MODULE', '-sFETCH', '-sFETCH_SUPPORT_INDEXEDDB', '-sLEGACY_GL_EMULATION', @@ -14103,7 +14106,7 @@ def test_jspi_code_size(self): def test_no_cfi(self): self.assert_fail([EMCC, '-fsanitize=cfi', '-flto', test_file('hello_world.c')], 'emcc: error: emscripten does not currently support -fsanitize=cfi') - @also_without_bigint + @also_with_wasm2js def test_parseTools(self): # Suppress js compiler warnings because we deliberately use legacy parseTools functions self.cflags += ['-Wno-js-compiler', '--js-library', test_file('other/test_parseTools.js')] @@ -14355,7 +14358,7 @@ def test_itimer_pthread(self): self.do_other_test('test_itimer.c') def test_itimer_standalone(self): - self.do_other_test('test_itimer_standalone.c', cflags=['-sSTANDALONE_WASM', '-sWASM_BIGINT']) + self.do_other_test('test_itimer_standalone.c', cflags=['-sSTANDALONE_WASM']) for engine in config.WASM_ENGINES: print('wasm engine', engine) self.assertContained('done\n', self.run_js('test_itimer_standalone.wasm', engine)) diff --git a/tools/settings.py b/tools/settings.py index 1ace508d110df..bc439323fdae9 100644 --- a/tools/settings.py +++ b/tools/settings.py @@ -109,6 +109,7 @@ DEPRECATED_SETTINGS = { 'RUNTIME_LINKED_LIBS': 'you can simply list the libraries directly on the commandline now', 'CLOSURE_WARNINGS': 'use -Wclosure/-Wno-closure instead', + 'WASM_BIGINT': 'no longer needed. Should only ever be implicitly disabled by -sWASM=0', 'ASYNCIFY_EXPORTS': 'please use JSPI_EXPORTS instead', 'LINKABLE': 'under consideration for removal (https://github.com/emscripten-core/emscripten/issues/25262)', 'EXPORT_EXCEPTION_HANDLING_HELPERS': 'getExceptionMessage is exported anyway when ASSERTIONS or EXCEPTION_STACK_TRACES is set, which are set by default at -O0. At -O1 or above, you can export it separately by -sEXPORTED_RUNTIME_METHODS=getExceptionMessage,decrementExceptionRefcount.',