Skip to content

Commit

Permalink
Add multi-memory example (#35)
Browse files Browse the repository at this point in the history
This adds an example of how to use multiple memories in Web Assembly. 
- It shows how to create two memories in JavaScript and import to the
WASM, and one memory in WASM and export to the JavaScript.
- It updates each with different text that gets printed to screen (uses
screen based logging rather than console logging, which is much nicer)
- It shows that the default memory is the 0 index one.

Still working on docs

This is part of work for mdn/content#32777

---------

Co-authored-by: Brian Thomas Smith <brian@smith.berlin>
  • Loading branch information
hamishwillee and bsmth authored Apr 15, 2024
1 parent 0777845 commit fb0118a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
70 changes: 70 additions & 0 deletions understanding-text-format/multi-memory.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<title>WASM multi-memory example</title>

<style>
#log {
height: 100px;
overflow: scroll;
padding: 0.5rem;
border: 1px solid black;
}
</style>
</head>

<body>
<h1>WASM multi-memory example</h1>
<p>Log:</p>
<pre id="log"></pre>

<script>
const logElement = document.querySelector("#log");
function log(text) {
logElement.innerText = `${logElement.innerText}${text}\n`;
logElement.scrollTop = logElement.scrollHeight;
}
</script>
<script>
const memory0 = new WebAssembly.Memory({ initial: 1 });
const memory1 = new WebAssembly.Memory({ initial: 1 });
let memory2; // Created by module

function consoleLogString(memoryInstance, offset, length) {
let memory;
switch (memoryInstance) {
case 0:
memory = memory0;
break;
case 1:
memory = memory1;
break;
case 2:
memory = memory2;
break;
// code block
}
const bytes = new Uint8Array(memory.buffer, offset, length);
const string = new TextDecoder("utf8").decode(bytes);
log(string);
}

const importObject = {
console: { log: consoleLogString },
js: { mem0: memory0, mem1: memory1 },
};

WebAssembly.instantiateStreaming(
fetch("multi-memory.wasm"),
importObject
).then((obj) => {
// Get exported memory
memory2 = obj.instance.exports.memory2;
// Log memory
obj.instance.exports.logAllMemory();
});
</script>
</body>
</html>
Binary file added understanding-text-format/multi-memory.wasm
Binary file not shown.
45 changes: 45 additions & 0 deletions understanding-text-format/multi-memory.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
(module
(import "console" "log" (func $log (param i32 i32 i32)))

(import "js" "mem0" (memory 1))
(import "js" "mem1" (memory 1))

;; Create and export a third memory
(memory $mem2 1)
(export "memory2" (memory $mem2))

(data (memory 0) (i32.const 0) "Memory 0 data")
(data (memory 1) (i32.const 0) "Memory 1 data")
(data (memory 2) (i32.const 0) "Memory 2 data")

;; Add text to default (0-index) memory
(data (i32.const 13) " (Default)")

(func $logMemory (param $memIndex i32) (param $memOffSet i32) (param $stringLength i32)
local.get $memIndex
local.get $memOffSet
local.get $stringLength
call $log
)

(func (export "logAllMemory")
;; Log memory index 0, offset 0
(i32.const 0) ;; memory index 0
(i32.const 0) ;; memory offset 0
(i32.const 23) ;; string length 23
(call $logMemory)

;; Log memory index 1, offset 0
i32.const 1 ;; memory index 1
i32.const 0 ;; memory offset 0
i32.const 20 ;; string length 20 - overruns the length of the data for illustration
call $logMemory

;; Log memory index 2, offset 0
i32.const 2 ;; memory index 2
i32.const 0 ;; memory offset 0
i32.const 13 ;; string length 13
call $logMemory
)

)

0 comments on commit fb0118a

Please sign in to comment.