如何将 Python/Boo/Ruby 语法编译到 C/C++/LLVM/JavaScript

74 阅读3分钟
  • 将具有 Python 语法的代码自动编译或转换为原生且快速的 JavaScript 代码。
  • 希望编译后代码具有良好的调试支持,类似于 Java 等语言提供的支持。
  • 由于 JavaScript 的浏览器环境更难调试,因此需要将复杂的主循环、时间线、物理模拟和复杂交互等可视化代码编译为 JavaScript。

huake_00015_.jpg

1.2 背景信息

  • Emscripten 允许将 C/C++ 编译为 JavaScript,由于 ArrayBuffer 的类型化数组支持和新的浏览器 JS 引擎(如 ASM.js 和 LLJS),JavaScript 在浏览器中的运行效率正在不断提高。
  • Altjs.org 列出了许多 JavaScript 替代方案,但尚未关注最近的速度改进或特定的良好语义。然而,人们使用更好的工具为浏览器编写代码变得越来越普遍。特别是 Emscripten 有很多令人惊叹的演示。

1.3 已经考虑的可能选项:

  • Shedskin - 由于作者 C++/C 技能有限,无法让 Shedskin 正常工作。
  • Unladen Swallow/RPython 到 LLVM - 目前尚未能在 Ubuntu 上正确设置。
  • Boo 到 Java 再到 LLVM - 尚未能在 Ubuntu 系统上设置。

1.4 附加约束:

  • 需要在 Ubuntu 系统上使用。
  • 编译后的 JavaScript 大小应该小于 1MB。
  • 应允许在跨编译的本机语言中进行调试,这能够利用现有的调试工具。

2. 解决方案

2.1 答案 1 的观点

  • 没有一种高级动态语言可以编译成高效的低级 JavaScript,因为如果动态语言足够快,就根本不需要 asm.js 了。
  • 如果想要编写编译为高效 JavaScript 的代码,就必须学习一种更底层的语言。
  • Emscripten 之所以快是因为它从一种允许编译器进行更多优化的低级语言(C/C++)编译而来,而不是普通的 JavaScript。这也正是 asm.js 和 LLVM 能够更快的的原因。它们的速度来自于没有动态类型、垃圾回收(这正是可以使用 ArrayBuffer 作为内存的原因)和其他高级特性。
  • 综上所述,目前没有工具可以将具有 Python 语义的语言编译成原生且快速的 JavaScript 代码。而且,根据语义的含义,不太可能出现这样的工具,因为 Python 本身就是一种速度较慢的语言。
  • 目前生成快速 JavaScript 的最佳选择是 Emscripten。作者还可以考虑 LLJS 或手动编写快速的 JavaScript(Chrome 为此提供了调试工具)。
  • 考虑到问题的标题,作者非常关心语法。但这不应该成为关注点。在为这项工作选择合适的语言时,语法是最不重要的因素之一。

2.2 答案 2 的观点

  • 鉴于作者自己提到了 Shedskin,作者应该能够分享一些自己的经验(并解释一下作者认为 Shedskin 缺少的具体内容,除了它的输入是一种受限的 Python 语法)。作者也可以假设 Cython/Pyrex 是不可接受的(由于语法限制)。
  • 如果 Shedskin 对作者来说还处于非常不稳定的早期阶段,那么作者可能正在寻找类似 Numba 项目的东西,其中包括将动态 Python 编译成 LLVM 的编译器,以及 llvm-py,后者允许链接 LLVM 公开的字节码(类似于 ctypes 允许链接共享库),并构建 LLVM IR 编译器。
  • 作者可以将 Numba 用作 numpy 的 JIT,这里有一个博客文章对此进行了说明,其中包括与等效 Cython 代码的性能比较。
  • Emscripten 应该允许作者公开和调用 Python -> llvm -> JS 代码,如其文档中所述。