patterntypescriptModerate
wasm-bindgen: passing complex types between Rust and JavaScript
Viewed 0 times
wasm-bindgenJsValueserde-wasm-bindgenlinear memorystring passingFFI
rustwasm
Problem
Rust WASM functions need to accept or return strings, arrays, or structs from JavaScript, but WASM only natively supports numeric types.
Solution
wasm-bindgen automatically handles String and Vec<u8> by writing to WASM linear memory and passing a pointer+length pair. For complex structs, use #[wasm_bindgen] on structs or serde-wasm-bindgen for JSON serialization.
Why
WASM's ABI only supports i32/i64/f32/f64. wasm-bindgen generates glue code that copies data through linear memory for higher-level types.
Gotchas
- String arguments are copied into WASM memory on each call — avoid for hot paths
- JsValue can hold any JS value but requires explicit conversion
- serde-wasm-bindgen is more flexible than direct wasm-bindgen struct exports for complex data
- Memory must be freed after use; wasm-bindgen generates __wbindgen_free for this
Code Snippets
Struct exported with wasm-bindgen using serde
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Point { pub x: f64, pub y: f64 }
#[wasm_bindgen]
pub fn midpoint(a: JsValue, b: JsValue) -> JsValue {
let a: Point = serde_wasm_bindgen::from_value(a).unwrap();
let b: Point = serde_wasm_bindgen::from_value(b).unwrap();
let mid = Point { x: (a.x + b.x) / 2.0, y: (a.y + b.y) / 2.0 };
serde_wasm_bindgen::to_value(&mid).unwrap()
}Revisions (0)
No revisions yet.