Компиляция 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, и есть ли потенциал для повторного использования существующих знаний и инструментов. Следующее дает довольно хороший обзор:
- зачем создавать новый стандарт, когда уже есть asm.Яш?
- в чем разница между asm.js и web ассамблея?
- почему 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 существует несколько существующих проектов:
- PyPy:в PyPy.js (автор говорить на PyCon). Вот!--69-->релиз РЕПО. Файл main Ж. С.,
pypyjs.vm.js
, составляет 13 МБ (2 МБ послеgzip -6
) + Python stdlib + другое материал. - CPython:EmPython, CPython-Emscripten, EmCPython, etc.
empython.js
5.8 MB (2.1 MB послеgzip -6
), нет stdlib. -
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
toCC = 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++) был настолько сложным, вы можете увидеть подробные причины этого краткого ответа, но я думаю, что это выходит за рамки вашего вопроса.