Re-publication du billet de CLOCHIX sur son blog

asm.js est un projet de recherche de Mozilla qui vise à améliorer les performances de JavaScript en n’utilisant qu’un sous-ensemble du langage, plus facile à optimiser.

Il se compose de plusieurs sous-projets :

  1. la spécification du langage ;
  2. OdinMonkey, un module de l’interpréteur JavaScript SpiderMonkey, qui prend en charge le code asm.js ;
  3. des travaux sur emscriptem pour que le code généré soit conforme à la spécification asm.js ;

Asm.js

La spécification ne conserve qu’un sous-ensemble strict et bien typé d’EcmaScript, fonctionnant déjà dans tous les navigateurs. Elle impose par exemple que les variables incluent des indications sur leur type, afin que l’interpréteur n’ait pas à le deviner. Elle permet également une meilleure utilisation de la mémoire, limitant les ralentissements causés par le garbage collector (le code asm.js utilise des tableaux typés (_typed arrays_) comme pile pour certaines opérations).  Elle offre aussi la possibilité d’interagir sur le DOM par l’intermédiaire de fonctions externes.

Pour indiquer à l’interpréteur JS que le code respecte la spécification et peut être optimisé, il suffit d’ajouter une nouvelle directive "use asm" de syntaxe similaire au "use strict". Si l’interpréteur ne reconnait pas cette directive, il l’ignorera et interprètera le code normalement. Sinon, il validera que le code respecte bien la norme, et si oui, l’exécutera de façon optimisée.

OdinMonkey

OdinMonkey va bientôt être intégré au tronc de SpiderMonkey. Les performances semblent intéressantes, puisque du code C++ compilé via Emscriptem puis interprété par OdinMonkey ne s’exécute que deux fois plus lentement que lorsqu’il est compilé avec gcc -O2. Ce sont des performances similaires à celles de langages utilisant une machine virtuelle, comme Java ou C#.

Emscriptem

Emscriptem est un compilateur qui traduit en JavaScript du bytecode LLVM obtenu à partir de source en C ou C++. Il permet donc de porter des programmes écrits en C ou C++ pour les exécuter dans un interpréteur JavaScript. À titre d’exemple, un portage de la bibliothèque de composants graphiques multi-plateformes Qt est en cours, qui permet d’exécuter des applications « natives » écrites pour Qt dans un navigateur, la balise canvas étant utilisée pour l’affichage. Pour tester les possibilités d’asm.js en matière de jeux, un portage du jeu de tir en vue subjective Cube 2: Sauerbraten a été entrepris.

D’autres expériences visent à porter les interpréteurs de divers langages. Repl.it propose d’exécuter directement dans le navigateur, après conversion en JavaScript, des programmes écrits en Ruby, Python, Lua, Scheme

L’assembleur du Web

Plus que les implications en terme de performance, l’intérêt d’asm.js est qu’il permet de faire un pas de plus vers le Web comme plate-forme applicative, dont les navigateurs seront le système d’exploitation. D’ici quelques années, il sera possible de faire fonctionner n’importe quel code, quel que soit le langage dans lequel il a été écrit, dans un navigateur.

Bien sûr, il faut raison garder. Il n’y a pas grand-chose de neuf sous le soleil. Le portage d’applications natives vers le navigateur est une vieille lune. Java promettait cela il y a 15 ans, avec le succès que l’on sait. GWT permet depuis des années de compiler d’autres langages en JS, et je n’ai pas l’impression qu’il soit très utilisé hors de Google. Je ne crois guère que des applications entières seront portées directement en JS. Mais je pense que cela va accroitre la perméabilité entre les environnements frontend et backend. Avec SpiderMonkey et node, du code JS écrit pour le navigateur pouvait s’exécuter sur le serveur. Bientôt, toute bibliothèque “serveur” pourra s’exécuter dans le navigateur. On pourra ainsi réellement partager du code, l’écrire dans son langage de prédilection et l’exécuter selon le contexte dans le navigateur ou sur un serveur.

Quelques liens

* une présentation d’Alon Zakai, chercheur de Mozilla et un des trois pères d’asm.js ;

* asm.js: closing the gap between JavaScript and native par le toujours complet Dr. Axel Rauschmayer ;

* asm.js: A Low Level, Highly Optimizable Subset of JavaScript for Compilers.