What does HackerNews think of wasm-bindgen?

Facilitating high-level interactions between Wasm modules and JavaScript

Language: Rust

#42 in JavaScript
#46 in Rust
I've never tried it, but apparently some bindings exist, e.g. https://github.com/rustwasm/wasm-bindgen

So you can either try manipulating the DOM w/ some bindings or draw to canvas.

> types other than int

Floating point values are also supported.

> for example strings and what not without the hacks of passing string lengths and addresses?

That's not so much a "hack" per se, so much as it is fundamentally how string types are represented when broken down into their basic components. ARM, x64, etc. interact with strings in similar ways. Tools like wasm-bindgen[1] generate JS wrappers around the raw WASM calls, which wrap the address+length APIs in string accepting ones. For non-JS hosts, you might have to roll your own boilerplate or boilerplate generators, but that's straightforward.

> sharing of data. That is can I declare a struct of some sort in the main program, pass that to the webassembly script, operate on it, and return it? Last I looked at that the only thing I could come up with was passing it back and forth as a (pick your format here) json string.

Multiple WASM instances can share a single memory instance without copying data. A non-wasm host will typically copy/serialize data into/out-of WASM memory for simplicitly/convenience/durability, but there are APIs[2][3] that let you directly manipulate WASM memory - and there's nothing stopping you from generating identical structures on both ends and directly using them without copying.

[1]: https://github.com/rustwasm/wasm-bindgen

[2]: https://docs.rs/wasmer/latest/wasmer/struct.Memory.html#meth...

[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

> Accessiblity will not work as emscripten does not have access to the DOM at this time.

Rust has had this figured out for a while. You build a few helper methods in Javascript and call them from WASM.[0]

WASM has access to Javascript, so it has access to everything in the browser; that's already how Qt is getting the mouse position and intercepting keyboard events. Spitting pixels onto a canvas is an architecture decision, not a language restriction -- it's possible to build accessible WASM apps.

> Seems responsive to me, tab works fine and dandy, text is selectable, right click works fine as well. I dunno what you are complaining about.

From a quick test in Chromium:

- Right click won't work on mobile (long presses should trigger a right-click).

- Clicking on the main document to enter edit mode is broken via touch controls. You literally can't enter edit mode at all.

- Tab support is poorly implemented. On the web, when we talk about tab support, what we mean is that you should be able to use the entire interface from the keyboard. Here if you open a menu you'll immediately get stuck in an infinite loop. This is something you'd get for free if the menu was rendered with a

    element.

    - Scrolling is inverted from my browser settings.

    - Middle-click scrolling doesn't work at all.

    - Searching for text doesn't work at all.

    - On mobile interfaces or when looking at the app in responsive design mode, the entire interface gets scaled by a fixed percentage. This is particularly interesting, because that had to be a conscious choice. Container sizing just works on the web, I would need to think about how to break something like that.

    - I don't know if the intention was to support all of the keyboard shortcuts the app lists (ctrl-f/command-f), but a lot of them don't work. I'm impressed that command-z gets correctly interpreted as undo. I guess the app must just check the user string to determine what OS I'm working on. I'm curious whether that'll also work on less common operating systems.

    - Accessibility is obviously nonexistent, but the position of multiple Qt developers I've talked to is that this is apparently the browser's fault, not theirs. Still worth bringing up though, none of these apps are ever going to be compliant with A11y standards.

    I'm leaving out any of the bugs I'm noticing with collision detection or resize performance, and just pointing out the issues that would be immediately fixed, for free, by rendering to HTML.

    Also as a quick sidenote, stuff like broken scrolling isn't an "issue" in quotation marks. It's just a bug. I don't think you can chock something up like "my mouse scroll wheel should work" to a user preference. In the same way, you can blame accessibility problems on whoever you'd like, but a text editor that's impossible for a blind person to use is a real issue.

    [0]: https://github.com/rustwasm/wasm-bindgen

> Writing C++ defensively (i.e. Do what the guidelines tell you, Preach Andrei and Bjarne etc), and using sanitizers cleans up a huge amount of C++ code.

Well sure, but the joy of Rust is that I don't have to worry about any of that. I can write my code naively, and the compiler will throw an error if I do anything stupid.

> This is still not conclusive, as the runtimes will probably have to be significantly modified (at the ABI/System level, so around the edges) given that they will have to get memory from the browser etc. This leaves much room for WASM specific optimisation

Certainly if/when this happens, other languages will be a lot viable in the compile-to-wasm. But you can run Rust (and C/C++) in the WASM runtime without issues today. And Rust even has a number of high-level libraries which provide binding to JavaScript APIs (e.g. https://github.com/rustwasm/wasm-bindgen)

Miiiiinor point/caveat here but jotting it down just for others that might be less familiar!

Today WebGL is commonly referred to as a JS API because pretty much every WebGL app is written using JS.

But, even though that MDN link quite literally says "JavaScript API", it turns out that WebGL is entirely specified in WebIDL and isn't coupled to JS.

Because of this, `wasm-bindgen` [1] is able to auto-generate all of the WebGL bindings [2] that I used for this demo.

Today `wasm-bindgen` automatically generates some JS shims because that's the only way to call the WebGL APIs at this time, but once anyref and host bindings land you'll be able to interface with the WebGL APIs directly without going through JS.

`wasm-bindgen` already plans to just replace those JS shims with direct host bindings.

But yup - totally agree with your points here - just sharing this minor detail that will be more relevant in the future!

[1] - https://github.com/rustwasm/wasm-bindgen

[2] - https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.W...

Check out Rust’s wasm-bindgen - https://github.com/rustwasm/wasm-bindgen if ya haven’t already.

Right now it you call into JS to interact with the DOM but when the host bindings proposal sees fruit it’ll replace the JS shims with direct DOM manipulation!

Yes. For a while, you've been able to embed JavaScript wrappers using stdweb (https://github.com/koute/stdweb). There are pre-built libraries covering much of the DOM. But you may need to submit PRs if you get heavily into or something else with non-standard APIs.

The shiny new toy is wasm-bindgen (https://github.com/rustwasm/wasm-bindgen), which will soon allow the use of WebIDL (https://heycam.github.io/webidl/) to wrap the entire browser API, if I understand correctly.

In practice, it all seems to work pretty well. But for public-facing sites, you need to watch the number of dependencies you include and keep the *.wasm size down.

WebAssembly is actually simple to work with.

If you want to obtain a "C" pseudocode, you can give a wasm file to wasm2c [1].

You can re-obtain a WebAssembly folded-expression text format using wasm2wat [1].

You can obtain a call-graph from a WebAssembly module by generating the wat representation using wasm2wat and pasting it into main.wat on https://webassembly.studio/ (-> Empty Wat Project). Then save and build; right click the new main.wasm and select "Generate Call Graph."

That said, check out this encrypted and anonymous "pastebin" I built [2] with the crypto being written in Rust and bindings generated using wasm-bindgen [3]. It surprisingly hard to debug when optimized using wasm-opt [4].

[1] Part of WebAssembly Binary Toolkit: https://github.com/WebAssembly/wabt

[2] Source code on Github: https://github.com/psychonautwiki/impis/blob/master/core/src... — Demo paste: https://imp.is/n/7NFsfEiCjkFBVgC6A4JS6GyqN7puN5Sg7ed11m8VrtT...

[3] https://github.com/rustwasm/wasm-bindgen

[4] Part of Binaryen: https://github.com/WebAssembly/binaryen

In my understanding, part of why they don't have that in Rust yet is the lack of Cargo support; you'd want to use https://github.com/rustwasm/wasm-bindgen (and its README.md has said hello example in it) but there's no easy way to use it just yet. It's coming though.