Help us make `wasm-bindgen` support more targets

EDIT: It turned out that wasm-bindgen can support wasm32-wasi on the web with browser shims. This idea might be redundant.

Currently, wasm-bindgen doesn't support wasm32-wasi target.

wasm-bindgen needs a consistent C ABI between wasm32-unknown-unknown and wasm32-wasi to support wasm32-wasi. However, wasm32-unknown-unknown is using legacy ABI right now, and this has to be replaced with a standard-ish ABI that matches clang and wasm32-wasi.

As discussed in #88947, wasm Rust has serious ABI incompatibility issues right now. To make wasm32-unknown-unknown adopt the standard-ish ABI, we have to come up with a simultaneous strategy that makes the change in both Rust and wasm-bindgen repositories, because Rust's wasm32-unknown-unknown and wasm-bindgen are tightly interconneted.

The initial effort started more than 3 years ago, but Rust's wasm32-unknown-unknown is still using the legacy ABI(which the original author wrote that he/she expects the code to be replace in the near future). wasm-bindgen says that Rust should switch to the new ABI first, but Rust is saying that wasm-bindgen should support the new ABI first. It's somewhat like a chicken-egg problem.

Up until now, this legacy ABI was working fine. However recently wasm32-wasi started becoming a thing and the Rust ecosystem is actively being built around it. That's why I and some other contributors came up to extend wasm-bindgen and suggest this ABI change of wasm32-unknown-unknown. Most of the users will just need to update wasm-bindgen and re-generate the code. Appropriate warning and version-specific workaround should be provided from Rust compiler, though.

The best strategy seems to be(at least for me and some GitHub contributors) accepting breaking changes and notifying the users in a proper way. I suggest that wasm-bindgen go on from 0.2.x to 0.3.0 that adopts unified Rust ABI for both wasm32-unknown-unknown and wasm32-wasi. In this scenario, the new Rust(Possibly 1.75) can warn users using wasm-bindgen 0.2.x to upgrade, as warning about a specific crate's version is possible from the Rust side.

To narrow the focus on web browsers, many native functionalities including std::thread, std::time::Instant, std::fs are not working right now with wasm32-unknown-unknown. Consequently, fragmentation arises as many crates now ship with separated wasm and non-wasm versions, simply because they can't use std properly.

If wasm-bindgen gets to support wasm32-wasi, various crates will be able to use thread, time, file, network operations on the web only with std without any custom JavaScript glue, just like they do on native platforms. JavaScript polyfill libraries(such as wasmer-js, browser_wasi_shim) claims that they can handle that WASI syscalls, utilizing existing web APIs to mimic native functionalities.

I hope we can reach a certain consensus first, because supporting wasm32-wasi cannot be done without cooperation between Rust and wasm-bindgen. Please support this progress by leaving your opinions and thoughts so that we can effectively make the transition. Thank you :slight_smile:

Top-level issues:

Pull requests:

Other links:

3 Likes

Maybe it's time to start deprecating wasm32-unknown-unknown and creating a replacement target, if needed? It seems like there's going to be a lot breaking and churn in trying to make -unknown-unknown play nice with newer targets.

Yeah, it should really be wasm32-unknown-web or wasm32-unknown-browser if you are targeting the browser or a NodeJS environment.

The -unknown triple is pretty much perfect for if you are targeting something custom (e.g. you set up the runtime with custom imports), but it is now going to be forever tainted by packages that think it is synonymous with the web and unconditionally pull in wasm-bindgen.

3 Likes