Skip to content

Commit 637a1e1

Browse files
authored
Add feature matrix item for Legacy Wasm EH and Wasm Exnref EH, and separate test skipping to two environment variables (#25423)
Add feature for Wasm Exnref support and separate test skips for legacy vs Exnref EH skipping. This will automatically set min browser versions when either Wasm legacy or Exnref exception handling is used, and error our if the users explictly requests a too-old browser version.
1 parent 09534bb commit 637a1e1

File tree

7 files changed

+52
-18
lines changed

7 files changed

+52
-18
lines changed

.circleci/config.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,8 @@ jobs:
11991199
# https://github.com/emscripten-core/emscripten/pull/11382#pullrequestreview-428902638
12001200
EMTEST_LACKS_NATIVE_CLANG: "1"
12011201
EMTEST_SKIP_V8: "1"
1202-
EMTEST_SKIP_EH: "1"
1202+
EMTEST_SKIP_WASM_LEGACY_EH: "1"
1203+
EMTEST_SKIP_WASM_EH: "1"
12031204
EMTEST_SKIP_WASM64: "1"
12041205
EMTEST_SKIP_SCONS: "1"
12051206
EMTEST_SKIP_RUST: "1"
@@ -1235,7 +1236,8 @@ jobs:
12351236
# We don't install d8 or modern node on the mac runner so we skip any
12361237
# tests that depend on those.
12371238
EMTEST_SKIP_V8: "1"
1238-
EMTEST_SKIP_EH: "1"
1239+
EMTEST_SKIP_WASM_LEGACY_EH: "1"
1240+
EMTEST_SKIP_WASM_EH: "1"
12391241
EMTEST_SKIP_WASM64: "1"
12401242
EMTEST_SKIP_SCONS: "1"
12411243
EMTEST_SKIP_RUST: "1"

ChangeLog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ See docs/process.md for more on how version tagging works.
322322
- Emscripten version was bumped to 4.0.0. Happy new year, happy new major
323323
version! While version has a few interesting changes, there is nothing huge
324324
that makes it different from any other release. (#19053)
325-
- `-sWASM_LEAGCY_EXCEPTIONS` option is added. (#23365) If true, it will emit
325+
- `-sWASM_LEGACY_EXCEPTIONS` option is added. (#23365) If true, it will emit
326326
instructions for the legacy Wasm exception handling proposal
327327
(https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md),
328328
and if false, the new standardized exception handling proposal

src/settings_internal.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,11 @@ var CAN_ADDRESS_2GB = false;
180180
// This has no effect if DWARF is not being emitted.
181181
var SEPARATE_DWARF = false;
182182

183-
// New WebAssembly exception handling
183+
// Target WebAssembly exception handling instead of JavaScript-side exception
184+
// handling. Furthermore, if WASM_LEGACY_EXCEPTIONS=1, then old legacy Wasm
185+
// exception handling is used, and if WASM_LEGACY_EXCEPTIONS=0, then Wasm
186+
// exception handling is targeted.
187+
// Enabled by passing -fwasm-exceptions on the command line.
184188
var WASM_EXCEPTIONS = false;
185189

186190
// Set to true if the program has a main function. By default this is

test/codesize/test_codesize_cxx_except_wasm.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"a.out.js": 19555,
3-
"a.out.js.gz": 8099,
2+
"a.out.js": 19486,
3+
"a.out.js.gz": 8077,
44
"a.out.nodebug.wasm": 144630,
55
"a.out.nodebug.wasm.gz": 54894,
6-
"total": 164185,
7-
"total_gz": 62993,
6+
"total": 164116,
7+
"total_gz": 62971,
88
"sent": [
99
"_abort_js",
1010
"_tzset_js",

test/common.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,8 +1132,9 @@ def require_simd(self):
11321132
self.fail('either d8 or node >= 16 required to run wasm64 tests. Use EMTEST_SKIP_SIMD to skip')
11331133

11341134
def require_wasm_legacy_eh(self):
1135-
if 'EMTEST_SKIP_EH' in os.environ:
1136-
self.skipTest('test requires node >= 17 or d8 (and EMTEST_SKIP_EH is set)')
1135+
if 'EMTEST_SKIP_WASM_LEGACY_EH' in os.environ:
1136+
self.skipTest('test requires node >= 17 or d8 (and EMTEST_SKIP_WASM_LEGACY_EH is set)')
1137+
11371138
self.set_setting('WASM_LEGACY_EXCEPTIONS')
11381139
if self.try_require_node_version(17):
11391140
return
@@ -1144,11 +1145,11 @@ def require_wasm_legacy_eh(self):
11441145
self.js_engines = [v8]
11451146
return
11461147

1147-
self.fail('either d8 or node >= 17 required to run wasm-eh tests. Use EMTEST_SKIP_EH to skip')
1148+
self.fail('either d8 or node >= 17 required to run legacy wasm-eh tests. Use EMTEST_SKIP_WASM_LEGACY_EH to skip')
11481149

11491150
def require_wasm_eh(self):
1150-
if 'EMTEST_SKIP_EH' in os.environ:
1151-
self.skipTest('test requires node v24 or d8 (and EMTEST_SKIP_EH is set)')
1151+
if 'EMTEST_SKIP_WASM_EH' in os.environ:
1152+
self.skipTest('test requires node v24 or d8 (and EMTEST_SKIP_WASM_EH is set)')
11521153
self.set_setting('WASM_LEGACY_EXCEPTIONS', 0)
11531154
if self.try_require_node_version(24):
11541155
self.node_args.append('--experimental-wasm-exnref')
@@ -1164,7 +1165,7 @@ def require_wasm_eh(self):
11641165
self.v8_args.append('--experimental-wasm-exnref')
11651166
return
11661167

1167-
self.fail('either d8 or node v24 required to run wasm-eh tests. Use EMTEST_SKIP_EH to skip')
1168+
self.fail('either d8 or node v24 required to run wasm-eh tests. Use EMTEST_SKIP_WASM_EH to skip')
11681169

11691170
def require_jspi(self):
11701171
if 'EMTEST_SKIP_JSPI' in os.environ:

test/test_other.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3644,7 +3644,7 @@ def test_embind_tsgen_jspi(self):
36443644
})
36453645
def test_embind_tsgen_exceptions(self, legacy):
36463646
if not legacy and shared.get_node_version(config.NODE_JS)[0] < 22:
3647-
self.skipTest('Node version needs to be 22 or greater to run tsgen with exnref')
3647+
self.skipTest('Node version needs to be 22 or greater to run tsgen with Wasm EH')
36483648
self.set_setting('WASM_LEGACY_EXCEPTIONS', legacy)
36493649

36503650
# Check that when Wasm exceptions and assertions are enabled bindings still generate.
@@ -14332,10 +14332,10 @@ def test_reproduce(self):
1433214332

1433314333
def test_min_browser_version(self):
1433414334
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-Wno-transpile', '-Werror', '-sWASM_BIGINT', '-sMIN_SAFARI_VERSION=130000'])
14335-
self.assertContained('emcc: error: MIN_SAFARI_VERSION=130000 is not compatible with WASM_BIGINT (150000 or above required)', err)
14335+
self.assertContained('emcc: error: MIN_SAFARI_VERSION=130000 is not compatible with WASM_BIGINT (MIN_SAFARI_VERSION=150000 or above required)', err)
1433614336

1433714337
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-Wno-transpile', '-Werror', '-pthread', '-sMIN_FIREFOX_VERSION=65'])
14338-
self.assertContained('emcc: error: MIN_FIREFOX_VERSION=65 is not compatible with pthreads (79 or above required)', err)
14338+
self.assertContained('emcc: error: MIN_FIREFOX_VERSION=65 is not compatible with pthreads (MIN_FIREFOX_VERSION=79 or above required)', err)
1433914339

1434014340
def test_signext_lowering(self):
1434114341
# Use `-v` to show the sub-commands being run by emcc.

tools/feature_matrix.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class Feature(IntEnum):
4040
MEMORY64 = auto()
4141
WORKER_ES6_MODULES = auto()
4242
OFFSCREENCANVAS_SUPPORT = auto()
43+
WASM_LEGACY_EXCEPTIONS = auto()
44+
WASM_EXCEPTIONS = auto()
4345

4446

4547
disable_override_features = set()
@@ -105,6 +107,26 @@ class Feature(IntEnum):
105107
'safari': 170000,
106108
'node': 0, # This is a browser only feature, no requirements on Node.js
107109
},
110+
# Legacy Wasm exceptions was the first (now legacy) format for native
111+
# exception handling in WebAssembly.
112+
Feature.WASM_LEGACY_EXCEPTIONS: {
113+
'chrome': 95,
114+
'firefox': 100,
115+
'safari': 150200,
116+
'node': 170000,
117+
},
118+
# Wasm exceptions is a newer format for native exception handling in
119+
# WebAssembly.
120+
Feature.WASM_EXCEPTIONS: {
121+
'chrome': 137,
122+
'firefox': 131,
123+
'safari': 180400,
124+
# Supported with flag --experimental-wasm-exnref (TODO: Change this to
125+
# unflagged version of Node.js 260000 that ships Wasm EH enabled, after
126+
# Emscripten unit testing has migrated to Node.js 26, and Emsdk ships
127+
# Node.js 26)
128+
'node': 240000,
129+
},
108130
}
109131

110132
# Static assertion to check that we actually need each of the above feature flags
@@ -165,7 +187,7 @@ def enable_feature(feature, reason, override=False):
165187
diagnostics.warning(
166188
'compatibility',
167189
f'{name}={user_settings[name]} is not compatible with {reason} '
168-
f'({min_version} or above required)')
190+
f'({name}={min_version} or above required)')
169191
else:
170192
# If no conflict, bump the minimum version to accommodate the feature.
171193
logger.debug(f'Enabling {name}={min_version} to accommodate {reason}')
@@ -199,3 +221,8 @@ def apply_min_browser_versions():
199221
enable_feature(Feature.WORKER_ES6_MODULES, 'EXPORT_ES6 with -sWASM_WORKERS')
200222
if settings.OFFSCREENCANVAS_SUPPORT:
201223
enable_feature(Feature.OFFSCREENCANVAS_SUPPORT, 'OFFSCREENCANVAS_SUPPORT')
224+
if settings.WASM_EXCEPTIONS or settings.SUPPORT_LONGJMP == 'wasm': # Wasm longjmp support will lean on Wasm (Legacy) EH
225+
if settings.WASM_LEGACY_EXCEPTIONS:
226+
enable_feature(Feature.WASM_LEGACY_EXCEPTIONS, 'Wasm Legacy exceptions (-fwasm-exceptions with -sWASM_LEGACY_EXCEPTIONS=1)')
227+
else:
228+
enable_feature(Feature.WASM_EXCEPTIONS, 'Wasm exceptions (-fwasm-exceptions with -sWASM_LEGACY_EXCEPTIONS=0)')

0 commit comments

Comments
 (0)