Create and Import a WebAssembly Memory

Guy Bedford
InstructorGuy Bedford
Share this video with your friends

Social Share Links

Send Tweet

Starting from the previous example, we rebuild the program code to import its memory instead of exporting it. We then use this to simplify the application loading code.

Emscripten: https://kripken.github.io/emscripten-site/

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

[00:00] There's quite a complex instantiation process going on for loading program and memory.wasm them together in this application. The reason for this is the program is exporting its memory, and then memory needs to import that same memory.

[00:13] We instantiate program first, take its memory export, which is m.exports.memory, and pass it in as the memory import when we instantiate memory. Another way to do this is to create the memory in JavaScript before instantiating the WebAssembly modules.

[00:28] The WebAssembly memory constructor takes a single argument, which can then set the initial memory size in WebAssembly pages. WebAssembly pages are 64 kibibytes, or 2^16 bytes. One will be more than enough for this application.

[00:44] With the memory now created in JavaScript, we can then pass it into the memory import when we instantiate the memory module. We'd like to do the same for the instantiation of the program module as well, because we need all of our modules to be sharing the same memory in this example.

[01:02] Unfortunately, program doesn't have a memory import, because it was compiled with a memory export, which by definition, means it has a different, separate memory. We're going to need to recompile program to support this.

[01:14] From the original compilation, I'm going to take the WAST output, and copy it into WebAssembly Explorer. In WebAssembly Explorer, we can edit this WAST output. I'm going to find that memory over here where it's defined. I'm going to remove the memory definition from inside the module, and convert the export memory into an import memory.

[01:37] We need to import memory from the module called environment, because that's where we're importing everything from. Then I'm going to replace this memory declaration with a memory declaration including the initial size, which is that first parameter one.

[01:51] I can then assemble and download this converted binary. When compiling locally, there is an import memory flag for doing this automatically. Returning to the local application with the new program.wasm wired in, it'll now accept a memory import under the environment namespace.

[02:07] I can now simplify this instantiation by first instantiating memory, and then with the memory module that we get back, we can pass the memory.export's .free and malloc directly into the program imports because it's already bound to the same memory that program's using.

[02:23] With the results and instantiation of program, we've then got our final module value, and a much simpler instantiation process. There's a little bit of work to wiring these WebAssembly modules together correctly here.

[02:35] The benefit is, we're able to finally control the bootstrap of our application for our exact needs. If you are looking for a comprehensive solution for managing the setup of WebAssembly, I highly recommend trying out Emscripten, which comes with standard C, C++ application compilation out of the box, taking care of all the wiring itself. There's a link to the project in the description.