Introducing WebAssembly with examples

Hi folks, continuing with my previous post  WebAssembly, the end of Javascript era? , today we are going to demonstrate WebAssembly with two simple
examples, one with C++ and the other with GO language. The example from two languages will help us to see different implementations that allow us to reach the same result.

Tool set

Before jumping into setting up WebAssembly, I want to briefly cover the tools I’ve used to create this example ranging from IDE (integrated development environment) to WebAssembly plugin

In the C++ project I used CLion and for the GO project I pick the Goland  which are both created by JetBrain . Of course, there are alternatives IDEs but these two have been chosen for consistency for side-by-side comparison

The other thing we will need in both cases is to compile and integrate with javascript. GO since version 1.11.4 already included WebAssembly port as a build-in feature we will go in depth in the next section.

For C++, we will have to install and set up EMSDK, a toolchain provided by WebAssembly  that not only compile your code into .wasm file, but also provides a scripting language that you can embed on your C++, allows extern “c” statements, generate HTML output (including javascript’s integration of wasm) and more.

The setup

As I already mentioned, for GO lang we will need to have version 1.11, which includes an experimental port to WebAssembly.
Now you only need to set GOARCH=wasm and GOOS=js environment variables to compile this small example into WebAssembly:

package main

import "fmt"

func main() {
    fmt.Println("Hello, WebAssembly!")
}

with just this line,

$ GOOS=js GOARCH=wasm go build -o main.wasm

Of course you can always automate this task in your IDE, here’s how to configure Goland

For C++, in addition to the compiler that match your OS, for example gcc, you will need to install the EMSDK.

$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest

If you don’t want to use git, you can download the zip version.

GO example

For a fully working example, the wasm file is not enough. Here we will need a web server that serves the HTML and javascript, and the javascript file that execute the wasm in the browser.
First we need to get the wasm_exec.js and and wasm_exec.html that can be copied from GO installation

cp "$(go env GOROOT)/misc/wasm/wasm_exec.*” .

The next thing will be a web server, here’s a snippet of a simple net/http based server:

package main

import (
 "flag"
 "log"
 "net/http"
)

var (
 listen = flag.String("listen", ":8080", "listen address")
 dir = flag.String("dir", ".", "directory to serve")
)

func main() {
 flag.Parse()
 log.Printf("listening on %q...", *listen)
 log.Fatal(http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir))))
}

And finally “the code”, you will notice that instead of  import “fmt” I use “syscall/js”, this library gives us the ability to access to DOM elements and invoke javascript actions on them.

package main

import (
 "syscall/js"
)


func main() {
 console := js.Global().Get("console")
 console.Call("log", "Hi!")

wasmtest := js.Global().Get("document").Call("getElementById", "wasmtest")
 wasmtest.Set("innerText", "Am I a Gopher?")
}

When this code is loaded, it shows a “Run” button and when you click it, a “Hi!” message will be printed in browser’s console and a “<p>” element enclosingAm I a Gopher?”  will append to the browser.

C++ exmaple

This example workflow is slightly easier than the previous one thanks of the EMSDK.
In this case we only need to implement the C++ code

#include <iostream>

int main() {
 std::cout << "Hello, WebAssemby!" << std::endl;
 return 0;
}

The SDK will generate all support files needed, such as Make files. To compile run:

emcc main.cpp -s WASM=1 -o hello.html

Once it finishes you can either open the HTML file in the browser or run a web server pointing to you project directory.

$ emrun --no_browser --port 8080 .

and open in your browse http://localhost:8080/hello.html

You will see a debug page created by emscripten.

You can do more elaborated things using emscripten library which allows you, for example,  run native C++ code in the browser  with the use of “extern C”

#include <stdio.h>
#include <emscripten/emscripten.h>

int main(int argc, char ** argv) {
    printf("Hello WebAssembly\n");
}

#ifdef __cplusplus
extern "C" {
#endif

void EMSCRIPTEN_KEEPALIVE myCustomLog(int argc, char ** argv) {
  printf("myCustomLog Called: %s", argv[0]);
}

#ifdef __cplusplus
}
#endif

For more information about this library take a peek at  EMScripten documentation

Final thoughts

As you could sneak peek with these two small examples, this is a promising new tech. However, as a very early tool scarce in features, it will take a while for WebAssembly to takeoff. Despite it’s lack in features, I am excited to see what the web could become.

Hope you enjoyed reading and see you on the next post. Thank you!

Comments

See how we can help

Lets talk!

Stay up to date on the latest technologies

Join our mailing list, we promise not to spam.