Skip to content

Instantly share code, notes, and snippets.

@cure53
Last active October 17, 2023 00:16
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save cure53/f4581cee76d2445d8bd91f03d4fa7d3b to your computer and use it in GitHub Desktop.
Save cure53/f4581cee76d2445d8bd91f03d4fa7d3b to your computer and use it in GitHub Desktop.
Calling alert from WASM

Calling alert from WebAssembly (WASM)

This very simple and minimal tutorial documents in a few easy steps how to play with WebAssembly (WASM) and get first results within minutes.

While the code below is mostly useless, it will show, how to call the alert function from within a WASM file and thus demonstrate how to import and export DOM objects.

Of course, this exercise has no real use. It is just meant to show, that getting started with WASM isn't hard. And there is no need for a complex build-chain, tons of tools or a dedicated VMs. Just use a browser, one online tool and that's it.

And Now?

To execute the code shown below, we need a very modern browser. WASM likely needs to be enabled via configuration flag. We tested on Chrome Version 52.0.2741.0 Canary and activated chrome://flags/#enable-webassembly. Same for Firefox 49.0a1 with javascript.options.wasm: true.

Tools

We need nothing else but the browser, one HTML file and a WASM file. We can use the amazing tool linked below to generate the WASM file for us - from WAST. No complex build chain needed:

https://cdn.rawgit.com/WebAssembly/sexpr-wasm-prototype/2bb13aa785be9908b95d0e2e09950b39a26004fa/demo/index.html

Setup

Create an HTML file using the following source code:

<script>
/* An XHR fetching the WASM file as ArrayBuffer */
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = ready;
xhr.open('GET', 'test.wasm');
xhr.send(null);

/* Execute once the file was fetched  */
function ready() {
    var info = {
        foo: {bar: alert} // "import" the alert method
    };
    var a = Wasm.instantiateModule(
        new Uint8Array(xhr.response), info
    ).exports;
    a.f(); // execute the f method, that is foo.bar()
}
</script>

Now, let's create some WAST code to feed to the tool linked above and generate a WASM for for us (test.wasm, as referenced in the HTML):

(module ;; start the module
  (import "foo" "bar") ;; import foo.bar
  (func $bar (call_import 0 )) ;; map bar()
  (export "f" 0) ;; export bar()
)

Click "Download", grab the resulting WASM file, place it in the same folder as your HTML file, open the HTML in Chrome or any WASM-compatible browser of choice, see the alert pop. Done :) Why? Because why not!

More Info

@guest271314
Copy link

@Zibri See https://depth-first.com/articles/2020/01/13/first-steps-in-webassembly-hello-world/, https://www.webassemblyman.com/wat/hello_world.zip

WebAssembly.instantiate(new Uint8Array([0,97,115,109,1,0,0,0,1,8,2,96,1,127,0,96,0,0,2,15,1,3,101,110,118,7,106,115,112,114,105,110,116,0,0,3,2,1,1,5,3,1,0,1,7,27,2,10,112,97,103,101,109,101,109,111,114,121,2,0,10,104,101,108,108,111,119,111,114,108,100,0,1,10,8,1,6,0,65,0,16,0,11,11,19,1,0,65,0,11,13,72,101,108,108,111,32,87,111,114,108,100,33,0]), {
  env: {
    jsprint: function jsprint(byteOffset) {
      console.log(new TextDecoder().decode(new Uint8Array(memory.buffer).filter(Boolean)));
    }
  }
})
.then(results => {
  instance = results.instance;
  memory = instance.exports.pagememory;
  instance.exports.helloworld();
}).catch(console.error);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment