Skip to content

Commit

Permalink
Add experimental support for the anyref type
Browse files Browse the repository at this point in the history
This commit adds experimental support to `wasm-bindgen` to emit and
leverage the `anyref` native wasm type. This native type is still in a
proposal status (the reference-types proposal). The intention of
`anyref` is to be able to directly hold JS values in wasm and pass the
to imported functions, namely to empower eventual host bindings (now
renamed WebIDL bindings) integration where we can skip JS shims
altogether for many imports.

This commit doesn't actually affect wasm-bindgen's behavior at all
as-is, but rather this support requires an opt-in env var to be
configured. Once the support is stable in browsers it's intended that
this will add a CLI switch for turning on this support, eventually
defaulting it to `true` in the far future.

The basic strategy here is to take the `stack` and `slab` globals in the
generated JS glue and move them into wasm using a table. This new table
in wasm is managed at the fringes via injected shims. At
`wasm-bindgen`-time the CLI will rewrite exports and imports with shims
that actually use `anyref` if needed, performing loads/stores inside the
wasm module instead of externally in the wasm module.

This should provide a boost over what we have today, but it's not a
fantastic strategy long term. We have a more grand vision for `anyref`
being a first-class type in the language, but that's on a much longer
horizon and this is currently thought to be the best we can do in terms
of integration in the near future.

The stack/heap JS tables are combined into one wasm table. The stack
starts at the end of the table and grows down with a stack pointer (also
injected). The heap starts at the end and grows up (state managed in
linear memory). The anyref transformation here will hook up various
intrinsics in wasm-bindgen to the runtime functionality if the anyref
supoprt is enabled.

The main tricky treatment here was applied to closures, where we need JS
to use a different function pointer than the one Rust gives it to use a
JS function pointer empowered with anyref. This works by switching up a
bit how descriptors work, embedding the shims to call inside descriptors
rather than communicated at runtime. This means that we're accessing
constant values in the generated JS and we can just update the constant
value accessed.
  • Loading branch information
alexcrichton committed Feb 20, 2019
1 parent 8f69578 commit 4181fb3
Show file tree
Hide file tree
Showing 14 changed files with 1,727 additions and 411 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ matrix:
- cargo test
# Run the main body of the test suite
- cargo test --target wasm32-unknown-unknown
# Make sure the anyref pass at least compiles even if it doesn't run
- NODE_ARGS=/dev/null WASM_BINDGEN_ANYREF=1 cargo test --target wasm32-unknown-unknown --test wasm
# Rerun the test suite but disable `--debug` in generated JS
- WASM_BINDGEN_NO_DEBUG=1 cargo test --target wasm32-unknown-unknown
# Make sure our serde tests work
Expand Down
16 changes: 16 additions & 0 deletions crates/anyref-xform/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "wasm-bindgen-anyref-xform"
version = "0.2.37"
authors = ["The wasm-bindgen Developers"]
license = "MIT/Apache-2.0"
repository = "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/anyref-xform"
homepage = "https://rustwasm.github.io/wasm-bindgen/"
documentation = "https://docs.rs/wasm-bindgen-anyref-xform"
description = """
Internal anyref transformations for wasm-bindgen
"""
edition = '2018'

[dependencies]
failure = "0.1"
walrus = "0.4"
Loading

0 comments on commit 4181fb3

Please sign in to comment.