将Python编译为WebAssembly

将Python编译为WebAssembly,python,emscripten,webassembly,Python,Emscripten,Webassembly,我已经读到了将Python2.7代码转换为Web程序集是可能的,但我找不到关于如何转换的明确指南 到目前为止,我已经使用Emscripten及其所有必要组件编译了一个用于Web组装的C程序,所以我知道它正在工作(使用指南:) 为了在Ubuntu机器上实现这一点,我必须采取哪些步骤?我是否必须将python代码转换为LLVM位代码,然后使用Emscripten进行编译?如果是这样,我将如何实现这一点?在web程序集实现垃圾收集之前,这是不可能的。您可以在此处跟踪进度:WebAssembly vs

我已经读到了将Python2.7代码转换为Web程序集是可能的,但我找不到关于如何转换的明确指南

到目前为止,我已经使用Emscripten及其所有必要组件编译了一个用于Web组装的C程序,所以我知道它正在工作(使用指南:)


为了在Ubuntu机器上实现这一点,我必须采取哪些步骤?我是否必须将python代码转换为LLVM位代码,然后使用Emscripten进行编译?如果是这样,我将如何实现这一点?

在web程序集实现垃圾收集之前,这是不可能的。您可以在此处跟踪进度:

WebAssembly vs asm.js

首先,让我们来看看,原则上,WebAssembly如何不同于ASM.JS,以及是否有重用现有知识和工具的潜力。下面给出了一个很好的概述:

让我们概括一下WebAssembly(MVP,大致上还有更多内容):

  • 是一种带有静态类型的AST二进制格式,可由现有JavaScript引擎执行(因此可JIT或编译AOT)
  • 它比JavaScript紧凑10-20%(gzip比较),解析速度快一个数量级
  • 它可以表达不适合JavaScript语法的低级操作,读取asm.js(例如64位整数、特殊CPU指令、SIMD等)
  • 可以(在某种程度上)从asm.js转换到asm.js
因此,目前WebAssembly是asm.js上的一个迭代,只针对C/C++(和类似的语言)

网络上的Python 看起来GC并不是阻止Python代码以WebAssembly/asm.js为目标的唯一因素。两者都表示低级静态类型的代码,而Python代码无法(实际地)表示。由于WebAssembly/asm.js当前的工具链是基于LLVM的,因此可以将一种易于编译为LLVM IR的语言转换为WebAssembly/asm.js。但遗憾的是,PyPy和pypypy已经证明,Python过于动态,不适合它

此asm.js演示文稿已完成。这意味着目前只能将整个VM(C/C++语言实现)编译为WebAssembly/asm.js并解释(可能的话使用JIT)原始源代码。对于Python,有几个现有项目:

  • 派比:(作者)。给你。主JS文件
    pypyjs.vm.JS
    ,是13MB(在
    gzip-6
    之后是2MB)+Python stdlib+其他东西

  • CPython:,,等。
    empython.js
    是5.8MB(在
    gzip-6
    之后是2.1MB),没有stdlib

  • 微型蟒蛇:

    那里没有构建JS文件,所以我可以使用现成的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.1MB的
    micropython.js
    (在
    gzip-d之后是225KB)。如果您只需要非常兼容的实现而不使用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应用程序

  • 这里另一个有趣的事情是,Python到C++编译器。潜在地,可以将您的Python应用程序构建到C++,然后与Emscripten一起使用CPython编译它。但实际上我不知道怎么做

    解决 目前,如果您正在构建一个传统的web站点或web应用程序,下载几兆字节的JS文件几乎不是一个选项,那么看看Python到JavaScript的transpilers(例如)或JavaScript Python实现(例如)。或者和其他人一起碰碰运气

    否则,如果下载大小不是一个问题,并且您已经准备好处理许多粗糙的边缘,请在以上三种之间进行选择

    2020年第三季度更新
  • 将JavaScript端口转换为MicroPython。它生活在

  • 该端口作为名为的npm包提供。 你可以在家里试一试

  • Rust中有一个积极开发的Python实现,名为 . 因为Rust的官方支持,所以在 自述文件的顶部。虽然现在还早。他们的免责声明如下

    RustPython正处于开发阶段,不应在中使用 生产或故障不容忍设置

    我们当前的构建只支持Python语法的一个子集


  • 简而言之:有Transpiler,但您不能自动将任何任意Python转换为Web汇编,我怀疑您在很长一段时间内都不能。虽然从理论上讲,这些语言同样强大,而且手动翻译总是可能的,但Python允许一些数据结构和表达模式,这需要非常智能的跨语言编译器(或transpiler)[见下文]。解决方法可能是Python-to-C-to-Web组装,因为Python-to-C技术已经相当成熟,但这通常也不起作用,因为Python-to-C也很脆弱(见下文)

    WebAssembly专门针对类C语言,如您在

    从Python到C的转换可以通过PyPy这样的工具完成,PyPy已经开发了很长时间,但对于任意Python代码仍然不起作用。这有几个原因:

  • Python有一些非常方便、抽象和漂亮的数据结构,但它们很难转换为静态代码
  • Python依赖于动态垃圾收集
  • 大多数Python代码在很大程度上依赖于各种库,每个库都有自己的怪癖和问题(比如用C语言编写,甚至用汇编语言编写)
  • 如果您更仔细地研究Python-to-C(或Python-to-C++)为何如此棘手,您可以看到这个简洁答案背后的详细原因,但我认为这超出了y的范围