class: center, middle # WebAssembly ### Une nouvelle cible de compilation pour le Web --- background-image: url(./img/firefox.png) background-size: 50% auto --- class: middle, center # SpiderMonkey .inline-img[![IonMonkey](img/ion.jpg)] .inline-img[![OdinMonkey](img/odin.jpg)] .inline-img[![BaldrMonkey](img/baldr.jpg)] --- class: middle # Qu'est-ce que WebAssembly ? - Un **standard** du W3C. - Coopération entre Apple, Google, Microsoft et Mozilla. - Un format **binaire**... - *compact* ; - *portable* ; - *sûr* ; - rapide à *charger* ; - rapide à *exécuter* ; - ... et un format **texte**\*. .right.small-text[\*(alerte divulgachâge, `view-source` n'est pas mort).] ??? un "assembleur" pour le web, pas un langage de programmation en soi. format texte : - correspondant directement au format binaire ; - plus simple que du vrai assembleur. --- class: middle, big # Plusieurs manières de voir WebAssembly 1. un complément à JavaScript 2. l'évolution d'asm.js 3. une cible de compilation 4. un jeu d'instructions *virtuel* --- class: middle, big # Un complément à JavaScript - Hautes performances. - Facile à mettre en cache. - Et à partager. ??? - **Idéal** pour des bibliothèques de code ! --- class: middle, big # Usages - *frameworks*. - programme lourd + front HTML écrit à la main. - programme entier compilé. ??? - e.g. Ember --- class: middle, big # Domaines - compression d'images ou de vidéos côté client. - intégration de codecs expérimentaux. - traitement du signal. - cryptographie. - moteurs physiques. - jeux vidéos. --- class: middle, big # L'évolution d'asm.js *Sous-ensemble* de JavaScript, sujet à *validation* et *pré-compilation*, hautement optimisable avec des *performances élevées* garanties, issu de la compilation de code C/C++. --- class: clear-slide # Juste du JavaScript ``` (function module(global, imports, heap) { var F64View = new global.Float64Array(heap); var print = imports.print; function f(i) { i = i | 0; var y = 0.; y = +F64View[i >> 3]; y = +(+(i|0) + y); print(y); } return { f: f }; })(window, { print(x) { console.log(x); } }, new ArrayBuffer(0x10000)) .f(42); ``` --- class: clear-slide # Un indice, chez vous ``` (function module(global, imports, heap) { * "use asm"; var F64View = new global.Float64Array(heap); var print = imports.print; function f(i) { i = i | 0; var y = 0.; y = +F64View[i >> 3]; y = +(+(i|0) + y); print(y); } return { f: f }; })(window, { print(x) { console.log(x); } }, new ArrayBuffer(0x10000)) .f(42); ``` --- class: big # Pourquoi asm.js ? - Porter des applications natives vers le Web. -- - Profiter de bibliothèques natives dans JavaScript. -- - Garantir des performances proches du natif. -- - **Eviter les plugins.** --- class: big # L'histoire d'asm.js - 2009-2012 : Mozilla Research : *Emscripten*, *asm.js*. - 2013-2014 : asm.js optimisé dans **Firefox** ; preuve de concept. - 2015-2016 : **Edge** optimise asm.js ; utilisé par Adobe, AutoDesk, Epic, Facebook, Mega, [Unity](http://beta.unity3d.com/jonas/DT2/). ??? - 2009-2012 : Mozilla Research commence des expérimentations : - *Emscripten* : ensemble d'outils, basés sur `clang` et `LLVM`, pour compiler de C/C++ vers JavaScript. - *asm.js* : optimisation du code généré par Emscripten. - 2013-2014 : - asm.js publié dans Firefox. - les optimisations prouvent qu'il est possible de lancer des jeux vidéos dans le navigateur. - 2015-2016 : - Microsoft Edge implémente la précompilation et des optimisations d'asm.js. - Adobe, AutoDesk, Epic, Facebook, Mega, [Unity](http://beta.unity3d.com/jonas/DT2/) utilisent du code asm.js généré avec Emscripten. --- class: big # Aller plus loin qu'asm.js - threads (*SharedArrayBuffer* + *Atomics*). - SIMD (*SIMD.js*). - *dynamic linking*. - mémoire élastique. --- class: big # Aller plus loin qu'asm.js - Réduire le temps de compilation. -- - Réduire le temps de chargement. -- - Réduire l'empreinte mémoire. -- - Réduire le fossé avec les performances natives. --- class: middle, center, clear-slide # WebAssembly comme évolution naturelle ``` (x + y | 0) => i32.add F64View[ptr >> 3] | 0 ~> f64.load Math.fround(x + y) => f32.add ??? => i64.add ``` --- class: big # Une cible de compilation - Objectifs : compact, rapide à *compiler*. -- - \~langage assembleur. -- - *stack machine* typée. -- - encodage postfixe d'un *abstract syntax tree* (**AST**). -- - *control flow* structuré. ??? - Conçu pour minimiser la *taille du code* (compact) et maximiser la *vitesse de compilation*. - \~langage assembleur. - typé statiquement - plus abstrait qu'un vrai asm - stack machine typée. - rapide à compiler (en une passe) - simple à compiler (allocation de registres) - encodage postfixe d'un *abstract syntax tree* (**AST**). - simple à valider - simple à afficher sous forme de texte - *control flow* structuré. - pas de goto - simplifie beaucoup d'algorithmes --- class: big # Un jeu d'instructions virtuel - *Sandbox* (mémoire linéaire). -- - Portable. -- - Proche du code machine. -- - Indépendent de l'environnement *hôte*. ??? - Sûreté du code (*sandboxing*) - Pas d'*aliasing* entre les adresses de retour et la mémoire. - Vérification des accès mémoires. - Portabilité : - inter-navigateurs (Firefox, etc.). - inter-architectures (x64, x86. ARM, etc.). - inter-OS (Windows, GNU/Linux, MacOS, etc.). - Aussi proche que possible du code machine (pour la performance). - tension avec l'objectif de portabilité. - Peut s'exécuter dans un environnement Web, ou node, ou ... --- class: middle, not-so-big # Exemples
wasm
x86
ARM
i32.add
addl
ADD
call
call
BL
i32.load8_s
(check) + movsb
(check) + LDRSB
--- class: middle, big # *Work in progress* - Spécifié et implémenté de manière incrémentale. - Interopérabilité entre Chrome, Edge et Firefox (Nightly). - *MVP* = asm.js + stéroïdes. - [Démo](http://webassembly.github.io/demo) ??? Puisque le MVP n'est qu'une version améliorée d'asm.js, asm.js peut être utilisé en tant que polyfill de wasm en attendant. --- class: middle, center # Des formats texte *temporaires* .centered[![Exemple de format texte](img/ast-to-sexpr.png)] --- class: clear-slide # Une simple addition ```wasm ;; wasm source (module (func $add (param $lhs i32) (param $rhs i32) (result i32) (i32.add (get_local $lhs) (get_local $rhs)) ) (export "add" $add) ) ``` ```javascript fetch('demo.wasm').then(response => response.arrayBuffer() ).then(bytes => { * let module = new WebAssembly.Module(bytes); * let instance = new WebAssembly.Instance(module); alert("13 + 37 = " + instance.exports.add(13, 37)); }); ```
Demo
--- class: clear-slide # Aller plus loin ``` // integration (possible) avec les modules ES6 ``` ``` // Avec des Promises. fetch('demo.wasm').then(response => response.arrayBuffer() // ou des streams ? // response.body.getReader() ).then(bytes => * WebAssembly.compile(bytes); ).then(module => { * let instance = new WebAssembly.Instance(module); alert("1 + 2 = " + instance.exports.add(1, 2)); }); ``` --- class: middle, big # Au delà de C++ : Java, .NET... - *Garbage-collector*. - *[TypedObjects](https://github.com/nikomatsakis/typed-objects-explainer)* (~`struct` en C). - Notifications post-mortem. ??? - Intégration du *garbage-collector*. - *[TypedObjects](https://github.com/nikomatsakis/typed-objects-explainer)* (~`struct` en C). - Notifications post-mortem (*finalizers*). --- class: middle, big # ... Ruby, Python, JS - Valeurs dynamiques. - *stub compilation*. - *patching*. ??? - Support pour des valeurs dynamiques (non typées). - *Patching*. - Compilation de tous petits morceaux de code. --- background-image: url(./img/yo-dawg.png) background-size: 100% auto --- class: middle, center # FAQ --- class: middle, center # Quand sortira WebAssembly ? ??? Fin d'année pour une version de démonstration. --- class: middle, center # Pourrait-on avoir un compilateur JS -> wasm ? ??? Oui, mais c'est équivalent à réimplémenter une VM JS. --- class: middle, center # Est-ce la mort de JavaScript ? ??? Non (à mon humble avis). - Communauté hyper active autour de JavaScript. - JS devient *plaisant* à utiliser (notamment avec ~~ES6~~ ES2015). - Toujours présent dans les navigateurs et langage de prédilection du web. --- class: middle, center # Voir aussi ## [https://webassembly.github.io/](https://webassembly.github.io/) ## [https://github.com/WebAssembly](https://github.com/WebAssembly) ## [http://bnjbvr.github.io/slides/2016/parisweb-wasm/](http://bnjbvr.github.io/slides/2016/parisweb-wasm/) ## [@bnjbvr](https://twitter.com/bnjbvr) --- class: middle, center, big # Bonus : plus de démos - [DeadTrigger2](http://beta.unity3d.com/jonas/DT2/) (asm.js). - [Caesar III](http://epicport.com/en/caesar3) (asm.js). - [Angry Bots](http://webassembly.github.io/demo) (wasm/asm.js).