WebAssembly contro asm.js
Innanzitutto, diamo un'occhiata a come, in linea di principio, WebAssembly è diverso da asm.js e se esiste il potenziale per riutilizzare le conoscenze e gli strumenti esistenti. Quanto segue fornisce una panoramica abbastanza buona:
Ricapitoliamo, WebAssembly (MVP, poiché c'è di più sulla sua roadmap , più o meno):
- è un formato binario di AST con tipizzazione statica, che può essere eseguito da motori JavaScript esistenti (e quindi AOT compilato o compatibile con JIT),
- è del 10-20% più compatto (confronto con gzip) e un ordine di grandezza più veloce da analizzare rispetto a JavaScript,
- può esprimere più operazioni di basso livello che non si adattano alla sintassi JavaScript, leggere asm.js (es. interi a 64 bit, istruzioni speciali per CPU, SIMD, ecc.)
- è convertibile (in una certa misura) in / da asm.js.
Pertanto, attualmente WebAssembly è un'iterazione su asm.js e si rivolge solo a C / C ++ (e linguaggi simili).
Python sul Web
Non sembra che GC sia l'unica cosa che impedisce al codice Python di prendere di mira WebAssembly / asm.js. Entrambi rappresentano codice di basso livello tipizzato staticamente, in cui il codice Python non può (realisticamente) essere rappresentato. Poiché l'attuale toolchain di WebAssembly / asm.js è basato su LLVM, un linguaggio che può essere facilmente compilato in LLVM IR può essere convertito in WebAssembly / asm.js. Ma ahimè, Python è troppo dinamico per adattarsi anche a esso, come dimostrato da Unladen Swallow e diversi tentativi di PyPy.
Questa presentazione di asm.js contiene diapositive sullo stato dei linguaggi dinamici . Ciò significa che attualmente è possibile solo compilare l'intera VM (implementazione del linguaggio in C / C ++) in WebAssembly / asm.js e interpretare (con JIT dove possibile) fonti originali. Per Python ci sono diversi progetti esistenti:
PyPy: PyPy.js ( discorso dell'autore a PyCon ). Ecco il repo di rilascio . Il file JS principale ,, pypyjs.vm.js
è 13 MB (2 MB dopo gzip -6
) + stdlib Python + altre cose.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython , ecc. empython.js
È di 5,8 MB (2,1 MB dopo gzip -6
), nessuno stdlib.
Micropython: questo fork .
Non c'era alcun file JS trzeci/emscripten/
compilato lì, quindi sono stato in grado di crearlo con una toolchain Emscripten già pronta. Qualcosa di simile a:
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
1,1 MB (225 KB dopo gzip -d
). Quest'ultimo è già qualcosa da considerare, se hai bisogno solo di un'implementazione molto conforme senza stdlib.
Per produrre WebAssembly build è possibile modificare la riga 13 del Makefile
a
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Quindi make -j
produce:
113 KB micropython.js
240 KB micropython.wasm
Puoi guardare l'output HTML di emcc hello.c -s WASM=1 -o hello.html
, per vedere come usare questi file.
In questo modo puoi anche potenzialmente creare PyPy e CPython in WebAssembly per interpretare la tua applicazione Python in un browser conforme.
Un'altra cosa potenzialmente interessante qui è Nuitka , un compilatore da Python a C ++. Potenzialmente può essere possibile costruire la tua app Python in C ++ e quindi compilarla insieme a CPython con Emscripten. Ma praticamente non ho idea di come farlo.
Soluzioni
Per il momento, se stai realizzando un sito web convenzionale o un'app web in cui scaricare un file JS da diversi megabyte è a malapena un'opzione, dai un'occhiata ai transpilers da Python a JavaScript (ad esempio Transcrypt ) o alle implementazioni JavaScript Python (ad esempio Brython ). Oppure tenta la fortuna con altri dall'elenco dei linguaggi che si compilano in JavaScript .
Altrimenti, se la dimensione del download non è un problema e sei pronto per affrontare molti bordi irregolari, scegli tra i tre sopra.
Aggiornamento Q3 2020
La porta JavaScript è stata integrata in MicroPython. Vive in
port / javascript .
Il port è disponibile come pacchetto npm chiamato MicroPython.js . Puoi provarlo in RunKit .
C'è un'implementazione Python sviluppata attivamente in Rust, chiamata
RustPython . Poiché Rust supporta ufficialmente WebAssembly come destinazione della compilazione , non sorprende che ci sia un collegamento demo proprio all'inizio del file readme. Tuttavia, è presto. Segue il loro disclaimer.
RustPython è in una fase di sviluppo e non dovrebbe essere utilizzato in produzione o in un ambiente intollerante ai guasti.
La nostra build attuale supporta solo un sottoinsieme della sintassi Python.