Read WebAssembly Memory from JavaScript

Guy Bedford
InstructorGuy Bedford
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 6 years ago

We use an offset exporting function to get the address of a string in WebAssembly memory. We then create a typed array on top of the WebAssembly memory representing the raw string data, and decode that into a JavaScript string.

WASM Fiddle: https://wasdk.github.io/WasmFiddle/?6wzgh

Demo Repo: https://github.com/guybedford/wasm-intro

[00:00] Using functions in WebAssembly, we can pass individual numeric values. We're restricted to integers and floats, either 32 bits or 64 bits. The standard WASM filler example has a function that returns a number. When we build and run this, we can log that number. We're passing numbers through the interfaces.

[00:18] What if I wanted to deal with something like a string of characters? In C, we define a string using a character array. If I wanted this "hello world" string to be passed into JavaScript, how might I do that?

[00:31] One option would be to create a function, getChar, that returns individual characters at a single offset. We're still returning a number representing the character, but we can call it many times to get the whole string.

[00:43] If I return the individual item of the string, we can then call this function from JavaScript. Calling the getChar function in JavaScript with zero to get the first character of the string, we can then see the char code for H being returned.

[01:00] We could then use some code to convert that into the correct string character, and we could read out the string letter-by-letter. Thankfully, there's a better way to do this. Instead of a getChar function, I'm going to create a char pointer-returning function called getStringOffset.

[01:17] What this function will do is it'll return the memory address of the first character of the string. When we build this, we can see in the code below, getStringOffset is returning a single number, which is a 32-bit integer. It's a constant integer, 16.

[01:35] This is the address of our string in the WebAssembly memory. If we look further up in this output, we can see that there's a data section. The data section is used to create pre-allocated memory in our WebAssembly modules.

[01:49] This data section is allocating at address number 16, the contents "hello world." Then our memory is also being exported over here. We've got this single piece of addressable linear memory that contains the data we want.

[02:05] Now, we just have to write the JavaScript to read it. The first thing I'm going to do is read out that memory export, which is directly the instance.export's memory property. The way that we access raw memory in JavaScript is using typed arrays.

[02:20] We want to create a typed array on top of this WebAssembly memory that represents our string. Each character of the string is eight bits. I'm going to use the Uint8 array typed array on top of the WebAssembly memory, the memory.buffer property, and then specify the offset within the WebAssembly memory that our string starts.

[02:41] Calling the getStringOffset function, we can get this address, 16. The last argument for our typed array is the length of the buffer, in this case 11 characters for the string. Finally, to convert this raw buffer into an actual JavaScript string, we use the text decode API. We pass the raw buffer, and it gives us back the string that we can then log in the console.

egghead
egghead
~ 31 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today