Slide 1

Slide 1 text

2018 @arturparkhisenko 1 Photo by Ilnur Kalimullin on Unsplash WEBASSEMBLY

Slide 2

Slide 2 text

Closure, Scala, Ruby, Python, Perl, Go, Java/JVM, Erlang, Elixir, C#, F#, Lisp, Scheme, OCaml, Haskell, Smalltalk, C/C++, Basic, PHP, ActionScript, Prolog, Lua and others here. But there’s A New Hope... 2 JavaScript is a compile target for

Slide 3

Slide 3 text

WASM 1. Who is 2. How it works 3. Usage: Why, Where, How 4. Examples 3

Slide 4

Slide 4 text

● Java Applets ● ActiveX ● NaCl & PNaCl ● asm.js *2013 History 4

Slide 5

Slide 5 text

function f(i) { 'use asm'; i = i | 0; return (i + 1) | 0; } ASM.js example 5 int f(int i) { return i + 1; } C++ ASM.js

Slide 6

Slide 6 text

6 source [####################] 19.55s JavaScript [###############_____] 15.67s Asm.js [##########__________] 10.27s Native ASM.js execution time

Slide 7

Slide 7 text

7 Don't reinvent the wheel? ancient-wheel.png

Slide 8

Slide 8 text

8 Size and load-time-efficient binary format (.wasm) It has Intermediate representation (.wast) Compiler target Who is WEBASSEMBLY or WASM Open standard with cross-browser support W3C 20180215: WebAssembly First Public Working Drafts

Slide 9

Slide 9 text

9 C | C++ | Rust | C# | JAVA | Kotlin | AssemblyScript(TS) | Swift And others in future Portability Windows | MacOS | Linux | Android | iOS ... x86_64 | arm | arm64 | i686 | mips | powerpc ... V8 | SpiderMonkey | Chakra | JSC(Nitro) … Compile target for

Slide 10

Slide 10 text

C/C++ Source => Emscripten => WebAssembly C++ -> Clang -> LLVM(IR) -> Emscripten(asm.js) -> binaryen(asm2wasm) -> webAssembly OR C/C++ Source => WASM LLVM backend => s2wasm => WebAssembly C++ -> Clang -> LLVM(IR) -> webAssembly How it works 10

Slide 11

Slide 11 text

11 https://medium.com/reloading/javascript-start-up-performance-69200f43b201

Slide 12

Slide 12 text

12 https://blog.sessionstack.com/how-javascript-works-a-comparison-with- webassembly-why-in-certain-cases-its-better-to-use-it-d80945172d79

Slide 13

Slide 13 text

13 JavaScript code is much more expensive, byte for byte, than an image, because of the time spent parsing and compiling it. It's possible to parse and compile wasm as fast as it comes over the network, which makes it much more like an image than JavaScript code. Game changer! Yehuda Katz, twitter @wycats said:

Slide 14

Slide 14 text

● Existing code portability to web ● Compact (but requires a glue code) ● No Parsing ● Optimization and Deoptimization ● Lower-level (no garbage collection) ● Typed (everything is static) ● A linear memory model (auto-increasing heap) Why WASM 14

Slide 15

Slide 15 text

● No garbage collection: Both asm.js and WASM do not produce ‘garbage’ that needs to be collected ● Everything is static: Once the code is compiled, it is guaranteed to stay that way. ● A linear memory model: C/C++ heap into a single Javascript TypedArray 15 Why WASM is fast

Slide 16

Slide 16 text

2D/3D: AR/VR, Computer vision, Games (Unity, Unreal, etc…), WebGL, mapping – Altus platform, Google Earth, User-interface design, Medical imaging Data processing: Multimedia (Image/Audio/Video) Edit/Recognize/Codecs: Audio mixing , Video codec support , Digital signal processing, Language detection, Compression – zlib-asm, Brotli, lzma, Computer algebra Other: ReactJS ;)? Cross-platform node extensions: performant CLI tooling (LibSass). Desktop apps using Electron / PWA: CAD, Editors. Simulations: Physical simulation / Platform simulation / emulation (ARC, DOSBox, QEMU, MAME) Where 16 source

