2017-06-26 217 views
18

我讀過,有可能將Python 2.7代碼轉換爲Web Assembly,但是我無法找到關於如何這樣做的權威性指南。編譯Python到WebAssembly

到目前爲止,我已經彙編了一份使用Emscripten及其所有必要組件的C程序的Web組件,所以我知道這是工作(指導使用:http://webassembly.org/getting-started/developers-guide/

什麼是我必須採取以做的步驟這在Ubuntu機器上?我必須將python代碼轉換爲LLVM bitcode,然後使用Emscripten編譯它嗎?如果是這樣,我將如何實現這一目標?

+0

@guettli https://github.com/pypyjs/pypyjs/issues/145 – denfromufa

回答

22

WebAssembly VS asm.js

首先,讓我們來看看如何在原則上,WebAssemblyasm.js不同,以及是否有潛在的重用現有的知識和工具。下面給出了相當不錯的概述:

讓我們來概括,WebAssembly(MVP,因爲有更多的its roadmap,大約):

  • 是AST與靜態類型的二進制格式,可以是由現有的JavaScript引擎執行(因此可以進行JIT編譯或AOT編譯),它可以比JavaScript更快10-20%(gzipip比較),解析速度比JavaScript快一個數量級,不適合JavaScript語法的高級操作,請閱讀asm.js(例如64位整數,特殊CPU指令,SIMD等)
  • 可以在一定程度上轉換爲/從asm.js.

因此,目前WebAssembly是一個關於asm.js的迭代,僅針對C/C++。

Python中的Web

它看起來並不像GC上是從目標WebAssembly/asm.js停止Python代碼的唯一的事情。兩者都代表低級靜態類型代碼,其中Python代碼不能(真實地)表示。由於WebAssembly/asm.js的當前工具鏈基於LLVM,可以輕鬆編譯爲LLVM IR的語言可以轉換爲WebAssembly/asm.js。但是,唉,PyPy的Unladen Swallowseveral attempts證明,Python太動態也無法適應它。

此asm.js演示文稿有slides about the state of dynamic languages。這意味着目前只能將整個VM(C/C++中的語言實現)編譯爲WebAssembly/asm.js並解釋(儘可能使用JIT)原始資源。對於Python,有幾個現有項目:

  1. PyPy:PyPy.js(作者的talk at PyCon)。這是release repo。主JS文件,pypyjs.vm.js,是13 MB(gzip -6後2MB)+ Python stdlib +其他東西。
  2. CPython:EmPythonCPython-Emscripten, EmCPythonempython.js是5.8 MB(gzip -6後2.1 MB),沒有stdlib。
  3. Micropython:this fork

    有沒有內置的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 
    

    它產生1.1的micropython.js MB(225 KB 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 
    

    你可以看看emcc hello.c -s WASM=1 -o hello.html HTML輸出,來看看如何使用這些文件。

    這種方式,您可能還可以建立PyPy和CPython的在WebAssembly來解釋一個兼容的瀏覽器您的Python應用程序。

另一個潛在的有趣的事情是Nuitka,一個Python到C++編譯器。可能有可能將您的Python應用程序構建到C++,然後使用Emscripten與CPython一起進行編譯。但實際上我不知道該怎麼做。

解決方案

暫時,如果你正在建設一個傳統的網站或網絡應用程序,其中下載數兆字節的JS文件僅僅是一個選項,看看的Python到JavaScript transpilers(如Transcrypt)或JavaScript Python實現(例如Brython)。或嘗試與list of languages that compile to JavaScript其他人的運氣。

否則,如果下載大小不是問題了,你準備好應付很多粗糙的邊緣,上述三者之間進行選擇。

6

這是不可能的,直到Web組裝實現垃圾收集。你可以在這裏跟蹤進度:https://github.com/WebAssembly/design/issues/1079

+3

不一定。您可以在Wasm之上實現GC - 特別是引用計數,因爲它已被Python IIRC使用。原則上,您應該能夠使用Emscripten將CPython編譯爲Wasm。 –

+0

我從OP得到的結果是他們想要使用現有的工具 - 在wasm上實現cpython GC聽起來像是一個項目本身 –

+0

您不應該做任何額外的事情,只需要讓CPython編譯。它已經包含RC實現,AFAICT。 –

2

簡而言之:你不能隨心所欲的Python轉換爲Web大會,我懷疑你將能夠長一段時間來。一種解決方法可能是Python到C到Web Assembly,但是由於Python到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++)非常棘手,你可以看到這個簡潔答案背後的詳細原因,但我認爲這超出了你的問題範圍。