Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with using cargo-wasi in conjunction with wasm-bindgen #110

Closed
nwoods-cimpress opened this issue Oct 18, 2021 · 9 comments
Closed

Comments

@nwoods-cimpress
Copy link

I'm having problems using cargo-wasi in conjunction with with wasm-bindgen. Specifically, cargo-wasi seems to force WebAssembly interface types to be enabled, and if there is a technique to turn it off, I can't seem to find it.

This seems to happen with a completely fresh project. Steps to reproduce:

  1. cargo new uses-wasm-bindgen --lib
  2. Add wasm-bindgen = "0.2.78" to the [dependencies] section of Cargo.toml
  3. Add wasm-bindgen-test = "0.3.13" to the [dev-dependencies] section of Cargo.toml
  4. cargo wasi test --release

Running this gives me the following message:

Error: failed to run main module C:\dev\uses-wasm-bindgen\target\wasm32-wasi\release\deps\uses_wasm_bindgen-40c17809ffa9b77b.wasm

Caused by:
0: failed to parse WebAssembly module
1: Unsupported feature: Support for interface types has temporarily been removed from wasmtime.

   For more information about this temoprary you can read on the issue online:

       https://github.com/bytecodealliance/wasmtime/issues/1271

   and for re-adding support for interface types you can see this issue:

       https://github.com/bytecodealliance/wasmtime/issues/677

Curiously wasm-pack test --node works just fine (though it reports no tests to run in this trivial case)

I want to make some use of wasm-bindgen to generate bindings so that I can invoke Rust methods from JavaScript, but cargo-wasi seems to force on a capability (interface types) not supported by wasm-bindgen. I'm very new to WebAssembly, so I could be making a simple mistake.

@nwoods-cimpress
Copy link
Author

I tried downloading the cargo-wasi source, and tried cargo wasi test in examples/markdown and got a different error

     Running unittests (C:\dev\cargo-wasi\target\wasm32-wasi\debug\deps\markdown-f5c64e63cb7747b9.wasm)
thread 'main' panicked at 'unknown instruction LocalTee(LocalTee { local: Id { idx: 75044 } })', crates\wasm-interpreter\src\lib.rs:363:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: failed to process wasm at `C:\dev\cargo-wasi\target\wasm32-wasi\debug\deps\markdown-f5c64e63cb7747b9.rustc.wasm`

Caused by:
    failed to execute "C:\\Users\\NathanielWoods\\AppData\\Local\\cargo-wasi\\0.1.23\\wasm-bindgen\\0.2.78\\wasm-bindgen.exe" "C:\\dev\\cargo-wasi\\target\\wasm32-wasi\\debug\\deps\\markdown-f5c64e63cb7747b9.rustc.wasm" "--keep-debug" "--out-dir" "C:\\dev\\cargo-wasi\\target\\wasm32-wasi\\debug\\deps\\.tmpvI5W3K" "--out-name" "foo"
        status: exit code: 101

@alexcrichton
Copy link
Member

Thanks for the report but this is expected. The wasm-bindgen support here is quite dated and intended for a feature that never got across the finish line, so if you'd like a tool to manage wasm-bindgen it's recommended to use wasm-pack instead (or run wasm-bindgen manually)

@nwoods-cimpress
Copy link
Author

Thank you for the info!

Should my takeaway from your message be that invoking wasm-bindgen manually is in fact a viable course of action, and that there is nothing fundamental about the rustc wasm32-wasi target that wasm-bindgen cannot handle?

When you reference "a feature that never got across the finish line", precisely what are you referring to? A feature of some part of the WASI ecosystem (cargo-wasi? WASI itself?) or something else?

I'm still learning the whole WebAssembly ecosystem, so thank you and please forgive me for what are certainly newbie questions!

@alexcrichton
Copy link
Member

Oh sorry yeah to expand more, the wasm32-wasi target is unlikely to work with wasm-bindgen. There's not a lot of fundamental issues it's just mostly that things aren't wired up. When using wasm-bindgen it's recommended to use wasm32-unknown-unknown.

For the feature I was referring to it was interface types in wasm-bindgen itself. That work stalled out quite some time ago and isn't intended to really be used any more at this point.

@nwoods-cimpress
Copy link
Author

In my case my entire motivation for using wasm32-wasi has been the need to statically link with existing C/C++ code that have dependencies on the standard C/C++ libraries. None of these libraries was intended to be exposed to wasm-bindgen directly; the code between C/C++ and JS was intended to be 100% Rust.

Correct me if I am wrong, but I don't get the standard C/C++ libraries (even malloc) if I target wasm32-unknown-unknown.

Again I'm new to the ecosystem, but I'd be somewhat surprised if I was the only person trying to do this. Thanks!

@alexcrichton
Copy link
Member

For C/C++ on the web it currently works best with Emscripten. While it's theoretically possible to get it working with wasm32-unknown-unknown you'll end up doing a good deal of the work yourself and there's no toolchain readily available. The Rust Emscripten targets I think are somewhat in a state of disrepair and they may or may not work, IIRC they haven't received maintenance in awhile and may not work. It's worth pointing out that with wasm-bindgen it's not really compatible with either WASI or Emscripten, so unfortunately effectively wasm-bindgen can't really be used with C/C++, or at least not easily.

@nwoods-cimpress
Copy link
Author

So I have one last question, and at this point this is to assuage my intellectual curiosity:

Why would a difference between the wasm32-unknown-unknown and wasm32-wasi targets manifest themselves as a failure to process the WebAssembler LocalTee instruction? I don't know much about WebAssembler opcodes, but LocalTee appears to a WebAssembler opcode, and I would expect the opcodes emitted for all WebAssembler targets to be roughly the same, even if things like calling conventions etc are different.

This feels equivalent to the clang x64 backend handling SSE differently for the Linux and Windows platforms.

In any case, thank you so much for your help!

@alexcrichton
Copy link
Member

IIRC that was a bug in wasm-bindgen a few months ago which has since been fixed. That's not a difference between the targets but rather most likely a difference between LLVM versions used when wasm-bindgen was written vs what you're using now.

@teohhanhui
Copy link

Would it make sense to provide a way to disable using wasm-bindgen processing even when the wasm-bindgen crate is found in the dependencies?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants