Skip to content

Support -Cpanic=unwind on WASI targets#156061

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
alexcrichton:unwinding-onw-asi
May 8, 2026
Merged

Support -Cpanic=unwind on WASI targets#156061
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
alexcrichton:unwinding-onw-asi

Conversation

@alexcrichton
Copy link
Copy Markdown
Member

@alexcrichton alexcrichton commented May 1, 2026

View all comments

This commit is some minor updates/restructuring in a few locations with the end result being supporting -Cpanic=unwind on WASI targets. This continues to be off-by-default insofar as WASI targets default to -Cpanic=abort, meaning that actually using anything in this commit requires -Zbuild-std. Specifically the changes made here are:

  • The self-contained sysroot for WASI targets now contains a copy of libunwind.a from wasi-sdk, first shipped with wasi-sdk-33 (also updated here).
  • The unwind crate here in this repository uses the libunwind module instead of the custom bare-metal wasm implementation of exceptions. This means that Rust uses the _Unwind_* symbols which allows it to interoperate with C/C++/etc.
  • Wasm targets are all updated to pass the LLVM argument -wasm-use-legacy-eh=false to differ from LLVM's/clang's default of using the legacy exception handling proposal for WebAssembly. This has no effect by default because panic=abort is used on most targets. Emscripten is exempted from this as the Emscripten target is explicitly intended to follow LLVM's/clang's defaults.
  • There's a single test in the test suite that links to the panic_unwind crate which ended up requiring -Wexceptions from Wasmtime, so the test parts were updated and Wasmtime was updated in CI, too.

The net result of all of this is that this should not actually affect any WebAssembly target's default behavior. Optionally, though, WASI programs can be built with exception handling via:

RUSTFLAGS='-Cpanic=unwind' cargo +nightly run -Z build-std --target wasm32-wasip2

Effectively -Zbuild-std and -Cpanic=unwind is all that's necessary to enable this support on wasm targets.

Finally, this ends up closing #154593 as well. The WASI targets are now defined to use -lunwind to implement unwinding. This means that the in-tree definition of __cpp_exception is no longer of concern and the definition is always sourced externally. If Rust is linked with other C/C++ code using WASI then these idioms are compatible with wasi-sdk, for example, to use that as a linker. The main caveat is that when using an external linker the -fwasm-exceptions argument needs to be passed to clang for it to be able to find the libunwind.a library to link against.

Closes #154593

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 1, 2026

These commits modify compiler targets.
(See the Target Tier Policy.)

@rustbot rustbot added A-CI Area: Our Github Actions CI A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. labels May 1, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 1, 2026

r? @marcoieni

rustbot has assigned @marcoieni.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: infra-ci
  • infra-ci expanded to Kobzol, Mark-Simulacrum, jdno, jieyouxu, marcoieni
  • Random selection from Mark-Simulacrum, jdno, jieyouxu, marcoieni

@rustbot

This comment has been minimized.

// actually turned on, which it's not by default on this target. For
// `-Zbuild-std` builds, however, this affects when rebuilding libstd
// with unwinding.
llvm_args: cvs!["-wasm-use-legacy-eh=false"],
Copy link
Copy Markdown
Member

@bjorn3 bjorn3 May 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't

// Returns `true` if this session's target will use native wasm
// exceptions. This means that the VM does the unwinding for
// us
pub fn wants_wasm_eh(sess: &Session) -> bool {
sess.target.is_like_wasm
&& (sess.target.os != Os::Emscripten || sess.opts.unstable_opts.emscripten_wasm_eh)
}
already supposed to do this?

Edit: Might be confused with wasm vs js exception handling.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe, yeah, that's related to the Emscripten-specific scheme of exceptions pre-wasm-exceptions of using JS instead. Effectively there's 3 modes of exceptions on Wasm:

  1. Historical JS-based support for Emscripten. That's used when wants_wasm_eh is false and is only applicable to historical versions of the Emscripten target (or -Zemscripten-wasm-eh=false)
  2. Historical wasm support. This uses the now-legacy exception-handling proposal that shipped in browsers but was never standardized. This uses wasm instructions and has wants_wasm_eh is true. LLVM by default emits this today.
  3. Modern wasm support. This uses the now-standard exception-handling proposal as the successor to the "legacy exceptions" of above. This is wants_wasm_eh is true plus an option to LLVM to use the new instructions.

For (1) the LLVM IR is different, and for (2) and (3) they're the same IR. I don't know much about (1) myself. For WASI this PR only exposes (3)

@marcoieni
Copy link
Copy Markdown
Member

The changes in src/ci/docker look good. Someone else should review the other files since I'm not familiar with them.

@alexcrichton
Copy link
Copy Markdown
Member Author

@bjorn3 would you be up for reviewing the non-infra-related bits?

Comment thread library/unwind/src/libunwind.rs
Comment thread src/bootstrap/src/core/build_steps/compile.rs
Comment thread src/bootstrap/src/lib.rs
&& let Ok(mut path) = path.into_os_string().into_string()
{
path.push_str(" run -C cache=n --dir .");
path.push_str(" run -Wexceptions -C cache=n --dir .");
Copy link
Copy Markdown
Member

@bjorn3 bjorn3 May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no tests added that use exceptions, right?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost yeah, but there's one test that does extern crate panic_unwind; which pulls in libunwind which pulls in a throw instruction which then needs this to validate

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised that even works without //@ needs-unwind to only run the test for panic=unwind. I thought rustc refused to link a panic runtime that doesn't match the -Cpanic=..., but I guess that check is only done when the panic runtime dependency is injected by rustc, not when it is explicitly done by the user.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 5, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@bjorn3
Copy link
Copy Markdown
Member

bjorn3 commented May 6, 2026

@bors r+

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 6, 2026

📌 Commit 13c6e60 has been approved by bjorn3

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 6, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 6, 2026
…bjorn3

Support `-Cpanic=unwind` on WASI targets

This commit is some minor updates/restructuring in a few locations with the end result being supporting `-Cpanic=unwind` on WASI targets. This continues to be off-by-default insofar as WASI targets default to `-Cpanic=abort`, meaning that actually using anything in this commit requires `-Zbuild-std`. Specifically the changes made here are:

* The self-contained sysroot for WASI targets now contains a copy of `libunwind.a` from wasi-sdk, first shipped with wasi-sdk-33 (also updated here).
* The `unwind` crate here in this repository uses the `libunwind` module instead of the custom bare-metal wasm implementation of exceptions. This means that Rust uses the `_Unwind_*` symbols which allows it to interoperate with C/C++/etc.
* Wasm targets are all updated to pass the LLVM argument `-wasm-use-legacy-eh=false` to differ from LLVM's/clang's default of using the legacy exception handling proposal for WebAssembly. This has no effect by default because `panic=abort` is used on most targets. Emscripten is exempted from this as the Emscripten target is explicitly intended to follow LLVM's/clang's defaults.
* There's a single test in the test suite that links to the `panic_unwind` crate which ended up requiring `-Wexceptions` from Wasmtime, so the test parts were updated and Wasmtime was updated in CI, too.

The net result of all of this is that this should not actually affect any WebAssembly target's default behavior. Optionally, though, WASI programs can be built with exception handling via:

    RUSTFLAGS='-Cpanic=unwind' cargo +nightly run -Z build-std --target wasm32-wasip2

Effectively `-Zbuild-std` and `-Cpanic=unwind` is all that's necessary to enable this support on wasm targets.

Finally, this ends up closing rust-lang#154593 as well. The WASI targets are now defined to use `-lunwind` to implement unwinding. This means that the in-tree definition of `__cpp_exception` is no longer of concern and the definition is always sourced externally. If Rust is linked with other C/C++ code using WASI then these idioms are compatible with wasi-sdk, for example, to use that as a linker. The main caveat is that when using an external linker the `-fwasm-exceptions` argument needs to be passed to `clang` for it to be able to find the `libunwind.a` library to link against.

Closes rust-lang#154593
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 6, 2026
…bjorn3

Support `-Cpanic=unwind` on WASI targets

This commit is some minor updates/restructuring in a few locations with the end result being supporting `-Cpanic=unwind` on WASI targets. This continues to be off-by-default insofar as WASI targets default to `-Cpanic=abort`, meaning that actually using anything in this commit requires `-Zbuild-std`. Specifically the changes made here are:

* The self-contained sysroot for WASI targets now contains a copy of `libunwind.a` from wasi-sdk, first shipped with wasi-sdk-33 (also updated here).
* The `unwind` crate here in this repository uses the `libunwind` module instead of the custom bare-metal wasm implementation of exceptions. This means that Rust uses the `_Unwind_*` symbols which allows it to interoperate with C/C++/etc.
* Wasm targets are all updated to pass the LLVM argument `-wasm-use-legacy-eh=false` to differ from LLVM's/clang's default of using the legacy exception handling proposal for WebAssembly. This has no effect by default because `panic=abort` is used on most targets. Emscripten is exempted from this as the Emscripten target is explicitly intended to follow LLVM's/clang's defaults.
* There's a single test in the test suite that links to the `panic_unwind` crate which ended up requiring `-Wexceptions` from Wasmtime, so the test parts were updated and Wasmtime was updated in CI, too.

The net result of all of this is that this should not actually affect any WebAssembly target's default behavior. Optionally, though, WASI programs can be built with exception handling via:

    RUSTFLAGS='-Cpanic=unwind' cargo +nightly run -Z build-std --target wasm32-wasip2

Effectively `-Zbuild-std` and `-Cpanic=unwind` is all that's necessary to enable this support on wasm targets.

Finally, this ends up closing rust-lang#154593 as well. The WASI targets are now defined to use `-lunwind` to implement unwinding. This means that the in-tree definition of `__cpp_exception` is no longer of concern and the definition is always sourced externally. If Rust is linked with other C/C++ code using WASI then these idioms are compatible with wasi-sdk, for example, to use that as a linker. The main caveat is that when using an external linker the `-fwasm-exceptions` argument needs to be passed to `clang` for it to be able to find the `libunwind.a` library to link against.

Closes rust-lang#154593
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors r-
#156233 (comment)

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 6, 2026
@jhpratt
Copy link
Copy Markdown
Member

jhpratt commented May 7, 2026

@bors r-

#156254 (comment)

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 7, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 7, 2026

This pull request was unapproved.

This PR was contained in a rollup (#156261), which was unapproved.

View changes since this unapproval

This commit is some minor updates/restructuring in a few locations with
the end result being supporting `-Cpanic=unwind` on WASI targets. This
continues to be off-by-default insofar as WASI targets default to
`-Cpanic=abort`, meaning that actually using anything in this commit
requires `-Zbuild-std`. Specifically the changes made here are:

* The self-contained sysroot for WASI targets now contains a copy of
  `libunwind.a` from wasi-sdk, first shipped with wasi-sdk-33 (also
  updated here).
* The `unwind` crate here in this repository uses the `libunwind` module
  instead of the custom bare-metal wasm implementation of exceptions.
  This means that Rust uses the `_Unwind_*` symbols which allows it to
  interoperate with C/C++/etc.
* Wasm targets are all updated to pass the LLVM argument
  `-wasm-use-legacy-eh=false` to differ from LLVM's/clang's default of
  using the legacy exception handling proposal for WebAssembly. This has
  no effect by default because `panic=abort` is used on most targets.
  Emscripten is exempted from this as the Emscripten target is
  explicitly intended to follow LLVM's/clang's defaults.
* There's a single test in the test suite that links to the
  `panic_unwind` crate which ended up requiring `-Wexceptions` from
  Wasmtime, so the test parts were updated and Wasmtime was updated in
  CI, too.

The net result of all of this is that this should not actually affect
any WebAssembly target's default behavior. Optionally, though, WASI
programs can be built with exception handling via:

    RUSTFLAGS='-Cpanic=unwind' cargo +nightly run -Z build-std --target wasm32-wasip2

Effectively `-Zbuild-std` and `-Cpanic=unwind` is all that's necessary
to enable this support on wasm targets.

Finally, this ends up closing 154593 as well. The WASI targets are now
defined to use `-lunwind` to implement unwinding. This means that the
in-tree definition of `__cpp_exception` is no longer of concern and the
definition is always sourced externally. If Rust is linked with other
C/C++ code using WASI then these idioms are compatible with wasi-sdk,
for example, to use that as a linker. The main caveat is that when using
an external linker the `-fwasm-exceptions` argument needs to be passed
to `clang` for it to be able to find the `libunwind.a` library to link
against.

Closes 154593
@alexcrichton
Copy link
Copy Markdown
Member Author

I've updated the assembly-llvm test for wasm exceptions to no longer look for the legacy exception handling instructions and instead look for the standard ones.

@alexcrichton
Copy link
Copy Markdown
Member Author

@bors r=bjorn3

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 7, 2026

📌 Commit 506693e has been approved by bjorn3

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 7, 2026
rust-bors Bot pushed a commit that referenced this pull request May 7, 2026
…uwer

Rollup of 6 pull requests

Successful merges:

 - #156061 (Support `-Cpanic=unwind` on WASI targets)
 - #151753 (Experiment: Reborrow traits)
 - #156280 (Add regression test for closure return ICE)
 - #152487 (core: drop unmapped ZSTs in array `map`)
 - #153759 (Add a suite of ChunkedBitSet union/subtract/intersect test scenarios)
 - #156198 (Add `sync` option to `-Z threads` to force synchronization on one thread)
@rust-bors rust-bors Bot merged commit 71597bc into rust-lang:main May 8, 2026
11 checks passed
@rustbot rustbot added this to the 1.97.0 milestone May 8, 2026
guybedford added a commit to wasm-bindgen/wasm-bindgen that referenced this pull request May 13, 2026
rust-lang/rust#156061 flipped the wasm `-Cpanic=unwind` default from
legacy EH (try/catch) to modern (exnref) EH. Adjust CI and justfile so
the legacy EH path now requires an explicit `-Cllvm-args=-wasm-use-legacy-eh`
opt-in, while the unmarked `-Cpanic=unwind` invocations follow the new
modern default.

* legacy EH CI job now passes `-Cllvm-args=-wasm-use-legacy-eh` (Node 20
  remains fine since legacy EH is still validated there).
* exnref CI job drops the now-redundant `=false` opt-out and runs on
  Node 25 (modern EH needs V8 12.5+, i.e. Node 22.22.3+ or 24+).
* test_native bumped from Node 20 to 24 because the cli termination
  tests build with `-Cpanic=unwind` and now emit modern EH wasm.
* justfile: `test-wasm-bindgen-unwind` no longer needs the opt-out and
  `test-wasm-bindgen-unwind-eh` is renamed to
  `test-wasm-bindgen-unwind-legacy-eh` with the explicit legacy opt-in.

TODOs noted in CI to drop modern-EH jobs back to Node 22 LTS once
22.22.3 ships on 2026-05-13.
guybedford added a commit to wasm-bindgen/wasm-bindgen that referenced this pull request May 13, 2026
Rename the Unreleased `Fixed` section to `Notices` (both entries are
nightly toolchain compatibility heads-ups rather than wasm-bindgen bug
fixes) and add an entry for rust-lang/rust#156061 flipping the wasm
panic=unwind EH default to modern (exnref).
guybedford added a commit to wasm-bindgen/wasm-bindgen that referenced this pull request May 13, 2026
Two adjustments to the legacy EH job:

* Pin nightly to 2026-05-06 (last nightly before rust-lang/rust#156061
  flipped the wasm target spec to force modern EH). Plain
  `-Cpanic=unwind` again produces legacy EH wasm.
  `-Cllvm-args=-wasm-use-legacy-eh` cannot override the new target
  spec's `-wasm-use-legacy-eh=false` because LLVM is last-wins and
  rustc puts target args after user args, so a pinned nightly is
  currently the only reliable way to keep legacy EH coverage.

* Bump Node to 22.22.3 \u2014 wasm-bindgen's legacy EH catch handlers
  import `WebAssembly.JSTag`, which is only available in Node 22.4+.
  Node 20 has legacy EH instructions but not the JSTag global.

Document the Node 22.22.3+ floor in the catch-unwind guide and
changelog, with a pointer to #5151 for tracking Node 20 support.
guybedford added a commit to wasm-bindgen/wasm-bindgen that referenced this pull request May 13, 2026
* ci: pin legacy EH job to nightly-2026-05-12

The legacy EH CI job has started failing because recent nightlies emit
wasm-gc value types (e.g. `noexternref`) in the standard library that
Node.js 20's V8 11.3 cannot validate, even when explicitly opted into
legacy EH via `-Cllvm-args=-wasm-use-legacy-eh`.

Pin the legacy EH job to `nightly-2026-05-12` (the last nightly without
this issue) so we keep Node 20 compatibility coverage. Dated nightlies
remain available on the rust-lang dist server indefinitely.

Also note this requirement in the catch-unwind guide and changelog so
downstream users targeting Node 20 know to pin their nightly too.

* ci: try nightly-2026-05-11 instead

2026-05-12 still has the noexternref issue. Try the previous day.

* ci: pin legacy EH to nightly-2026-05-06 and Node 22.22.3

Two adjustments to the legacy EH job:

* Pin nightly to 2026-05-06 (last nightly before rust-lang/rust#156061
  flipped the wasm target spec to force modern EH). Plain
  `-Cpanic=unwind` again produces legacy EH wasm.
  `-Cllvm-args=-wasm-use-legacy-eh` cannot override the new target
  spec's `-wasm-use-legacy-eh=false` because LLVM is last-wins and
  rustc puts target args after user args, so a pinned nightly is
  currently the only reliable way to keep legacy EH coverage.

* Bump Node to 22.22.3 \u2014 wasm-bindgen's legacy EH catch handlers
  import `WebAssembly.JSTag`, which is only available in Node 22.4+.
  Node 20 has legacy EH instructions but not the JSTag global.

Document the Node 22.22.3+ floor in the catch-unwind guide and
changelog, with a pointer to #5151 for tracking Node 20 support.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 15, 2026
…lexcrichton

Allow user-provided `llvm_args` to override target spec arguments

This switches the order in which `-Cllvm-args` is applied between target-spec arguments and user-provided LLVM arguments.

This came up in rust-lang#156061, where the target passing `-Cllvm-args=-wasm-use-legacy-eh=false` means that a user passing `-Cllvm-args=-wasm-use-legacy-eh=true` cannot override this value since the LLVM arguments support the last argument overriding the previous, and user arguments were chained first.

With this change, it is possible for Wasm targets to opt into legacy EH for compatibility with runtimes that don't yet implement the modern exnref/try_table instructions, such as Node.js 20 on V8 11.3 and older browsers. While Node.js 20 is formally EOL, many libraries will still need to support this version for a few months yet, so this would ease the transition path to modern exception handling having an opt-out.

Originally this PR added support for a dedicated `-Z` flag for switching to legacy exception handling, but fine-grained control over the arguments would be a preferable solution provided it does not conflict with other behaviours.

//cc @alexcrichton
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 15, 2026
…lexcrichton

Allow user-provided `llvm_args` to override target spec arguments

This switches the order in which `-Cllvm-args` is applied between target-spec arguments and user-provided LLVM arguments.

This came up in rust-lang#156061, where the target passing `-Cllvm-args=-wasm-use-legacy-eh=false` means that a user passing `-Cllvm-args=-wasm-use-legacy-eh=true` cannot override this value since the LLVM arguments support the last argument overriding the previous, and user arguments were chained first.

With this change, it is possible for Wasm targets to opt into legacy EH for compatibility with runtimes that don't yet implement the modern exnref/try_table instructions, such as Node.js 20 on V8 11.3 and older browsers. While Node.js 20 is formally EOL, many libraries will still need to support this version for a few months yet, so this would ease the transition path to modern exception handling having an opt-out.

Originally this PR added support for a dedicated `-Z` flag for switching to legacy exception handling, but fine-grained control over the arguments would be a preferable solution provided it does not conflict with other behaviours.

//cc @alexcrichton
rust-timer added a commit that referenced this pull request May 16, 2026
Rollup merge of #156554 - guybedford:wasm-use-legacy-eh, r=alexcrichton

Allow user-provided `llvm_args` to override target spec arguments

This switches the order in which `-Cllvm-args` is applied between target-spec arguments and user-provided LLVM arguments.

This came up in #156061, where the target passing `-Cllvm-args=-wasm-use-legacy-eh=false` means that a user passing `-Cllvm-args=-wasm-use-legacy-eh=true` cannot override this value since the LLVM arguments support the last argument overriding the previous, and user arguments were chained first.

With this change, it is possible for Wasm targets to opt into legacy EH for compatibility with runtimes that don't yet implement the modern exnref/try_table instructions, such as Node.js 20 on V8 11.3 and older browsers. While Node.js 20 is formally EOL, many libraries will still need to support this version for a few months yet, so this would ease the transition path to modern exception handling having an opt-out.

Originally this PR added support for a dedicated `-Z` flag for switching to legacy exception handling, but fine-grained control over the arguments would be a preferable solution provided it does not conflict with other behaviours.

//cc @alexcrichton
renovate Bot added a commit to oxc-project/json-strip-comments that referenced this pull request May 24, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [serde_json](https://redirect.github.com/serde-rs/json) |
dev-dependencies | patch | `1.0.149` → `1.0.150` |
| [wasm-bindgen](https://wasm-bindgen.github.io/wasm-bindgen)
([source](https://redirect.github.com/wasm-bindgen/wasm-bindgen)) |
dependencies | patch | `0.2.105` → `0.2.122` |

---

### Release Notes

<details>
<summary>serde-rs/json (serde_json)</summary>

###
[`v1.0.150`](https://redirect.github.com/serde-rs/json/releases/tag/v1.0.150)

[Compare
Source](https://redirect.github.com/serde-rs/json/compare/v1.0.149...v1.0.150)

- Reject non-string enum object keys
([#&#8203;1324](https://redirect.github.com/serde-rs/json/issues/1324),
thanks
[@&#8203;puneetdixit200](https://redirect.github.com/puneetdixit200))

</details>

<details>
<summary>wasm-bindgen/wasm-bindgen (wasm-bindgen)</summary>

###
[`v0.2.122`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02122)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.121...0.2.122)

##### Notices

- Threading support now requires `-Clink-arg=--export=__heap_base` to be
set
  in `RUSTFLAGS` for nightly toolchains from 2026-05-06 onward, after

[rust-lang/rust#156174](https://redirect.github.com/rust-lang/rust/pull/156174)
  removed the implicit `__heap_base`/`__data_end` exports on `wasm*`
  targets. Atomics CI, CLI reference tests, and the `nodejs-threads`,
  `raytrace-parallel`, and `wasm-audio-worklet` examples have been
  updated to pass `--export=__heap_base` explicitly. The flag is
  backward-compatible with older nightlies.

- `-Cpanic=unwind` on wasm targets now emits modern (exnref) exception
  handling by default after

[rust-lang/rust#156061](https://redirect.github.com/rust-lang/rust/pull/156061),
and requires Node.js 22.22.3+ (for `WebAssembly.JSTag`). Legacy EH wasm
  can still be produced on current nightlies by adding
  `-Cllvm-args=-wasm-use-legacy-eh` to `RUSTFLAGS`; Node.js 20 may be
  supported with legacy exception handling, with a tracking issue in

[#&#8203;5151](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5151).

##### Added

- Implemented `TryFromJsValue` for `Vec<T>` where `T: TryFromJsValue`.
  A JS value converts when it is a real `Array` (per `Array.isArray`)
  and every element converts via `T::try_from_js_value`. This composes
  recursively (`Vec<Vec<String>>`, `Vec<Option<T>>`) and works for any
  `T` with a `TryFromJsValue` impl, including primitives, `String`,
  `JsValue`, and `JsCast` types. Array-likes (objects with `length` and
  numeric indices) are intentionally rejected to mirror the static ABI
  representation used by `js_value_vector_from_abi`.

- New `extends_js_class` and `extends_js_namespace` attributes on
  exported structs to allow defining the parent `js_class` name when
it has been customized by `js_name` and the parent's own `js_namespace`
  as well in turn. New validation is added at code generation time that
  will now catch these cases instead of emitting invalid code. Example:

  ```rust
  #[wasm_bindgen(js_name = "Animal", js_namespace = zoo)]
  pub struct AnimalImpl { /* ... */ }

  #[wasm_bindgen(
      extends = AnimalImpl,
      extends_js_class = "Animal",
      extends_js_namespace = zoo,
  )]
  pub struct DogImpl { /* ... */ }
  ```


[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5154)

##### Changed

- When an exported struct uses `js_namespace`, the corresponding value
  must now be repeated on every `impl` block. Previously the impl-side
  defaults silently worked resulting in inconsistent emission. Example:

  ```rust
  // Before:
  #[wasm_bindgen(js_namespace = "default")]
  pub struct Counter { /* ... */ }

  #[wasm_bindgen]              // worked, but fragile
  impl Counter { /* ... */ }

  // After:
  #[wasm_bindgen(js_namespace = "default")]
  pub struct Counter { /* ... */ }

  #[wasm_bindgen(js_namespace = "default")]   // now required
  impl Counter { /* ... */ }
  ```

  To ease this transition for `js_namespace` usage, diagnostic
  messages now include hints for missing namespaces for easier
  fixing.


[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5154)

##### Fixed

- Fixed the descriptor interpreter panicking on `Br` and `BrIf`
  instructions emitted by recent nightly compilers when building with
  `panic=unwind`.

[#&#8203;5158](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5158)

- Emscripten output now works against vanilla upstream emscripten
without
  requiring a fork. Dependency tracking, `HEAP_DATA_VIEW` setup,
  function-decl intrinsic inlining, catch-wrapper gating, and imported
  global handling have all been corrected; ESM imports
  (`#[wasm_bindgen(module = "...")]` and snippets) are emitted to a
  sidecar `library_bindgen.extern-pre.js` consumers pass to emcc via
  `--extern-pre-js`; namespaced exports (`js_namespace = [...]` on a
  struct/impl) now attach to `Module.<segments>` instead of emitting
  top-level `export const` (which emcc's library evaluator rejects);
  the generated `.d.ts` for namespaced exports is now valid TypeScript
  (mangled identifiers stay module-internal via `declare class` /
  `declare enum` / `declare function` plus `export { BindgenModule };`
  to mark the file as a module; no spurious unqualified `Calc:`
  property on `BindgenModule` for namespaced items; namespace shapes
  land as plain interface members (`app: { math: { Calc: typeof
  app__math__Calc } };`) instead of the previously-emitted `export
  let app: { ... };` which was invalid TS1131 syntax inside an
  interface body).

[#&#8203;5156](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5156)

- Fixed a duplicate phantom class being emitted for an exported struct
  renamed via `js_name` (Rust ident != JS class name) and/or placed in a
  `js_namespace`, when the struct crosses the boundary as a `JsValue`
(e.g. via `.into()`). The `WrapInExportedClass` / `UnwrapExportedClass`
  imports were keyed by the Rust ident rather than the qualified JS name
that `exported_classes` is keyed by (a regression from
[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5154)),
so a
  fresh empty class entry was minted and emitted alongside the real one,
  with a `free()` referencing a nonexistent wasm export. Riding the
same release's
[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5154)
wire-format bump, the now-vestigial `rust_name`
  field is dropped from the schema and the namespace-qualified name is
  no longer cached on `AuxStruct`, `AuxEnum`, or `ExportedClass`
  (derived on demand from `(name, js_namespace)`), collapsing three
fallback chains that only papered over the
[pre-#&#8203;5154](https://redirect.github.com/pre-/wasm-bindgen/issues/5154)
keying.


[#&#8203;5160](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5160)

***

###
[`v0.2.121`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02121)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.120...0.2.121)

##### Added

- Added the `slice_to_array` attribute for imported JS functions,
  which makes a `&[T]` (or `Option<&[T]>`) argument arrive on the JS
  side as a plain `Array` rather than a typed array — without
  changing the Rust-side `&[T]` signature. Useful when binding JS
  APIs that take `T[]` rather than `TypedArray<T>`. For primitive
  element kinds the wire is the same zero-copy borrow used by plain
  `&[T]`, with the JS-side shim wrapping the view in `Array.from(...)`
  to materialise the `Array` — no extra allocation. For `String`,
  `JsValue`, and JS-imported element types the Rust side builds a
  fresh `[u32]` index buffer that JS reads and frees, with per-element
  `&T -> JsValue` (refcount bump for handle-shaped types). No `T:
  Clone` bound is required. The attribute can be set per-fn
  (`#[wasm_bindgen(slice_to_array)] fn ...`) or per-block on an
  `extern "C" { ... }` declaration to apply to every imported function
  in that block. `&[ExportedRustStruct]` remains unsupported (use
  owned `Vec<T>` for that). Has no effect on exported functions;
  default `&[T]` (typed-array view / memory borrow) and owned
  `Vec<T>` semantics are unchanged for callers that didn't opt in.
  See the
[`slice_to_array` guide
page](reference/attributes/on-js-imports/slice_to_array.html).

[#&#8203;5145](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5145)

- Added `js_sys::AggregateError` bindings (constructor, `errors` getter,
and
`new_with_message` / `new_with_options` overloads). `AggregateError`
represents
  multiple unrelated errors wrapped in a single error, e.g. as thrown by
`Promise.any` when all input promises reject, along with
`js_sys::ErrorOptions`,
  accepted by built-in error constructors. `ErrorOptions::new(cause)`
  constructs an instance pre-populated with `cause`, and `get_cause` /
  `set_cause` provide typed access to the property. All standard error
  constructors that previously took only a `message` (`EvalError`,
`RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError`,
  `WebAssembly.CompileError`, `WebAssembly.LinkError`,
  `WebAssembly.RuntimeError`) now expose a `new_with_options(message,
  &ErrorOptions)` overload, and `Error` gains
`new_with_error_options(message, &ErrorOptions)` alongside the existing
untyped `new_with_options`. `AggregateError::new_with_options` also
takes
  `&ErrorOptions`.

[#&#8203;5139](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5139)

- Added inheritance for Rust-exported types: an exported struct may
  declare `#[wasm_bindgen(extends = Parent)]` to inherit from another
  exported `#[wasm_bindgen]` struct. The macro injects a hidden
  `parent: wasm_bindgen::Parent<Parent>` field (a refcounted cell around
  the parent value) and emits `class Child extends Parent` in the
  generated JS / `.d.ts`. The child gets an `AsRef<Parent<Parent>>` impl
  for the direct parent, and threads per-class pointer slots through
  the wasm ABI so that `instanceof Parent` is true and parent methods
  dispatch soundly via the JS prototype chain. From inside child
  methods, parent data is reached via `self.parent.borrow()` /
  `self.parent.borrow_mut()`. See the new
[`extends` guide
page](reference/attributes/on-rust-exports/extends.html).

[#&#8203;5120](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5120)

- Added `js_sys::FinalizationRegistry` bindings (constructor,
`register`,
`register_with_token`, and `unregister`). The cleanup callback parameter
is typed as `&Function<fn(JsValue) -> Undefined>`, so closures created
via
  `Closure::new` can be passed using `Function::from_closure` (for owned
closures retained by JS) or `Function::closure_ref` (for borrowed scoped
  closures). Pairs with the existing `js_sys::WeakRef` bindings.

[#&#8203;5140](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5140)

- Added support for well-known symbols in `js_name`, `getter`, and
  `setter` via the explicit bracket-string form
  `"[Symbol.<name>]"`. This works for imported and exported methods,
  fields, getters, and setters. For example,
  `#[wasm_bindgen(js_name = "[Symbol.iterator]")]` on an exported method
  generates `[Symbol.iterator]() { ... }` on the generated JS class, and
  the same syntax works for `getter` / `setter` and for imported items.

[#&#8203;4230](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4230)

- Added level 2 bindings for `ViewTransition` to `web-sys`.

[#&#8203;5138](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5138)

- Add support for dynamic unions: a `#[wasm_bindgen]` enum that mixes
string-literal
variants with single-field tuple variants is now exported as an untagged
TypeScript
union and dispatched dynamically at the JS↔Rust boundary. The new
enum-level
  `#[wasm_bindgen(fallback)]` attribute makes the last tuple variant an
unconditional catch-all, supporting unions whose trailing variant has no
  runtime check (e.g., interface-only imports). String enums and dynamic
unions now emit `export type` (was bare `type`) so the alias is a named
  export, and both honour the `private` flag to suppress the keyword.

[#&#8203;4734](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4734)

[#&#8203;2153](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/2153)

[#&#8203;2088](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/2088)

##### Fixed

- `From<Promise<T>> for JsFuture<T>` and `IntoFuture for Promise<T>` now
  accept any `T: FromWasmAbi` (rather than `T: JsGeneric`), letting
  imported `async fn`s return dynamic-union enums.

- `TryFromJsValue` for C-style enums no longer accepts non-numeric
values
via JS unary `+` coercion. Previously calling `dyn_into::<MyEnum>()` on
  a string would silently coerce it via `+"foo"` (yielding `NaN`, then
  `NaN as u32 = 0`) and could match a discriminant by accident; the
  conversion now returns `None` for any value that is not a JS number.

[#&#8203;4734](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4734)

- Fix compilation failure with `no_std` + `release`

[#&#8203;5134](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5134)

- Raw identifiers (`r#name`) on enums, enum variants, extern types,
statics,
and `impl` blocks no longer leak the `r#` prefix into generated JS / TS
output and shim names. The Rust-side identifier and the JS-side name are
  now tracked separately for enum variants, and all known identifier
  fallback paths apply `Ident::unraw()` so e.g.
  `pub enum r#Enum { r#A }` generates `Enum.A` instead of producing
  syntactically invalid JS.

[#&#8203;4323](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4323)

- Using the `-C panic=unwind` option when building for the bundler
target
  would produce invalid JS.

[#&#8203;5142](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5142)

##### Changed

- `js_sys::DataView` now implements the `js_sys::TypedArray` trait. A
  `FIXME` notes that the trait should be renamed to `ArrayBufferView` in
  the next major release to better reflect the WebIDL spec name covering
  both `DataView` and the typed-array types.

[#&#8203;5135](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5135)

***

###
[`v0.2.120`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.118...0.2.120)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.118...0.2.120)

###
[`v0.2.118`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02118)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.117...0.2.118)

##### Added

- Added `Error::stack_trace_limit()` and
`Error::set_stack_trace_limit()` bindings
  to `js-sys` for the non-standard V8 `Error.stackTraceLimit` property.

[#&#8203;5082](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5082)

- Added support for multiple `#[wasm_bindgen(start)]` functions, which
are
  chained together at initialization, as well as a new
  `#[wasm_bindgen(start, private)]` to register a start function without
  exporting it as a public export.

[#&#8203;5081](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5081)

- Reinitialization is no longer automatically applied when using
`panic=unwind`
and `--experimental-reset-state-function`, instead it is triggered by
any
  use of the `handler::schedule_reinit()` function under `panic=unwind`,
which is supported from within the `on_abort` handler for reinit
workflows.
Renamed `handler::reinit()` to `handler::schedule_reinit()` and removed
  the `set_on_reinit()` handler. The `__instance_terminated` address
  is now always a simple boolean (`0` = live, `1` = terminated).

[#&#8203;5083](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5083)

- `handler::schedule_reinit()` now works under `panic=abort` builds.
Previously
it was a no-op; it now sets the JS-side reinit flag and the next export
call
  transparently creates a fresh `WebAssembly.Instance`.

[#&#8203;5099](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5099)

##### Changed

- MSRV bump from 1.71 to 1.76 for the CLI, and 1.82 to 1.86 for the API

[#&#8203;5102](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5102)

##### Fixed

- ES module `import` statements are now hoisted to the top of generated
JS
  files, placed right after the `@ts-self-types` directive. This ensures
  valid ES module output since `import` declarations must precede other
  statements.

[#&#8203;5103](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5103)

- Fixed two CLI issues affecting WASM modules built by rustc 1.94+.
First,
a panic (`failed to find N in function table`) caused by lld emitting
element
segment offsets as `global.get $__table_base` or extended const
expressions
instead of plain `i32.const N` for large function tables; the fix adds a
const-expression evaluator in `get_function_table_entry` and guards
against
integer underflow in multi-segment tables. Second, the descriptor
interpreter
now routes all global reads/writes through a single `globals` HashMap
seeded
from the module's own globals, and mirrors the module's actual linear
memory
rather than a fixed 32KB buffer, so the stack pointer's real value is
valid
without any override. This fixes panics like `failed to find 32752 in
function
table` caused by `GOT.func.internal.*` globals being misidentified as
the
  stack pointer.

[#&#8203;5076](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5076)

[#&#8203;5080](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5080)

[#&#8203;5093](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5093)

[#&#8203;5095](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5095)

###
[`v0.2.117`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02117)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.116...0.2.117)

##### Fixed

- Fixed a regression introduced in
[#&#8203;5026](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5026)
where stable `web-sys` methods that
  accept a union type containing a `[WbgGeneric]` interface (e.g.
`ImageBitmapSource`, which includes `VideoFrame`) incorrectly applied
typed
generics to all union expansions rather than only those whose argument
type
is itself `[WbgGeneric]`. In practice this caused
`Window::create_image_bitmap_with_*`
  and the corresponding `WorkerGlobalScope` overloads to return
  `Promise<ImageBitmap>` instead of `Promise<JsValue>` for the stable
(non-`VideoFrame`) call sites, breaking
`JsFuture::from(promise).await?`.

[#&#8203;5064](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5064)

[#&#8203;5073](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5073)

- Fixed handling logic for environment variable
`WASM_BINDGEN_TEST_ADDRESS` in
  the test runner, when running tests in headless mode.

[#&#8203;5087](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5087)

###
[`v0.2.116`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02116)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.115...0.2.116)

##### Added

- Added `js_sys::Float16Array` bindings, `DataView` float16 accessors
using
  `f32`, and raw `[u16]` helper APIs for interoperability with binary16
  representations such as `half::f16`.

[#&#8203;5033](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5033)

##### Changed

- Updated to Walrus 0.26.1 for deterministic type section ordering.

[#&#8203;5069](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5069)

- The `#[wasm_bindgen]` macro now emits `&mut (impl FnMut(...) +
MaybeUnwindSafe)`
/ `&(impl Fn(...) + MaybeUnwindSafe)` for raw `&mut dyn FnMut` / `&dyn
Fn`
import arguments instead of a hidden generic parameter and where-clause.
The
generated signature is cleaner and the `MaybeUnwindSafe` bound is
visible
directly in the argument position. The ABI and wire format are
unchanged.
When building with `panic=unwind`, closures that capture
non-`UnwindSafe`
values (e.g. `&mut T`, `Cell<T>`) must wrap them in `AssertUnwindSafe`
before
capture; on all other targets `MaybeUnwindSafe` is a no-op blanket impl.

[#&#8203;5056](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5056)

###
[`v0.2.115`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02115)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.114...0.2.115)

##### Added

- `console.debug/log/info/warn/error` output from user-spawned `Worker`
and
`SharedWorker` instances is now forwarded to the CLI test runner during
headless browser tests, just like output from the main thread. Works for
blob URL workers, module workers, URL-based workers (importScripts),
nested
workers, and shared workers (including logs emitted before the first
port
connection). Non-cloneable arguments are serialized via `String()`
rather
  than crashing the worker. The `--nocapture` flag is respected.

[#&#8203;5037](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5037)

- `js_sys::Promise<T>` now implements `IntoFuture`, enabling direct
`.await` on
any JS promise without a wrapper type. The `wasm-bindgen-futures`
implementation
has been moved into `js-sys` behind an optional `futures` feature, which
is
activated automatically when `wasm-bindgen-futures` is a dependency. All
existing `wasm_bindgen_futures::*` import paths continue to work
unchanged via
re-exports. `js_sys::futures` is also available directly for users who
want
  `promise.await` without depending on `wasm-bindgen-futures`.

[#&#8203;5049](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5049)

- Added `--target emscripten` support, generating a `library_bindgen.js`
file
for consumption by Emscripten at link time. Includes support for
futures,
JS closures, and TypeScript output. A new Emscripten-specific test
runner is
  also included, along with CI integration.

[#&#8203;4443](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4443)

- Added `VideoFrame`, `VideoColorSpace`, and related WebCodecs
dictionaries/enums to `web-sys`.

[#&#8203;5008](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5008)

- Added `wasm_bindgen::handler` module with `set_on_abort` and
`set_on_reinit`
hooks for `panic=unwind` builds. `set_on_abort` registers a callback
invoked
  after the instance is terminated (hard abort, OOM, stack overflow).
`set_on_reinit` registers a callback invoked after `reinit()` resets the
WebAssembly instance via `--experimental-reset-state-function`. Handlers
are
stored as Wasm indirect-function-table indices so dispatch is safe even
when
  linear memory is corrupt.

##### Changed

- Replaced per-closure generic destructors with a single
`__wbindgen_destroy_closure`
  export.

[#&#8203;5019](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5019)

- Refactored the headless browser test runner logging pipeline for
dramatically improved
performance (>400x faster on Chrome, >10x on Firefox, \~5x on Safari).
Switched to
incremental DOM scraping with `textContent.slice(offset)`, append-only
output semantics,
unified log capture across all log levels on failure, and
browser-specific invisible-div
optimizations (`display:none` for Chrome/Firefox, `visibility:hidden`
for Safari).

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- TTY-gated status/clear output in the test runner shell to avoid `\r`
control-character
  artifacts in non-interactive (CI) environments.

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- Added `bench_console_log_10mb` benchmark alongside the existing 1MB
benchmark for the
headless test runner. The main branch cannot complete this benchmark at
any volume.

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- Updated to Walrus 0.26

[#&#8203;5057](https://redirect.github.com/wasm-bindgen/walrus/pull/5057)

##### Fixed

- Fixed argument order when calling multi-parameter functions in the
`wasm-bindgen` interpreter by reversing the args collected from the
stack.

[#&#8203;5047](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5047)

- Added support for per-operation `[WbgGeneric]` in WebIDL, restoring
typed
generic return types (e.g. `Promise<ImageBitmap>`) for
`createImageBitmap` on
  `Window` and `WorkerGlobalScope` that were lost after the `VideoFrame`
  stabilization.

[#&#8203;5026](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5026)

- Fixed missing `#[cfg(feature = "...")]` gates on deprecated dictionary
builder
methods and getters for union-typed fields (e.g.
`{Open,Save,Directory}FilePickerOptions::start_in()`),
and fixed per-setter doc requirements to list each setter's own required
features.

[#&#8203;5039](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5039)

- Fixed `JsOption::new()` to use `undefined` instead of `null`, to be
compatible with `Option::None` and JS default parameters.

[#&#8203;5023](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5023)

- Fixed unsound `unsafe` transmutes in `JsOption<T>::wrap`, `as_option`,
and `into_option`
by replacing `transmute_copy` with `unchecked_into()`. Also tightened
the `JsGeneric`
trait bound and `JsOption<T>` impl block to require `T: JsGeneric`
(which implies `JsCast`),
  preventing use with arbitrary non-JS types.

[#&#8203;5030](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5030)

- Fixed headless test runner emitting `\r` carriage-return sequences in
non-TTY environments,
which polluted captured logs in CI and complicated output-matching
tests.

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- Fixed headless test runner printing incomplete and out-of-order log
output on test failures
  by merging all five log levels into a single unified output div.

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- Fixed large test outputs (10MB+) causing oversized WebDriver responses
that were either
extremely slow or crashed completely, by switching to incremental
streaming output collection.

[#&#8203;4960](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4960)

- Fixed a duplciate wasm export in node ESM atomics, when compiled in
debug mode

[#&#8203;5028](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5028)

- Fixed a type inference regression (`E0283: type annotations needed`)
introduced
in v0.2.109 where the stable `FromIterator` and `Extend` impls on
`js_sys::Array`
were changed from `A: AsRef<JsValue>` to `A: AsRef<T>`. Because
`#[wasm_bindgen]`
generates multiple `AsRef` impls per type, the compiler could not
uniquely resolve
`T`, breaking code like `Array::from_iter([my_wasm_value])` without
explicit
annotations. The stable impls are restored to `A: AsRef<JsValue>`
(returning
`Array<JsValue>`); the generic `A: AsRef<T>` forms remain available
under
  `js_sys_unstable_apis`.

[#&#8203;5052](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5052)

- Fixed `skip_typescript` not being respected when using `reexport`,
causing
TypeScript definitions to be incorrectly emitted for re-exported items
marked
  with `#[wasm_bindgen(skip_typescript)]`.

[#&#8203;5051](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5051)

##### Removed

###
[`v0.2.114`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02114)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.113...0.2.114)

##### Added

- Added `[WbgGeneric]` WebIDL extended attribute for opting stable
dictionary and interface
definitions into typed generics (the same signatures unstable APIs use),
avoiding legacy
  `&JsValue` fallbacks. Applied to all new VideoFrame-related types.

[#&#8203;5008](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5008)

- Added `unchecked_optional_param_type` attribute for marking exported
function parameters as
optional in TypeScript (`?:`) and JSDoc (`[paramName]`) output. Mutually
exclusive with
`unchecked_param_type`. Required parameters after optional parameters
are rejected at compile time.

[#&#8203;5002](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5002)

- Added termination detection for `panic=unwind` builds. When a non-JS
exception (e.g. a Rust
panic) escapes from Wasm, the instance is marked as terminated and
subsequent calls from JS
into Wasm will throw a `Module terminated` error instead of re-entering
corrupted state.

[#&#8203;5005](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5005)

- When `--reset-state` is combined with `panic=unwind` builds, the Wasm
instance is
automatically reset after a fatal termination, allowing subsequent calls
to succeed
  instead of throwing a `Module terminated` error.

[#&#8203;5013](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5013)

##### Changed

- Replaced runtime `0x80000000` vtable bit-flag for closure unwind
safety with a
compile-time `const UNWIND_SAFE: bool` generic on the invoke shim,
`OwnedClosure`,
and `BorrowedClosure`. Removes `OwnedClosureUnwind` and deduplicates
internal
  closure helpers. The public API is unchanged.

[#&#8203;5003](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5003)

- Removed unused `IntoWasmClosureRef*::WithLifetime` types,
  `WasmClosure::to_wasm_slice`, and a lifetime from
`IntoWasmClosureRef*`; moved `Static` associated type into
`WasmClosure`.

[#&#8203;5003](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5003)

##### Fixed

- Fixed exported structs/enums/functions with the same `js_name` but
different
`js_namespace` values producing symbol collisions at compile time, by
deriving
internal wasm symbols from a qualified name that includes the namespace.

[#&#8203;4977](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4977)

- Fixed soundness hole in `ScopedClosure`'s `UpcastFrom` that allowed to
extend the lifetime after the original `ScopedClosure` was dropped.

[#&#8203;5006](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5006)

###
[`v0.2.113`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02113)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.112...0.2.113)

##### Changed

- Reduced usage of `unsafe` code: replaced `transmute`/`transmute_copy`
with safe
alternatives for `Boolean`/`Null`/`Undefined` constants and `ArrayTuple`
conversions,
unified duplicated `AsRef`/`From` impls for generic imported types, and
removed the
`__wbindgen_object_is_undefined` intrinsic in favor of a safe Rust-side
equivalent.

[#&#8203;4993](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4993)

- Renamed `__wbindgen_object_is_null_or_undefined` intrinsic to
`__wbindgen_is_null_or_undefined` and removed the
`__wbindgen_object_is_undefined`
intrinsic, replacing it with a safe Rust-side check. The
`is_null_or_undefined` check
  now uses safe `&JsValue` ABI instead of raw `u32`.

[#&#8203;4994](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4994)

##### Fixed

- Fixed incorrect method naming for stable web-sys methods that
reference unstable
types (e.g. `texImage2D` taking a `VideoFrame` parameter). These methods
were
being named in a separate unstable expansion namespace, producing
overly-short
  names like `tex_image_2d` instead of the correct
`tex_image_2d_with_u32_and_u32_and_video_frame`. The fix separates the
signature
classification to distinguish "from unstable IDL" (authoritative
overrides) from
"stable method using an unstable type", ensuring the latter is named as
part of
  the stable expansion.

[#&#8203;4991](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4991)

###
[`v0.2.112`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02112)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.111...0.2.112)

##### Removed

- Removed `ImmediateClosure` type introduced in 0.2.109. Stack-borrowed
`&dyn Fn` / `&mut dyn FnMut`
closures are now treated as unwind safe by default (panics are caught
and converted to JS exceptions
with proper unwinding). A unified `ScopedClosure::immediate` approach
may be revisited in a future
  release.

[#&#8203;4986](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4986)

###
[`v0.2.111`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02111)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.110...0.2.111)

##### Fixed

- Restored backwards compatibility for breaking changes introduced in
0.2.110:
re-added deprecated `Promise::then2` binding, reverted
`Promise::all_settled`
stable signature to take `&JsValue` instead of owned `Object`, and added
default type parameters (`= JsValue`) to `ArrayIntoIter`, `ArrayIter`,
and
  `Iter` structs.

[#&#8203;4979](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4979)

###
[`v0.2.110`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02110)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.109...0.2.110)

##### Changed

- Refactor new closure methods - ensures that all closure constructor
functions have the variants `Closure::foo()`, `Closure::foo_aborting()`
and
`Closure::foo_assert_unwind_safe()` this then fully allows switching
from the UnwindSafe bound now being applies on foo() to use one of the
alternatives, given these limitations of AssertUnwindSafe. The same
applies to `ImmediateClosure`. In addition, mutable reentrancy guards
are
added for `ImmediateClosure`, and it is updated to be pass-by-value as
well.

[#&#8203;4975](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4975)

##### Fixed

- Fixed a regression where Array.of1,... variants using generic
`Array<T>` broke inference.
Reverted to use non-generic JsValue arguments. In addition extends
generic class hoisting to
for constructors to also include `static_method_of` methods returning
the own type, to allow
  `Array::of` generic to now be on the `Array<T>` impl block.

[#&#8203;4974](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4974)

###
[`v0.2.109`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02109)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.108...0.2.109)

##### Added

- Added support for erasable generic type parameters on imported
JavaScript types,
using sound type erasure in JS bindgen boundary. Includes updated js-sys
bindings
with generic implementations for many standard JS types and functions
including
  `Array<T>`, `Promise<T>`, `Map<K, V>`, `Iterator<T>`, and more.

[#&#8203;4876](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4876)

- Added `ScopedClosure<'a, T>` as a unified closure type with lifetime
parameter. `ScopedClosure::borrow(&f)` (for immutable `Fn`) and
`ScopedClosure::borrow_mut(&mut f)` (for mutable `FnMut`) create
borrowed closures that can capture non-`'static` references, ideal for
immediate/synchronous JS callbacks. `Closure<T>` is now a type alias for
`ScopedClosure<'static, T>`, maintaining backwards compatibility. Also
added `IntoWasmAbi` implementation for `Closure<T>` enabling
pass-by-value ownership transfer to JavaScript.

- Added `ImmediateClosure<'a, T>` as a lightweight, unwind-safe
replacement for
`&dyn FnMut` in immediate/synchronous callbacks. Unlike `ScopedClosure`,
it has
no JS call on creation, no JS call on drop, and no GC overhead—the same
ABI as
`&dyn FnMut` but with panic safety. Use `ImmediateClosure::new(&f)` for
immutable `Fn` closures (easier to satisfy unwind safety) or
`ImmediateClosure::new_mut(&mut f)` for
mutable `FnMut` closures. Closure parameter types are automatically
inferred from context.
Also implements `From<&ImmediateClosure<T>> for ScopedClosure<T>` for
API migration.

[#&#8203;4950](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4950)

- Implement `#[wasm_bindgen(catch)]` exception handling directly in Wasm
using
`WebAssembly.JSTag` when Wasm exception handling is available. This
generates
smaller and faster code by avoiding JavaScript `handleError` wrapper
functions.

[#&#8203;4942](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4942)

- Add Node.js `worker_threads` support for atomics builds. When
targeting Node.js with atomics enabled, wasm-bindgen now generates
`initSync({ module, memory, thread_stack_size })` and
`__wbg_get_imports(memory)` functions that allow worker threads to
initialize with a shared WebAssembly.Memory and pre-compiled module.
Auto-initialization occurs only on the main thread for backwards
compatibility.

- Added a panic message when a getter has more than one argument.

[#&#8203;4936](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4936)

- Added support for WebIDL namespace attributes in
`wasm-bindgen-webidl`. This enables
APIs like the CSS Custom Highlight API which adds the `highlights`
attribute to the `CSS` namespace.

[#&#8203;4930](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4930)

- Added stable `ShowPopoverOptions` dictionary and
`show_popover_with_options()` method to
`HtmlElement`, and unstable `TogglePopoverOptions` dictionary per the
WHATWG HTML spec.

[#&#8203;4968](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4968)

- Added unstable Geolocation API types per the latest W3C spec:
`GeolocationCoordinates`,
`GeolocationPosition`, and `GeolocationPositionError`. The `Geolocation`
interface now
has both stable methods (using the old `Position`/`PositionError` types
with `[Throws]`)
and unstable methods (using the new types without `[Throws]}`, matching
actual browser behavior).

[#&#8203;2578](https://redirect.github.com/AbesBend662/AbesBend662.github.io/pull/2578)

- Added `matrixTransform()` method to `DOMPointReadOnly` in `web-sys`.

[#&#8203;4962](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4962)

- Added the `web` and `node` targets to the
`--experimental-reset-state-function` flag.

[#&#8203;4909](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4909)

- Added `oncancel` event handler to `GlobalEventHandlers` (available on
`HtmlElement`,
  `Document`, `Window`, etc.).

[#&#8203;4542](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4542)

- Added `CommandEvent` and `CommandEventInit` from the Invoker Commands
API.

[#&#8203;4552](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4552)

- Added `AbstractRange`, `StaticRange`, and `StaticRangeInit`
interfaces.

[#&#8203;4221](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4221)

- Updated WebCodecs API to Working Draft 2026-01-29 and MediaRecorder
API to 2025-04-17.
  Added `rotation` and `flip` to `VideoDecoderConfig`.

[#&#8203;4411](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4411)

- Added support for unstable WebIDL to override stable attribute types,
allowing
corrected type signatures behind `web_sys_unstable_apis`. Applied to
`MouseEvent`
coordinate attributes (`clientX`, `clientY`, `screenX`, `screenY`,
`offsetX`,
`offsetY`, `pageX`, `pageY`) which now return `f64` instead of `i32`
when
  unstable APIs are enabled, per the CSSOM View spec draft.

[#&#8203;4935](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4935)

- Added support for unstable WebIDL to override stable method return
types. This
enables User Timing Level 3 APIs where `Performance.mark()` and
`Performance.measure()`
return `PerformanceMark` and `PerformanceMeasure` respectively (instead
of `undefined`)
when `web_sys_unstable_apis` is enabled. Also added
`PerformanceMarkOptions`,
`PerformanceMeasureOptions`, and the `detail` attribute on
marks/measures.

[#&#8203;3734](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/3734)

- Added non-standard `mode` option for
`FileSystemFileHandle.createSyncAccessHandle()`.
Also improved WebIDL generator to track stability at the signature
level, allowing
  stable methods to have unstable overloads.

[#&#8203;4928](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4928)

- Updated WebGPU bindings to the February 2026 spec. Dictionary fields
with union
types now generate multiple type-safe setters (e.g.
`set_resource_gpu_sampler()`,
`set_resource_gpu_texture_view()`) alongside a deprecated fallback
setter. Sequence
arguments in unstable APIs now use typed slices (`&[T]`) instead of
`&JsValue`.
Fixed inner string enum types to use `JsString` in generic positions,
added `BigInt`
to builtin identifiers, and fixed dictionary field feature gates to not
over-constrain
  getters with setter type requirements.

[#&#8203;4955](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4955)

- Improved dictionary union type expansion: stable fallback setters are
no longer
deprecated, and unstable builder methods now use the first typed variant
instead
of `&JsValue`. Dictionaries with required union fields now generate
expanded
constructors for each variant (e.g. `new()`,
`new_with_gpu_texture_view()`),
  with duplicate-signature variants elided.

[#&#8203;4966](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4966)

##### Changed

- Increased externref stack size from 128 to 1024 slots to prevent
"table index is out of bounds"
errors in applications with deep call stacks or many concurrent async
operations.

[#&#8203;4951](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4951)

- `Closure::new()`, `Closure::once()`, and related methods now require
`UnwindSafe` bounds on closures when building with `panic=unwind`. New
`_aborting` variants (`new_aborting()`, `once_aborting()`, etc.) are
provided for closures that don't need panic catching and want to avoid
the `UnwindSafe` requirement.

[#&#8203;4893](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4893)

- `global` does not use the unsafe-eval `new Function` trick anymore
allowing to have CSP strict compliant packages with `wasm-bindgen`.

[#&#8203;4910](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4910)

- `eval` and `Function` constructors are now gated behind the
`unsafe-eval` feature.

[#&#8203;4914](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4914)

##### Fixed

- Fixed incorrect JS export names when LLVM merges identical functions
at `opt-level >= 2`.

[#&#8203;4946](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4946)

- Fixed incorrect `Closure` adapter deduplication when wasm-ld's
Identical Code Folding merges
  invoke functions for different closure types into the same export.

[#&#8203;4953](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4953)

- Fixed `ReferenceError` when using Rust struct names that conflict with
JS builtins (e.g., `Array`).
The constructor now correctly uses the aliased `FinalizationRegistry`
identifier.

[#&#8203;4932](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4932)

- Fixed `Element::scroll_top()`, `Element::scroll_left()`, and
`HtmlElement::scroll_top()`
to return `f64` instead of `i32` per the CSSOM View spec, behind
`web_sys_unstable_apis`.
  The stable API is unchanged for backwards compatibility.

[#&#8203;4525](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/4525)

- Added spec-compliant `i32` parameter types for
`CanvasRenderingContext2d::get_image_data()`
and `put_image_data()` (and `OffscreenCanvasRenderingContext2d`
equivalents) behind
`web_sys_unstable_apis`. Per the HTML spec, `getImageData` and
`putImageData` use `long`
(i32) for coordinates, not `double` (f64). The stable API is unchanged
for backwards
  compatibility.

[#&#8203;1920](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/1920)

- Fixed incorrect `#[cfg(web_sys_unstable_apis)]` gating on stable
method signatures that
share a WebIDL operation with unstable overloads. For example,
`Clipboard.read()` (0 args)
was incorrectly gated as unstable because the unstable `read(options)`
overload existed.
The WebIDL code generator now uses an authoritative expansion model
where stable and unstable
signature sets are built independently and compared: identical
signatures merge (no gate),
stable-only signatures get `not(unstable)`, and unstable-only signatures
get `unstable`.
Also adds typed generics (`Promise<T>`, `Array<T>`, `Function<fn(...)>`,
etc.) to all
unstable API methods, and adds missing `PhotoCapabilities`,
`PhotoSettings`,
`MediaSettingsRange`, `Point2D`, `RedEyeReduction`, `FillLightMode`, and
`MeteringMode`
  types from the W3C Image Capture spec.

[#&#8203;4964](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4964)

- Fixed `unfulfilled_lint_expectations` warnings when using
`#[expect(...)]` attributes
on functions annotated with `#[wasm_bindgen]`. The `#[expect]`
attributes are now
converted to `#[allow]` in generated code to prevent spurious warnings.

[#&#8203;4409](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4409)

###
[`v0.2.108`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02108)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.107...0.2.108)

##### Fixed

- Fixed regression where `panic=unwind` builds for non-Wasm targets
would trigger `UnwindSafe` assertions.

[#&#8203;4903](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4903)

###
[`v0.2.107`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02107)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.106...0.2.107)

##### Added

- Support catching panics, and raising JS Exceptions for them, when
building
  with panic=unwind on nightly, with the `std` feature.

[#&#8203;4790](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4790)

- Added support for passing `&[JsValue]` slices from Rust to JavaScript
functions.

[#&#8203;4872](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4872)

- Added `private` attribute on exported types to allow generating
  exports and structs as implicit internal exported types for function
  arguments and returns, without exporting them on the public interface.

[#&#8203;4788](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4788)

- Added `iter_custom` and `iter_custom_future` for bench to do custom
measurements.

[#&#8203;4841](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4841)

- Added [Window Management
API](https://w3c.github.io/window-management/).

[#&#8203;4843](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4843)

##### Changed

- Changed WASM import namespace from `wbg` to `./{name}_bg.js` for `web`
and `no-modules` targets,
aligning with `bundler` and `experimental-nodejs-module` to enable
cross-target WASM sharing.

[#&#8203;4850](https://redirect.github.com/rustwasm/wasm-bindgen/pull/4850)

- Replace `WASM_BINDGEN_UNSTABLE_TEST_PROFRAW_OUT` and
`WASM_BINDGEN_UNSTABLE_TEST_PROFRAW_PREFIX` with parsing
`LLVM_PROFILE_FILE` analogous to Rust test coverage.

[#&#8203;4367](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4367)

- Typescript custom sections sorted alphabetically across codegen-units.

[#&#8203;4738](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4738)

- Optimized demangling performance by removing redundant string
formatting

[#&#8203;4867](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4867)

- Changed WASM import namespace from `__wbindgen_placeholder__` to
`./{name}_bg.js` for `node` targets, aligning with `bundler` and
`experimental-nodejs-module` to enable cross-target WASM sharing.

[#&#8203;4869](https://redirect.github.com/rustwasm/wasm-bindgen/pull/4869)

- Changed WASM import namespace from `__wbindgen_placeholder__` to
`./{name}_bg.js` for `deno` and `module` targets, aligning with `node`,
`bundler` and `experimental-nodejs-module` to enable cross-target WASM
sharing.

[#&#8203;4871](https://redirect.github.com/rustwasm/wasm-bindgen/pull/4871)

- Consolidate JavaScript glue generation
Move target-specific JS emission into a single finalize phase, reducing
branching and making the generated output more consistent across
targets.
- Centralize JS output assembly in a single finalize phase
(exports/imports/wasm loading).
- Make `--target experimental-nodejs-module` emit one JS entrypoint (no
separate `_bg.js`).
- Ensure Node (CJS/ESM) and bundler entrypoints only expose public
exports (no internal import shims).
- Add `/* @&#8203;ts-self-types="./<name>.d.ts" */` to JS entrypoints
for JSR/Deno resolution.
  - Refresh reference test fixtures.

[#&#8203;4879](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4879)

- Forward worker errors to test output in the test runner.

[#&#8203;4855](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4855)

##### Fixed

- Fix: Include doc comments in TypeScript definitions for classes

[#&#8203;4858](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4858)

- Interpreter: support try\_table blocks

[#&#8203;4862](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4862)

- Interpreter: Stop interpretting descriptor after
`__wbindgen_describe_cast`

[#&#8203;4862](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4898)

###
[`v0.2.106`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02106)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.105...0.2.106)

##### Added

- New MSRV policy, and bump of the MSRV fo 1.71.

[#&#8203;4801](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull4801)

- Added `CSS Custom Highlight` API to `web-sys`.

[#&#8203;4792](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4792)

- Added typed `this` support in the first argument in free function
exports via
  a new `#[wasm_bindgen(this)]` attribute.

[#&#8203;4757](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4757)

- Added `reexport` attribute for imports to support re-exporting
imported types,
  with optional renaming.

[#&#8203;4759](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4759)

- Added `js_namespace` attribute on exported types, mirroring the import
  semantics to enable arbitrarily nested exported interface objects.

[#&#8203;4744](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4744)

- Added 'container' attribute to `ScrollIntoViewOptions`

[#&#8203;4806](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4806)

- Updated and refactored output generation to use alphabetical ordering
  of declarations.

[#&#8203;4813](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4813)

- Added benchmark support to `wasm-bindgen-test`.

[#&#8203;4812](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4812)

[#&#8203;4823](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4823)

##### Fixed

- Fixed node test harness getting stuck after tests completed.

[#&#8203;4776](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4776)

- Quote names containing colons in generated .d.ts.

[#&#8203;4488](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4488)

- Fixes TryFromJsValue for structs JsValue stack corruption on failure.

[#&#8203;4786](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4786)

- Fixed `wasm-bindgen-test-runner` outputting empty line when using the
`--list` option. In particular, `cargo-nextest` now works correctly.

[#&#8203;4803](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4803)

- It now works to build with `-Cpanic=unwind`.

[#&#8203;4796](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4796)

[#&#8203;4783](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4783)

[#&#8203;4782](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4782)

- Fixed duplicate symbols caused by enabling v0 mangling.

[#&#8203;4822](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4822)

- Fixed a multithreaded wasm32+atomics race where `Atomics.waitAsync`
promise callbacks could call `run` without waking first, causing
sporadic panics.

[#&#8203;4821](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/4821)

##### Removed

</details>

---

### Configuration

📅 **Schedule**: (in timezone Asia/Shanghai)

- Branch creation
  - "before 10am on monday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/oxc-project/json-strip-comments).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate Bot added a commit to oxc-project/oxc-browserslist that referenced this pull request May 24, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [js-sys](https://wasm-bindgen.github.io/wasm-bindgen/)
([source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/tree/HEAD/crates/js-sys))
| dependencies | patch | `0.3.98` → `0.3.99` |
| [serde_json](https://redirect.github.com/serde-rs/json) |
workspace.dependencies | patch | `1.0.149` → `1.0.150` |
| [wasm-bindgen](https://wasm-bindgen.github.io/wasm-bindgen)
([source](https://redirect.github.com/wasm-bindgen/wasm-bindgen)) |
dependencies | patch | `0.2.121` → `0.2.122` |

---

### Release Notes

<details>
<summary>serde-rs/json (serde_json)</summary>

###
[`v1.0.150`](https://redirect.github.com/serde-rs/json/releases/tag/v1.0.150)

[Compare
Source](https://redirect.github.com/serde-rs/json/compare/v1.0.149...v1.0.150)

- Reject non-string enum object keys
([#&#8203;1324](https://redirect.github.com/serde-rs/json/issues/1324),
thanks
[@&#8203;puneetdixit200](https://redirect.github.com/puneetdixit200))

</details>

<details>
<summary>wasm-bindgen/wasm-bindgen (wasm-bindgen)</summary>

###
[`v0.2.122`](https://redirect.github.com/wasm-bindgen/wasm-bindgen/blob/HEAD/CHANGELOG.md#02122)

[Compare
Source](https://redirect.github.com/wasm-bindgen/wasm-bindgen/compare/0.2.121...0.2.122)

##### Notices

- Threading support now requires `-Clink-arg=--export=__heap_base` to be
set
  in `RUSTFLAGS` for nightly toolchains from 2026-05-06 onward, after

[rust-lang/rust#156174](https://redirect.github.com/rust-lang/rust/pull/156174)
  removed the implicit `__heap_base`/`__data_end` exports on `wasm*`
  targets. Atomics CI, CLI reference tests, and the `nodejs-threads`,
  `raytrace-parallel`, and `wasm-audio-worklet` examples have been
  updated to pass `--export=__heap_base` explicitly. The flag is
  backward-compatible with older nightlies.

- `-Cpanic=unwind` on wasm targets now emits modern (exnref) exception
  handling by default after

[rust-lang/rust#156061](https://redirect.github.com/rust-lang/rust/pull/156061),
and requires Node.js 22.22.3+ (for `WebAssembly.JSTag`). Legacy EH wasm
  can still be produced on current nightlies by adding
  `-Cllvm-args=-wasm-use-legacy-eh` to `RUSTFLAGS`; Node.js 20 may be
  supported with legacy exception handling, with a tracking issue in

[#&#8203;5151](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5151).

##### Added

- Implemented `TryFromJsValue` for `Vec<T>` where `T: TryFromJsValue`.
  A JS value converts when it is a real `Array` (per `Array.isArray`)
  and every element converts via `T::try_from_js_value`. This composes
  recursively (`Vec<Vec<String>>`, `Vec<Option<T>>`) and works for any
  `T` with a `TryFromJsValue` impl, including primitives, `String`,
  `JsValue`, and `JsCast` types. Array-likes (objects with `length` and
  numeric indices) are intentionally rejected to mirror the static ABI
  representation used by `js_value_vector_from_abi`.

- New `extends_js_class` and `extends_js_namespace` attributes on
  exported structs to allow defining the parent `js_class` name when
it has been customized by `js_name` and the parent's own `js_namespace`
  as well in turn. New validation is added at code generation time that
  will now catch these cases instead of emitting invalid code. Example:

  ```rust
  #[wasm_bindgen(js_name = "Animal", js_namespace = zoo)]
  pub struct AnimalImpl { /* ... */ }

  #[wasm_bindgen(
      extends = AnimalImpl,
      extends_js_class = "Animal",
      extends_js_namespace = zoo,
  )]
  pub struct DogImpl { /* ... */ }
  ```


[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5154)

##### Changed

- When an exported struct uses `js_namespace`, the corresponding value
  must now be repeated on every `impl` block. Previously the impl-side
  defaults silently worked resulting in inconsistent emission. Example:

  ```rust
  // Before:
  #[wasm_bindgen(js_namespace = "default")]
  pub struct Counter { /* ... */ }

  #[wasm_bindgen]              // worked, but fragile
  impl Counter { /* ... */ }

  // After:
  #[wasm_bindgen(js_namespace = "default")]
  pub struct Counter { /* ... */ }

  #[wasm_bindgen(js_namespace = "default")]   // now required
  impl Counter { /* ... */ }
  ```

  To ease this transition for `js_namespace` usage, diagnostic
  messages now include hints for missing namespaces for easier
  fixing.


[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5154)

##### Fixed

- Fixed the descriptor interpreter panicking on `Br` and `BrIf`
  instructions emitted by recent nightly compilers when building with
  `panic=unwind`.

[#&#8203;5158](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5158)

- Emscripten output now works against vanilla upstream emscripten
without
  requiring a fork. Dependency tracking, `HEAP_DATA_VIEW` setup,
  function-decl intrinsic inlining, catch-wrapper gating, and imported
  global handling have all been corrected; ESM imports
  (`#[wasm_bindgen(module = "...")]` and snippets) are emitted to a
  sidecar `library_bindgen.extern-pre.js` consumers pass to emcc via
  `--extern-pre-js`; namespaced exports (`js_namespace = [...]` on a
  struct/impl) now attach to `Module.<segments>` instead of emitting
  top-level `export const` (which emcc's library evaluator rejects);
  the generated `.d.ts` for namespaced exports is now valid TypeScript
  (mangled identifiers stay module-internal via `declare class` /
  `declare enum` / `declare function` plus `export { BindgenModule };`
  to mark the file as a module; no spurious unqualified `Calc:`
  property on `BindgenModule` for namespaced items; namespace shapes
  land as plain interface members (`app: { math: { Calc: typeof
  app__math__Calc } };`) instead of the previously-emitted `export
  let app: { ... };` which was invalid TS1131 syntax inside an
  interface body).

[#&#8203;5156](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5156)

- Fixed a duplicate phantom class being emitted for an exported struct
  renamed via `js_name` (Rust ident != JS class name) and/or placed in a
  `js_namespace`, when the struct crosses the boundary as a `JsValue`
(e.g. via `.into()`). The `WrapInExportedClass` / `UnwrapExportedClass`
  imports were keyed by the Rust ident rather than the qualified JS name
that `exported_classes` is keyed by (a regression from
[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5154)),
so a
  fresh empty class entry was minted and emitted alongside the real one,
  with a `free()` referencing a nonexistent wasm export. Riding the
same release's
[#&#8203;5154](https://redirect.github.com/wasm-bindgen/wasm-bindgen/issues/5154)
wire-format bump, the now-vestigial `rust_name`
  field is dropped from the schema and the namespace-qualified name is
  no longer cached on `AuxStruct`, `AuxEnum`, or `ExportedClass`
  (derived on demand from `(name, js_namespace)`), collapsing three
fallback chains that only papered over the
[pre-#&#8203;5154](https://redirect.github.com/pre-/wasm-bindgen/issues/5154)
keying.


[#&#8203;5160](https://redirect.github.com/wasm-bindgen/wasm-bindgen/pull/5160)

***

</details>

---

### Configuration

📅 **Schedule**: (in timezone Asia/Shanghai)

- Branch creation
  - "before 10am on monday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/oxc-project/oxc-browserslist).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CI Area: Our Github Actions CI A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WASI: -Cpanic=unwind does not work

6 participants