WebAssembly, bytecode pour navigateur

Ce projet conjoint entre éditeurs de navigateur propose un langage intermédiaire pour le Web basé au départ sur asm.js.

Présenté par Brendan Eich, le créateur de JavaScript et en partie d'Asm.js, WebAssembly ou Wasm, est un nouveau langage de représentation intermédiaire (IRL) compatible avec tous les navigateurs. Il permettra à différents langages de haut niveau, de fonctionner dans les navigateurs en étant compilés en Wasm. Le but initial est de compiler des programmes et bibliothèques de C et C++ en WebAssembly. Puis d'autres langages devront suivre.

En juin 2015, le développement ne fait que commencer. Mais il est facilité par l'utilisation d'Asm.js comme point de départ. Ce sous-ensemble de JavaScript est compatible avec tous les navigateurs.

WebAssembly schéma de fonctionnement

Le but est de conserver la compatibilité entre Asm.js et wasm durant quelques années. Pas seulement pour le support avec les navigateurs, mais aussi parce qu'Asm.js est lui aussi en développement, et que les nouvelles possibilités qu'on lui inclut seront indispensables également à wasm. Par exemple les threads avec mémoire partagée, le support des processeurs multi-coeurs.

Par la suite, lorsque tous les navigateurs supporteront le nouveau langage WebAssembly, les deux langages pourront diverger. Le second sera modifié sans que l'on touche à Asm.js, et donc JavaScript.

Wasm reçoit notamment le support de Google avec l'implication du team NaCl, aussi on peut donc anticiper l'abandon de ce dernier dont l'objectif était assez proche: faire fonctionner des applications native dans le navigateur. Par ailleurs le team V8 a annoncé l'intégration en cours de wasm dans le compilateur JavaScript. Ainsi le moteur wasm peut produire code IR (représentation intermédiaire) qui est directement interprété en JIT.

Les expérimentations ont montré que pour le temps de parsing du nouveau code (pas la vitesse d'exécution) peut être plus rapide de 20 fois que celui d'Asm..js. La taille du code binaire produit elle est aussi moins importante qu'en Asm.js.
Selon Brendan Eich, wasm est en fait un "encodage AST compressé" et non un vrai bytecode. AST pour Abstract Syntax Tree, l'arborescence du code.

Quelques autres avantages de wasm:

Et un inconvénient:

Même si les langages compilés en WebAssembly deviennent une alternative possible à JavaScript, celui-ci restera supporté et privilégié par les navigateurs. Wasm fera partie du compilateur JS.

Pourquoi un nouveau langage intermédiaire?

Pourquoi ne pas utiliser simplement LLVM, le bytecode Java, ou .NET?

L'objectif premier de wasm est de pouvoir faire fonctionner le code source écrit en C et C++ dans les applications Web. Une quantité immense de fonctions a été écrite dans ces langages, pouvoir les réutiliser avec un temps d'exécution comparable est vraiment appréciable. Les jeux en 3D aussi sont pour la plupart écrits en C++: ils deviennent portables avec wasm.
Wasm veut être aux applications dans le navigateur ce que Vulkan est à OpenGL et DirectX: un code intermédiaire universel et portable avec une vitesse d'éxécution proche du natif.

LLVM

Le bitcode LLVM n'a pas été retenu parce qu'il n'est pas portable. Il contient des méta-données et est conçu pour produire des binaires exécutables, non pour fonctionner directemment sur tous les systèmes.
D'ailleurs Google a déjà essayé d'utiliser LLVM dans le navigateur avec NaCL et cela n'a pas été adopté par les autres éditeurs.
Cependant on utilise Emscriptem pour compiler le langage intermédiaire de LLVM en wasm, donc on garde le bénéfice de ses outils.

.NET

Le runtime .NET dispose d'un code intermédiaire qui peut s'exécuter avec une machine virtuelle ou être compilé. Cependant il ne convient pas aux langages C et C++. Microsoft utilise C++/CLI qui est différent du C++ natif.

JVM

La machine virtuelle Java n'en est pas une non plus car si de nombreux langages ont été portés sur cette plateforme, ce n'est pas le cas de C et C++. Sans même compter la propension d'Oracle à faire des procès pour un motif aussi futile que l'utilisation de son API. Le Web tout entier pourrait se trouver face à l'armée de juristes hargneux de la firme, ce qui serait désastreux. WebAssembly permettra de développer en paix.

Citations de Brendan Eich sur WebAssembly

La continuation de l'évolution d'ASM.js est wasm.

Au début, WebAssembly commence comme ASM.js, mais avec une syntaxe compressée, c'est une syntaxe binaire. Mais une fois que tous les navigateurs supporteront à la fois wasm et ASM.js, et après un intervalle décent de mises à jour des navigateurs, alors wasm pourra commencer à grandir avec des sémantiques de plus qui n'ont pas besoin d'être mises dans JavaScript.

Il y a une quantité de langages que vous pourriez compiler en wasm.

Assumer que le web est en stase - ce n'est pas une bonne hypothèse, je pense que c'est l'erreur qui s'est produite il y a longtemps avec des projets comme Portable Native Client, et Dart aussi.

WebAssembly vs Java

Lest créateurs du langage ont vu bien plus loin que le navigateur quand ils ont défini sa spécification. En fait elle est partagée en deux couches:

Le langage lui-même peut ainsi être utilisé dans toutes sortes de plateformes: sur le Web, sur le bureau, et sur tout système d'exploitation. Cela dépend des APIs que l'on ajoutera au langage et les développeurs sont en train actuellement de les multiplier. Il existe même un système d'exploitation, Nebulet, ou tout est écrit en wasm et compilé en binaire.

Le projet WASI a pour but de créer une interface standard à tous les systèmes d'exploitation pour qu'un même code binaire wasm puisse être compilé une seule fois et utilisé partout. On peut alors comparer WebAssembly à Java. Le premier à l'avantage de fonctionner en isolation avec sa propre mémoire, donc permettre des applications plus sûres. Il n'y a pas non plus l'ombre d'Oracle et ses restrictions sur la "propriété intellectuelle".

Un autre avantage sur Java est qu'étant conçu pour fonctionner même sur les mini processeurs de l'IoT, le runtime est beaucoup plus léger que celui de Java. Il peut cependant s'utiliser sur le bureau et sur serveur où il rendra les conteneurs comme docker superflus.

Comment créer et utiliser du code WebAssembly

Il vous faut installer emsdk, et wasmer ou wasmtime, pour produire des programmes wasm.

Vous pouvez alors compiler un source C ou C++ en wasm avec cette commande:

emcc demo.cpp -o demo.wasm

et exécuter le programme avec cette commande:

wasmtime demo.wasm

Un tutoriel complet en français est fourni sur le site: webassembly.fr.

Les outils pour générer le code et le faire fonctionner sont disponibles sur GitHub.

Références