2017-06-26 218 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++)非常棘手,你可以看到这个简洁答案背后的详细原因,但我认为这超出了你的问题范围。