WebAssembly vs asm.js
Primeiro, vamos dar uma olhada em como, em princípio, WebAssembly é diferente de asm.js e se há potencial para reutilizar o conhecimento e ferramentas existentes. O seguinte fornece uma visão geral muito boa:
Vamos recapitular, WebAssembly (MVP, pois há mais em seu roteiro , aproximadamente):
- é um formato binário de AST com tipagem estática, que pode ser executado por mecanismos JavaScript existentes (e, portanto, compatível com JIT ou AOT compilado),
- é 10-20% mais compacto (comparação com gzip) e uma ordem de magnitude mais rápida de analisar do que JavaScript,
- pode expressar mais operação de baixo nível que não se encaixa na sintaxe do JavaScript, leia asm.js (por exemplo, inteiros de 64 bits, instruções especiais de CPU, SIMD, etc)
- é conversível (até certo ponto) de / para asm.js.
Portanto, atualmente WebAssembly é uma iteração em asm.js e visa apenas C / C ++ (e linguagens semelhantes).
Python na web
Não parece que o GC é a única coisa que impede o código Python de direcionar WebAssembly / asm.js. Ambos representam código digitado estaticamente de baixo nível, no qual o código Python não pode (realisticamente) ser representado. Como a cadeia de ferramentas atual do WebAssembly / asm.js é baseada no LLVM, uma linguagem que pode ser facilmente compilada para LLVM IR pode ser convertida para WebAssembly / asm.js. Mas, infelizmente, Python é muito dinâmico para caber nele também, como comprovado por Unladen Swallow e várias tentativas de PyPy.
Esta apresentação do asm.js contém slides sobre o estado das linguagens dinâmicas . O que isso significa é que atualmente só é possível compilar VM inteira (implementação de linguagem em C / C ++) para WebAssembly / asm.js e interpretar (com JIT onde possível) fontes originais. Para Python, existem vários projetos existentes:
PyPy : PyPy.js ( palestra do autor na PyCon ). Aqui está o repo de lançamento . O arquivo JS principal ,, pypyjs.vm.js
tem 13 MB (2 MB depois gzip -6
) + Python stdlib + outras coisas.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython , etc. empython.js
é 5,8 MB (2,1 MB depois gzip -6
), sem stdlib.
Micropython: este garfo .
Não havia nenhum arquivo JS construído lá, então fui capaz de construí-lo com trzeci/emscripten/
uma cadeia de ferramentas Emscripten pronta. 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
Produz micropython.js
de 1,1 MB (225 KB depois gzip -d
). O último já é algo a ser considerado, se você precisar apenas de uma implementação muito compatível sem stdlib.
Para produzir a construção WebAssembly, você pode alterar a linha 13 do Makefile
para
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Em seguida, make -j
produz:
113 KB micropython.js
240 KB micropython.wasm
Você pode olhar a saída HTML de emcc hello.c -s WASM=1 -o hello.html
, para ver como usar esses arquivos.
Dessa forma, você também pode construir potencialmente PyPy e CPython em WebAssembly para interpretar seu aplicativo Python em um navegador compatível.
Outra coisa potencialmente interessante aqui é o Nuitka , um compilador de Python para C ++. Potencialmente, pode ser possível construir seu aplicativo Python para C ++ e, em seguida, compilá-lo junto com CPython com Emscripten. Mas praticamente não tenho ideia de como fazer isso.
Soluções
Por enquanto, se você estiver construindo um site ou aplicativo da web convencional em que baixar um arquivo JS de vários megabytes mal seja uma opção, dê uma olhada nos transpiladores de Python para JavaScript (por exemplo, Transcrypt ) ou implementações de Python de JavaScript (por exemplo, Brython ) Ou tente a sorte com outros na lista de linguagens que compilam para JavaScript .
Caso contrário, se o tamanho do download não for um problema e você estiver pronto para lidar com muitas arestas, escolha entre os três acima.
Atualização Q3 2020
A porta JavaScript foi integrada ao MicroPython. Vive em
ports / javascript .
A porta está disponível como um pacote npm chamado MicroPython.js . Você pode experimentar no RunKit .
Há uma implementação Python desenvolvida ativamente em Rust, chamada
RustPython . Como o Rust oferece suporte oficial ao WebAssembly como destino de compilação , não é surpresa que haja um link de demonstração logo no topo do readme. Porém, ainda é cedo. Sua isenção de responsabilidade segue.
RustPython está em uma fase de desenvolvimento e não deve ser usado na produção ou em uma configuração intolerante a falhas.
Nosso build atual suporta apenas um subconjunto da sintaxe Python.