Title: [v22.x] deps: V8: backport Wasm exception handling correctness fixes by guybedford · Pull Request #62783 · nodejs/node · GitHub
Open Graph Title: [v22.x] deps: V8: backport Wasm exception handling correctness fixes by guybedford · Pull Request #62783 · nodejs/node
X Title: [v22.x] deps: V8: backport Wasm exception handling correctness fixes by guybedford · Pull Request #62783 · nodejs/node
Description: This is a set of V8 backports that land correctness fixes for the modern WebAssembly exception handling (exnref / try_table / throw_ref) implementation in Node.js 22's V8 12.4.254.21. Node.js 22 force-enables --experimental-wasm-exnref at startup via src/node.cc, so the modern Wasm EH code paths are reachable by any Wasm module shipped by Node 22 users — including the default try_table / throw_ref sequences emitted by current toolchains (LLVM/Emscripten with -fwasm-exceptions, wasm-bindgen, AssemblyScript exception mode, etc.). V8 12.4's exnref implementation predates spec finalization (April 2025) and has known correctness bugs that manifest as runtime traps (RuntimeError: unreachable inside catch wrappers), validation errors on spec-conforming modules, wrong representation of null exnref, and mis-canonicalization of exception tags across instances. This PR brings in the strict-correctness subset of upstream V8's exnref fixes from 12.4.254.21..main, ordered chronologically to respect dependency order. Every commit is a focused correctness fix; refactors, DCHECK-only changes, Turboshaft-specific fixes (Node 22 uses Turbofan for Wasm), JSPI-specific fixes, and fuzzer-only hardening have been deliberately excluded. # SHA Subject 1 5f1342c20b59 [wasm][exnref] Fix broken abstract casts 2 b2f3aea23a01 [wasm][exnref] Do not allow exnref at wasm/JS boundary 3 c734674e03f9 [wasm][exnref] Fix null value for constant expressions 4 692f3d526a38 [wasm][exnref] Special behavior of WA.JSTag in try_table 5 cf03d55db2a0 [wasm][exnref] Fix default value for null exnref 6 b8f91e510e0f [wasm][exnref] Update WA.JSTag semantics 7 910cb91733dc [wasm][liftoff][arm64] Fix DropExceptionValueAtOffset 8 89dc6eab605c [wasm] Add missing type canonicalization for exceptions JS API 9 323942700cfe [wasm][exnref] Accept exnref subtypes for throw_ref 10 63b8849d73ae [wasm][exnref] Reject non-nullable exnref in JS import/export 11 8e214ec3ec8c [wasm][exnref] Fix catchless try_table 12 e7ccf0af1bdd [wasm] Fix default externref/exnref reference 13 7cb6188cf913 [wasm][exnref] Accept non-nullable exn catch type 14 b96e40d5ac85 [wasm][js-api] Fix exception handling in WebAssembly.Exception ctor 15 9997fc013952 [wasm][exnref] Use wasm_null for exnref (null representation fix) 16 1b27e4674f11 [wasm] Disallow v128 in exception handling JS API 17 85b390089e51 [wasm][eh] Fix getArg() when exception has an S128 Notable Commit #4 (692f3d526a38) in particular fixes a runtime RuntimeError: unreachable thrown from within the try_table JSTag catch wrapper on v22.x — the most user-visible symptom that motivated this triage. Commit #15 (9997fc013952) changes the internal representation of a null exnref to use V8's wasm_null sentinel so that throw_ref of a caught JS null vs. a null exnref can behave per the spec (one rethrowable, one not). The upstream patch adds a use_wasm_null() helper; in this backport the equivalent representation change has been applied directly to the three compilers (Liftoff / Turbofan / graph-builder-interface) and the constant-expression interface, since the helper doesn't exist in V8 12.4. The new WasmThrowRef builtin from the upstream patch is included verbatim. Commits #8 (89dc6eab605c) and #15 required manual porting because of V8 API drift; all others applied with git node v8 backport either cleanly or with only line-offset fuzz. Explicitly NOT included Per the Node.js V8 maintenance policy ("Only bug fixes are accepted for backporting") and scoping to observable user-facing correctness, the following upstream commits were excluded: Turboshaft-only fixes (Turboshaft for Wasm is not the default optimizer in V8 12.4) JSPI-specific fixes (--experimental-wasm-jspi is not forced on in Node 22) DCHECK-only fixes (no release-build impact) Fuzzer-only hardening of %GetWasmExceptionTag* intrinsics (require --allow-natives-syntax) The 737-line WasmJSApiScope refactor (7d4ba5062ac) and its follow-ups — error-message consistency, not correctness wasm_null helper follow-ups (47fb21842c1) — superseded by the direct application in commit #15 [wasm][eh] mixed old/new EH disabling (af887e07511 / bf0970ea9e5) — spec conformance rather than a crash/miscompile 5e3f70eb5b9 (Liftoff slot count for EH) — a legacy-EH bug, being tracked as a separate backport concern 2d499b85959 (top type) — compiler-hardening, not user-facing correctness A final omission worth calling out: 657d8de2742 [maglev] Fix throwing node inside eager inlining — the single most impactful remaining wasm-EH correctness fix upstream. This one applies equally to Node 22 and Node 24 and will be submitted as a separate PR so it can be released in parallel with this series. Verification make -j$(nproc) completes cleanly against v22.x-staging. Binary reports v22.22.3-pre / V8 12.4.254.21-node.40. WebAssembly EH JS APIs (WebAssembly.Tag, WebAssembly.Exception) present and functional. Wasm Bindgen panic=unwind test suite passes with this change The V8 CI run (node-test-commit-v8-linux) should be requested in addition to the regular CI per the Node.js V8 maintenance doc. /cc @nodejs/v8 @nodejs/lts @nodejs/releasers
Open Graph Description: This is a set of V8 backports that land correctness fixes for the modern WebAssembly exception handling (exnref / try_table / throw_ref) implementation in Node.js 22's V8 12.4.254.21. Node.js 2...
X Description: This is a set of V8 backports that land correctness fixes for the modern WebAssembly exception handling (exnref / try_table / throw_ref) implementation in Node.js 22's V8 12.4.254.21. Node....
Opengraph URL: https://github.com/nodejs/node/pull/62783
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/commits/:range(.:format) |
| route-controller | pull_requests |
| route-action | commits |
| fetch-nonce | v2:dbe78639-205c-17ee-76b3-cbf6b794d9b0 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | EBE6:17AB53:1FA527A:2ADDF0A:6A6557DA |
| html-safe-nonce | fb31d6eeaa462f6faf7ecd6b574cca64ac3cdb330ed7465a9d0b267447680cec |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFQkU2OjE3QUI1MzoxRkE1MjdBOjJBRERGMEE6NkE2NTU3REEiLCJ2aXNpdG9yX2lkIjoiNTMzOTY0Nzk4MTQ5MDg4NjYxOCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | da10c9be082759e7d95acd4bbf44d6e120e3bb8e6d946b90bfb4fec0ea5d4b74 |
| hovercard-subject-tag | pull_request:3542547341 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/nodejs/node/pull/62783/commits/a3e2702058f394f3714031adb91f72a051715f63 |
| twitter:image | https://avatars.githubusercontent.com/u/598730?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/598730?s=400&v=4 |
| og:image:alt | This is a set of V8 backports that land correctness fixes for the modern WebAssembly exception handling (exnref / try_table / throw_ref) implementation in Node.js 22's V8 12.4.254.21. Node.js 2... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 52c76df668885aaff23b50bdca1fa1ea44ac9c1553e888ebc70ff1e4daa4625b |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 309153364422b3c499922d1a2a6404910a58ed8e |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width