rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.72k stars 1.06k forks source link

Documentation: "Exported struct Whatever Rust Types" should clear up what happens with moved values #1658

Open mstange opened 5 years ago

mstange commented 5 years ago

On the page Exported struct Whatever Rust Types, there is no information about what happens if you pass such a type from JS to rust by value. Does the value get copied? Does the value get "moved"? Is the JS object still usable after you call the rust function?

And then the JS code in example causes even more confusion:

named_struct_by_value(namedStruct);
named_struct_by_shared_ref(namedStruct);
named_struct_by_exclusive_ref(namedStruct);

First, the example passes namedStruct into a rust function by value, and then passes the same object into two other rust functions by reference. When you actually run this code, it will throw errors.

I recommend the following paragraph be added at the top:

If the JavaScript representation of a rust struct object is passed by value, the value is moved, and the JavaScript representation is cleared. In other words, the JS object's internal pointer field is nulled out, just like if you had called .free() on the object, and you cannot use this object any more. This happens even if the rust struct implements the Copy trait.

And the example should be changed to:

named_struct_by_value(namedStruct); // This call "moves" namedStruct.

 // Get a new object, since the namedStruct JS object is now cleared.
namedStruct = return_named_struct(42);

named_struct_by_shared_ref(namedStruct);
named_struct_by_exclusive_ref(namedStruct);
alexcrichton commented 5 years ago

Thanks for the sharp eye! Your intuition here is spot on the example is definitely more instructive!

FWIW movement does not copy values, and it causes the JS value to throw an error if it's ever reused. Would be good to document this though explicitly!