[v22.x] deps: V8: backport Wasm exception handling correctness fixes#62783
Open
guybedford wants to merge 17 commits intonodejs:v22.x-stagingfrom
Open
[v22.x] deps: V8: backport Wasm exception handling correctness fixes#62783guybedford wants to merge 17 commits intonodejs:v22.x-stagingfrom
guybedford wants to merge 17 commits intonodejs:v22.x-stagingfrom
Conversation
Original commit message:
[wasm][exnref] Fix broken abstract casts
ref.test, ref.cast, br_on_cast, br_on_cast_fail allow arbitrary heap
types, so they also allow exnref and noexnref.
This CL also fixes the missing type checks in the js to wasm wrapper.
Bug: v8:14398
Change-Id: Ieefb9a8e99d3d7a4b175db60f55b7fa9a96c5203
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5372489
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#92867}
Refs: v8/v8@5f1342c
Collaborator
|
Review requested:
|
meixg
approved these changes
Apr 17, 2026
Collaborator
Collaborator
Collaborator
Collaborator
3e2a6d5 to
d9bc587
Compare
richardlau
reviewed
Apr 17, 2026
d9bc587 to
902731a
Compare
Original commit message:
[wasm][exnref] Do not allow exnref at the wasm/JS boundary
R=mliedtke@chromium.org
Bug: v8:14398
Change-Id: I5bb75a83e9de9f838d8e530c77c89aa031f473f9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5381603
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#92944}
Refs: v8/v8@b2f3aea
Original commit message:
[wasm][exnref] Fix null value for constant expressions
Bug: v8:14398
Change-Id: Ia00d2de97a897d608d6c043b6e267c7d6313a18b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5402583
Auto-Submit: Manos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#93107}
Refs: v8/v8@c734674
Original commit message:
[wasm][exnref] Implement special behavior of WA.JSTag in try_table.
This commit ports the changes from 4e79015dc28659a8a031f06580e902720b35674c
to `CatchCase`, i.e., the `try_table` instruction. In addition, it
implements the same changes in Turboshaft, for which the implementation
of exceptions initially came from 2c1c14d30c61fa4fa19184369e587cb663bd8580
and already contained the `JSTag` handling for `CatchException`.
This commit addresses part of https://issues.chromium.org/issues/333067164
but not all. Only catching with `try_table` is fixed. `throw` remains
unchanged.
Change-Id: I7bad031e28eaf609fb12e7706d0b6a7cc63fa09d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5435077
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#93303}
Refs: v8/v8@692f3d5
Original commit message:
[wasm][exnref] Fix default value for null exnref
R=manoskouk@chromium.org
Bug: 332081797
Change-Id: Ied777935946c880a78e2011040a4d9ab19a4ddd2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5444544
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#93310}
Refs: v8/v8@cf03d55
Original commit message:
[wasm][exnref] Update WA.JSTag semantics
According to the last spec updates:
- Passing WebAssembly.JSTag to the WebAssembly.Exception constructor is
not allowed in JS,
- Throwing an exception with the JSTag in wasm is allowed, but the
exception should conceptually be "unwrapped" when it exits wasm, and
JS should observe the raw externref. Instead, we simply throw the
externref in this case, which has the same observable behavior and is
consistent with how JSTag has been implemented so far.
R=ahaas@chromium.org
Bug: 333067164
Change-Id: I6f43df8d254dd7450137d99ff7cc9cbffb697663
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5454404
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#93398}
Refs: v8/v8@b8f91e5
Original commit message:
[wasm][liftoff][arm64] Fix DropExceptionValueAtOffset
We cannot exit the iteration early, we must update all entries
in the cache state.
Fixed: 343748812
Change-Id: I8353acb7bd0edc4b979db92e44d24cb9028fd92b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5596273
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94244}
Refs: v8/v8@910cb91733dc
Original commit message:
[wasm] Add missing type canonicalization for exceptions JS API
When we encode a JS value in a wasm exception, canonicalize the type
stored in the tag's signature first. Canonicalize it using the tag's
original module by storing the instance on the tag object.
R=jkummerow@chromium.org
Bug: 346197738
Change-Id: I7575fd79c792d98e4a11c00b466700f0ab82d164
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5613375
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#94335}
Refs: v8/v8@89dc6eab605c
Original commit message:
[wasm][exnref] Accept exnref subtypes for throw_ref
Only accepting a strict exnref type was incorrect in two cases:
- the stack-polymorphic case, with the bottom type
- a noexn param
R=jkummerow@chromium.org
Fixed: 332931390
Change-Id: I80c96a7026f2469e6a3ce54344c2d5e617b78be7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5904414
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96387}
Refs: v8/v8@323942700cfe
Original commit message:
[wasm][exnref] Reject non-nullable exnref in JS import/export
R=jkummerow@chromium.org
Change-Id: I0ba2deb1a9671d87e76fea7bfe76df9eee56442a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5920338
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96489}
Refs: v8/v8@63b8849d73ae
Original commit message:
[wasm][exnref] Fix catchless try_table
If the try_table does not have a catch handler, we don't update the
{current_catch_} index or set the {previous_catch} field of the block
when we enter it. Therefore also skip the reverse operation when the
block ends.
R=clemensb@chromium.org
Fixed: 372261626
Change-Id: Ib3a23e32f9d0ec153d6a00733d96b52cf040e8bd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5920086
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96481}
Refs: v8/v8@8e214ec
Original commit message:
[wasm] Fix default externref/exnref reference
- The default nullexternref should be null instead of undefined
- The default exnref/nullexnref should be null instead of wasm_null
R=mliedtke@chromium.org
Fixed: 372285204,372269618
Change-Id: Id5addce2b196f7ba81aac3c2dd9447a91ed2ce2b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5922878
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96531}
Refs: v8/v8@e7ccf0a
Original commit message:
[wasm][exnref] Accept non-nullable exn catch type
R=jkummerow@chromium.org
Fixed: 373681572
Change-Id: Iecfc86d2ce6592a6f442bc3504ddde58ff236f64
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5938956
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96637}
Refs: v8/v8@7cb6188
Original commit message:
[wasm][js-api] Fix exception handling in Exception
Calling `Get` on the third argument can throw. If so, return
immediately.
R=thibaudm@chromium.org
Fixed: 372993873
Change-Id: I70ec0d0421833a60151f6bcdc9c386f6ad864256
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5937803
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96627}
Refs: v8/v8@b96e40d
Original commit message:
[wasm][exnref] Use wasm_null for exnref
A JS null caught in wasm as an exnref with catch_(all_)ref should be
observably different from a null exnref: a JS null should behave like a
regular JS exception with null as the externref package, while a null
exnref is the actual null value for this type. In particular, a JS
null exception can be rethrown while a null exnref cannot.
Represent null exnrefs with wasm_null instead of JS null to avoid the
confusion.
R=jkummerow@chromium.org
Fixed: 374790906
Change-Id: If9f16a24407ee7d1399613255c3f14e0a6ebef9e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5953226
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#96782}
Refs: v8/v8@9997fc013952
Original commit message:
[wasm] Disallow v128 in exception handling JS API
R=jkummerow@chromium.org
Fixed: 395214627
Change-Id: Ief84b0fd79a87e539dfbfed31d475926f0f0a288
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6249317
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#98608}
Refs: v8/v8@1b27e4674f11
Original commit message:
[wasm][eh] Fix getArg() when exception has an S128
We cannot read an S128 exception value from JS, but we can read a value
at a higher index in the exception. So accept S128 values when we
compute the encoded index.
R=mliedtke@chromium.org
Fixed: 403675482
Change-Id: I7cc0238310863b6d579fcbe0a216ddce6f760c8b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6367014
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#99305}
Refs: v8/v8@85b390089e51
902731a to
37e2c4c
Compare
Contributor
Author
|
I ran it locally, and V8 CI should be passing now on this one. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-exnrefat startup viasrc/node.cc, so the modern Wasm EH code paths are reachable by any Wasm module shipped by Node 22 users — including the defaulttry_table/throw_refsequences 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: unreachableinside 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.5f1342c20b59[wasm][exnref]Fix broken abstract castsb2f3aea23a01[wasm][exnref]Do not allow exnref at wasm/JS boundaryc734674e03f9[wasm][exnref]Fix null value for constant expressions692f3d526a38[wasm][exnref]Special behavior ofWA.JSTagintry_tablecf03d55db2a0[wasm][exnref]Fix default value for null exnrefb8f91e510e0f[wasm][exnref]UpdateWA.JSTagsemantics910cb91733dc[wasm][liftoff][arm64]FixDropExceptionValueAtOffset89dc6eab605c[wasm]Add missing type canonicalization for exceptions JS API323942700cfe[wasm][exnref]Accept exnref subtypes forthrow_ref63b8849d73ae[wasm][exnref]Reject non-nullable exnref in JS import/export8e214ec3ec8c[wasm][exnref]Fix catchlesstry_tablee7ccf0af1bdd[wasm]Fix default externref/exnref reference7cb6188cf913[wasm][exnref]Accept non-nullable exn catch typeb96e40d5ac85[wasm][js-api]Fix exception handling inWebAssembly.Exceptionctor9997fc013952[wasm][exnref]Usewasm_nullfor exnref (null representation fix)1b27e4674f11[wasm]Disallow v128 in exception handling JS API85b390089e51[wasm][eh]FixgetArg()when exception has an S128Notable
Commit #4 (
692f3d526a38) in particular fixes a runtimeRuntimeError: unreachablethrown from within thetry_tableJSTag 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'swasm_nullsentinel so thatthrow_refof a caught JSnullvs. a null exnref can behave per the spec (one rethrowable, one not). The upstream patch adds ause_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 newWasmThrowRefbuiltin from the upstream patch is included verbatim.Commits #8 (
89dc6eab605c) and #15 required manual porting because of V8 API drift; all others applied withgit node v8 backporteither 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:
--experimental-wasm-jspiis not forced on in Node 22)%GetWasmExceptionTag*intrinsics (require--allow-natives-syntax)WasmJSApiScoperefactor (7d4ba5062ac) and its follow-ups — error-message consistency, not correctnesswasm_nullhelper follow-ups (47fb21842c1) — superseded by the direct application in commit domain: add arguments for the function in domain.run() #15[wasm][eh]mixed old/new EH disabling (af887e07511/bf0970ea9e5) — spec conformance rather than a crash/miscompile5e3f70eb5b9(Liftoff slot count for EH) — a legacy-EH bug, being tracked as a separate backport concern2d499b85959(top type) — compiler-hardening, not user-facing correctnessA 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 againstv22.x-staging.v22.22.3-pre/ V812.4.254.21-node.40.WebAssembly.Tag,WebAssembly.Exception) present and functional.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