Компиляция Python в WebAssembly

Я прочитал, что можно преобразовать код Python 2.7 в веб-сборку, но я не могу найти окончательного руководства о том, как это сделать.

до сих пор я скомпилировал программу C для веб-сборки с помощью Emscripten и всех ее необходимых компонентов, поэтому я знаю, что она работает (используется руководство:http://webassembly.org/getting-started/developers-guide/)

какие шаги я должен предпринять, чтобы сделать это на машине с Ubuntu? Должен ли я конвертировать код python чтобы LLVM bitcode затем скомпилировать его с помощью Emscripten? Если да, то как мне этого достичь?

3 ответов


WebAssembly vs asm.js

во-первых, давайте посмотрим, как, в принципе,WebAssembly отличается от asm.js, и есть ли потенциал для повторного использования существующих знаний и инструментов. Следующее дает довольно хороший обзор:

давайте резюмируем, WebAssembly (MVP, так как есть больше на плана, грубо):

  • - это двоичный формат AST со статической типизацией, который может быть выполнен существующими движками JavaScript (и, следовательно, JIT-able или скомпилированный AOT),
  • это на 10-20% компактнее (сравнение gzipped) и на порядок быстрее анализировать, чем JavaScript,
  • он может выражать более низкоуровневую операцию, которая не будет вписываться в синтаксис JavaScript, читать asm.js (например, 64-разрядные целые числа, специальные инструкции CPU, SIMD и т. д.)
  • конвертируется (в некоторой степени) в / из asm.js.

таким образом, в настоящее время WebAssembly является итерацией на asm.js и цели только C / C++.

Python в Интернете

не похоже, что GC-единственное, что останавливает код Python от таргетинга WebAssembly / asm.js. Оба представляют собой низкоуровневый статически типизированный код, в котором код Python не может (реалистично) быть представлен. Как текущая цепочка инструментов WebAssembly / asm.js основан на LLVM, языке, который можно легко скомпилировать в LLVM IR, можно преобразовать в WebAssembly / asm.js. Но, увы, Python слишком динамичен, чтобы вписаться в него, как доказано Порожнем и несколько попыток в в PyPy.

это asm.презентация JS имеет слайды о состояние динамических языков. Это означает, что в настоящее время можно скомпилировать всю виртуальную машину (языковую реализацию на C/C++) в WebAssembly/asm.js и интерпретировать (с JIT, где это возможно) исходные источники. Для Python существует несколько существующих проектов:

  1. PyPy:в PyPy.js (автор говорить на PyCon). Вот!--69-->релиз РЕПО. Файл main Ж. С., pypyjs.vm.js, составляет 13 МБ (2 МБ после gzip -6) + Python stdlib + другое материал.
  2. CPython:EmPython, CPython-Emscripten, EmCPython, etc. empython.js 5.8 MB (2.1 MB после gzip -6), нет stdlib.
  3. Micropython: эта вилка.

    там не было встроенного JS-файла, поэтому я смог построить его с помощью trzeci/emscripten/, готовый toolchain и Emscripten. Что-то вроде:

    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
    # to run REPL: npm install && nodejs server.js 
    

    производит micropython.js 1,1 МБ (225 КБ после gzip -d). Последнее уже стоит учитывать, если вам нужна только очень совместимая реализация без stdlib.

    для создания сборки WebAssembly вы можете изменить строку 13 Makefile to

    CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
    

    затем make -j выдает:

    113 KB micropython.js
    240 KB micropython.wasm
    

    вы можете посмотреть на вывод HTML emcc hello.c -s WASM=1 -o hello.html, чтобы увидеть, как использовать эти файлы.

    таким образом, вы также можете потенциально построить PyPy и CPython в WebAssembly для интерпретации вашего приложения Python в совместимый браузер.

еще одна потенциально интересная вещь здесь-это Nuitka, компилятор Python для C++. Потенциально можно создать приложение Python на C++, а затем скомпилировать его вместе с CPython с Emscripten. Но практически я понятия не имею, как это сделать.

решений

в настоящее время, если вы создаете обычный веб-сайт или веб-приложение, где загрузка нескольких мегабайт JS-файла едва ли является опция, взгляните на транспиляторы Python-to-JavaScript (например,Transcrypt) или реализации JavaScript Python (например,Brython). Или попытайте счастья с другими из список языков, которые компилируются в JavaScript.

в противном случае, если размер загрузки не является проблемой, и вы готовы решать много шероховатостей, выберите один из трех выше.


Это будет невозможно, пока веб-сборка не реализует сборку мусора. Вы можете следить за прогрессом здесь: https://github.com/WebAssembly/design/issues/1079


короче говоря: вы не можете конвертировать произвольный Python в веб-сборку, и я сомневаюсь, что вы сможете в течение длительного времени. Обходным путем может быть Python для C для веб-сборки, но это обычно не будет работать, так как Python-to-C является хрупким (см. ниже).

WebAssembly специально предназначен для C-подобных языков, как вы можете видеть наhttp://webassembly.org/docs/high-level-goals/

перевод с Python на C можно сделать с помощью таких инструментов, как PyPy, который разрабатывался в течение длительного времени, но который все еще не работает для произвольного кода Python. Для этого есть несколько причин:

1) Python имеет некоторые очень удобные, абстрактные и приятные структуры данных, но их трудно перевести в статический код. 2) Python зависит от динамической сборки мусора. 2) большинство кода Python сильно зависит от различных библиотек, каждая из которых имеет свои собственные причуды и проблемы (например, написанные на C или даже ассемблер.)

Если вы более внимательно посмотрите, почему Python-to-C (или Python на C++) был настолько сложным, вы можете увидеть подробные причины этого краткого ответа, но я думаю, что это выходит за рамки вашего вопроса.