Tuesday 20 November 2018

Post 68: Webassembly example

Lately I wanted to dive into Web Assembly. The examples I found on the internet wouldn't work or information was missing. I would spend a couple of hours to figure it out. In order to save yourself time, I created this post.

I was inpsired by this post (but the project wouldn't run for me): https://medium.freecodecamp.org/get-started-with-webassembly-using-only-14-lines-of-javascript-b37b6aaca1e4#--respond

The file structure will look like this:
wasmDemo
|_index.html
|_scripts.js
|_server.js
|_squarer.wasm

So, everything is in one directory with now subfolder.

First go to the following page in order to write a C++ program:
https://mbebenita.github.io/WasmExplorer/

Let's write a squarer program:

int squarer(int i) {
  return i * i;
}

Paste that into the site above. Then compile it and download the `.wasm` file. Move that file into our folder "wasmDemo".

Next create a html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>WASM Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>WASM Demo</h1>
<script src="./scripts.js"></script>
</body>
</html>

Then create a js file:
let squarer;

function loadWebAssembly(fileName) {
return fetch(fileName)
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {
return new WebAssembly.Instance(module);
});
}
loadWebAssembly('./squarer.wasm').then(instance => {
squarer = instance.exports._Z7squareri;
console.log('Finished compiling! Ready when you are...');
});

Since we have to run it on the server, let's create a server.js file for our node server:
var http = require('http');
var fs = require('fs');
var path = require('path');

const PORT = 8080;

http
.createServer(function(request, response) {
var filePath = '.' + request.url;
if (filePath == './') {
filePath = './index.html';
}

var extname = String(path.extname(filePath)).toLowerCase();
var mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.wasm': 'application/wasm'
};

var contentType = mimeTypes[extname] || 'application/octet-stream';

fs.readFile(filePath, function(error, content) {
if (error) {
response.writeHead(404);
response.end('404 Not Found');
} else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
})
.listen(PORT);

If everything is correct, then start the application with `node server.js`

Now you can access the squarer function, that we wrote in C++ also in the js file or in the console.
Tweet