PythonをWebAssemblyにコンパイルする


90

Python 2.7コードをWeb Assemblyに変換できることを読みましたが、その方法に関する明確なガイドが見つかりません。

これまで、Emscriptenとそのすべての必要なコンポーネントを使用してCプログラムをWeb Assemblyにコンパイルしたので、それが機能していることがわかります(使用ガイド:http//webassembly.org/getting-started/developers-guide/

Ubuntuマシンでこれを行うために私が取らなければならないステップは何ですか?PythonコードをLLVMビットコードに変換してからEmscriptenを使用してコンパイルする必要がありますか?もしそうなら、私はこれをどのように達成しますか?



1
チェックアウトpyodidehacks.mozilla.org/2019/04/...
アレックス・

1
Pyodideは、WebAssemblyを介してPythonランタイムをブラウザーにもたらします:github.com/iodide-project/pyodide
guettli

回答:


146

WebAssemblyとasm.js

まず、原則としてWebAssemblyasm.jsとどのように異なるのか、そして既存の知識とツールを再利用する可能性があるかどうかを見てみましょう。以下は、かなり良い概要を示しています。

要約してみましょう、WebAssembly(MVP、ロードマップには詳細があります):

  • は、静的型付けを使用したASTのバイナリ形式であり、既存のJavaScriptエンジン(したがって、JIT対応またはコンパイル済みAOT)で実行できます。
  • JavaScriptよりも10〜20%コンパクト(gzip圧縮された比較)であり、解析が1桁高速です。
  • JavaScript構文に適合しない、より低レベルの操作を表現できます。asm.jsを読み取ります(64ビット整数、特別なCPU命令、SIMDなど)。
  • asm.jsとの間で(ある程度)変換可能です。

したがって、現在WebAssemblyはasm.jsのイテレーションであり、C / C ++(および同様の言語)のみを対象としています。

Web上のPython

PythonコードがWebAssembly / asm.jsをターゲットにするのを阻止するのはGCだけではないようです。どちらも低レベルの静的に型付けされたコードを表しており、Pythonコードは(現実的に)表現できません。WebAssembly / asm.jsの現在のツールチェーンはLLVMに基づいているため、LLVMIRに簡単にコンパイルできる言語をWebAssembly / asm.jsに変換できます。しかし残念ながらUnladen Swallowいくつかの試みで証明されているように、Pythonは動的すぎてそれに適合しません。PyPyの。

このasm.jsプレゼンテーションには、動的言語の状態に関するスライドがあります。つまり、現在、VM全体(C / C ++での言語実装)をWebAssembly / asm.jsにコンパイルし、(可能な場合はJITを使用して)元のソースを解釈することしかできません。Pythonの場合、いくつかの既存のプロジェクトがあります。

  1. PyPy:PyPy.jsPyConでの著者の講演)。これがリリースリポジトリです。メインのJSファイルpypyjs.vm.jsは13MB(2MB後gzip -6)+ Python stdlib +その他のものです。

  2. CPython:pyodideEmPythonCPython-EmscriptenEmCPythonなどempython.jsは5.8 MB(2.1 MB以降gzip -6)で、stdlibはありません。

  3. Micropython:このフォーク

    そこにはビルドされたJSファイルがなかったのでtrzeci/emscripten/、既製の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.js1.1メガバイト(後に225キロバイトのgzip -d)。stdlibを使用せずに非常に準拠した実装のみが必要な場合は、後者をすでに検討する必要があります。

    WebAssemblyあなたがの行13に変更することができます構築するために、生産Makefileへの

     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これらのファイルの使用方法を確認できます。

    このようにして、WebAssemblyでPyPyとCPythonをビルドして、準拠したブラウザーでPythonアプリケーションを解釈することもできます。

ここでもう1つの潜在的に興味深いのは、Nuitkaです。、PythonからC ++へのコンパイラです。潜在的に、PythonアプリをC ++でビルドし、Emscriptenを使用してCPythonと一緒にコンパイルすることが可能です。しかし、実際にはどうすればいいのかわかりません。

ソリューション

