cargo-web icon indicating copy to clipboard operation
cargo-web copied to clipboard

`unsupported custom section: '__wasm_bindgen_unstable'`

Open ForsakenHarmony opened this issue 7 years ago • 15 comments

Not sure if I have something configured wrong, but I get this error all the time

> cargo web build --release
    Finished release [optimized] target(s) in 0.23 secs
    Garbage collecting "yew_test.wasm"...
    Processing "yew_test.wasm"...
thread 'main' panicked at 'unsupported custom section: '__wasm_bindgen_unstable'', src\wasm_context.rs:646:25
note: Run with `RUST_BACKTRACE=1` for a backtrace.

ForsakenHarmony avatar Apr 21 '18 22:04 ForsakenHarmony

Can you post an example which reproduces this?

koute avatar Apr 22 '18 21:04 koute

Hi @koute, here's a minimal example: https://github.com/flodiebold/wasm_bindgen_cargo_web.

> $ cargo web build
warning: debug builds on the wasm32-unknown-unknown are currently totally broken
         forcing a release build
    Finished release [optimized] target(s) in 0.23 secs
    Garbage collecting "wasm_bindgen_cargo_web.wasm"...
    Processing "wasm_bindgen_cargo_web.wasm"...
thread 'main' panicked at 'unsupported custom section: '__wasm_bindgen_unstable'', src/wasm_context.rs:646:25
note: Run with `RUST_BACKTRACE=1` for a backtrace.
> $ cargo web -V
cargo-web 0.6.10

In general, any use of wasm_bindgen seems to produce this for me.

flodiebold avatar Apr 30 '18 20:04 flodiebold

Ah, right. wasm-bindgen won't work will cargo-web right now; I wouldn't be against making it work in the future though. (This would need some integration work as right now both wasm-bindgen and cargo-web generate their own .js shims under wasm32-unknown-unknown.)

koute avatar Apr 30 '18 22:04 koute

Supporting wasm-bindgen would be wonderful! It took me a while to debug the situation and realize this isn't supported . Maybe put a note to the readme?

oleid avatar Nov 16 '18 18:11 oleid

Hi @koute! Can we expect progress on this in the near future? ) I would love to see both cargo-web and wasm-bindgen in my project!

P.S. Now it fails not during the building process, but on opening the web page: Error loading Rust wasm module 'wasm_bindgen_cargo_web': TypeError: WebAssembly Instantiation: Import #0 module="__wbindgen_placeholder__" error: module is not an object or function

vladbat00 avatar Dec 27 '18 16:12 vladbat00

@mvlabat I still haven't fully thought out how to integrate those two, but it is on my TODO list.

