Skip to content

Add wasm64-emscripten arm for unwinder_private_data_size#156912

Closed
gergelyvagujhelyi wants to merge 1 commit into
rust-lang:mainfrom
nobodywho-ooo:wasm64-emscripten-unwind-arm
Closed

Add wasm64-emscripten arm for unwinder_private_data_size#156912
gergelyvagujhelyi wants to merge 1 commit into
rust-lang:mainfrom
nobodywho-ooo:wasm64-emscripten-unwind-arm

Conversation

@gergelyvagujhelyi

Copy link
Copy Markdown

library/unwind/src/libunwind.rs has a cfg dispatch on
(target_arch, target_os) for unwinder_private_data_size. There's an
arm for wasm32-emscripten but none for wasm64-emscripten, so
building std for wasm64-unknown-emscripten (consumed as a tier-3
target via a custom JSON spec and -Z build-std) fails with
E0425: cannot find value 'unwinder_private_data_size' in this scope.

This PR adds the missing arm, mirroring the existing
wasm32-emscripten value of 20. The constant is a count of
_Unwind_Word fields in _Unwind_Exception, not a byte size, so the
same value is correct for both pointer widths — Emscripten's libunwind
is what determines how many private words the struct needs (~18 for
the libcxxabi __cxa_exception overlay, plus the standard Itanium
private_1 / private_2), and that count is target-uniform.

 #[cfg(all(target_arch = "wasm32", target_os = "emscripten"))]
 pub const unwinder_private_data_size: usize = 20;
+
+#[cfg(all(target_arch = "wasm64", target_os = "emscripten"))]
+pub const unwinder_private_data_size: usize = 20;

 #[cfg(all(target_arch = "wasm32", any(target_os = "linux", target_os = "wasi")))]
 pub const unwinder_private_data_size: usize = 2;

Context

wasm64-unknown-emscripten isn't an officially listed target, but it's
buildable today as a tier-3 target via a custom JSON spec mirroring
wasm32-unknown-emscripten with arch=wasm64,
target-pointer-width=64, and Emscripten's -sMEMORY64=1 in
post-link-args. The motivation is running LLM inference workloads
whose working set exceeds 4 GiB (model tensors + KV cache + compute)
in a browser via Emscripten, which is impossible on wasm32 regardless
of how the bytes are loaded.

Without this arm, std itself fails to build because the unwind
crate is foundational — any crate using String / Vec / etc.
transitively pulls in unwind. With it, the entire toolchain chain
(rustc → wasm-bindgen-cli → emcc post-link with -sMEMORY64=1 -fwasm-exceptions) links cleanly and the resulting wasm runs
real-world inference workloads end-to-end. Verified with Gemma 3 4B
(~3.5 GiB on-disk; ~5 GiB working set) on Node 22.

Test plan

No new tests needed — the change is a single const for an inactive
target. Existing CI continues to skip wasm64-emscripten (not in
src/tools/build-manifest / dist-various-2).

Manual verification: cargo +nightly build --target wasm64-unknown-emscripten.json -Z build-std=panic_abort,std -Zjson-target-spec succeeds for a minimal String-using crate
with this patch; fails with E0425 without it.

Prior art for similar arms

The cfg chain in this file already has dedicated arms for several
tier-3 / late-tier-2 targets — riscv32/riscv64, hexagon,
loongarch32/loongarch64, wasm32-wasi, wasm32-emscripten. This
PR follows the same pattern, adding only the missing
wasm64-emscripten line.

wasm64-unknown-emscripten is buildable as a tier-3 target via a custom
JSON spec, but library/unwind has no cfg arm for it in this chain, so
std builds fail with E0425 (unwinder_private_data_size unresolved).

Mirrors the wasm32-emscripten arm right above. unwinder_private_data_size
is a count of _Unwind_Word fields, not a byte size, so the value matches
between wasm32 and wasm64 — only pointer widths differ.
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 25, 2026
@rustbot

rustbot commented May 25, 2026

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
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:

  • Fallback group: @Mark-Simulacrum, @jieyouxu
  • @Mark-Simulacrum, @jieyouxu expanded to Mark-Simulacrum, jieyouxu

gergelyvagujhelyi added a commit to nobodywho-ooo/nobodywho that referenced this pull request May 25, 2026
Post-wasm64 audit caught three stale spots:

js/README.md "v1 limitations": the "Models >2 GiB on disk" item read
as a flat capability gap. Splits into two accurate items now:
  - >2 GiB on disk via modelBytes in Node: use Chat.create({modelPath})
    which streams chunks into MEMFS; browser is unaffected (modelUrl
    streams via fetch + Cache API).
  - >4 GiB total working set on wasm32: build the sibling wasm64
    artifact; ceiling lifts to 16 GiB. Links rust-lang/rust#156912
    for the unwind patch that's gating contributors today.

core/src/llm.rs get_model_from_path doc: parenthetical claimed the
wasm32 4 GiB ceiling "still applies" with no escape hatch. Updated to
point at the sibling wasm64 build script.

js/README.md cfg-shorthand: a stray `cfg(not(wasm32))` reference left
over from before the workspace-wide widening to
`cfg(not(target_family = "wasm"))`. Updated for consistency with the
code.

No functional changes.
gergelyvagujhelyi added a commit to nobodywho-ooo/nobodywho that referenced this pull request May 26, 2026
Remove references to the deleted build-pkg-emscripten-wasm64.sh
script and the rust-lang/rust#156912 PR link.
@Mark-Simulacrum Mark-Simulacrum added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-blocked Status: Blocked on something else such as an RFC or other implementation work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants