I will start this post with a quote from webassembly.org:
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
That’s a lot of technical jargon. In very simple terms, Wasm provides a way to run code written in multiple languages on the web at near-native speed. Where multiple languages refers to all these languages.
Basically what web assembly allows us to write code in any supported favorite language, compile it to binary (typically with the extension
Web Assembly in Go is still experimental API. And the API may change in future, which means it is backward incompatible.
According to Wikipedia:
And regarding the support in browsers, this is what Wikipedia has to say:
As of May 2020, 91.44% of installed browsers (91.56% of desktop browsers and 92.94% of mobile browsers) support WebAssembly.
That’s too much of information for today. Let’s do some quick example.
Wasm and Go
As I am a Go fan, let’s do a Hello WASM! application with it. WebAssembly works with Go 1.11 and above. I am writing along this blog post with go verison 1.14.2.
There are 4 ingredients we need.
- wasm binary which we are going to compile
- wasm_exec.js which will hold the connector code between wasm binary and HTML file
- an HTML page to hook the wasm_exec.js file to
- a web server to host these three
Normally to generate an executable, I would have done
go build -o hello.wasm hello_wasm.go (frankly speaking, I just do
go build on my Fedora). But to create a WASM binary we gotta set some environment variables. And those variables are
GOOS=js GOARCH=wasm. So the full command would be something like this:
GOOS=js GOARCH=wasm go build -o hello.wasm hello_wasm.go
Next, copy wasm_exec.js to cwd from go installation directory:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
If you are somehow not able to find the files there, like me, get it from https://github.com/golang/go/tree/master/misc/wasm. Just to make sure, this piece of code is from master branch, and you are expected to use it with latest version of golang. Otherwise go to specific branch and then download.
curl https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.js -O
Use this HTML snippet:
WebAssembly.instantiateStreaming takes in our binary and import object. And returns WebAssembly.Module and a WebAssembly.Instance object, which in above example is assigned to
inst variable respectively.
I’m going to ditch golang and start a web server with Python. 🤭 It’s simple.
This will start serving files from the current directory. Head over to http://127.0.0.1:8000. Once the wasm_exec.html is loaded, you will see a button named Run.
document and eventually everything in the DOM.
foo and sets the text to
Equivalent code in Go would look like this:
Note that signature has to be like that. This will make
barFunc available to global namespace.
Moreover, there is a whole lot of resources available regarding Go and WASM at https://github.com/golang/go/wiki/WebAssembly
We are not limited to DOM manipulation with WASM. We can use any existing browser API such as using network calls, LocalStorage, using WebGL etc. I would recommend this GopherCon video by Johan Brandhorst who is a contributor to golang codebase.
This was an eagle eye introduction to WebAssembly in Go. Let me end this post with some security concerns of WebAssembly.
WebAssembly has been criticized for allowing greater ease of hiding the evidence for malware writers, scammers and phishing attackers; WebAssembly is only present on the user’s machine in its compiled form, which “makes malware detection difficult”.
The speed and concealability of WebAssembly have led to its use in hidden crypto mining on the website visitor’s device. Coinhive, a now defunct service facilitating cryptocurrency mining in website visitors' browsers, claims their “miner uses WebAssembly and runs with about 65% of the performance of a native Miner.”
A June 2019 study from the Technische Universität Braunschweig, analyzed the usage of WebAssembly in the Alexa top 1 million websites and found the prevalent use was for malicious crypto mining, and that malware accounted for more than half of the WebAssembly-using websites studied.