WASM?

AWSM!

Wer bin ich?

preface
Hintergrund
JavaScript Performance

Warum nutzen wir JavaScript?

  1. es ist schรถn โœ…๏ธ
  2. es ist async โœ…
  3. is halt schon im browser ๐Ÿคฆ๐Ÿปโ€โ™€๏ธ
  4. es schnell๐Ÿ’”๏ธ*
    * native browser APIs zรคhlen nicht
  5. konkurierende Implementierungenโœ…

Lin Clark "A cartoon intro to WebAssembly"

Lin Clark "A cartoon intro to WebAssembly"

Warum is es so schwer Javascript schneller zu machen?

"scriptsprache"

history: asm.js

AOT?

asm.js

... can be used as a low-level,
efficient target language for compilers.

The asm.js language provides an abstraction similar to the C/C++ virtual machine: a large binary heap with efficient loads and stores, integer and floating-point arithmetic, first-order function definitions, and function pointers.

asm.js spec (faq)
... ein kleines, striktes Subset von JavaScript das nur while, if, Zahlen und Toplevel-Funktionen erlaubt.
[...] es erlaubt keine, Strings, Closurs oder irgendwas was den heap braucht. mdn

asm.js Beispiel

function MyAsmModule(stdlib, foreign, heap) {
    "use asm";
    // module body...
    return {
        export1: f1,
        // ...
    };
}
function add1(x) {
    x = x|0; // x : int
    return (x+1)|0;
}
var heap = new ArrayBuffer(0x10000);          // 64k heap 
asm.js spec

Wir kompilieren jetzt also native Sprachen nach JavaScript das mehr wie C aussieht, damit es
die JavaScript Engine im Browser JITen kann

nachdem es heruntergeladen wurde

Limitationen von asm.js

  • es ist nicht Assembly!
  • es ist JavaScript!
  • ๐Ÿง
  • immernoch JavaScript Syntax
  • groรŸer Download
  • Optimierungen unterscheiden sich
  • aber einfacher zu JITen ๐Ÿคท๐Ÿฝโ€โ™‚๏ธ
webassembly logo

Was ist WebAssembly?

... a simple machine model and executable format with an extensive specification . It is designed to be portable, compact, and execute at or near native speeds
...low-level, assembly-like language rust wasm book
WebAssembly

konsequenter als asm.js

  1. kleinerer download
  2. einfacher zu parsen
  3. echtes assembly
  4. immernoch in der Javascript VM
  5. ๐ŸŽ๏ธ noch schneller

Alon Zakai @mozilla hacks
"Why WebAssembly is Faster Than asm.js"
bonus: "A WebAssembly Toolchain Story"
WebAssembly Startup
Lin Clark "What makes WebAssembly fast?"
youtube 6v4E6oksar0
#direkteinspritzung
compiling the web - Google IO'17
performance

Performance vs ...

WASM vs JavaScript

it's 30x Faster
WebAssembly is โ€œ30Xโ€ Faster than JavaScript

WASM vs asm.js

wasm vs asm.js Mind the Gap

WASM vs Native

...of the 24 benchmarks evaluated, seven run within 10% of native execution and almost all of them run less than 2ร— slower.

Bringing the web up to speed
wasm vs native Mind the Gap
discussion

Pros

  • streng getypt
  • kleiner Downloads
  • performance
  • target fรผr existierenden nativen code
  • Starkes Isolationsmodel
  • neue Sprachen braucht das Web!
  • tooling

Cons

Aber ist das nicht einfach nur wieder der gleiche ScheiรŸ wie JavaApplets oder Flash?

nรถ
  • es ist nicht von Firmen geownet
  • es ist ein Teil des Browsers
  • keine plugins, keine extra Angriffsflรคche
  • Sandboxed genau wie JavaScript
  • Standard, ergo ein Teil des Webs
kudos steve klabnik

๐Ÿ•บAWSM!๐Ÿ’ƒ

capabilities

Was nu?

๐Ÿค” was macht man damit?

... alles was das Web halt kann!

DOM Apis, WebGL, WebAudio, Canvas, alles was ne Javascript Api hat ๐Ÿคท๐Ÿผโ€โ™€๏ธ

und was nicht?

was das Web halt auch nicht kann
udp*
native syscalls: fs, clock, etc*

use cases

Web, Binary
Binary protocols, parsers
Audio*/Video/Image Processing
Cryptography
Computer vision
Emulation: e.g. Gameboy or x86
Web, High Performance
CAD, Science, Games
Low latency apps: VR
As a RunTime
wasmtime, lucet,
wasmjit or wasmer
WASI
CloudABI
in the โ˜๏ธCloud
on cloudflare workers
in AWS Lambda*
More
even moar

๐Ÿ˜๐Ÿ˜ Port your Desktop code to the Web

Und wer macht das schon?

๐Ÿคท๐Ÿผโ€โ™€๏ธ ihr kรถnntet bereits WebAssembly benutzen ๐Ÿฆ

web-dsp

http://tiny.cc/webdsp

rnnoise*

https://people.xiph.org/~jm/demo/rnnoise/

*here asm.js

picovoice

wake word demo