当分の間、あなたは、ダウンロードに数メガバイトJSファイルはほとんどのオプションである、従来のWebサイトやWebアプリケーションを構築している場合は、PythonのツーJavaScriptのtranspilers(例えば見てみましょうTranscrypt)またはJavaScriptのPython実装(例えばBrython)。または、JavaScriptにコンパイルされる言語のリストから他の人と運試しをしてみてください。

それ以外の場合、ダウンロードサイズが問題ではなく、多くの荒削りに取り組む準備ができている場合は、上記の3つから選択してください。

2020年第3四半期の更新

  1. JavaScriptポートMicroPythonに統合されました。それは ports / javascriptにあります。

  2. このポートは、MicroPython.jsと呼ばれるnpmパッケージとして利用できます。RunKitで試すことができます。

  3. Rustには、RustPythonと呼ばれる活発に開発されたPython実装があり ます。RustはコンパイルターゲットとしてWebAssemblyを公式にサポートしているため、Readmeの上部にデモリンクがあります。しかし、それは早いです。彼らの免責事項は次のとおりです。

    RustPythonは開発段階にあるため、本番環境や障害に耐えられない設定では使用しないでください。

    現在のビルドは、Python構文のサブセットのみをサポートしています。


1
これらの.jsと.wasmのサイズは実際には公平ではありません。ストリーム圧縮は十分にサポートされており、両方のサイズを縮小するために使用できます。同じファイルのgzip圧縮されたサイズはどれくらいですか?それ以外は、良い答えです。
enigmaticPhysicist

それで、2020年にそれを追加したかったので、pyodideはOPが探している最も近いもののようです。これは、WebアセンブリのPythonランタイムです(Cを入れてからPythonをwasmに入れると仮定します)。複数のライブラリもサポートしています。また、使いやすいようです。
デビッドフリック

3

これは、Webアセンブリがガベージコレクションを実装するまで不可能です。ここで進捗状況を確認できます:https//github.com/WebAssembly/proposals/issues/16


17
必ずしも。Wasmの上にGC(特にPython IIRCで使用されている参照カウント)を実装できます。原則として、CPythonを使用して、Emscriptenを使用してWasmにコンパイルできるはずです。
アンドレアスロスバーグ2017

1
OPからの私の見解は、既存のツールを使用したいというものでした-wasmの上にcpython GCを実装すること自体がプロジェクトのように聞こえます
Malcolm White

3
特別なことをする必要はありません。CPythonをコンパイルするだけです。すでにRC実装AFAICTが含まれています。
アンドレアスロスバーグ2017

3

つまり、トランスパイラーはありますが、任意のPythonをWeb Assemblyに自動的に変換することはできません。また、今後長い間変換できるとは思えません。理論的には言語は同等に強力であり、手動翻訳は常に可能ですが、Pythonでは、非常にスマートな言語間コンパイラ(またはトランスパイラー)を必要とするいくつかのデータ構造と表現モードが可能です[以下を参照]。Python-to-Cテクノロジーは適度に成熟しているため、回避策はPython to C to Web Assemblyである可能性がありますが、Python-to-Cも脆弱であるため、一般的には機能しません(以下を参照)。

WebAssemblyは、http://webassembly.org/docs/high-level-goals/で確認できるように、特にCのような言語を対象としています

PythonからCへの変換は、長い間開発されてきたPyPyのようなツールを使用して実行できますが、それでも任意のPythonコードでは機能しません。これにはいくつかの理由があります。

  1. Pythonには非常に便利で抽象的で優れたデータ構造がいくつかありますが、静的コードに変換するのは困難です。
  2. Pythonは動的ガベージコレクションに依存しています。
  3. ほとんどのPythonコードは、さまざまなライブラリに大きく依存しており、各ライブラリには独自の癖や問題があります(Cで記述されている、またはアセンブラであるなど)。

Python-to-C(またはPython to C ++)が非常にトリッキーである理由をもっと注意深く調べると、この簡潔な答えの背後にある詳細な理由を見ることができますが、それはあなたの質問の範囲外だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.