Today we cannot directly pass strings to WebAssembly, but we can pass a variety of TypedArrays, in other words an array of floats or numbers only. The one I particularly like is Unit8Array, it's an array of numbers that can have a max highest number of 255.
[255, 6, 0]
What is also good to know is Utf8 is a map of numbers to characters.
"my string".charCodeAt(0) //int
Given you can lookup a char to an representative int, which correct me if I am wrong, fits within the 0 - 255 range? Either way you get the idea. So char by char you could produce a string to an array of chars,then map each char to utf8 using charCodeAt
, that's going to give you an array of numbers that WASM can understand and the guest language could convert back. Nice ... An answer worthy of stack overflow, but ehat's that I hear you say 📯, there has to be a better way?
Well let's take a look at two exciting JavaScript built-in APIs I had no idea existed into yesterday,
TextEncoder ⚡ TextDecoder
source MDN
TextEncoder takes a stream of code points as input and emits a stream of bytes.
Example bellow encodes and decodes for no good reason.
const encoder = new TextEncoder()
const view = encoder.encode('Hello DEV')
console.log(view); // Uint8Array
const output = someWasmFunc(view); // Uint8Array with some changes
const decoder = new TextDecoder(); // Uint8Array
const str = decoder.decode(output); // String "Hello Dev"
The wasm code usage for example in rust, might look like this.
use std::str;
// some bytes, in a vector, originally the same Uint8Array from above
let sparkle_heart = vec![240, 159, 146, 150];
// We know these bytes are valid, so just use `unwrap()`.
let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
assert_eq!("💖", sparkle_heart);
That's all for now folks. ♥️