Skip to content

Commit

Permalink
Add JS builtin examples (#40)
Browse files Browse the repository at this point in the history
Chrome 130 supports [WebAssembly JS String
builtins](https://github.com/WebAssembly/js-string-builtins/blob/main/proposals/js-string-builtins/Overview.md).

This PR adds some examples to accompany the documentation I am writing
for JS String builtins, plus an update to the readme to explain how to
successfully compile the wasm modules.
  • Loading branch information
chrisdavidmills authored Dec 12, 2024
1 parent 7e4038f commit 01fcd00
Show file tree
Hide file tree
Showing 21 changed files with 212 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Code examples that accompany the MDN WebAssembly documentation — see https://d
The examples can be tested locally by running a [local server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server#using_python) to serve your directory of choice.

If you modify any `.wat` files for testing you will need to generate a corresponding `.wasm` file, replacing the existing version in the folder.
This can be done using the `wat2wasm` tool, which is part of the [WABT: The WebAssembly Binary Toolkit](https://github.com/WebAssembly/wabt/) (for setup/usage see [Converting the text .wat into a binary .wasm file](https://developer.mozilla.org/en-US/docs/WebAssembly/Text_format_to_Wasm#converting_the_text_.wat_into_a_binary_.wasm_file) on MDN and the readme in the WABT GitHub repo.
For most examples, this can be done using the `wat2wasm` tool, which is part of the [WABT: The WebAssembly Binary Toolkit](https://github.com/WebAssembly/wabt/) (for setup/usage see [Converting the text .wat into a binary .wasm file](https://developer.mozilla.org/en-US/docs/WebAssembly/Text_format_to_Wasm#converting_the_text_.wat_into_a_binary_.wasm_file) on MDN and the readme in the WABT GitHub repo.

Note that some examples use features that are still considered optional.
These are listed in the [supported proposals](https://github.com/WebAssembly/wabt/#supported-proposals) section on the WABT README.md, along with the flags used to invoke them.
Expand Down
17 changes: 17 additions & 0 deletions js-builtin-examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# WebAssembly JavaScript builtins examples

WebAssembly JavaScript builtins examples.

## Testing/modifying the JavaScript builtins examples

The `wat2wasm` tool does not support the [JS builtins](https://github.com/WebAssembly/js-string-builtins/blob/main/proposals/js-string-builtins/Overview.md) examples. To compile `.wat` files that make use of JavaScript builtins, you need to use the `wasm-as` tool, which is part of the [Binaryen library](https://github.com/WebAssembly/binaryen). You'll need to run `wasm-as` with reference types and GC enabled for these examples to compile successfully:

```sh
wasm-as --enable-reference-types -–enable-gc module.wat -o module.wasm
```

Or you can use the `-all` flag in place of `--enable-reference-types -–enable-gc`:

```sh
wasm-as -all module.wat -o module.wasm
```
15 changes: 15 additions & 0 deletions js-builtin-examples/compile-streaming/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
16 changes: 16 additions & 0 deletions js-builtin-examples/compile-streaming/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const importObject = { // Regular import
m: {
log: console.log
}
};

const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

WebAssembly.compileStreaming(fetch("log-concat.wasm"), compileOptions)
.then(module => WebAssembly.instantiate(module, importObject))
.then(instance => instance.exports.main());


Binary file not shown.
15 changes: 15 additions & 0 deletions js-builtin-examples/compile/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
18 changes: 18 additions & 0 deletions js-builtin-examples/compile/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const importObject = { // Regular import
m: {
log: console.log
}
};

const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

fetch("log-concat.wasm")
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.compile(bytes, compileOptions))
.then(module => WebAssembly.instantiate(module, importObject))
.then(instance => instance.exports.main());


Binary file added js-builtin-examples/compile/log-concat.wasm
Binary file not shown.
15 changes: 15 additions & 0 deletions js-builtin-examples/instantiate-streaming/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
15 changes: 15 additions & 0 deletions js-builtin-examples/instantiate-streaming/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const importObject = { // Regular import
m: {
log: console.log
}
};

const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

WebAssembly.instantiateStreaming(fetch("log-concat.wasm"), importObject, compileOptions)
.then(result => result.instance.exports.main());


Binary file not shown.
15 changes: 15 additions & 0 deletions js-builtin-examples/instantiate/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
17 changes: 17 additions & 0 deletions js-builtin-examples/instantiate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const importObject = { // Regular import
m: {
log: console.log
}
};

const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

fetch("log-concat.wasm")
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes, importObject, compileOptions))
.then(result => result.instance.exports.main());


Binary file added js-builtin-examples/instantiate/log-concat.wasm
Binary file not shown.
9 changes: 9 additions & 0 deletions js-builtin-examples/log-concat.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(module
(global $h (import "#" "hello ") externref)
(global $w (import "#" "world!") externref)
(func $concat (import "wasm:js-string" "concat")
(param externref externref) (result (ref extern)))
(func $log (import "m" "log") (param externref))
(func (export "main")
(call $log (call $concat (global.get $h) (global.get $w))))
)
15 changes: 15 additions & 0 deletions js-builtin-examples/module-constructor/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
18 changes: 18 additions & 0 deletions js-builtin-examples/module-constructor/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const importObject = { // Regular import
m: {
log: console.log
}
};

const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

fetch("log-concat.wasm")
.then(response => response.arrayBuffer())
.then(bytes => {
const module = new WebAssembly.Module(bytes, compileOptions);
WebAssembly.instantiate(module, importObject)
.then(instance => instance.exports.main());
})
Binary file not shown.
15 changes: 15 additions & 0 deletions js-builtin-examples/validate/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WebAssembly JS String Builtins example</title>

<script defer src="index.js"></script>
</head>

<body>
<p>My template</p>
</body>

</html>
11 changes: 11 additions & 0 deletions js-builtin-examples/validate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const compileOptions = {
builtins: ["js-string"], // Opt-in to get magic imported functions
importedStringConstants: "#" // Opt-in to get magic imported globals
}

fetch("log-concat.wasm")
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.validate(bytes, compileOptions))
.then(result => console.log(`wasm module valid: ${result}`));


Binary file added js-builtin-examples/validate/log-concat.wasm
Binary file not shown.

0 comments on commit 01fcd00

Please sign in to comment.