WebAssembly vs asm.js
Primero, veamos cómo, en principio, WebAssembly es diferente de asm.js , y si existe la posibilidad de reutilizar el conocimiento y las herramientas existentes. A continuación, se ofrece una descripción general bastante buena:
Recapitulemos, WebAssembly (MVP, ya que hay más en su hoja de ruta , aproximadamente):
- es un formato binario de AST con escritura estática, que puede ser ejecutado por motores JavaScript existentes (y por lo tanto compatible con JIT o AOT compilado),
- es un 10-20% más compacto (comparación con gzip) y un orden de magnitud más rápido de analizar que JavaScript,
- puede expresar más operaciones de bajo nivel que no encajan en la sintaxis de JavaScript, leer asm.js (por ejemplo, enteros de 64 bits, instrucciones especiales de CPU, SIMD, etc.)
- es convertible (hasta cierto punto) a / desde asm.js.
Por lo tanto, actualmente WebAssembly es una iteración de asm.js y se dirige solo a C / C ++ (y lenguajes similares).
Python en la Web
No parece que GC sea lo único que impide que el código Python se dirija a WebAssembly / asm.js. Ambos representan código escrito estáticamente de bajo nivel, en el que el código Python no se puede representar (de manera realista). Como la cadena de herramientas actual de WebAssembly / asm.js se basa en LLVM, un lenguaje que se puede compilar fácilmente a LLVM IR se puede convertir a WebAssembly / asm.js. Pero, lamentablemente, Python también es demasiado dinámico para encajar en él, como lo demuestran Unladen Swallow y varios intentos de PyPy.
Esta presentación de asm.js tiene diapositivas sobre el estado de los lenguajes dinámicos . Lo que significa es que actualmente solo es posible compilar VM completa (implementación del lenguaje en C / C ++) en WebAssembly / asm.js e interpretar (con JIT cuando sea posible) las fuentes originales. Para Python hay varios proyectos existentes:
PyPy: PyPy.js ( charla del autor en PyCon ). Aquí está el repositorio de lanzamiento . El archivo JS principal ,, pypyjs.vm.js
tiene 13 MB (2 MB después gzip -6
) + Python stdlib + otras cosas.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython , etc. empython.js
es de 5,8 MB (2,1 MB después gzip -6
), sin stdlib.
Micropython: esta bifurcación .
No había ningún archivo JS construido allí, así que pude construirlo con trzeci/emscripten/
una cadena de herramientas Emscripten lista para usar. Algo como:
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
Produce micropython.js
de 1,1 MB (225 KB después gzip -d
). Esto último ya es algo a considerar, si solo necesita una implementación muy compatible sin stdlib.
Para producir WebAssembly construir puede cambiar la línea 13 de la Makefile
a
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Luego make -j
produce:
113 KB micropython.js
240 KB micropython.wasm
Puede mirar la salida HTML de emcc hello.c -s WASM=1 -o hello.html
, para ver cómo usar estos archivos.
De esta manera, también puede potencialmente construir PyPy y CPython en WebAssembly para interpretar su aplicación Python en un navegador compatible.
Otra cosa potencialmente interesante aquí es Nuitka , un compilador de Python a C ++. Potencialmente, puede ser posible construir su aplicación Python en C ++ y luego compilarla junto con CPython con Emscripten. Pero prácticamente no tengo idea de cómo hacerlo.
Soluciones
Por el momento, si está creando un sitio web convencional o una aplicación web donde descargar un archivo JS de varios megabytes es apenas una opción, eche un vistazo a los transpilers de Python a JavaScript (por ejemplo, Transcrypt ) o implementaciones de Python de JavaScript (por ejemplo, Brython ). O pruebe suerte con otros de la lista de lenguajes que se compilan en JavaScript .
De lo contrario, si el tamaño de la descarga no es un problema y está listo para abordar muchos aspectos ásperos, elija entre los tres anteriores.
Actualización del tercer trimestre de 2020
El puerto de JavaScript se integró en MicroPython. Vive en
ports / javascript .
El puerto está disponible como un paquete npm llamado MicroPython.js . Puedes probarlo en RunKit .
Hay una implementación de Python desarrollada activamente en Rust, llamada
RustPython . Debido a que Rust admite oficialmente WebAssembly como destino de compilación , no es de extrañar que haya un enlace de demostración justo en la parte superior del archivo Léame. Aunque es temprano. Su descargo de responsabilidad sigue.
RustPython se encuentra en una fase de desarrollo y no debe usarse en producción o en una configuración intolerante a fallas.
Nuestra compilación actual solo admite un subconjunto de la sintaxis de Python.