Slide 17

Slide 17 text

How 17

Slide 18

Slide 18 text

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. LLVM itself is written in C++. It has an IR - intermediate representation. Clang is an "LLVM native" C/C++/Objective-C compiler. LLVM and Clang 18

Slide 19

Slide 19 text

& other: ● Binaryen - Binary + Emscripten: asm2wasm, s2wasm, AssemblyScript, wasm2asm, mir2wasm ● WABT - WebAssembly Binary Toolkit: wat2wasm, wasm2wat, wasm-objdump, wasm-interp, wat-desugar, wasm-link(lld), wasm2c Toolchain 19 LLVM to JavaScript compiler provides: libc, libc++, SDL, GLES2, GLFW

Slide 20

Slide 20 text

20 emsdk - sdk manager, used to perform all SDK maintenance and can install sdk as a bundle which contains: clang, node, emscripten(emcc). emcc - emscripten compiler frontend (use in cli) Emscripten Toolchain

Slide 21

Slide 21 text

JavaScript API ● WebAssembly namespace ● Module ● Loading and running ● Function imports and exports ● Memory 21 to read 1 to read 2

Slide 22

Slide 22 text

Usage 22 to read

Slide 23

Slide 23 text

23 int sum(int x, int y) { return x + y; } sum.c

Slide 24

Slide 24 text

24 emcc -s WASM=1 -s SIDE_MODULE=1 -Oz -g4 -o sum.wasm sum.c Run

Slide 25

Slide 25 text

25 emcc -s WASM=1 -Oz -g4 -o sum.js or -o sum.html sum.c Run

Slide 26

Slide 26 text

26 sum.wast (module (export "_sum" (func $_sum)) (func $_sum (; 0 ;) (param $0 i32) (param $1 i32) (result i32) (i32.add (get_local $1) (get_local $0) ))) This code was a little bit cleaned ;)

Slide 27

Slide 27 text

27 JS loader const loadWASM = async (url, importObject) => { const buffer = await fetch(url) .then(r => r.arrayBuffer()); const result = await WebAssembly .instantiate(buffer, importObject); return result.instance; };

Slide 28

Slide 28 text

28 JS loader const loadWASM2 = (url, importObject) => fetch(url) .then(response => response.arrayBuffer()) .then(buffer => WebAssembly .compile(buffer)) .then(module => new WebAssembly .Instance(module, importObject));

Slide 29

Slide 29 text

