Skip to content

Memory Operations

Ashton Meuser edited this page Aug 27, 2023 · 3 revisions

Overview

Because WebAssembly has only integers and floats as primitive types i.e. supported as function argument types, it is often necessary to communicate with a Wasm module via direct memory manipulation. Writing to and reading from Wasm memory allows for transferring arbitrary data across the WebAssembly VM boundary.

To facilitate Wasm memory operations, Godot Wasm provides the WasmMemory class accessible via the Wasm.memory property. This object uses Godot's familiar StreamPeer interface.

The internal WasmMemory class mirrors the seek() and get_position() methods of StreamPeerBuffer with the addition of seek() returning a reference to the StreamPeer allowing chaining i.e. wasm.memory.seek(0).get_u64().

Note that, as mentioned in Godot's StreamPeer documentation, writing strings via put_string() and put_utf8_string() will prepend four bytes containing the length of the string.

Imported Memory

Often, a Wasm module will handle creating its own memory. In some cases, however, a module may require an imported memory. In this situation, an external standalone WasmMemory can be created. Before passing to the module to be instantiated, the memory should be sized correctly using the WasmMemory.grow. The external memory should be grown to at least the required size of your Wasm module's import memory. Finally, the external memory can be provided to the Wasm module as an import during instantiation as follows.

var memory = WasmMemory.new()
memory.grow(100)
var imports = { "memory": memory }
var wasm = load_wasm("memory-import", imports)

Examples

The Wasm Test example project tests many of the capabilities of the WasmMemory class and may provide some insight.

The Wasm Visualizations example project makes heavy use of writing to and reading from Wasm module memory.

Clone this wiki locally