Skip to content

Commit 619f08d

Browse files
authored
[EH] Add new test setting for new Wasm EH (#21906)
`with_all_eh_sjlj` and `with_all_sjlj` decorators (previously `with_both_eh_sjlj` and `with_both_sjlj` but recently got renamed) currently tests two modes: Emscripten EH and Wasm EH (pre-2023). We decided to switch to a new version of the Wasm EH proposal in Oct 2023, so this adds a new test setting for the new Wasm EH proposal in those decorators. Currently we have two parameters: - ``: Emscripten EH - `wasm`: Wasm EH (pre-2023) This changes it to these three parameters: - `emscripten`: Emscripten EH - `wasm`: Wasm EH (pre-2023) - `wasm_exnref`: Wasm EH (New proposal adopted on Oct 2023) To use the new mode in the command line, you use `-fwasm-exceptions` as in the old Wasm EH, but add `-sWASM_EXNREF` additionally. This currently uses the Binaryen translator that translates old Wasm EH instruction to the new ones (https://github.com/WebAssembly/binaryen/blob/main/src/passes/TranslateEH.cpp) at the end of the Binaryen pipeline to produce new binaries.
1 parent 1ee1f88 commit 619f08d

File tree

5 files changed

+75
-12
lines changed

5 files changed

+75
-12
lines changed

site/source/docs/tools_reference/settings_reference.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,17 @@ ASSERTIONS is enabled. This option is for users who want exceptions' stack
994994
traces but do not want other overheads ASSERTIONS can incur.
995995
This option implies EXPORT_EXCEPTION_HANDLING_HELPERS.
996996

997+
.. _wasm_exnref:
998+
999+
WASM_EXNREF
1000+
===========
1001+
1002+
Emit instructions for the new Wasm exception handling proposal with exnref,
1003+
which was adopted on Oct 2023. The implementation of the new proposal is
1004+
still in progress and this feature is currently experimental.
1005+
1006+
.. note:: Applicable during both linking and compilation
1007+
9971008
.. _nodejs_catch_exit:
9981009

9991010
NODEJS_CATCH_EXIT

src/settings.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,12 @@ var EXPORT_EXCEPTION_HANDLING_HELPERS = false;
779779
// [link]
780780
var EXCEPTION_STACK_TRACES = false;
781781

782+
// Emit instructions for the new Wasm exception handling proposal with exnref,
783+
// which was adopted on Oct 2023. The implementation of the new proposal is
784+
// still in progress and this feature is currently experimental.
785+
// [compile+link]
786+
var WASM_EXNREF = false;
787+
782788
// Emscripten throws an ExitStatus exception to unwind when exit() is called.
783789
// Without this setting enabled this can show up as a top level unhandled
784790
// exception.

test/common.py

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,16 @@ def decorated(self, *args, **kwargs):
285285
return decorated
286286

287287

288+
def requires_wasm_exnref(func):
289+
assert callable(func)
290+
291+
def decorated(self, *args, **kwargs):
292+
self.require_wasm_exnref()
293+
return func(self, *args, **kwargs)
294+
295+
return decorated
296+
297+
288298
def requires_v8(func):
289299
assert callable(func)
290300

@@ -500,24 +510,29 @@ def metafunc(self, standalone):
500510

501511

502512
# Tests exception handling / setjmp/longjmp handling in Emscripten EH/SjLj mode
503-
# and if possible, new wasm EH/SjLj mode. This tests two combinations:
513+
# and new wasm EH/SjLj modes. This tests three combinations:
504514
# - Emscripten EH + Emscripten SjLj
505-
# - Wasm EH + Wasm SjLj
515+
# - Wasm EH + Wasm SjLj (Phase 3, to be deprecated)
516+
# - Wasm EH + Wasm SjLj (New proposal witn exnref, experimental)
506517
def with_all_eh_sjlj(f):
507518
assert callable(f)
508519

509520
@wraps(f)
510-
def metafunc(self, is_native, *args, **kwargs):
511-
if is_native:
521+
def metafunc(self, mode, *args, **kwargs):
522+
if mode == 'wasm' or mode == 'wasm_exnref':
512523
# Wasm EH is currently supported only in wasm backend and V8
513524
if self.is_wasm2js():
514525
self.skipTest('wasm2js does not support wasm EH/SjLj')
515-
self.require_wasm_eh()
516526
# FIXME Temporarily disabled. Enable this later when the bug is fixed.
517527
if '-fsanitize=address' in self.emcc_args:
518528
self.skipTest('Wasm EH does not work with asan yet')
519529
self.emcc_args.append('-fwasm-exceptions')
520530
self.set_setting('SUPPORT_LONGJMP', 'wasm')
531+
if mode == 'wasm':
532+
self.require_wasm_eh()
533+
if mode == 'wasm_exnref':
534+
self.require_wasm_exnref()
535+
self.set_setting('WASM_EXNREF')
521536
f(self, *args, **kwargs)
522537
else:
523538
self.set_setting('DISABLE_EXCEPTION_CATCHING', 0)
@@ -529,8 +544,9 @@ def metafunc(self, is_native, *args, **kwargs):
529544
self.set_setting('DEFAULT_TO_CXX')
530545
f(self, *args, **kwargs)
531546

532-
parameterize(metafunc, {'': (False,),
533-
'wasm': (True,)})
547+
parameterize(metafunc, {'emscripten': ('emscripten',),
548+
'wasm': ('wasm',),
549+
'wasm_exnref': ('wasm_exnref',)})
534550
return metafunc
535551

536552

@@ -540,22 +556,27 @@ def with_all_sjlj(f):
540556
assert callable(f)
541557

542558
@wraps(f)
543-
def metafunc(self, is_native):
544-
if is_native:
559+
def metafunc(self, mode):
560+
if mode == 'wasm' or mode == 'wasm_exnref':
545561
if self.is_wasm2js():
546562
self.skipTest('wasm2js does not support wasm SjLj')
547-
self.require_wasm_eh()
548563
# FIXME Temporarily disabled. Enable this later when the bug is fixed.
549564
if '-fsanitize=address' in self.emcc_args:
550565
self.skipTest('Wasm EH does not work with asan yet')
551566
self.set_setting('SUPPORT_LONGJMP', 'wasm')
567+
if mode == 'wasm':
568+
self.require_wasm_eh()
569+
if mode == 'wasm_exnref':
570+
self.require_wasm_exnref()
571+
self.set_setting('WASM_EXNREF')
552572
f(self)
553573
else:
554574
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
555575
f(self)
556576

557-
parameterize(metafunc, {'': (False,),
558-
'wasm': (True,)})
577+
parameterize(metafunc, {'emscripten': ('emscripten',),
578+
'wasm': ('wasm',),
579+
'wasm_exnref': ('wasm_exnref',)})
559580
return metafunc
560581

561582

@@ -877,6 +898,26 @@ def require_wasm_eh(self):
877898
else:
878899
self.fail('either d8 or node >= 17 required to run wasm-eh tests. Use EMTEST_SKIP_EH to skip')
879900

901+
def require_wasm_exnref(self):
902+
nodejs = self.get_nodejs()
903+
if nodejs:
904+
version = shared.get_node_version(nodejs)
905+
if version >= (22, 0, 0):
906+
self.js_engines = [nodejs]
907+
self.node_args.append('--experimental-wasm-exnref')
908+
return
909+
910+
if config.V8_ENGINE and config.V8_ENGINE in self.js_engines:
911+
self.emcc_args.append('-sENVIRONMENT=shell')
912+
self.js_engines = [config.V8_ENGINE]
913+
self.v8_args.append('--experimental-wasm-exnref')
914+
return
915+
916+
if 'EMTEST_SKIP_EH' in os.environ:
917+
self.skipTest('test requires node >= 22 or d8 (and EMTEST_SKIP_EH is set)')
918+
else:
919+
self.fail('either d8 or node >= 22 required to run wasm-eh tests. Use EMTEST_SKIP_EH to skip')
920+
880921
def require_jspi(self):
881922
# emcc warns about stack switching being experimental, and we build with
882923
# warnings-as-errors, so disable that warning

test/test_core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,7 @@ def clear_all_relevant_settings(self):
15571557
self.clear_setting('DISABLE_EXCEPTION_CATCHING')
15581558
self.clear_setting('SUPPORT_LONGJMP')
15591559
self.clear_setting('ASYNCIFY')
1560+
self.clear_setting('WASM_EXNREF')
15601561

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

tools/link.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ def check_human_readable_list(items):
427427
extras = settings.BINARYEN_EXTRA_PASSES.split(',')
428428
passes += [('--' + p) if p[0] != '-' else p for p in extras if p]
429429

430+
# Run the translator to the new EH instructions with exnref
431+
if settings.WASM_EXNREF:
432+
passes += ['--experimental-new-eh']
433+
430434
return passes
431435

432436

0 commit comments

Comments
 (0)