web-dev-qa-db-ja.com

PythonをWebAssemblyにコンパイル

Python 2.7コードをWebアセンブリに変換することが可能であることを読みましたが、その方法に関する決定的なガイドが見つかりません。

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

Ubuntuマシンでこれを行うために必要な手順は何ですか? pythonコードをLLVMビットコードに変換してから、Emscriptenを使用してコンパイルする必要がありますか?もしそうなら、どうすればこれを達成できますか?

54
Robbie

WebAssemblyとasm.js

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

要約しましょう、WebAssembly(MVP、詳細については そのロードマップ 、大体):

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

したがって、現在WebAssemblyはasm.jsの反復であり、C/C++のみを対象としています。

Python on the Web

PythonコードがWebAssembly/asm.jsをターゲットとするのを止めるのはGCだけではないようです。両方とも、低レベルの静的に型付けされたコードを表し、Pythonコードは(現実的に)表現できません。 WebAssembly/asm.jsの現在のツールチェーンはLLVMに基づいているため、LLVM IRに簡単にコンパイルできる言語はWebAssembly/asm.jsに変換できます。しかし悲しいかな、PyPyの nladen Swallow および 数回の試行 によって証明されているように、Pythonはあまりにも動的なので、それに収まりません。

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

  1. PyPy: PyPy.js (著者の PyConで話す )。 リリースリポジトリ です。メインのJSファイルpypyjs.vm.jsは13 MB(gzip -6の後に2MB)+ Python stdlib +その他のものです。
  2. CPython: pyodideEmPythonCPython-EmscriptenEmCPython など。empython.jsは5.8 MB(2.1 MB後) gzip -6)、stdlibなし。
  3. Micropython: this fork

    そこにはビルドされたJSファイルがなかったので、既製のEmscriptenツールチェーンである trzeci/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 
    

    1.1 MBのmicropython.jsgzip -dの後の225 KB)を生成します。後者は、stdlibを使用せずに非常に準拠した実装のみが必要な場合、すでに考慮すべき事項です。

    WebAssemblyビルドを作成するには、Makefileの13行目を

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

    次に、make -jは以下を生成します。

    113 KB micropython.js
    240 KB micropython.wasm
    

    これらのファイルの使用方法については、emcc hello.c -s WASM=1 -o hello.htmlのHTML出力をご覧ください。

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

ここで興味深い可能性のある別のものは、C++コンパイラへのPythonである Nuitka です。 PythonアプリをC++にビルドし、Escriptnを使用してCPythonとともにコンパイルすることが可能です。しかし、実際にはそれを行う方法がわかりません。

解決策

とりあえず、数メガバイトのJSファイルをダウンロードするという選択肢がほとんどない従来のWebサイトまたはWebアプリを構築する場合は、PythonからJavaScriptへのトランスパイラーを見てください(例 Transcrypt )またはJavaScript Python実装(例 Brython )。または、 JavaScriptにコンパイルされる言語のリスト から他の人と運を試してください。

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

94
saaj

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

4
Malcolm White

要するに、あなたは任意のPythonをWebアセンブリに変換することはできません。そして、私はあなたがこれから長い間できることを疑います。回避策はPython to C to Web Assemblyかもしれませんが、Python-to-Cは脆弱であるため、一般的には機能しません(以下を参照)。

http://webassembly.org/docs/high-level-goals/ で見ることができるように、WebAssemblyは特にCに似た言語を対象としています。

PythonからCへの変換は、PyPyなどのツールで実行できます。PyPyは長い間開発中ですが、任意のPythonコードではまだ機能しません。これにはいくつかの理由があります。

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

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

3
GregD