There are a few ways we could go about here:

  • add wasm-bindgen support to cargo-web, with the implication that you'd use cargo-web instead of wasm-bindgen, but the result would be wasm-bindgen-like and compatible with the wasm-bindgen ecosystem
  • add support for JS shims to wasm-bindgen, which would make it mostly naturally compatible with stdweb so that you could only use wasm-bindgen tooling instead of cargo-web (Probably isn't going to happen? I could port the code from cargo-web as a wasm-bindgen PR, but I doubt it'd get accepted.)
  • add an extra subcommand to cargo-web which you would use alongside wasm-bindgen tooling (basically you'd postprocess your .wasm file with both wasm-bindgen and cargo-web)

If you have any thoughts regarding this I'd love to hear them.

koute avatar Dec 29 '18 22:12 koute

(Probably isn't going to happen? I could port the code from cargo-web as a wasm-bindgen PR, but I doubt it'd get accepted.)

I can't speak for @alexcrichton, but maybe a very stripped down and simplified version of the js! macro would be accepted?

Something that provides the absolute barest functionality, and stdweb can then build the js! macro on top of it.

Pauan avatar Dec 29 '18 23:12 Pauan

We definitely want to support a macro like js! in wasm-bindgen, but our preference would be to not move it into wasm-bindgen itself but rather build the tools in wasm-bindgen that would enable building such a macro in the ecosystem.

Along those lines it'd be great to see what the stripped down and simplified version looks like. If it requires features that still require some design on the wasm-bindgen side of things we could always add a small implementation and work around the difficulties on wasm-bindgen/wasm-pack to unblock this!

alexcrichton avatar Jan 02 '19 16:01 alexcrichton

@alexcrichton Let's me quickly describe the current implementation of the underlying mechanism through which my js! macro works and maybe you can tell me if it would be acceptable to (experimentally?) bring it to wasm-bindgen in a similar way?

The js_raw! procedural macro (the fully featured js! is built on top of this) takes a string with a snippet of JS code and a list of parameters, e.g.:

let value: i32 = 123;
js_raw!("console.log($0);", value);

and generates something like the following code: (not exactly, but that's not important)

{
    extern "C" {
        pub fn __cargo_web_snippet_$code_hash(arg: i32);
    }
    __cargo_web_snippet_$code_hash(value)
}

and generates a JSON file like this:

{
    "name": "__cargo_web_snippet_$code_hash",
    "code": "console.log($0);",
    "arg_count": 1
}

which is saved to: target/.cargo-web/snippets/XX/XXXXXXXX.json (where the Xes is the hash of the name of the import).

(I originally used custom sections, but that cannot work until https://github.com/rust-lang/rust/issues/56639 is fixed.)

Then cargo-web checks the imports of the .wasm file, cross-checks it with the snippets and generates the following import on the .js side:

"__cargo_web_snippet_$code_hash": function($0) {
    console.log($0);
}

So would something like this be acceptable as-is? If not what changes would have to be made?

One problem I can see here in bringing this as-is is that procedural macros don't know where the target directory is located (unless the user explicitly sets $CARGO_TARGET_DIR) - I'm actually working around the issue by exporting the path to target as an environment variable with cargo-web, but obviously with wasm-bindgen it would have to work standalone, so either rustc/cargo would have to always start telling the procedural plugins where the target is (e.g. by simply always setting $CARGO_TARGET_DIR), or the snippets would have to be written into a shared per-user directory. (Again, we can't put this in a custom section right now due to https://github.com/rust-lang/rust/issues/56639)

koute avatar Jan 02 '19 17:01 koute

it would have to work standalone, so either rustc/cargo would have to always start telling the procedural plugins where the target is (e.g. by simply always setting $CARGO_TARGET_DIR), or the snippets would have to be written into a shared per-user directory. (Again, we can't put this in a custom section right now due to rust-lang/rust#56639)

So my understanding is that the biggest issue right now is the lack of custom sections, and custom sections will basically solve all the problems?

If so, then pushing hard on 56639 sounds like a good idea. Maybe it can be fixed by #[inline(never)]? I'm not experienced at all with this low-level compiler stuff.

Pauan avatar Jan 02 '19 19:01 Pauan

As this is a procedural macro it seems pretty reasonable that wasm-bindgen would have enough support for this one day. For example I could imagine something like for the snippet above:

  1. The procedural macro generates fooXXXXX.js in the $OUT_DIR
  2. The procedural macro then generates:
#[wasm_bindgen(module = "/path/to/fooXXXXX.js")]
extern {
    fn the_function(a: i32);
}
unsafe {
    the_function(value)
}
  1. Eventually that gets all packaged up with wasm-bindgen and/or wasm-pack.

And I think that'd all end up working?

alexcrichton avatar Jan 03 '19 19:01 alexcrichton

And I think that'd all end up working?

Doesn't the #[wasm_bindgen] macro use custom sections? If so then so constructed js! macro will be broken due to https://github.com/rust-lang/rust/issues/56639.

koute avatar Jan 03 '19 19:01 koute

It does use custom sections, yes, but it employs a number of tricks to ensure that it doesn't hit that issue.

alexcrichton avatar Jan 03 '19 19:01 alexcrichton

So is there actually a way to always force a custom section to be emitted or something? When I tried to use custom sections for my js! macro I tried various things and none worked, so if it's actually possible I'd love to know.

koute avatar Jan 03 '19 19:01 koute

There sort of is, I explained a bit on the bug but this is just how linkers, object files, and the Rust compilation model works. The wasm-bindgen macro generates exported functions in the same object file as custom sections and the exported functions force the custom sections to be included. The exported functions are later removed by wasm-bindgen itself.

alexcrichton avatar Jan 03 '19 19:01 alexcrichton