WebAssembly

WebAssembly is a new type of code that can be run in modern web browsers alongside JavaScript. It is a low-level assembly-like language with a compact binary format that runs with near-native performance demanded by applications such as 3D games, virtual and augmented reality, computer vision, image/video editing, etc. The storage requirements of WebAssembly programs are relatively less demanding, making it suitable for mobile and other resource-constrained platforms.

The tools to compile to WASM include:

WebAssembly.studio

WebAssembly Explorer

WASMFiddle

wat2wasm

Right now, there are five main entry points:

Porting a C/C++ application with Emscripten.


#include<stdio.h> int square(int n) {
    return n*n; }

emcc square.c -s STANDALONE_WASM –o findsquare.wasm

<!doctype html> <html>
   <head>
      <meta charset="utf-8">
      <title>WebAssembly Square function</title>
      <style>
         div {
             font-size : 30px; text-align : center; color:orange;
          }
       </style>
   </head>
    <body>
      <div id="textcontent"></div>
      <script>
       let square;
       fetch("findsquare.wasm")
      .then(bytes => bytes.arrayBuffer())
      .then(mod=>WebAssembly.compile(mod))
       .then(module => {
         return new WebAssembly.Instance(module);})
      .then(instance => {
         square = instance.exports.square(13);
          console.log("The square of 13 = " +square);
                  document.getElementById("textcontent").innerHTML
               = "The square of 13 = " +square;
       });
       </script>
   </body></html>

Writing or generating WebAssembly directly at the assembly level.

WebAssembly has a text format and a binary format. Below is a WAT (WebAssembly Text) function adding two integers.
(module
  (func (export "addTwo") (param i32 i32) (result i32)
    local.get 0
    local.get 1
    i32.add))

Writing a Go application and targeting WebAssembly as its output.


package mainimport "fmt"func main() {
    var a int = 100
    var b int = 200
    var ret int
    ret = sum(a, b)
    fmt.Printf( "Sum is : %d\n", ret ) } /* function returning the max between two numbers */ func sum(num1, num2 int) int {
    return num1+num2 }

Set GOOS=jsGOARCH=wasmgo build -o testnum.wasm testnum.go

<html>
    <head>
       <meta charset="utf-8"/>
      <script src="wasm_exec.js"></script>
   </head>
   <body>
      <script type="text/javascript">
          const importObj = {
            module: {}
          };
         const go = new Go();
          async function fetchAndInstantiate() {
             const response = await fetch("testnum.wasm");
             const buffer = await response.arrayBuffer();
             const obj = await WebAssembly.instantiate(
                                                 buffer, go.importObject);
             console.log(obj);
             go.run(obj.instance);
          }
          fetchAndInstantiate();
       </script>
   </body></html>

Writing a Rust application and targeting WebAssembly as its output.


#[no_mangle]pub extern "C" fn add_ints(lhs: i32, rhs: i32) -> i32 {
   lhs+rhs}

Using AssemblyScript which looks like TypeScript and compiles to WebAssembly binary.


// module.ts/* Calculates the n-th Fibonacci number. */export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a}

;; INFO asc module.ts --textFile module.wat --binaryFile ;;
                                    module.wasm -O3 --runtime half(module (type $i32_=>_i32 (func (param i32) (result i32))) (memory $0 0) (export "memory" (memory $0)) (export "fib" (func $module/fib)) (func $module/fib (param $0 i32) (result i32)
  (local $1 i32)
  (local $2 i32)
  (local $3 i32)
  i32.const 1
  local.set $1
  local.get $0
  i32.const 0
  i32.gt_s
  if
   loop $while-continue|0
    local.get $0
    i32.const 1
    i32.sub
    local.tee $0
    if
     local.get $1
     local.get $2
     i32.add
     local.get $1
     local.set $2
     local.set $1
     br $while-continue|0
    end
   end
   local.get $1
   return
  end
  i32.const 0 ))

<textarea id="output" style="height: 100%; width: 100%" readonly></textarea><script>loader.instantiate(module_wasm, { /* imports */ })
  .then(({ exports }) => {
    const output = document.getElementById('output')
    for (let i = 0; i <= 10; ++i) {
      output.value += `fib(${i}) = ${exports.fib(i)}\n`
    }
  })</script>

fib(0) = 0fib(1) = 1fib(2) = 1fib(3) = 2fib(4) = 3fib(5) = 5fib(6) = 8fib(7) = 13fib(8) = 21fib(9) = 34fib(10) = 55

This WebAssembly.instantiateStreamingAPI takes care of compiling as well as instantiating the WebAssembly module from the .wasm code given.


<script type="text/javascript">
        const importObj = {
       module: {}
    };
   WebAssembly.instantiateStreaming(
          fetch("findsquare.wasm"), importObj).then(obj => {
      console.log(obj);
    }); </script>