Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for emitting a Wasm Interface Types section #1725

Merged
merged 1 commit into from
Aug 19, 2019

Conversation

alexcrichton
Copy link
Contributor

This commit adds support to wasm-bindgen to emit a WebAssembly module
that contains a WebAssembly Interface Types section. As of today there are no
native consumers of these WebAssembly modules, and the actual binary format
here is basically arbitrary (chosen by the wasm-webidl-bindings crate). The
intention is that we'll be following the WebAssembly Interface
Types proposal
very closely and update here as necessary.

The main feature added in this PR is that a new experimental environment
variable, WASM_INTERFACE_TYPES=1, is recognized by the wasm-bindgen
CLI tool. When present the CLI tool will act differently than it does
today:

  • The anyref feature will be implicitly enabled
  • A WebAssembly interface types section will be emitted in the
    WebAssembly module
  • For now, the WebAssembly module is strictly validated to require zero
    JS glue. This means that wasm-bindgen is producing a fully
    standalone WebAssembly module.

The last point here is one that will change before this functionality is
stabilized in wasm-bindgen. For now it reflects the major use case of
this feature which is to produce a standalone WebAssembly module with no
support JS glue, and to do that we need to verify properties like it's
not using JS global names, nonstandard binding expressions, etc. The
error messages here aren't the best but they at least fail compilation
at some point instead of silently producing weird wasm modules.

Eventually it's envisioned that a WebAssembly module will contain an
interface types section but also have JS glue so binding expressions
can be used when available but otherwise we'd still generate JS glue for
things like nonstandard expressions and accessing JS global values.

It should be noted that a major feature not implemented in
wasm-bindgen yet is the multi-value proposal for WebAssembly. This is
coming soon (as soon as we can) in walrus and later for a pass here,
but for now this means that returning multiple values (like a string
which has a pointer/length) is a bit of a hack. To enable this use case
a wasm-bindgen-specific-convention which will never be stabilized is
invented here by using binding expression to indicate "this return value
is actually returned through an out-ptr as the first argument list".
This is a gross hack and is guaranteed to be removed. Eventually we will
support multi-value and the wasm module emitted will simply use
multi-value and contain internal polyfills for Rust's ABI which returns
values through out-ptrs.

Overall this should make wasm-bindgen usable for playing around with
the WebIDL bindings proposal and helping us get a taste of what it looks
like to have entirely standalone WebAssembly modules running in multiple
environments, no extra fluff necessary!

This commit adds support to `wasm-bindgen` to emit a WebAssembly module
that contains a WebAssembly Interface Types section. As of today there are no
native consumers of these WebAssembly modules, and the actual binary format
here is basically arbitrary (chosen by the `wasm-webidl-bindings` crate). The
intention is that we'll be following the [WebAssembly Interface
Types proposal][proposal] very closely and update here as necessary.

The main feature added in this PR is that a new experimental environment
variable, `WASM_INTERFACE_TYPES=1`, is recognized by the `wasm-bindgen`
CLI tool. When present the CLI tool will act differently than it does
today:

* The `anyref` feature will be implicitly enabled
* A WebAssembly interface types section will be emitted in the
  WebAssembly module
* For now, the WebAssembly module is strictly validated to require zero
  JS glue. This means that `wasm-bindgen` is producing a fully
  standalone WebAssembly module.

The last point here is one that will change before this functionality is
stabilized in `wasm-bindgen`. For now it reflects the major use case of
this feature which is to produce a standalone WebAssembly module with no
support JS glue, and to do that we need to verify properties like it's
not using JS global names, nonstandard binding expressions, etc. The
error messages here aren't the best but they at least fail compilation
at some point instead of silently producing weird wasm modules.

Eventually it's envisioned that a WebAssembly module will contain an
interface types section but *also* have JS glue so binding expressions
can be used when available but otherwise we'd still generate JS glue for
things like nonstandard expressions and accessing JS global values.

It should be noted that a major feature not implemented in
`wasm-bindgen` yet is the multi-value proposal for WebAssembly. This is
coming soon (as soon as we can) in `walrus` and later for a pass here,
but for now this means that returning multiple values (like a string
which has a pointer/length) is a bit of a hack. To enable this use case
a `wasm-bindgen`-specific-convention which will never be stabilized is
invented here by using binding expression to indicate "this return value
is actually returned through an out-ptr as the first argument list".
This is a gross hack and is guaranteed to be removed. Eventually we will
support multi-value and the wasm module emitted will simply use
multi-value and contain internal polyfills for Rust's ABI which returns
values through out-ptrs.

Overall this should make `wasm-bindgen` usable for playing around with
the WebIDL bindings proposal and helping us get a taste of what it looks
like to have entirely standalone WebAssembly modules running in multiple
environments, no extra fluff necessary!

[proposal]: https://github.com/webassembly/webidl-bindings
@alexcrichton
Copy link
Contributor Author

There's a few things worth noting here as well:

  • "Wasm Interface Types" is the most likely renaming of the current "WebIDL Bindings" proposal
  • I've been working with @fitzgen with this for some time now, so I'm gonna go ahead and merge this when CI is green
  • Naturally this is all extremely experimental, but it's good to start playing with to help the wasm proposal make progress!

@alexcrichton alexcrichton merged commit 487289c into rustwasm:master Aug 19, 2019
@alexcrichton alexcrichton deleted the real-webidl-section branch August 19, 2019 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant