Webassembly and Rust state

I've just started messing with WebAssembly using Rust.

I've gotten a few examples working but I am a little confused about how the state of any Rust structs are maintained when rust code cedes control back to the browser UI.

If I return a struct marked with #[wasm_bindgen] from a Rust function and store it in a javascript variable, is that inefficient if the struct is very large? Is there a better way?

All rust state will be in the wasm machine's memory image. This is persistent between calls.

No—that returns a pointer to the structure, which will be wrapped on the js side so that you can call methods on it, not a copy of the structure. So it doesn't matter how large the underlying structure is.

1 Like

That sounds good, but I'm confused how. Must the object be returned from the function and assigned to a javascript variable to persist it? If not, I don't see how the next function call would be able to reference anything from a previous call.

Like this?

#[wasm_bindgen]
pub fn initialize() -> MyStruct {
  MyStruct{}
}

and then some other function:

#[wasm_bindgen]
pub fn cycle(r: &mut MyStruct) {
  //do stuff
}

So initialize creates the struct and the return value gets assigned to a javscript var, and then that var gets passed to repeated calls to cycle?

I was hoping that to be the case. Good to know.

Yes. It needs to be returned from the function. Returning it from the function moves your structure out of the function and into the WebAssemly heap (as I understand).

You don't strictly need to assign it to something at the JS side to persist it, though you usually would want to, even if it's to call .free() on it later to free it again on the rust side.

The documentation on this is here: https://rustwasm.github.io/docs/wasm-bindgen/contributing/design/exporting-rust-struct.html

Yes, exactly.

1 Like