class: middle, less-space, title-bg, title, jskongress-title # WebAssembly for the Rust of Us ## Rust Hungary 3rd Edition ## Jan-Erik Rediger — [@badboy_](https://twitter.com/badboy_) — 2017-11-23 .rusthungary[![Rust Hungary](media/rusthungary.png)] --- layout: true --- class: center, middle
Activate Demo
--- class: center, middle, less-space, introduction
Jan-Erik Rediger
@badboy_
Organizer
Work / Tech Speaker
--- class: middle, center, wasmlogo ![](media/web-assembly-logo.svg) --- class: center, middle, wasmlogo ![What is WebAssembly?](media/web-assembly-questionmark.svg) --- class: center, middle # History time --- class: jslogo # 1995 ![](media/js.jpg) --- class: jslogo # 2000s ![](media/adobe_flash.svg) --- class: jslogo # 2008 ![](media/v8.png) --- class: jslogo, asmjs # 2013 ## asm.js ### an extraordinarily optimizable, low-level subset of JavaScript .footnote[\* slide design adapted from [asmjs.org](http://asmjs.org/)] --- class: code, big, nospecialhighlight # Type Annotations in asm.js ```javascript function add(x, y) { ` ` ` ` return (x + y); } ``` --- class: code, big # Type Annotations in asm.js ```javascript function add(x, y) { `x = x|0;` // <- parameter type annotation y = y|0; `return (x + y) | 0;` } // ^- return type annotation ``` ??? > --- class: imgfull # Linear memory access ![](media/memory.svg) .footnote[from ["Introduction to WebAssembly"](https://rsms.me/wasm-intro) by Rasmus Andersson] --- class: code, increased, hiddenslide # Linear memory access ```c size_t strlen(char *ptr) { char *curr = ptr; while (*curr != 0) { curr++; } return (curr - ptr); } ``` --- class: code, increased, hiddenslide # Linear memory access ```js function strlen(ptr) { ptr = ptr|0; var curr = 0; curr = ptr; while (HEAP8[curr]|0 != 0) { curr = (curr + 1)|0; } return (curr - ptr)|0; } ``` --- class: code, increased, hiddenslide # Linear memory access ```js function strlen(ptr) { ptr = ptr|0; var curr = 0; curr = ptr; * while (HEAP8[curr]|0 != 0) { curr = (curr + 1)|0; } return (curr - ptr)|0; } ``` --- class: wasmlogo # 2015 ![](media/web-assembly-logo.svg) --- class: center, middle, wasmlogo ![What is WebAssembly?](media/web-assembly-questionmark.svg) --- class: code, increased # What is WebAssembly? * Binary executable format for the web ```binary 00 61 73 6d 01 00 00 00 01 86 80 80 80 00 01 60 01 7f 01 7f 03 82 80 80 80 00 01 00 04 84 80 80 80 00 01 70 00 00 05 83 80 80 80 00 01 00 01 06 81 80 80 80 00 00 07 91 80 80 80 00 02 06 6d 65 6d 6f 72 79 02 00 04 68 61 6c 66 00 00 0a 8d 80 80 80 00 01 87 80 80 80 00 00 20 00 41 01 6d 0b ``` --- class: code, increased # What is WebAssembly? * General purpose virtual architecture ```binary get_local $0 i32.const 2 i32.add i32.const 42 i32.eq return ``` --- class: wasmlogo # What is WebAssembly? * Compiler target ![](media/compiler-process.svg) --- class: wasmlogo # What is WebAssembly? * Open standard ![W3C](media/w3c-cg.svg) --- class: middle, center, browserlogos ![](media/firefox.svg) ![](media/chrome.svg) ![](media/edge.svg) ![](media/safari.svg) .footnote[[WebAssembly support now shipping in all major browsers](https://blog.mozilla.org/blog/2017/11/13/webassembly-in-browsers/)] --- class: underlinedstrong, centeredanswer # What is WebAssembly __not__? --- class: underlinedstrong, centeredanswer # What is WebAssembly __not__? ## Replacement for JavaScript --- class: underlinedstrong, centeredanswer # What is WebAssembly __not__? ## Programming Language --- class: underlinedstrong, centeredanswer # What is WebAssembly __not__? ## Target for every language\* .footnote[\* yet] --- class: center, middle, hiddenslide # Why WebAssembly? --- class: smaller-list, hiddenslide # Why not use asm.js? .-- .left-col[ ## Pros: * "It's just JavaScript" * It's fast ] .-- .right-col[ ## Cons: * Informal spec * No speed guarantuees * Hard to extend ] --- # Why WebAssembly? --- class: centeredanswer # Why WebAssembly? ## Smaller than asm.js --- class: centeredanswer # Why WebAssembly? ## Faster parsing --- class: centeredanswer # Why WebAssembly? ## Freedom to extend --- class: centeredanswer # Why WebAssembly? ## Formal specification --- class: wasmlogo # How to use it ## Use the compiler! ![](media/compiler-process.svg) --- class: center, biggerh2 ![](media/emscripten-logo.svg) ## open source LLVM-based compiler from C and C++\* to JavaScript/asm.js/WebAssembly .footnote.big[\* and Rust] -- .no[![no](media/no.gif)] --- class: code, big # Some C code ```c int half(int x) { return x / 2; } ``` -- .no[![no](media/no.gif)] --- class: big, center, middle # [#45905: std: Add a new wasm32-unknown-unknown target](https://github.com/rust-lang/rust/pull/45905) .footnote[Landed in nightly, but is missing LLVM bits] --- class: big, center, middle # Anyway ... --- class: code, big # Some Rust code ```rust #[no_mangle] pub extern "C" fn greet() -> &'static str { "Jó estét, Budapest!" } fn main() {} // necessary, // because it's not a lib ``` --- class: code, large # Compile it (native) ```binary rustc -O greet.rs ``` --- class: code, large # Compile it (wasm) ```binary rustc -O --target \ wasm32-unknown-unknown \ greet.rs ``` --- class: code, large # Keep it small ```binary wasm-gc \ greet.wasm greet.gc.wasm ``` .footnote[[github.com/alexcrichton/wasm-gc](https://github.com/alexcrichton/wasm-gc), will be unnecessary eventually] --- class: code, increased ## Wasm (binary representation) ```binary 00 61 73 6d 01 00 00 00 01 40 0b 60 03 7f 7f 7f 01 7f 60 01 7f 00 60 01 7f 01 7e 60 03 7f 7f 7f 05 08 08 04 09 04 01 05 01 03 03 08 04 01 03 01 06 07 06 03 01 07 07 02 05 05 01 05 01 00 05 05 01 00 05 05 03 01 01 01 01 02 01 01 05 01 05 01 05 01 05 01 07 05 07 07 01 02 01 00 05 05 07 07 01 00 04 09 07 01 07 01 03 07 03 05 07 00 05 01 07 00 06 05 05 05 05 00 05 09 0a 00 05 01 00 05 05 01 00 05 05 05 05 07 00 05 00 04 04 04 05 01 70 01 3e 3e 05 03 01 00 11 07 28 03 06 6d 65 6d 6f 72 79 02 00 05 67 72 65 65 74 00 00 13 72 75 73 74 5f 65 68 5f 70 65 72 73 6f 6e 61 6c 69 74 ``` --- class: code, increased, fixhighlight ## Wasm (binary representation) ```binary `00 a s m ` 01 00 00 00 01 40 0b 60 03 7f 7f 7f 01 7f 60 01 7f 00 60 01 7f 01 7e 60 03 7f 7f 7f 05 08 08 04 09 04 01 05 01 03 03 08 04 01 03 01 06 07 06 03 01 07 07 02 05 05 01 05 01 00 05 05 01 00 05 05 03 01 01 01 01 02 01 01 05 01 05 01 05 01 05 01 07 05 07 07 01 02 01 00 05 05 07 07 01 00 04 09 07 01 07 01 03 07 03 05 07 00 05 01 07 00 06 05 05 05 05 00 05 09 0a 00 05 01 00 05 05 01 00 05 05 05 05 07 00 05 00 04 04 04 05 01 70 01 3e 3e 05 03 01 00 11 07 28 03 06 6d 65 6d 6f 72 79 02 00 05 67 72 65 65 74 00 00 13 72 75 73 74 5f 65 68 5f 70 65 72 73 6f 6e 61 6c 69 74 ``` --- class: code, increased ## Wasm (binary representation) ```binary 00 a s m 01 00 00 00 01 40 0b 60 03 7f 7f 7f 01 7f 60 01 7f 00 60 01 7f 01 7e 60 03 7f 7f 7f 05 08 08 04 09 04 01 05 01 03 03 08 04 01 03 01 06 07 06 03 01 07 07 02 05 05 01 05 01 00 05 05 01 00 05 05 03 01 01 01 01 02 01 01 05 01 05 01 05 01 05 01 07 05 07 07 01 02 01 00 05 05 07 07 01 00 04 09 07 01 07 01 03 07 03 05 07 00 05 01 07 00 06 05 05 05 05 00 05 09 0a 00 05 01 00 05 05 01 00 05 05 05 05 07 00 05 00 04 04 04 05 01 70 01 3e 3e 05 03 01 00 11 07 28 03 06 `m e m` `o r y` 02 00 05 67 72 65 65 74 00 00 13 72 75 73 74 5f 65 68 5f 70 65 72 73 6f 6e 61 6c 69 74 ``` --- class: code, increased ## Wasm (binary representation) ```binary 00 a s m 01 00 00 00 01 40 0b 60 03 7f 7f 7f 01 7f 60 01 7f 00 60 01 7f 01 7e 60 03 7f 7f 7f 05 08 08 04 09 04 01 05 01 03 03 08 04 01 03 01 06 07 06 03 01 07 07 02 05 05 01 05 01 00 05 05 01 00 05 05 03 01 01 01 01 02 01 01 05 01 05 01 05 01 05 01 07 05 07 07 01 02 01 00 05 05 07 07 01 00 04 09 07 01 07 01 03 07 03 05 07 00 05 01 07 00 06 05 05 05 05 00 05 09 0a 00 05 01 00 05 05 01 00 05 05 05 05 07 00 05 00 04 04 04 05 01 70 01 3e 3e 05 03 01 00 11 07 28 03 06 6d 65 6d 6f 72 79 02 00 05 `g r e e t ` 00 00 13 72 75 73 74 5f 65 68 5f 70 65 72 73 6f 6e 61 6c 69 74 ``` --- class: code, large # Make it readable ```binary wasm2wat \ greet.gc.wasm > greet.wat ``` .footnote[[github.com/WebAssembly/wabt](https://github.com/WebAssembly/wabt)] --- class: code, increased ## Wat (text representation) ```binary (module (memory (;0;) 17) (export "memory" (memory 0)) (export "greet" (func 0)) (func (;0;) (param i32) get_local 0 i32.const 21 i32.store offset=4 get_local 0 i32.const 16 i32.store) (data (i32.const 16) "J\c3\b3 est\c3\a9t, Budapest!") ) ``` --- class: code, increased ## Wat (text representation) ```binary (module `(memory (;0;) 17)` `(export "memory" (memory 0))` `(export "greet" (func 0))` (func (;0;) (param i32) get_local 0 i32.const 21 i32.store offset=4 get_local 0 i32.const 16 i32.store) (data (i32.const 16) "J\c3\b3 est\c3\a9t, Budapest!") ) ``` --- class: code, increased ## Wat (text representation) ```binary (module (memory (;0;) 17) (export "memory" (memory 0)) `(export "greet" (func 0))` (func (;0;) (param i32) get_local 0 i32.const 21 i32.store offset=4 get_local 0 i32.const 16 i32.store) (data (i32.const 16) "J\c3\b3 est\c3\a9t, Budapest!") ) ``` --- class: code, increased ## Wat (text representation) ```binary (module (memory (;0;) 17) (export "memory" (memory 0)) (export "greet" (func 0)) `(func (;0;) (param i32)` ` get_local 0` ` i32.const 21` ` i32.store offset=4` ` get_local 0` ` i32.const 16` ` i32.store)` (data (i32.const 16) "J\c3\b3 est\c3\a9t, Budapest!") ) ``` --- class: code, increased ## Helpers on the other side ```javascript function alloc_out_param() { const ptr = alloc(2 * POINTER_WIDTH); return ptr; } ``` .footnote[all examples shortened, full code in [github.com/killercup/wasm-experiments](https://github.com/killercup/wasm-experiments)] -- .overlay-box[![](media/out-param.svg)] --- class: code, increased ## Helpers inside ```rust // Poor dev's allocator #[no_mangle] pub extern "C" fn alloc(size: usize) -> *mut c_void { let mut buf = Vec::with_capacity(size); let ptr = buf.as_mut_ptr(); mem::forget(buf); return ptr as *mut c_void; } ``` .footnote[all examples shortened, full code in [github.com/killercup/wasm-experiments](https://github.com/killercup/wasm-experiments)] --- class: code, increased ## Helpers on the other side (again) ```javascript function getStr(ptr) { const dataPtr = getI32(ptr); const length = getI32(ptr + POINTER_WIDTH); const bufferAsU8 = getSliceData(pointer, length); const utf8Decoder = new TextDecoder("UTF-8"); const bufferAsUtf8 = utf8Decoder.decode(bufferAsU8); return bufferAsUtf8; } ``` .footnote[all examples shortened, full code in [github.com/killercup/wasm-experiments](https://github.com/killercup/wasm-experiments)] --- class: code, big, gap, button # JavaScript API ```javscript fetch('src/greet.gc.wasm') .then(data => data.arrayBuffer()) .then(buf => WebAssembly.compile(buf)) .then(mod => WebAssembly.instantiate(mod)) .then(ins => /* code from before */ ) ```
Run code
--- class: middle, center # [hellorust.com](http://hellorust.com/) --- class: # What's missing? * `libstd` stubbed out -- * JS implementations -- * Testing -- * Documentation, examples, tutorials --- class: wasmlogo # Soon: ![](media/webpack.svg) ### "Drop Rust files into a folder and it will *Just Work*!" .footnote[["Implementing first-class support for WebAssembly" funded by Mozilla Open Source Support](https://medium.com/webpack/webpack-awarded-125-000-from-moss-program-f63eeaaf4e15)] --- class: inline-img, centeredhead, hiddenslide # 🦄 WebAssembly's future 🦄 .-- * Threads - [#1073](https://github.com/WebAssembly/design/issues/1073) .-- * SIMD - [#1075](https://github.com/WebAssembly/design/issues/1075) .-- * GC/DOM/Web API integration - [#1079](https://github.com/WebAssembly/design/issues/1079) --- class: less-space, title, jskongress-title ## Rust Hungary 3rd Edition
Budapest, 23 November 2017 # Thank you! ## Jan-Erik Rediger — [@badboy_](https://twitter.com/badboy_) ## Slides: [fnordig.de/rust-hungary2017](https://fnordig.de/rust-hungary2017) --- class: credits ### Sources & Credit * Code File: Pham Thi Dieu Linh, [The Noun Project](https://thenounproject.com/), CC BY 3.0 * Gears: Gregor Cresnar, [The Noun Project](https://thenounproject.com/), CC BY 3.0 * Linear Memory: [Introduction to WebAssembly](https://rsms.me/wasm-intro) * [WebAssembly Video Editor](https://d2jta7o2zej4pf.cloudfront.net/) * [hellorust.com](http://www.hellorust.com/) - Demos & Info * [github.com/killercup/wasm-experiments](https://github.com/killercup/wasm-experiments)