-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a
--reference-types
CLI flag (#2257)
This proposal is now shipping in browsers!
- Loading branch information
1 parent
b72678a
commit ebc1e92
Showing
5 changed files
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Support for Reference Types | ||
|
||
WebAssembly recently has gained support for a new value type called `externref`. | ||
Proposed in the [WebAssembly reference types | ||
repo](https://github.com/webassembly/reference-types) this feature of | ||
WebAssembly is hoped to enable more efficient communication between the host | ||
(JS) and the wasm module. This feature removes the need for much of the JS glue | ||
generated by `wasm-bindgen` because it can natively call APIs with JS values. | ||
|
||
For example, this Rust function: | ||
|
||
```rust | ||
#[wasm_bindgen] | ||
pub fn takes_js_value(a: &JsValue) { | ||
// ... | ||
} | ||
``` | ||
|
||
generates this JS glue *without* reference types support: | ||
|
||
```js | ||
const heap = new Array(32).fill(undefined); | ||
|
||
heap.push(undefined, null, true, false); | ||
|
||
let stack_pointer = 32; | ||
|
||
function addBorrowedObject(obj) { | ||
if (stack_pointer == 1) throw new Error('out of js stack'); | ||
heap[--stack_pointer] = obj; | ||
return stack_pointer; | ||
} | ||
|
||
export function takes_js_value(a) { | ||
try { | ||
wasm.takes_js_value(addBorrowedObject(a)); | ||
} finally { | ||
heap[stack_pointer++] = undefined; | ||
} | ||
} | ||
``` | ||
|
||
We can see here how under the hood the JS is managing a table of JS values which | ||
are passed to the wasm binary, so wasm actually only works in indices. If we | ||
pass the `--reference-types` flag to the CLI, however, the generated JS looks like: | ||
|
||
```js | ||
export function takes_js_value(a) { | ||
wasm.takes_js_value(a); | ||
} | ||
``` | ||
|
||
And that's it! The WebAssembly binary takes the JS value directly and manages it | ||
internally. | ||
|
||
Currently this feature is supported in Firefox 79+ and Chrome. Support in other | ||
browsers is likely coming soon! In Node.js this feature is behind the | ||
`--experimental-wasm-anyref` flag, although the support does not currently align | ||
with the upstream specification as of 14.6.0. |