rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.75k stars 1.07k forks source link

Hello World! example breaks with Rust 1.82.0 #4211

Open ctm opened 3 days ago

ctm commented 3 days ago

Describe the Bug

The Hello World! example fails to run or even compile with Rust 1.82.0, presumably due to reference types. That example uses webpack with a configuration that will invoke @webassemblyjs/wasm-parser which doesn't support reference types. This other bug report has a backtrace that is similar to what happens now.

Steps to Reproduce (when using Rust 1.82.0)

  1. cd examples/hello_world
  2. install the needed node packages (I used yarn install, I'm sure npm has something similar, possibly npm install)
  3. Try to build (e.g. npm run build or yarn build)
  4. See backtrace

Everything you need is in this repository other than installing the npm modules.

Expected Behavior

[main]% rustup default 1.81.0
rustup default 1.81.0
info: using existing install for '1.81.0-x86_64-apple-darwin'
info: default toolchain set to '1.81.0-x86_64-apple-darwin'

  1.81.0-x86_64-apple-darwin unchanged - rustc 1.81.0 (eeb90cda1 2024-09-04)

[main]% npm run build
npm run build

> build
> webpack

🧐  Checking for wasm-pack...

βœ…  wasm-pack is installed at /Users/ctm/.cargo/bin/wasm-pack. 

ℹ️  Compiling your crate in development mode...

[INFO]: 🎯  Checking for the Wasm target...
[INFO]: πŸŒ€  Compiling to Wasm...
   Compiling hello_world v0.0.0 (/Users/ctm/git_others/wasm-bindgen/examples/hello_world)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: ✨   Done in 0.87s
[INFO]: πŸ“¦   Your wasm pkg is ready to publish at /Users/ctm/git_others/wasm-bindgen/examples/hello_world/pkg.
βœ…  Your crate has been correctly compiled

assets by status 54 KiB [cached] 1 asset
asset index.js 16.3 KiB [emitted] (name: main)
asset index.html 232 bytes [compared for emit]
runtime modules 4.87 KiB 7 modules
cacheable modules 3.61 KiB (javascript) 54 KiB (webassembly)
  modules by path ./pkg/*.js 3.5 KiB
    ./pkg/index.js 141 bytes [built] [code generated]
    ./pkg/index_bg.js 3.36 KiB [built] [code generated]
  ./index.js 48 bytes [built] [code generated]
  ./pkg/index_bg.wasm 70 bytes (javascript) 54 KiB (webassembly) [built] [code generated]
webpack 5.95.0 compiled successfully in 1640 ms

Actual Behavior

[main]% rustup default stable
rustup default stable
info: using existing install for 'stable-x86_64-apple-darwin'
info: default toolchain set to 'stable-x86_64-apple-darwin'

  stable-x86_64-apple-darwin unchanged - rustc 1.82.0 (f6e511eec 2024-10-15)

[main]% npm run build
npm run build

> build
> webpack

🧐  Checking for wasm-pack...

βœ…  wasm-pack is installed at /Users/ctm/.cargo/bin/wasm-pack. 

ℹ️  Compiling your crate in development mode...

[INFO]: 🎯  Checking for the Wasm target...
[INFO]: πŸŒ€  Compiling to Wasm...
   Compiling hello_world v0.0.0 (/Users/ctm/git_others/wasm-bindgen/examples/hello_world)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.37s
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: ✨   Done in 0.80s
[INFO]: πŸ“¦   Your wasm pkg is ready to publish at /Users/ctm/git_others/wasm-bindgen/examples/hello_world/pkg.
βœ…  Your crate has been correctly compiled

assets by status 1.58 KiB [cached] 1 asset
asset index.js 13.2 KiB [emitted] (name: main)
asset index.html 232 bytes [compared for emit]
runtime modules 1.77 KiB 4 modules
cacheable modules 3.91 KiB (javascript) 56.1 KiB (webassembly)
  modules by path ./pkg/*.js 3.82 KiB
    ./pkg/index.js 167 bytes [built] [code generated]
    ./pkg/index_bg.js 3.66 KiB [built] [code generated]
  ./index.js 48 bytes [built] [code generated]
  ./pkg/index_bg.wasm 40 bytes (javascript) 56.1 KiB (webassembly) [built] [code generated] [1 error]

ERROR in ./pkg/index_bg.wasm
Module parse failed: Unknown element type in table: 0xNaN
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Error: Unknown element type in table: 0xNaN
    at parseTableType (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/@webassemblyjs/wasm-parser/lib/decoder.js:1018:13)
    at parseTableSection (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/@webassemblyjs/wasm-parser/lib/decoder.js:1274:24)
    at parseSection (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/@webassemblyjs/wasm-parser/lib/decoder.js:1406:24)
    at Object.decode (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/@webassemblyjs/wasm-parser/lib/decoder.js:1740:25)
    at decode (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/@webassemblyjs/wasm-parser/lib/index.js:253:21)
    at WebAssemblyParser.parse (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyParser.js:61:19)
    at /Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/webpack/lib/NormalModule.js:1303:19
    at processResult (/Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/webpack/lib/NormalModule.js:937:11)
    at /Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/webpack/lib/NormalModule.js:1030:5
    at /Users/ctm/git_others/wasm-bindgen/examples/hello_world/node_modules/loader-runner/lib/LoaderRunner.js:407:3
 @ ./pkg/index.js 1:0-40 4:15-19 5:0-21
 @ ./index.js 1:0-30 3:0-5

webpack 5.95.0 compiled with 1 error in 1532 ms

Additional Context

I believe this can be fixed by disabling the reference-types feature for wasm32-unknown-unknown, however even after reading the Enabled WebAssembly Features section of the rustc book (and trying various things), I have not been successful at disabling that feature.

widavies commented 3 days ago

I second this, cannot get this working on latest versions

Rust: 1.82 Webpack: 5.95.0 wasm-bindgen: 0.2.95

Trying to add a wasm rule in my Webpack config just leads to different errors:

  module: {
    rules: [
      {
        test: /\.wasm$/,
        type: "asset/resource"
      }
    ]
  },
ERROR in ../pkg/index.js 5:0-21
Can't import the named export '__wbindgen_start' (imported as 'wasm') from default-exporting module (only default export is available)
 @ ./index.js 1:0-43 4:17-29
 @ ./bootstrap.js 4:0-20
ctm commented 2 days ago

Upon further reading and experimenting, I suspect that for now it will simply impossible to use 1.82.0 with anything that uses wasm-pack, because disabling reference-types requires unstable features and 1.82.0 itself is stable. If so, this demo won't be able to use a stable 1.82 or later rust release until they either make it so that reference-types is not enabled by default or provide a stable way (that works through the wasm-pack stack) to disable that default.

nickbabcock commented 2 days ago

Similarly, Rust 1.82 and Node 18 don't play well together when running wasm-bindgen-test, as node will crash with a bit of a nasty stacktrace.

CryZe commented 2 days ago

So there's multiple things at play here. LLVM activated the reference-types feature by default, which got pulled into Rust 1.82. The reference-types feature generally affects almost nothing in how LLVM generates code, except it now supports some extended table index encoding.

The problem is that wasm-bindgen looks at the features section of the module and assumes that you want FULL reference-types support. It does so here:

https://github.com/rustwasm/wasm-bindgen/blob/76776ef54cce17f1c7442b010e26d7eadaea3cd0/crates/cli-support/src/lib.rs#L326-L330

Usually you are meant to use the wasm-bindgen CLI flag --reference-types to achieve the same effect. But this automatic detection above activates it anyway now.

This by itself isn't really a problem, but webpack, or rather its webassemblyjs dependency is mostly unmaintained and does not currently support the reference-types proposal.

@daxpedda I propose that wasm-bindgen for the time being should be patched to not automatically turn on the externref support if it detects it from the features section. I can do that PR if you think this is the right course of action.