JavaScript en ligne de commande avec le compilateur V8
Un compilateur JIT qui peut fonctionner dans un navigateur ou de façon indépendante pour utiliser JavaScript localement comme langage de scripting.
Ce compilateur est fourni sous forme open source par Google ce qui a permis le développement d'outils comme la plateforme de serveur d'applications Node.js.
Sa rapidité d'exécution en effet permet d'utiliser JavaScript pour réaliser des logiciels systèmes. Il n'interprète pas le code mais le compile avant de l'exécuter, bien que les variables soient dynamiques et donc puissent changer de type au cours du développement du programme. Mais on dispose de techniques comme l'inférence de type pour gérer ce problème.
V8 dispose d'un garbage collector (du type stop-the-world, il stoppe l'exécution pour un cycle de nettoyage), un avantage par rapport au langage C++. Il recourt à un assembleur basé sur celui de Smalltalk (Strongtalk), pour créer du code natif à partir du bytecode de haut-niveau.
Il implémente (en 2012) ECMA-262, la troisième édition de JavaScript, et fonctionne sur Windows, MacOS et Linux (ARM ou x386).
V8 est très rapide et on se demande s'il a besoin d'Asm.js à la vue du dernier benchmark (en octobre 2013) de l'équipe de Google, qui compare le compilateur V8 avec le compilateur de Firefox, les deux avec du code Asm.js.
Vitesse comparée d'exécution du code Asm.js sur Firefox et sur Chrome (Source Google)
La valeur 1 signifie une fois la vitesse du code binaire
On a pu croire qu'Asm.js avait été implémenté dans Chrome. Ce n'est pas le cas, la vitesse de V8 est telle que dans certains cas, le code JavaScript (pas seulement le sous-ensemble Asm.js), fonctionne aussi vite qu'avec le compilateur spécialisé Asm.js de Firefox!
Utiliser V8 comme outil de scripting
On peut donc grâce à V8 utiliser JavaScript comme langage de script et éventuellement doter les scripts d'interface graphique hors navigateur en les intégrant à du code C++ et ses librairies graphiques.
V8 est conçu comme une librairie que l'on peut lier à tout projet C++ et donc utiliser le compilateur comme une fonction d'un système plus vaste.
C'est ce que fait le navigateur Chrome, pour lequel il a été écrit, et auquel il procure sa rapidité d'exécution supérieure à celle des concurrents. Mais ceux-ci tendent à adopter les mêmes techniques et à le rattraper.
On peut l'intégrer à un programme C++ en tant que librairie ou l'utiliser seul pour exécuter, comme le fait un interpréteur, un programme JavaScript. Dans le second cas il faut créer une fonction main qui sert a appeler le parseur, lui fournir un code source à compiler et afficher le résultat de la compilation.
Mais le code généré peut fonctionner en interaction avec les librairies incluses dans le projet.
En schématisant, pour exécuter un programme, on doit créer un lanceur C++ que l'on va lier au code de V8 avant de compiler celui-ci. On crée ainsi un interpréteur qui pourra parser et exécuter des scripts JavaScript.
int main(int argc, char* argv[]) { String source = String::New($argv[1]); Script script = Script::Compile(source); Value result = script->Run(); String::AsciiValue ascii(result); printf("%s\n", *ascii); return 0; }
La version détaillée et les instructions pour construire l'interpréteur JIT se trouvent sur le site de V8.
Mais il y a une solution beaucoup plus simple.
Exécuter un script JavaScript en ligne de commande
Node.js est un framework de serveur écrit en JavaScript destiné à des applications qui peuvent se développer sans limitation dans le temps. Il est asynchrone et réagit, comme les applications HTML, aux évènements. Il est utilisé par Microsoft pour le service Azure, par eBay, par LinkedIn pour les mobiles, le moteur de recherche Yandex, par Yahoo pour le projet Manhattan.
Et vous pouvez l'utiliser vous aussi pour exécuter vos propres scripts.
Supposons que votre script est dans le fichier hello.js.
Téléchargez et installer Node.js, vous entrez dans le répertoire où se trouve l'exécutable node.exe, et tapez:
node hello.js
Et c'est tout!
Entrées-sorties JavaScript en ligne de commande
Pour communiquer avec le script, lui fournir des informations, Node dispose de l'objet process.
L'attribut process.argv contient les paramètres passés en ligne de commande.
Ainsi si la commande est node hello.js moi, le contenu de process.argv sera:
- node.exe
- hello.js
- moi
L'attribut length indique le nombre d'arguments:
process.argv.length
Et pour afficher les résultats, vous pouvez utiliser l'objet console.
console.log("Hello toi!");
Le script de démonstration complet:
console.log("Arguments:" +process.argv.length);
var name = process.argv[2];
console.log("Hello " + name + "!");
Mais en utilisant Node.js, on peut aller bien au-delà de cela...
- Accéder au système de fichiers.
- Utiliser une interface HTML 5 grâce à WebSocket.
- Créer un serveur local...
- etc...
Des démonstrations en sont données dans ce dossier JavaScript.
Autres implémentations pour utiliser JavaScript en ligne de commande
- Narwhal. Conçu pour pouvoir utiliser des interpréteurs JavaScript différents.
- K8. Ajoute des fonctions d'entrées-sorties. (Linux).
Référence
- Conception de V8. (Anglais).