Skip to content

Commit cbf40dc

Browse files
authored
[EH] Add WASM_LEGACY_EXCEPTIONS option (#23365)
This replaces the existing `WASM_EXNREF` option with `WASM_LEGACY_EXCEPTIONS` option, in an effort to make the new standardized exnref proposal the 'default' state and the legacy proposal needs to be separately enabled an option. But given that most users haven't switched to the new proposal and major web browsers haven't turned it on by default, this `WASM_LEGACY_EXCEPTIONS` is turned on by default for the moment. This changes the following function names in `test/common.py` as well: - `require(s)_wasm_eh` -> `require(s)_wasm_legacy_eh` - `require(s)_wasm_exnref` -> `require(s)_wasm_eh` Even if `WASM_LEGACY_EXCEPTIONS` defaults to true for now, this adds `set_setting(WASM_LEGACY_EXCEPTIONS)` in the tests to minimize future fixes when `WASM_LEGACY_EXCEPTIONS` will eventually be turned off by default. The test names and suffixes will be changed accordingly in a follow-up. This is in line with llvm/llvm-project#122158.
1 parent 0265d84 commit cbf40dc

File tree

7 files changed

+59
-47
lines changed

7 files changed

+59
-47
lines changed

ChangeLog.md

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ See docs/process.md for more on how version tagging works.
2323
- Emscripten version was bumped to 4.0.0. Happy new year, happy new major
2424
version! While version has a few interesting changes, there is nothing huge
2525
that makes it different from any other release. (#19053)
26+
- `-sWASM_LEAGCY_EXCEPTIONS` option is added. (#23365) If true, it will emit
27+
instructions for the legacy Wasm exception handling proposal
28+
(https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md),
29+
and if false, the new standardized exception handling proposal
30+
(https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md).
31+
This option defaults to true, given that major web browsers do not support the
32+
new proposal by default yet. This option replaces the existing
33+
`-sWASM_EXNREF`, whose meaning was the opposite.
2634
- compiler-rt, libcxx, libcxxabi, and libunwind were updated to LLVM 19.1.6.
2735
(#22937, #22994, and #23294)
2836
- The default Safari version targeted by Emscripten has been raised from 14.1

site/source/docs/tools_reference/settings_reference.rst

+8-7
Original file line numberDiff line numberDiff line change
@@ -1155,16 +1155,17 @@ This option implies EXPORT_EXCEPTION_HANDLING_HELPERS.
11551155

11561156
Default value: false
11571157

1158-
.. _wasm_exnref:
1158+
.. _wasm_legacy_exceptions:
11591159

1160-
WASM_EXNREF
1161-
===========
1160+
WASM_LEGACY_EXCEPTIONS
1161+
======================
11621162

1163-
Emit instructions for the new Wasm exception handling proposal with exnref,
1164-
which was adopted on Oct 2023. The implementation of the new proposal is
1165-
still in progress and this feature is currently experimental.
1163+
If true, emit instructions for the legacy Wasm exception handling proposal:
1164+
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
1165+
If false, emit instructions for the standardized exception handling proposal:
1166+
https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
11661167

1167-
Default value: false
1168+
Default value: true
11681169

11691170
.. _nodejs_catch_exit:
11701171

src/settings.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -777,11 +777,12 @@ var EXPORT_EXCEPTION_HANDLING_HELPERS = false;
777777
// [link]
778778
var EXCEPTION_STACK_TRACES = false;
779779

780-
// Emit instructions for the new Wasm exception handling proposal with exnref,
781-
// which was adopted on Oct 2023. The implementation of the new proposal is
782-
// still in progress and this feature is currently experimental.
780+
// If true, emit instructions for the legacy Wasm exception handling proposal:
781+
// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
782+
// If false, emit instructions for the standardized exception handling proposal:
783+
// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
783784
// [link]
784-
var WASM_EXNREF = false;
785+
var WASM_LEGACY_EXCEPTIONS = true;
785786

786787
// Emscripten throws an ExitStatus exception to unwind when exit() is called.
787788
// Without this setting enabled this can show up as a top level unhandled

test/common.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -277,23 +277,23 @@ def decorated(self, *args, **kwargs):
277277
return decorated
278278

279279

280-
def requires_wasm_eh(func):
280+
def requires_wasm_legacy_eh(func):
281281
assert callable(func)
282282

283283
@wraps(func)
284284
def decorated(self, *args, **kwargs):
285-
self.require_wasm_eh()
285+
self.require_wasm_legacy_eh()
286286
return func(self, *args, **kwargs)
287287

288288
return decorated
289289

290290

291-
def requires_wasm_exnref(func):
291+
def requires_wasm_eh(func):
292292
assert callable(func)
293293

294294
@wraps(func)
295295
def decorated(self, *args, **kwargs):
296-
self.require_wasm_exnref()
296+
self.require_wasm_eh()
297297
return func(self, *args, **kwargs)
298298

299299
return decorated
@@ -647,10 +647,9 @@ def metafunc(self, mode, *args, **kwargs):
647647
self.emcc_args.append('-fwasm-exceptions')
648648
self.set_setting('SUPPORT_LONGJMP', 'wasm')
649649
if mode == 'wasm':
650-
self.require_wasm_eh()
650+
self.require_wasm_legacy_eh()
651651
if mode == 'wasm_exnref':
652-
self.require_wasm_exnref()
653-
self.set_setting('WASM_EXNREF')
652+
self.require_wasm_eh()
654653
f(self, *args, **kwargs)
655654
else:
656655
self.set_setting('DISABLE_EXCEPTION_CATCHING', 0)
@@ -683,10 +682,9 @@ def metafunc(self, mode, *args, **kwargs):
683682
self.skipTest('Wasm EH does not work with asan yet')
684683
self.set_setting('SUPPORT_LONGJMP', 'wasm')
685684
if mode == 'wasm':
686-
self.require_wasm_eh()
685+
self.require_wasm_legacy_eh()
687686
if mode == 'wasm_exnref':
688-
self.require_wasm_exnref()
689-
self.set_setting('WASM_EXNREF')
687+
self.require_wasm_eh()
690688
f(self, *args, **kwargs)
691689
else:
692690
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
@@ -997,7 +995,8 @@ def require_simd(self):
997995
else:
998996
self.fail('either d8 or node >= 16 required to run wasm64 tests. Use EMTEST_SKIP_SIMD to skip')
999997

1000-
def require_wasm_eh(self):
998+
def require_wasm_legacy_eh(self):
999+
self.set_setting('WASM_LEGACY_EXCEPTIONS')
10011000
nodejs = self.get_nodejs()
10021001
if nodejs:
10031002
version = shared.get_node_version(nodejs)
@@ -1015,7 +1014,8 @@ def require_wasm_eh(self):
10151014
else:
10161015
self.fail('either d8 or node >= 17 required to run wasm-eh tests. Use EMTEST_SKIP_EH to skip')
10171016

1018-
def require_wasm_exnref(self):
1017+
def require_wasm_eh(self):
1018+
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
10191019
nodejs = self.get_nodejs()
10201020
if nodejs:
10211021
if self.node_is_canary(nodejs):

test/test_core.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from common import read_file, read_binary, requires_v8, requires_node, requires_wasm2js, requires_node_canary
2929
from common import compiler_for, crossplatform, no_4gb, no_2gb, also_with_minimal_runtime
3030
from common import with_all_fs, also_with_nodefs, also_with_nodefs_both, also_with_noderawfs, also_with_wasmfs
31-
from common import with_all_eh_sjlj, with_all_sjlj, also_with_standalone_wasm, can_do_standalone, no_wasm64, requires_wasm_exnref
31+
from common import with_all_eh_sjlj, with_all_sjlj, also_with_standalone_wasm, can_do_standalone, no_wasm64, requires_wasm_eh
3232
from common import NON_ZERO, WEBIDL_BINDER, EMBUILDER, PYTHON
3333
import clang_native
3434

@@ -856,7 +856,7 @@ def test_longjmp_zero(self):
856856
self.skipTest('https://github.com/emscripten-core/emscripten/issues/21533')
857857
self.do_core_test('test_longjmp_zero.c')
858858

859-
@requires_wasm_exnref
859+
@requires_wasm_eh
860860
def test_longjmp_with_and_without_exceptions(self):
861861
# Emscripten SjLj with and without Emscripten EH support
862862
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
@@ -875,8 +875,8 @@ def test_longjmp_with_and_without_exceptions(self):
875875
self.emcc_args.append('-fwasm-exceptions')
876876
for arg in ('-fwasm-exceptions', '-fno-exceptions'):
877877
self.do_core_test('test_longjmp.c', emcc_args=[arg])
878-
# Wasm SjLj with and with new EH (exnref) support
879-
self.set_setting('WASM_EXNREF')
878+
# Wasm SjLj with and with the standardized EH (exnref) support
879+
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
880880
self.do_core_test('test_longjmp.c', emcc_args=['-fwasm-exceptions'])
881881

882882
@with_all_sjlj
@@ -994,7 +994,7 @@ def test_exceptions(self):
994994
self.maybe_closure()
995995
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
996996

997-
@requires_wasm_exnref
997+
@requires_wasm_eh
998998
def test_exceptions_with_and_without_longjmp(self):
999999
self.set_setting('EXCEPTION_DEBUG')
10001000
self.maybe_closure()
@@ -1014,8 +1014,8 @@ def test_exceptions_with_and_without_longjmp(self):
10141014
for support_longjmp in (0, 'wasm'):
10151015
self.set_setting('SUPPORT_LONGJMP', support_longjmp)
10161016
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
1017-
# Wasm new EH (exnref) with and without Wasm SjLj support
1018-
self.set_setting('WASM_EXNREF')
1017+
# Wasm standardized EH (exnref) with and without Wasm SjLj support
1018+
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
10191019
for support_longjmp in (0, 'wasm'):
10201020
self.set_setting('SUPPORT_LONGJMP', support_longjmp)
10211021
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
@@ -1519,7 +1519,7 @@ def clear_all_relevant_settings(self):
15191519
self.clear_setting('DISABLE_EXCEPTION_CATCHING')
15201520
self.clear_setting('SUPPORT_LONGJMP')
15211521
self.clear_setting('ASYNCIFY')
1522-
self.clear_setting('WASM_EXNREF')
1522+
self.clear_setting('WASM_LEGACY_EXCEPTIONS')
15231523

15241524
# Emscripten EH and Wasm EH cannot be enabled at the same time
15251525
self.set_setting('DISABLE_EXCEPTION_CATCHING', 0)

test/test_other.py

+16-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from common import env_modify, no_mac, no_windows, only_windows, requires_native_clang, with_env_modify
3636
from common import create_file, parameterized, NON_ZERO, node_pthreads, TEST_ROOT, test_file
3737
from common import compiler_for, EMBUILDER, requires_v8, requires_node, requires_wasm64, requires_node_canary
38-
from common import requires_wasm_exnref, crossplatform, with_all_eh_sjlj, with_all_sjlj
38+
from common import requires_wasm_eh, crossplatform, with_all_eh_sjlj, with_all_sjlj
3939
from common import also_with_standalone_wasm, also_with_wasm2js, also_with_noderawfs, also_with_wasmfs
4040
from common import also_with_minimal_runtime, also_with_wasm_bigint, also_with_wasm64, flaky
4141
from common import EMTEST_BUILD_VERBOSE, PYTHON, WEBIDL_BINDER
@@ -3539,7 +3539,7 @@ def test_embind_tsgen_jspi(self):
35393539
'wasm_exnref': [1]
35403540
})
35413541
def test_embind_tsgen_exceptions(self, wasm_exnref):
3542-
self.set_setting('WASM_EXNREF', wasm_exnref)
3542+
self.set_setting('WASM_LEGACY_EXCEPTIONS', wasm_exnref == 1)
35433543
# Check that when Wasm exceptions and assertions are enabled bindings still generate.
35443544
self.run_process([EMXX, test_file('other/embind_tsgen.cpp'),
35453545
'-lembind', '-fwasm-exceptions', '-sASSERTIONS',
@@ -8928,8 +8928,8 @@ def test_codesize_minimal_pthreads(self):
89288928
'mangle': (['-O2', '-fexceptions',
89298929
'-sDEMANGLE_SUPPORT', '-Wno-deprecated'], [], ['waka']), # noqa
89308930
# Wasm EH's code size increase is smaller than that of Emscripten EH
8931-
'except_wasm': (['-O2', '-fwasm-exceptions'], [], ['waka']),
8932-
'except_wasm_exnref': (['-O2', '-fwasm-exceptions', '-sWASM_EXNREF'], [], ['waka']),
8931+
'except_wasm': (['-O2', '-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS'], [], ['waka']),
8932+
'except_wasm_exnref': (['-O2', '-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS=0'], [], ['waka']),
89338933
# eval_ctors 1 can partially optimize, but runs into getenv() for locale
89348934
# code. mode 2 ignores those and fully optimizes out the ctors
89358935
'ctors1': (['-O2', '-sEVAL_CTORS'], [], ['waka']),
@@ -9230,8 +9230,8 @@ def test_lto(self, args):
92309230
@parameterized({
92319231
'noexcept': [],
92329232
'except': ['-sDISABLE_EXCEPTION_CATCHING=0'],
9233-
'except_wasm': ['-fwasm-exceptions'],
9234-
'except_wasm_exnref': ['-fwasm-exceptions', '-sWASM_EXNREF']
9233+
'except_wasm': ['-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS'],
9234+
'except_wasm_exnref': ['-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS=0']
92359235
})
92369236
def test_lto_libcxx(self, *args):
92379237
self.run_process([EMXX, test_file('hello_libcxx.cpp'), '-flto'] + list(args))
@@ -9250,13 +9250,14 @@ def test_lto_flags(self):
92509250

92519251
# We have LTO tests covered in 'wasmltoN' targets in test_core.py, but they
92529252
# don't run as a part of Emscripten CI, so we add a separate LTO test here.
9253-
@requires_wasm_exnref
9253+
@requires_wasm_eh
92549254
def test_lto_wasm_exceptions(self):
92559255
self.set_setting('EXCEPTION_DEBUG')
9256+
self.set_setting('WASM_LEGACY_EXCEPTIONS')
92569257
self.emcc_args += ['-fwasm-exceptions', '-flto']
92579258
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
92589259
# New Wasm EH with exnref
9259-
self.set_setting('WASM_EXNREF')
9260+
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
92609261
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
92619262

92629263
@parameterized({
@@ -9319,7 +9320,7 @@ def test_exceptions_stack_trace_and_message(self):
93199320
# optional 'traceStack' option in WebAssembly.Exception constructor
93209321
# (https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception/Exception)
93219322
# and embeds stack traces unconditionally. Change this back to
9322-
# self.require_wasm_eh() if this issue is fixed later.
9323+
# self.require_wasm_legacy_eh() if this issue is fixed later.
93239324
self.require_v8()
93249325

93259326
# Stack traces are enabled when either of ASSERTIONS or
@@ -9360,7 +9361,7 @@ def test_exceptions_rethrow_stack_trace_and_message(self):
93609361
# optional 'traceStack' option in WebAssembly.Exception constructor
93619362
# (https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception/Exception)
93629363
# and embeds stack traces unconditionally. Change this back to
9363-
# self.require_wasm_eh() if this issue is fixed later.
9364+
# self.require_wasm_legacy_eh() if this issue is fixed later.
93649365
self.require_v8()
93659366
# Rethrowing exception currently loses the stack trace before the rethrowing
93669367
# due to how rethrowing is implemented. So in the examples below we don't
@@ -12761,15 +12762,16 @@ def test_standalone_export_main(self):
1276112762
# We should consider making this a warning since the `_main` export is redundant.
1276212763
self.run_process([EMCC, '-sEXPORTED_FUNCTIONS=_main', '-sSTANDALONE_WASM', test_file('core/test_hello_world.c')])
1276312764

12764-
@requires_wasm_exnref
12765+
@requires_wasm_eh
1276512766
def test_standalone_wasm_exceptions(self):
1276612767
self.set_setting('STANDALONE_WASM')
1276712768
self.set_setting('WASM_BIGINT')
1276812769
self.wasm_engines = []
1276912770
self.emcc_args += ['-fwasm-exceptions']
12771+
self.set_setting('WASM_LEGACY_EXCEPTIONS')
1277012772
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
1277112773
# New Wasm EH with exnref
12772-
self.set_setting('WASM_EXNREF')
12774+
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
1277312775
self.do_run_in_out_file_test('core/test_exceptions.cpp', out_suffix='_caught')
1277412776

1277512777
def test_missing_malloc_export(self):
@@ -15310,8 +15312,8 @@ def test_SUPPORT_BIG_ENDIAN(self):
1531015312
'noexcept': ['-fno-exceptions'],
1531115313
'default': [],
1531215314
'except': ['-sDISABLE_EXCEPTION_CATCHING=0'],
15313-
'except_wasm': ['-fwasm-exceptions'],
15314-
'except_wasm_exnref': ['-fwasm-exceptions', '-sWASM_EXNREF']
15315+
'except_wasm': ['-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS'],
15316+
'except_wasm_exnref': ['-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS=0']
1531515317
})
1531615318
def test_std_promise_link(self, *args):
1531715319
# Regression test for a bug where std::promise's destructor caused a link

tools/link.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,8 @@ def check_human_readable_list(items):
432432
extras = settings.BINARYEN_EXTRA_PASSES.split(',')
433433
passes += [('--' + p) if p[0] != '-' else p for p in extras if p]
434434

435-
# Run the translator to the new EH instructions with exnref
436-
if settings.WASM_EXNREF:
435+
# Run the translator to the new standardized EH instructions with exnref
436+
if not settings.WASM_LEGACY_EXCEPTIONS:
437437
passes += ['--emit-exnref']
438438

439439
# If we are going to run metadce then that means we will be running binaryen

0 commit comments

Comments
 (0)