DEV Community

Adam Crockett 🌀
Adam Crockett 🌀

Posted on

WASM passing strings explained.

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]
Enter fullscreen mode Exit fullscreen mode

What is also good to know is Utf8 is a map of numbers to characters.

"my string".charCodeAt(0) //int
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

That's all for now folks. ♥️

Top comments (0)