wasm-bindgen
wasm-bindgen copied to clipboard
Documentation: The "Supported types: number slices" page is confusing
The documentation about passing number slices between JS and rust is a bit confusing to me, because it doesn't make clear whether there are any copies happening when passing such data, and if they happen, when.
The "Javascript Representation" column currently says:
A JavaScript
TypedArrayview of the Wasm memory for the boxed slice of the appropriate type (Int32Array,Uint8Array, etc)
First, there is no boxed slice here, this page is about slice references. Second, "view of the Wasm memory" makes it sound like JavaScript has direct access to the wasm module's memory buffer, which is also not the case. Everything is copied.
I recommend changing the "JavaScript Representation" column to just the following:
A JavaScript
TypedArrayof the appropriate type (Int32Array,Uint8Array, etc)
And then adding the following note about copies underneath:
The contents of the JavaScript
TypedArrayget copied into wasm memory when the function is called. For arrays which are passed to a&mut Tparameter, there is an additional copy: The modified values are copied back out into the JavaScriptTypedArrayat the end of the function call, so that any mutations are reflected on the JS side.
Thanks again for the sharp eye! This is unfortunately nuanced though and doesn't have an easily documentable answer. As incoming arguments to WebAssembly, typed arrays must be copied in. As outgoing arguments to JS, we pass raw views of wasm memory that don't copy any data. Basically we don't copy wherever we can, but otherwise we're forced to in a number of situations.
Oh, but the table on that page says that number slices are not supported as return values anyway. There are only two "Yes" cells in the table: "&T parameter" and "&mut T parameter". So "as incoming arguments" is the only case that applies here, I think. Or is the table inaccurate?
The table is accurate but there's a distinction between "this is coming from JS to wasm" and "this is going from wasm to JS". When coming into wasm we have no choice but to copy bytes, but when going out to JS we can give out cheap views.
Oohh! You just made me realize a fundamental gap in my understanding of these documentation pages: I thought the "&T parameter" column meant "JS passing something to a &T parameter of an exported rust function". But apparently it also means "Rust passing something to a &T parameter of an imported JS function"?
Brb, filing more issues.
Ok, filed #1667 about my confusion about which parameter direction is described by these documentation pages. I also filed #1668 about the fact that the "cheap views" trick doesn't work reliably.
Is there any way to give Rust a read-only view of a typed array in the JS runtime? It sounds like "no," but it really lowers the value of WebAssembly for me if I can't pass in typed array references. (Not that I blame any wasm-bindgen developers; it sounds like an innate limitation.)
@JonathanWilbur This isn't a terrible limitation because you can treat the WebAssembly module as an allocator for all the typed arrays that you wish to create in your JS code.
I think this doc page would be less confusing if it had examples of the data flowing the other way. Currently it is only showing an example a number slice being consumed by the WASM module, not the other way around.