2018-02-06 11:44:28 -08:00
|
|
|
# Design of `wasm-bindgen`
|
|
|
|
|
2018-07-02 16:11:21 -07:00
|
|
|
This section is intended to be a deep-dive into how `wasm-bindgen` internally
|
|
|
|
works today, specifically for Rust. If you're reading this far in the future it
|
|
|
|
may no longer be up to date, but feel free to open an issue and we can try to
|
|
|
|
answer questions and/or update this!
|
2018-02-06 11:44:28 -08:00
|
|
|
|
|
|
|
## Foundation: ES Modules
|
|
|
|
|
|
|
|
The first thing to know about `wasm-bindgen` is that it's fundamentally built on
|
|
|
|
the idea of ES Modules. In other words this tool takes an opinionated stance
|
2018-07-02 16:11:21 -07:00
|
|
|
that wasm files *should be viewed as ES modules*. This means that you can
|
2018-02-06 11:44:28 -08:00
|
|
|
`import` from a wasm file, use its `export`-ed functionality, etc, from normal
|
|
|
|
JS files.
|
|
|
|
|
|
|
|
Now unfortunately at the time of this writing the interface of wasm interop
|
|
|
|
isn't very rich. Wasm modules can only call functions or export functions that
|
2018-02-06 14:46:50 -06:00
|
|
|
deal exclusively with `i32`, `i64`, `f32`, and `f64`. Bummer!
|
2018-02-06 11:44:28 -08:00
|
|
|
|
|
|
|
That's where this project comes in. The goal of `wasm-bindgen` is to enhance the
|
|
|
|
"ABI" of wasm modules with richer types like classes, JS objects, Rust structs,
|
|
|
|
strings, etc. Keep in mind, though, that everything is based on ES Modules! This
|
|
|
|
means that the compiler is actually producing a "broken" wasm file of sorts. The
|
|
|
|
wasm file emitted by rustc, for example, does not have the interface we would
|
|
|
|
like to have. Instead it requires the `wasm-bindgen` tool to postprocess the
|
2018-03-05 22:25:14 +01:00
|
|
|
file, generating a `foo.js` and `foo_bg.wasm` file. The `foo.js` file is the
|
2018-02-06 11:44:28 -08:00
|
|
|
desired interface expressed in JS (classes, types, strings, etc) and the
|
2018-03-05 22:25:14 +01:00
|
|
|
`foo_bg.wasm` module is simply used as an implementation detail (it was
|
2018-02-06 11:44:28 -08:00
|
|
|
lightly modified from the original `foo.wasm` file).
|
|
|
|
|
2018-07-02 16:11:21 -07:00
|
|
|
As more features are stabilized in WebAssembly over time (like host bindings)
|
|
|
|
the JS file is expected to get smaller and smaller. It's unlikely to ever
|
|
|
|
disappear, but `wasm-bindgen` is designed to follow the WebAssembly spec and
|
|
|
|
proposals closely to optimize JS/Rust as much as possible.
|
|
|
|
|
2018-02-07 16:41:33 -08:00
|
|
|
## Foundation #2: Unintrusive in Rust
|
|
|
|
|
|
|
|
On the more Rust-y side of things the `wasm-bindgen` crate is designed to
|
|
|
|
ideally have as minimal impact on a Rust crate as possible. Ideally a few
|
|
|
|
`#[wasm_bindgen]` attributes are annotated in key locations and otherwise you're
|
2018-07-02 16:11:21 -07:00
|
|
|
off to the races. The attribute strives to both not invent new syntax and work
|
|
|
|
with existing idioms today.
|
2018-02-07 16:41:33 -08:00
|
|
|
|
2018-07-02 16:11:21 -07:00
|
|
|
For example a library might exposed a function in normal Rust that looks like:
|
2018-02-07 16:41:33 -08:00
|
|
|
|
|
|
|
```rust
|
2018-07-02 16:11:21 -07:00
|
|
|
pub fn greet(name: &str) -> String {
|
2018-02-07 16:41:33 -08:00
|
|
|
// ...
|
|
|
|
}
|
2018-07-02 16:11:21 -07:00
|
|
|
```
|
2018-02-07 16:41:33 -08:00
|
|
|
|
2018-07-02 16:11:21 -07:00
|
|
|
And with `#[wasm_bindgen]` all you need to do in exporting it to JS is:
|
2018-02-07 16:41:33 -08:00
|
|
|
|
2018-07-02 16:11:21 -07:00
|
|
|
```rust
|
2018-02-07 16:41:33 -08:00
|
|
|
#[wasm_bindgen]
|
2018-07-02 16:11:21 -07:00
|
|
|
pub fn greet(name: &str) -> String {
|
2018-02-07 16:41:33 -08:00
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Additionally the design here with minimal intervention in Rust should allow us
|
|
|
|
to easily take advantage of the upcoming [host bindings][host] proposal. Ideally
|
2018-02-08 14:09:36 -05:00
|
|
|
you'd simply upgrade `wasm-bindgen`-the-crate as well as your toolchain and
|
|
|
|
you're immediately getting raw access to host bindings! (this is still a bit of
|
|
|
|
a ways off though...)
|
2018-02-07 16:41:33 -08:00
|
|
|
|
|
|
|
[host]: https://github.com/WebAssembly/host-bindings
|