Bonjour, Habr! Je vous présente la traduction de l'article
"Retour vers le futur avec WebAssembly" par Attila Vágó.
Cet article est la traduction d'un article qui parle des propriétés de WebAssemly et Emscripten. Article original en anglais.
L'auteur de l'article, Attila Vago, est un développeur de logiciels senior chez HMH. Écrit du code, des blogs et des trucs sur Internet. Une polyglotte de langages de programmation, une figure pragmatique, passionnée par JavaScript et facile d'accès. Personne facilement inspirée et inspirante avec une forte dépendance aux choses pour les nerds, la bonne bouffe, la bière artisanale et Lego. Utilisé par Mac. Il fait de l'exercice à 6 heures du matin.En 2011, j'ai écrit ma première ligne indépendante de code non HTML (j'ai travaillé avec elle en 2007), et elle a été écrite dans le très bon vieux C enseigné par le professeur David J. Malan de l'Université Harvard. Il restera à jamais mon inspiration non seulement pour l'étude de la programmation, mais aussi pour la réflexion programmatique. Je me suis également souvenu que faire un sandwich au beurre d'arachide est juste pour moi, mais c'est une tâche incroyablement difficile pour un ordinateur et tout aussi difficile pour une personne qui prétend être un ordinateur.
Si vous avez regardé la vidéo, au moins les 18 premières minutes (je sais que cela prend beaucoup de temps, mais la programmation prend du temps), alors vous comprendrez pourquoi à ce jour C me tient à cœur. À ma grande déception, je ne l'ai jamais appris, car, avouons-le, pour un développeur web, C est la moindre des priorités. Je n'ai jamais eu de vraie raison de plonger profondément dans cette langue, malgré l'achat d'innombrables cours Udemy et de livres C, je ne les ai jamais touchés (gardez votre regard critique pour vous, vous l'avez fait aussi) montre intelligente Pebble, qui fonctionne en C, alors assurez-vous d'écrire un code pour eux. Oui, bien sûr! Aucune de ces raisons n'était suffisante.
Qu'est-ce que WebAssembly et comment dépasse-t-il JS?
WebAssembly (Wasm pour faire court) est un format d'instructions binaires pour une machine virtuelle empilée.
«Wasm a été développé comme une plate-forme portable pour la compilation de langages de haut niveau tels que C / C ++ / Rust, qui vous permet de déployer des applications client et serveur sur Internet»
- explique gentiment webassembly.org
En d'autres termes, ce qui précède signifie que vous pouvez écrire des modules qui fonctionnent sur Internet dans un navigateur / serveur, mais qui sont écrits dans des langues telles que C, compilés dans un fichier binaire et donc incroyablement rapides car ils fonctionnent directement sur le matériel de la machine. Par rapport à eux, les langages de script tels que JavaScript ont plusieurs niveaux d'abstraction entre le code et le matériel, ce qui, entre autres, les ralentit. Bien sûr, cela n'a pas toujours d'importance, et chacun d'eux a sa propre place dans le programme ou même l'écosystème web.
Sur cette base, Wasm par structure (initialement) ne prend en charge que les entiers et les nombres à virgule flottante, ce qui donne une grande puissance de calcul et, par conséquent, est souvent utilisé pour les implémentations de type canevas. Il est important de comprendre que WebAssembly n'est pas une menace pour JavaScript - du moins pas encore - et, comme vous le verrez plus loin dans cet article, C et JavaScript peuvent réellement vivre très heureux dans le même projet et peuvent exécuter le code de l'autre. Oui, quelque chose comme ça.
Emscripten "colle" C et JS
Attends maintenant! Je sais ce que je dis. Vous ne pouvez pas dire des choses comme "exécuter C dans JS et vice versa" et vous attendre à ce que le monde ne réagisse pas. Peu importe à quel point cela semble étrange, je ne suis pas dupe. Il s'avère qu'Emscripten est une chaîne d'outils pour compiler dans asm.js et WebAssembly, conçu en utilisant LLVM (mon Dieu, j'ai appris la moitié de ces choses en tapant le texte de l'article), ce qui vous permet d'exécuter C et C ++ sur Internet à une vitesse presque native sans plug-ins.
Eh bien, voici ce que vous devez mettre en évidence par vous-même. Emscripten vous aide à compiler du code C dans WebAssembly, fournissant des outils supplémentaires pour alléger la charge du développeur en matière de communication entre les deux langues, et aide à lancer Wasm dans votre projet Web. La commande de compilation de base pour Emscripten est la suivante:
emcc lib/strings.c -s WASM=1 -o public/strings.js
Alors qu'une commande non basique s'exécute comme ceci:
emcc lib/imports.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -o public/imports.js
La mise en place d'Emscripten n'est pas la chose la plus simple, mais pas le lancement d'une fusée. La seule chose qui complique la configuration est qu'elle a de nombreuses dépendances comme Python, Node, xCode, Git et cMake. Toutes les instructions se trouvent sur la page d'installation et sont faciles à suivre.
Par conséquent, Emscripten:
- est un excellent outil de portage, vous permettant de compiler des projets existants écrits en C ou C ++ et de les exécuter dans tous les navigateurs modernes. Sortez d'ici, Internet Explorer!
- idéal pour les API car il convertit OpenGL en WebGL et vous permet d'utiliser des API familières comme SDL ou directement HTML5. Oh oui!
- Et c'est sacrément rapide: grâce à LLVM, Emscripten, asm.js et WebAssembly, le code s'exécute à presque sa propre vitesse. Courez, lapin, courez!
Remarque: Vous n'avez pas besoin d'Emscripten pour générer Wasm, car tous les nouveaux navigateurs ont une API pour prendre en charge Wasm dans la même fenêtre, qui exécute Emscripten comme couche supérieure, ce qui facilite la vie du développeur. Par exemple, Emscripten ajustera la quantité de mémoire pour vous, ce qui peut être fastidieux en C.
Des exemples ... des exemples partout!
Vous savez, comme on dit, "une ligne de code vaut mille mots" , - OK, c'est la prérogative du narrateur et tout cela, alors sans plus tarder, jetons un coup d'œil à un vrai code. Commentaire hors sujet: ce jour-là, je n'ai pas pu surmonter la syntaxe C. Elle n'a pas compilé la moitié du temps, car mon code serait fragile. Et après huit ans, je me dis: "Oui, ça ressemble à JavaScript . "
Les gars, si quelqu'un commence à voir le code C dans mon React, ramenez-moi simplement à la réalité, d'accord?
Un peu hors sujet, voici le code C actuel:

Et, en conséquence, en JavaScript:

OK, que se passe-t-il exactement dans ces fichiers? En fait, beaucoup, donc je vais énumérer.
- Il est important de comprendre que main () , sauf indication contraire, démarre toujours en premier et compile également par défaut. Si vous souhaitez compiler une autre fonction, vous devrez la définir spécifiquement dans l'indicateur du tableau EXPORTED_FUNCTIONS , comme indiqué dans la section précédente.
- Vous écrivez votre code C, comme d'habitude, en important ses bibliothèques régulières, mais en plus de cela, vous obtenez du sucre syntaxique Emscripten, ainsi que plus de méthodes / fonctions qu'avec tout autre outil.
- Le fichier imports.js (le nom est arbitraire, mais toujours le même que le fichier C) référencé par HTML n'est rien d'autre que l'Emscripten «glue», qui est généré automatiquement lors de la compilation. Pas besoin de s'en inquiéter, assurez-vous simplement qu'il est vraiment référencé.
- Printf est juste une instruction C ordinaire enregistrant une chaîne sur la console. Rien de spécial, passez à autre chose.
- Les lignes 14 et 17 sont un anti-modèle, mais un bon exemple d'exécution de JS dans votre code C. La seule vraie différence entre emscripten_run_script et emscripten_async_run_script est que ce dernier vous permet d'exécuter JS en C de manière asynchrone. Surtout avec setTimeout () . La raison pour laquelle j'ai dit qu'il s'agit d'un anti-modèle est qu'il l'est. L'idée de WebAssembly est d'exécuter C en JS, pas JS en C, et donc ...
- Les lignes 20 et 24 et leurs fonctions JS associées dans index.html représentent le modèle correct, à savoir déclarer votre JS dans votre JS et renvoyer quelque chose pour C.
- EM_JS , qui lance ensuite jsFunction , est simplement un moyen plus simple - pour atteindre le même objectif qu'aux points 4 et 5.
Le résultat prévu de ce qui précède est le suivant:

Mesdames devant!
Comme pour tout code, WebAssembly a également un ordre d'exécution. Ne jouez pas avec la file d'attente! La commande dans ce cas est standard pour la commande C. Tout commence dans Main () et chaque fois que main () est prêt, Wasm est prêt. Cependant, que se passe-t-il si vous avez besoin d'une fonction statique pour appeler au moment de l'exécution? Eh bien, juste un peu de sucre syntaxique Emscripten, et tout se passe comme sur des roulettes:

Nous collectons des mouches du gâteau
C'est du code bien écrit, en particulier les choses simples illustrées dans les sections précédentes, mais nous savons tous que le monde réel est beaucoup plus grand que «Hello World», et la moitié du temps de chaque développeur est consacré à comprendre pourquoi le code ne fait pas quoi devrait. Les bugs sont tout simplement inévitables et font en quelque sorte partie de la vie.
Lorsque vous exécutez C dans JS ou n'importe quel Wasm, d'ailleurs, tout peut devenir encore plus déprimant. Heureusement, Emscripten vient à la rescousse en fournissant deux méthodes de débogage très utiles:
// browser debugger gets triggered emscripten_debugger(); // browser console warning with stack-trace emscripten_log(EM_LOG_WARN, “'param' your message”);
Gonzalez se dépêche d'aider
Croyez-le ou non, les créateurs d'Emscripten ont pensé à tout. Une grande caractéristique - et la dernière que je mentionnerai dans cet article, car il y en a trop pour les mettre tous en un - est la base d'un développement et de tests rapides. Vous pouvez compiler votre Wasm, créer un projet et démarrer le serveur d'un seul coup:
emrun --port 7777 --no_browser public/index.html Now listening at http://localhost:7777/
La page html que vous exécutez n'est pas compatible avec emrun. La capture stdout, stderr et exit (returncode) ne fonctionnera pas. Recompilez l'application avec l'indicateur de l'éditeur de liens --emrun pour l'activer, ou passez --no_emrun_detect à emrun pour masquer cette vérification.
D'accord, chez deux boursiers ... l'exemple ci-dessus fonctionne, mais le suivant fonctionne mieux, ce qui explique l'erreur indiquée.
<b>// compile as emrun project emcc lib/strings.c -s WASM=1 --emrun -o public/index.html // run the emrun server again emrun --port 7777 --no_browser public/index.html</b>
Je laisse ça comme ça. En étudiant WebAssembly, j'ai célébré la Saint-Patrick et le lendemain. Je ne sais pas trop ce qui va se passer ensuite, mais cela m'a suffisamment excité pour m'asseoir devant le moniteur pendant deux jours, essayant d'entrer dans les bases de WebAssebly, et cela devrait signifier quelque chose, non? C'est le code C que j'ai écrit depuis 2011, et ça fait du bien. Je pense que WebAssembly a un réel avenir, mais je ne sais pas s'il va complètement prendre le contrôle du réseau et tuer JS, comme certains le prêchent. Qu'en penses-tu?