29 JS API const importObject = { env: { memoryBase: 0, tableBase: 0, memory: new WebAssembly.Memory({ // ArrayBuffer initial: 1, // 64KiB - single page maximum: 10 // 640KiB }), table: new WebAssembly.Table({ // Table initial: 0, // length element: 'anyfunc' }) } }; new WebAssembly.Memory({initial: 32767, maximum: 65536}) // tab will eat ~1.6gb(2gb), bigger values will throw a RangeError

Slide 30

Slide 30 text

30 JS API loadWASM('sum.wasm', importObject) .then(instance => { const {exports} = instance; const result = exports._sum(40, 2); console.log({instance, result}); });

Slide 31

Slide 31 text

31 JS API

Slide 32

Slide 32 text

32 JS API more ● Call compiled C functions from normal JS ● Call compiled C++ classes from JS ● Call JavaScript functions from C/C++ ● Call passed JS functions using pointers from C/C++

Slide 33

Slide 33 text

● Webpack ○ v2+ as global .js, ○ v3+ as .wasm using wasm-loader ○ v4+ as .wasm * async-only ● Parcel v1.5.0+, as .wasm/.rs Usage 33 A lot of examples here *Sync WebAssembly compilation is not yet implemented - v4.1.1

Slide 34

Slide 34 text

// Webpack 4.1.1 - Sync WebAssembly compilation is not yet implemented import {fib} from './fib.wasm'; console.log('import test fib', fib); Usage, Webpack and Parcel 34

Slide 35

Slide 35 text

// WebAssembly module (indirect) import('./fib-async').then(module => { const result = module.default(13); console.log('fib-async', result); }); Usage, Webpack and Parcel 35

Slide 36

Slide 36 text

// WebAssembly module (direct) import('./fib.wasm').then(({fib}) => { // arg is wasm.fib const result = fib(13); console.log('fib.wasm', result); }); Usage, Webpack and Parcel 36

Slide 37

Slide 37 text

import {fib} from './fib.wasm'; import {fib as fibRs} from './fib.rs'; console.log(fib(42)); console.log(fibRs(42)); import('./fib.rs').then(({fib}) => { // wasm.fib const result = fib(13); console.log('fib-async .rs', result); }); Usage, Parcel 37

Slide 38

Slide 38 text

Filesystem? Emscripten provides a virtual file system that simulates the local file system (MEMFS - default, NODEFS, IDBFS browser indexedDB). Emscripten-generated code running in the browser cannot access files in the local file system. You can use preloading and embedding(package). It is possible to allow access to local file system for code running in node.js, use the NODEFS filesystem option. 38 source

Slide 39

Slide 39 text

"-g" emcc command line option which controls how much debug information is kept when compiling from bitcode to JavaScript. Our case it’s "-g4". This is the highest level of debuggability: ● Don't minify ● Preserve function names ● Preserve variable names ● Preserve LLVM debug information (shows line number, debug comments, source maps) 39 Debugging

Slide 40

Slide 40 text

40 Source file as is Debugging .wast representation .js .wasm In both cases you’ll see human readable format, with ability to set breakpoints.

Slide 41

Slide 41 text

Yehuda Katz, twitter @wycats said: 41 The WebAssembly text format is called WAT (*W*eb*A*ssembly *T*ext format). Whose idea was it to call it WAT and not WTF (Wasm Text Format)?

Slide 42

Slide 42 text

Can i use ASM.js Edge Firefox Chrome Safari 16 53 57 11 42 Can i use WASM Edge Firefox Chrome Safari 13 22 28

Slide 43

Slide 43 text

FAQ 43 Is WebAssembly a security risk? No, unless you consider JS a security risk. WebAssembly is about as secure as Javascript since it runs in the same sandbox. Typical WebAssembly implementations only add a fairly small parser module to the existing JS engine. Can I start a program or process from WebAssembly? Nope, same reason as DLLs, it would be unsafe. ● Today Wasm runs just ~20% slower than native code execution. ● Today no multithreading :/ ● code-that-cannot-be-compiled source

Slide 44

Slide 44 text

FAQ 44 Can I access sockets, files, native API X… from WebAssembly? No, WebAssembly runs inside the browser sandbox and can only access Web APIs (just like Javascript). Emscripten SDK provides wrappers for many common native APIs which simplifies porting existing C/C++ code over (for instance sockets-to-WebSockets, GL-to-WebGL, OpenAL-to-WebAudio, and some more…). Can I load and call into a DLL from WebAssembly? No, DLLs are native machine code and thus off-limits. But WebAssembly supports dynamic linking between WASM modules, this allows to reuse shared code modules (they can be cached locally). source

Slide 45

Slide 45 text

Awesome things ● nectarjs - JS to ANY ● ide.onelang.io - JS to 10 languages ● mbasso/gccx - JSX? CPX support: JSX like syntax in C++ ○ mbasso/asm-dom + mbasso/asm-dom-boilerplate using gccx Perf tests ● why-webassembly-is-faster-than-asm-js ● getting-started-with-webassembly-in-node ● WebAssembly-benchmark ● how-to-get-a-performance-boost-using-webassembly ● WASM-vs-JS-Realtime-pitch-detection Languages ● wasm-wheel - Random Lang for WASM ● blazor-experimental-project - .Net ● teavm.org - Java ● webassembly-swift-c-java-and-oxygene-in-the-browser - Swift, C#, Java ● what-languages-can-be-compiled-to-web-assembly-or-wasm 45 URL’s

Slide 46

Slide 46 text

Examples from this presentation: https://github.com/arturparkhisenko/til/tree/master/wasm Web version (gh-pages): https://github.com/arturparkhisenko/til/tree/master/wasm ● from-asm-js-to-webassembly ● webassembly-for-beginners, ru ● awesome-wasm Video ● Real world WebAssembly - Sergey Rubanov, ru ● WebAssembly and Node.js - Ben Smith ● Compiling for the Web with WebAssembly ● What WebAssembly means for React - Lin Clark ● Hacker's guide to Web Assembly - Vigneshwer Dhinakaran ● Practical WebAssembly - Dan Callahan ● WebAssembly: What and What Next? - Ben Titzer and Andreas Rossberg Course (workshop) google codelabs web-assembly-intro URL’s 46

Slide 47

Slide 47 text

1. webassembly.studio 2. WasmExplorer + WasmFiddle 3. godbolt + gcc.godbolt 4. ast.run 5. shamadee/wasm-init 6. parcel-v1-5-0-released-source-maps-webassembly-rust 7. MichaReiser/speedy.js 8. AssemblyScript 9. npmjs webassembly + wasm 10. kripken binaryen 11. asampson llvm 12. what-is-llvm-the-power-behind-swift-rust-clang-and-more 13. kripken Porting-Examples-and-Demos URL’s : tools 47

Slide 48

Slide 48 text

1. an-introduction-to-webassembly 2. xtuc/js-webassembly-interpreter - polyfill 3. a-crash-course-in-memory-management in 3 parts 4. callahad tccc20-wasm 5. webassembly-demystified 6. WebAssembly/wabt 7. asmjs spec 8. WebAssembly and the Future of the Web - kgryte 9. kripken mloc_emscripten_talk 10. mozilla webassembly-in-browsers 11. how-javascript-works-a-comparison-with-webassembly-why-in-certain-cases-its-better-to-use-it 12. gurugio/lowlevelprogramming-university 13. speed-up-your-node-js-app-with-native-addons 14. AndrewScheidecker/WAVM 15. alexnoz/wasm-class-sample 16. ballercat/walt 17. ir-is-better-than-assembly 18. tomassetti introduction-to-webassembly 19. https://habrahabr.ru/post/345748/ ru (assemblers) 20. https://habrahabr.ru/post/342180/ ru 21. https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html 22. https://github.com/asRIA/emscripten-docker 23. https://developers.google.com/web/updates/2018/03/emscripting-a-c-library URL’s : other 48

Slide 49

Slide 49 text

Own arturparkhisenko wasm examples intro arturparkhisenko wasm examples fib-module-used Top 1. emulators win311vr 2. unity3d AngryBots 3. unreal EpicZenGarden + video 4. webassembly skeletal animation + repository Other 1. maierfelix wasm-particles + repository 2. floooh sokol-html5 + repository 3. funky karts + article about 4. webassembly demo tanks 5. sniklaus raytracer 6. aransentin cwasm 7. shamadee/web-dsp-demo + url 8. JasonHuang3D/AJC-Flash-WebAssembly-Examples 49 URL’s : demos

Slide 50

Slide 50 text

● Binary and text format ● Low-level compiler target ● Small, Fast & Robust ● Enhances existing code Conclusion 50 2018 @arturparkhisenko

Slide 51

Slide 51 text

● WasmWeekly twitter ● Alon Zakai twitter ● Dmitriy Tsvettsikh twitter, medium ● Sergey Rubanov twitter, medium Whom to follow 51 2018 @arturparkhisenko

Slide 52

Slide 52 text

URL: https://goo.gl/bUKdoq Thanks! Questions? 52 2018 @arturparkhisenko