`unsupported custom section: '__wasm_bindgen_unstable'`
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.
Can you post an example which reproduces this?
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.
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.)
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?
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
@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-bindgensupport tocargo-web, with the implication that you'd usecargo-webinstead ofwasm-bindgen, but the result would bewasm-bindgen-like and compatible with thewasm-bindgenecosystem - add support for JS shims to
wasm-bindgen, which would make it mostly naturally compatible withstdwebso that you could only usewasm-bindgentooling instead ofcargo-web(Probably isn't going to happen? I could port the code fromcargo-webas awasm-bindgenPR, but I doubt it'd get accepted.) - add an extra subcommand to
cargo-webwhich you would use alongsidewasm-bindgentooling (basically you'd postprocess your.wasmfile with bothwasm-bindgenandcargo-web)
If you have any thoughts regarding this I'd love to hear them.
(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.
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 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)
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.
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:
- The procedural macro generates
fooXXXXX.jsin the$OUT_DIR - The procedural macro then generates:
#[wasm_bindgen(module = "/path/to/fooXXXXX.js")]
extern {
fn the_function(a: i32);
}
unsafe {
the_function(value)
}
- Eventually that gets all packaged up with wasm-bindgen and/or wasm-pack.
And I think that'd all end up working?
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.
It does use custom sections, yes, but it employs a number of tricks to ensure that it doesn't hit that issue.
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.
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.