WebAssembly contre asm.js
Tout d'abord, voyons en quoi, en principe, WebAssembly est différent de asm.js , et s'il existe un potentiel de réutilisation des connaissances et des outils existants. Ce qui suit donne un assez bon aperçu:
Récapitulons, WebAssembly (MVP, car il y en a plus sur sa feuille de route , en gros):
- est un format binaire d'AST avec typage statique, qui peut être exécuté par les moteurs JavaScript existants (et donc JIT-able ou compilé AOT),
- il est 10 à 20% plus compact (comparaison gzippée) et un ordre de grandeur plus rapide à analyser que JavaScript,
- il peut exprimer plus d'opérations de bas niveau qui ne rentrent pas dans la syntaxe JavaScript, lire asm.js (par exemple, des entiers 64 bits, des instructions CPU spéciales, SIMD, etc.)
- est convertible (dans une certaine mesure) vers / depuis asm.js.
Ainsi, actuellement WebAssembly est une itération sur asm.js et ne cible que C / C ++ (et les langages similaires).
Python sur le Web
Il ne semble pas que GC soit la seule chose qui empêche le code Python de cibler WebAssembly / asm.js. Les deux représentent un code typé statiquement de bas niveau, dans lequel le code Python ne peut pas (de manière réaliste) être représenté. Comme la chaîne d'outils actuelle de WebAssembly / asm.js est basée sur LLVM, un langage qui peut être facilement compilé en LLVM IR peut être converti en WebAssembly / asm.js. Mais hélas, Python est trop dynamique pour s'y intégrer également, comme l'ont prouvé Unladen Swallow et plusieurs tentatives de PyPy.
Cette présentation asm.js a diapositives sur l'état des langages dynamiques . Cela signifie qu'actuellement, il est uniquement possible de compiler la VM entière (implémentation du langage en C / C ++) vers WebAssembly / asm.js et d'interpréter (avec JIT si possible) les sources originales. Pour Python, il existe plusieurs projets existants:
PyPy: PyPy.js ( exposé de l' auteur à PyCon ). Voici le repo de version . Le fichier JS principal,, pypyjs.vm.js
fait 13 Mo (2 Mo aprèsgzip -6
,, ) + Python stdlib + autres choses.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython , etc. empython.js
est de 5,8 Mo (2,1 Mo après gzip -6
), pas de stdlib.
Micropython: cette fourchette .
Il n'y avait pas de fichier JS intégré, donc j'ai pu le construire avec trzeci/emscripten/
une chaîne d'outils Emscripten prête à l'emploi. Quelque chose comme:
git clone https://github.com/matthewelse/micropython.git
cd micropython
docker run --rm -it -v $(pwd):/src trzeci/emscripten bash
apt-get update && apt-get install -y python3
cd emscripten
make -j
Il produit micropython.js
1,1 Mo (225 Ko après gzip -d
). Ce dernier est déjà quelque chose à considérer, si vous n'avez besoin que d'une implémentation très conforme sans stdlib.
Pour produire vous construire WebAssembly pouvez modifier la ligne 13 du Makefile
à
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Ensuite make -j
produit:
113 KB micropython.js
240 KB micropython.wasm
Vous pouvez consulter la sortie HTML de emcc hello.c -s WASM=1 -o hello.html
, pour voir comment utiliser ces fichiers.
De cette façon, vous pouvez également potentiellement créer PyPy et CPython dans WebAssembly pour interpréter votre application Python dans un navigateur compatible.
Une autre chose potentiellement intéressante ici est Nuitka , un compilateur Python vers C ++. Il est potentiellement possible de créer votre application Python en C ++, puis de la compiler avec CPython avec Emscripten. Mais pratiquement je ne sais pas comment faire.
Solutions
Pour le moment, si vous créez un site Web conventionnel ou une application Web où le téléchargement d'un fichier JS de plusieurs mégaoctets est à peine une option, jetez un coup d'œil aux transpileurs Python vers JavaScript (par exemple Transcrypt ) ou aux implémentations JavaScript Python (par exemple Brython ). Ou tentez votre chance avec d'autres parmi la liste des langages qui se compilent en JavaScript .
Sinon, si la taille du téléchargement n'est pas un problème et que vous êtes prêt à vous attaquer à de nombreux problèmes, choisissez entre les trois ci-dessus.
Mise à jour T3 2020
Le port JavaScript a été intégré à MicroPython. Il vit dans les
ports / javascript .
Le port est disponible sous la forme d'un package npm appelé MicroPython.js . Vous pouvez l'essayer dans RunKit .
Il existe une implémentation Python activement développée dans Rust, appelée
RustPython . Parce que Rust prend officiellement en charge WebAssembly comme cible de compilation , il n'est pas surprenant qu'il y ait un lien de démonstration juste en haut du readme. Cependant, il est tôt. Leur avertissement suit.
RustPython est en phase de développement et ne doit pas être utilisé en production ou dans un cadre intolérant aux pannes.
Notre version actuelle ne prend en charge qu'un sous-ensemble de la syntaxe Python.