Introduction to WebAssembly Text
Introduction to WebAssembly Text
| Previous | Next | |
|---|---|---|
| Creating a WebAssembly Module | Up | WAT Datatypes |
3: Using a Language Runtime as a WebAssembly Host Environment
Now that we can call our slightly-less-useless WebAssembly module from the command line, let’s look at calling it from a JavaScript program. In other words, we’re now going to use JavaScript as the WebAssembly host environment.
Create a .wasm file
When using wasmer as the host environment, behind the scenes it performed two tasks. It:
- Compiled the
.watfile into a.wasmfile, then - Executed the
.wasmfile
However, when a language runtime such as JavaScript acts as the host environment, these two tasks are typically performed at different times in the development process.
So first, we need to assemble the WebAssembly Text file into a .wasm file. To do this, change into the same directory as the .wat file, then invoke the wat2wasm tool:
wat2wasm 02-slightly-less-useless.wat
This now creates a .wasm file that is a mere 39 bytes in size.
Since there are some implementation differences between a server-side JavaScript environment and a browser-based JavaScript environment, it is necessary to provide two versions of the following example.
Using JavaScript (NodeJS) as the WebAssembly Host Environment
As a prerequisite for using NodeJS, we must first create a package.json file containing the single line:
{ "type": "module" }
Next, we need to create a JavaScript program that does the following:
- Synchronously read the contents of the
.wasmfile into a constant calledwasmBin - Create an executable instance of the
.wasmfile usingWebAssembly.instantiate() - Using the
wasmObj’sinstanceproperty, we can call theanswerfunction via theexportsproperty.
import { readFileSync } from 'fs'
const start = async () => {
const wasmBin = readFileSync('./02-slightly-less-useless.wasm')
const wasmObj = await WebAssembly.instantiate(wasmBin)
console.log(`Answer = ${wasmObj.instance.exports.answer()}`)
}
start()
Open a command line and run the above program using NodeJS
node 03-wasm-host-env.js
Answer = 42
Using JavaScript (Browser) as the WebAssembly Host Environment
If we now want to run the same WebAssembly module in a browser, we must modify the ablove JvaScript code slightly and wrap it in HTML:
<!DOCTYPE html>
<html>
<script>
const start = async () => {
const wasmObj = await WebAssembly.instantiateStreaming(fetch('./02-slightly-less-useless.wasm'))
console.log(`Answer = ${wasmObj.instance.exports.answer()}`)
}
start()
</script>
</html>
Place this file under your local webserver’s document root directory and display it through the browser. In your browser’s developer tools, you will see Answer = 42 displayed in the console.
IMPORTANT TECHNICAL DETAILS
-
For security reasons, browsers will not open
.wasmfiles using thefile://protocol. This means therefore that the web page within which this JavaScript code executes cannot be opened simply by pointing your browser at the.htmlfile in your local file system. Any Web page containing a WebAssembly module must be supplied to the browser using your local Web Server. -
Your local Web Server must be correctly configured to send
.wasmfiles with the correct MIME type ofapplication/wasm.For example on a macOS machine, ensure that the file
/private/etc/apache2/mime.typescontains the line:
application/wasm wasm -
If you are developing a WebAssembly program in which multiple instances of the same module will simultaneously act upon the same block of shared memory (by means of JavaScript Web Workers), then your local Web Server must additionally be configured to supply the
.wasmfile with the following HTTP headers:Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-originIf you are using Apache as your WebServer, then the
<Ifmodule headers_module>section ofhttpd.confshould contain at least these directives:<IfModule headers_module> Header set Cross-Origin-Embedder-Policy "require-corp" Header set Cross-Origin-Opener-Policy "same-origin" </IfModule>
Let’s now take a more detailed look at how to write a useful WebAssembly Text program.