Mariano Guerra (@warianoguerra)
Co-founder event-fabric.com
StuttgartJS, August 2016
The real one, often abbreviated asm:
Low-level programming language
Very strong (generally 1 to 1) correspondence between
The language
and the architecture's machine code instructions
Collection of modular and reusable compiler and toolchain technologies
Used to develop compiler front ends and back ends
Source Code -> LLVM IR*
* IR: intermediate representation
LLVM IR -> CPU specific binary*
* ARM, x86, MIPS, PowerPC etc.
Optimizable low-level subset of JavaScript*
* Not for humans
Portable
Size- and load-time-efficient format
Suitable for compilation to the web
It's not a replacement for js
It's not a programming language
It's not a separate VM
It's a complement to JS
Getting to MVP
LLVM backend upstream
Lots of tools
Reference implementation (spec) in Ocaml
3 Browser engines have native support in various stages
Google Chrome: fully spec compliant on all architectures, behind a flag
Mozilla Firefox: optimized for ia32 and x64, behind a flag
Microsoft Edge: support in an experimental build
MVP (Version 1.0) expected to be shipped this summer
Standardization expected by the end of the year
Browser | Wasm Support | View Source |
---|---|---|
Firefox Stable (44) | No | No |
Firefox Nightly | Yes | Yes[1] |
Chrome Stable (52) | Yes | No |
Chrome Canary | Yes | No |
Edge | No | No |
(as of August 10th, 2016)
[1] Custom Format (js-like, not s-expression based)
MVP
Post-MVP
Future
Will contain features which are available today in modern web browsers
Which perform well even on mobile devices
Leads to roughly the same functionality as asm.js
Threads
SIMD
Zero-cost Exception Handling
Feature Testing
Finer-grained control over memory
Large page support
More expressive control flow
goto, tail calls
GC
Source maps integration
Coroutines
Platform-independent JIT compilation
Multiprocess support
Additional float operators
Additional integer operators
min
max
abs
Integer Overflow Detection
Better feature testing support
Mutable global variables
Streaming Compilation
Multiple Tables and Memories
Module
AST
Binary format
Text format
To be implemented by
Web browsers
Completely different execution environments
Can be natively decoded much faster than JavaScript can be parsed
Experiments show more than 20X faster
Must be
Portable
Stable
Small
Fast to decode
Fast to compile
For "view source"
For tools, experiments, debugging, optimization
Equivalent and isomorphic to the binary format
Standardized only for tooling purposes
Nested statements
Instead of linear list like in asm
Prototypes use s-expression based syntax
Currently no final, official, text format
JS-like proposal from FF Nightly
void
i32
i64
f32
f64
Flat, single global table
Static binding
Indirect calls through table
Linear memory
Large, bounds-checked array
i32: + - * / % << >> >>> etc
i64: + - * / % << >> >>> etc
f32: + - * / sqrt ceil floor
f64: + - * / sqrt ceil floor
conversions
load store
call_direct call_indirect
if
loop
block
br
switch
Memory
Data
Imports
Exports
Start function
Global variables
Tables
Elements
Functions
Code
Provided, at instantiation time, by the host environment
Similar to a native syscall
Wasm doesn't know about Javascript or the DOM
Can import functions, globals, memory, tables
Returned at instantiation time to the host environment
Can export functions, globals, memory, tables
Can share with another Wasm instance
Called after module loading and before any call to the module function
Definition of zero or more linear memories
in the MVP it's limited to 1
Analogous to the .data section of native executables
Initializes memory
Zero or more definitions of distinct tables
In the MVP it's limited to 1
Table of pointer to provided opaque functions
called with call_indirect
Like data section but for tables
Declares the signatures of each internal function
Contains the function body of each function declared by the function section
Function Index Space
Global Index Space
Linear Memory Index Space
Table Index Space
C/C++ -> llvm* -> asm.js
* LLVM Emscripten backend
Compiler and toolchain infrastructure library for Wasm
Written in C++
wast -> wasm
Interpret wasm
asm.js -> wasm
Polyfill wasm
Binaryen (C++) -> Emscripten -> asm.js wasm polyfill
Let's translate hello.c to asm.js and Wasm.
Attempt 1: apt install emscripten
Ubuntu 16.04
FAIL: weird version errors
Attempt 2: emsdk
FAIL: no support for binaryen yet
Attempt 3: compile from source
FAIL: no support for binaryen yet (WAT)
Attempt 4: compile from source (incoming branch of emscripten)
SUCCESS!
Thanks to gh/qis for the tip
Instructions for linux and for windows
I like minimal simple things
I used to code in assembly
I convert any problem into a "let's implement a programming language" problem
A sometimes minimal FORTH compiler and tutorial for Linux but in WebAssembly!
No easy translation from asm to Wasm
Code is not stored on the same memory as data
Can't implement the threaded code technique
Translate the C version mentioned in the comments.
The code was a little unreadable: http://ftp.funet.fi/pub/doc/IOCCC/1992/buzzard.2.orig.c
First deobfuscated it
Compile the C version to asmjs and wasm
Translate it to Javascript by hand
Translate the C to the text format of wasm by hand
A Forth dialect base on buzzard.2
Implemented in C, Javascript and WebAssembly
Compiled from C to
asm.js (using emscripten)
Wasm (using binaryen)
Version | SLOC | Boilerplate | Total SLOC |
---|---|---|---|
C | 229 | 0 | 229 |
JS (me) | 241 | 0 | 241 |
Wasm (me) | 425 | 0 | 425 |
Wasm[1] (Binaryen) | 25626 | 5162 | 30788 |
asmjs[2] (Emscripten) | 10322 | 4740 | 15062 |
[1] I close parenthesis the lisp way, binaryen doesn't
[2] "almost wasm"
emscripten's emsdk/src/settings.js contains docs about the flags that can be passed to emcc