๐Ÿ˜ Lets start Hacking๐Ÿ”จ

๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿพโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿฟโ€๐Ÿ’ป

๐Ÿ‘จ๐Ÿฟโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป๐Ÿ™‹๐Ÿปโ€โ™‚๐Ÿ™‹๐Ÿปโ€๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿพโ€๐Ÿ’ป

building WebAssembly

artisan WebAssembly

ยซWATยป

(module
  (func $i (import "imports" "i") (param i32))
  (func (export "e")
    i32.const 42
    call $i))
Sprachen

Sprachen

WebAssembly Studio

WebAssemblyStudio webassembly.studio
go

Go

AssemblyScript logo

AssemblyScript

almost but not quite entirely unlike TypeScript

AssemblyScript: Limitations*

  • keine union types
  • kein any oder undefined
  • Primitive und Reference Typen
  • manuelles Memory Management
import "allocator/tlsf";
var ptr = memory.allocate(64);
//...
memory.free(ptr);
rust wasm

Rust for WebAssembly

browser API

Und wie kommt das in den Browser?

<html>
    <head>
        <script src="example.wasm" type="application/wasm"/>
    </head>
</html>
Nope!!! Es gibt noch keine Integration fรผr ES Modules 11.04.2019
๐Ÿ™„ sorry
  1. lad die .wasm bytes in einen typed array oder ArrayBuffer
  2. kompiliere es selbst in ein WebAssembly.Module
  3. Instantiiere das WebAssembly.Module mit imports und benutze dessen exports
๐Ÿคฏ
webassembly.org
module von Hand
fetch('simple.wasm')
    .then(response => response.arrayBuffer())
    .then(bytes => WebAssembly.instantiate(bytes, {}))
    .then(results => results.instance.exports);
mdn
await!
const obj = await WebAssembly.instantiateStreaming(
    fetch('simple.wasm'),
    importObject
);

obj.instance.exports.exported_func();
mdn

was ist dieses importObject?

const importObject = {
    env: {
        logger: (str) => console.info(str)
    },
}; 
๐Ÿ“— Understanding the JS API

wie redet man mit WebAssembly?

schreib einfach in JavaScript FFI ๐Ÿ˜จ und tunnel ๐Ÿ˜ฉ alles durch ein quasi C-isches interface ๐Ÿ˜ฑ ffi
๐Ÿ™‡ es gibt nicht mal strings
ist halt assembly ๐Ÿคทโ€โ™‚๏ธ
jumping ferris

exposing a c-like interface shy ferris

#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b + 100
}
// import { add } from 'rust-lib.wasm';
const { add } = await fetch('rust-lib.wasm')
    .then(response => response.arrayBuffer())
    .then(bytes => WebAssembly.instantiate(bytes))
    .then(result => result.instance.exports);

console.dir(add(1,2)); // โ†’ 103

FFI safetyfallen over ferris

const importObject = { env: {
    logger_num: (num) => console.info('logger_num', num),
    logger_str: (str) => console.warn('logger_str', str),
}}
extern "C" {
    fn logger_num(output: i32);
    fn logger_str(output: &str);
}

#[no_mangle]
pub unsafe fn speak() {
    logger_num(42); // 42
    logger_str("42"); // 1048576 ????
}
jumping ferris

codegen to the rescue

hello ferris rustwasm toolbox*

  • wasm-bindgen
  • web-sys & js-sys
  • wasm-pack
  • twiggy,* wee_alloc,* wasm-snip,*
  • @fixgen and @ag_dubs

wasm-bindgen๐Ÿ“•

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}

wasm-bindgen: exporting classes

#[wasm_bindgen]
pub struct Person {
    name: String, // UTF-8
}

#[wasm_bindgen]
impl Person {
    #[wasm_bindgen(constructor)]
    pub fn new(name: String) -> Person {
        Self { name }
    }

    pub fn get_name(&self) -> String {
        self.name.to_owned()
    }
}
import { Foo } from './my_module';
const p = new Person('hendrik');
console.log(p.get_name());

web-sys๐Ÿ“• / js-sys๐Ÿ“•

#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
    let window = web_sys::window().unwrap();
    let document = window.document().unwrap();
    let body = document.body().unwrap();

    let val = document.create_element("p")?;
    val.set_inner_html("Hello from Rust!");

    body.append_child(&val)?;

    Ok(())
}
#[wasm_bindgen]
pub fn left_pad(content: &str, width: usize) -> String {
    format!("{:๐Ÿ‘พ>w$}", content, w = width)
}

wasm-pack๐Ÿ“•

wasm-pack demo

AWSM-Gorillas

STOP! Demo Time

Have an Awsm day!

waving ferris
bonus

binary sizes

binaryen๐Ÿ”—
wasm-opt
wabt๐Ÿ”—
wasm-strip
rust wasm
wee_alloc
twiggy wasm size profiler
wasm-snip replace functions with unreachable

WebAssembly for Isolation

  • UNIX is unsafe
  • Binaries can open Files and NetworkSockets themselves
  • VMs or Docker?
  • JavaScript/wasm isolation model
  • WASMER, wasmtime, lucet, nodejs...
  • CloudABI @ 32c3 WASI ( overview )