What is WebAssembly?

by Steven Myers

preamble

  • Just-In-Time (JIT) Compilation
  • assembly

example optimization

This is an example of a monomorhpic stub.


							function arraySum(arr){
						   var sum = 0;
						   for (var i = 0; i < arr.length; i++) {
							    //if arr[i] is always int then compiler 
							    //will stub and run as int addition
							    sum += arr[i]; 
					    }
							}
						
example via Lin Clark

assembly

  • very terse
  • multiple dialects, typically 1-to-1 correspondence with machine instructions
  • rarely written by hand
```assembly PrintString: mov bx, 1 ; write to stdout mov ah, 040h ; write to file handle int 21h ; ignore return value ret ; ```

asm.js

  • first widely adopted solution for compiling C/C++ to run in browser -- without a plugin!
  • similiar to assembly in form
  • still relevant

the gist

  • parameter and return type annotations
  • "use asm" allows for code to bypass interpreter and immediately compile to assembly
  • uses an ArrayBuffer to "mock" the heap
### example of C -> asm.js compilation ```js function _sqlite3_value_int64($0) { $0 = $0|0; var $1 = 0, $2 = 0, $3 = 0, $4 = 0, label = 0, sp = 0; sp = STACKTOP; STACKTOP = STACKTOP + 16|0; $1 = sp; HEAP32[$1>>2] = $0; $2 = HEAP32[$1>>2]|0; $3 = (_sqlite3VdbeIntValue($2)|0); $4 = tempRet0; tempRet0 = ($4); STACKTOP = sp;return ($3|0); } ```

downsides

  • can generate large amounts of js --> slows down parse
  • limited ability to extend functionality
    • it's a subset of js afterall

wasm

"main problem that wasm is aiming to solve... quickly start large applications"
-- Alon Zakai
  • running your (second) favorite language in the browser isn't high on the list
binary format ```   00 61 73 6d 0b 00 00 00 04 74 79 70 65 87 80 80 |.asm.....type...| 00000010 80 00 01 40 02 01 01 01 01 08 66 75 6e 63 74 69 |...@......functi| 00000020 6f 6e 82 80 80 80 00 01 00 06 6d 65 6d 6f 72 79 |on........memory| 00000030 85 80 80 80 00 80 02 80 02 01 06 65 78 70 6f 72 |...........expor| 00000040 74 86 80 80 80 00 01 00 03 61 64 64 04 63 6f 64 |t........add.cod| 00000050 65 8c 80 80 80 00 01 86 80 80 80 00 00 14 00 14 |e...............| 00000060 01 40 04 6e 61 6d 65 86 80 80 80 00 01 03 61 64 |.@.name.......ad| 00000070 64 00   |d.| ```
we will load this wasm module ``` (module (func $i (import "imports" "imported_func") (param i32)) (func (export "exported_func") i32.const 42 call $i)) ```

						const importObject = { 
						  imports: { imported_func: arg => alert(arg) } 
						};
						fetch('assets/simple.wasm')
						  .then(response => response.arrayBuffer())
						  .then(bytes => WebAssembly.instantiate(bytes, importObject))
						  .then(results => results.instance.exports.exported_func())
						

check out this link

  • note that wasm is not strictly faster than js
  • some of the more involved filters benefit greatly from wasm -- 500% improvement etc
  • a good example of how wasm can provide solutions where js is unable to compete.
  • note: relative performance varies greatly by browser version (on Chrome)

How to try?

  • Use the emscripten sdk to set up and manage your enviroment.
  • the compiler 'emcc' feels like gcc -- produces a.out.js etc
  • can be used to generate html file that will load your wasm

gotchas

  • wasm binary format is somewhat in flux at the time of writing
  • projects ported to asm.js may provide an api incompatible with wasm code
  • porting larger projects may require some familiarity with linux or C++ build experience

resources

resources continued