编译 Swift 到 WebAssembly

Compile Swift to WebAssembly

LLVM 基础架构现在支持从 LLVM IR to WebAssembly 编译(至少是实验性的)。 Swift 使用 LLVM 编译器基础架构,可以轻松编译为 LLVM IR。所以我认为将一些 Swift 代码编译为 LLVM IR 然后再编译为 WebAssembly 会很简单。

然而事实证明这并不是那么容易。看起来 LLVM IR 并不完全独立于平台?不管幕后的原因是什么,在编译 Swift 到 LLVM IR 时,必须指定目标架构并且 WebAssembly 不可用。

那我有两个问题:

1) 目前(截至 2017 年 10 月)无法将 Swift 编译为 WebAssembly,我是否正确?

2) 如何使 WebAssembly 成为 Swift 到 LLVM IR 编译的受支持目标?

WebAssembly 目标就像是 llvm 的通用 unix 目标,所以我认为有人需要开发那个端口。

请注意 Swift -> 浏览器中的 Wasm 几乎没有用,因为 Wasm 没有 DOM 或 DOM API 访问权限,因此您仍然需要 JavaScript 做任何有意义的事情,因此问题是:为什么有人会费心去做港口?看起来 JavaScript 仍然是唯一的网络语言。如果你不喜欢JavaScript你最好忘记网络开发。

有可能 Swift 会在 Android 上 运行,然后在网络上 运行s,所以请坚持使用 Swift/iOS,然后将端口设置为Android 只要有可能。无论如何,人们不会经常使用 web/browser。

1) 据我所知,截至 2017 年 11 月初,您是正确的:没有通用的方法可以将 Swift 编译为 WebAssembly。也许某处某个有进取心的黑客已经实现了它,但如果是这样的话,她还没有与我们分享她的代码。

2) 为了启用 Wasm 支持,您可能需要破解几个不同的部分。我认为你可以在不了解编译器内部(例如解析器和优化器)的情况下做到这一点,但你需要了解工具链的工作原理以及它如何与平台集成 运行时间.

通过研究 Swift 是如何移植到 Android,您可以 了解您需要做什么。幸运的是,Brian Gesiak post写了一篇 非常 详细的博客 post 关于该端口的确切工作原理(警告:需要小额 Patreon 捐赠):

https://modocache.io/how-to-port-the-swift-runtime-to-android

说真的,如果你不读那篇文章就开始这个项目,那就太疯狂了。

尽管我 不是 专家,但基于该端口和我对 Swift 的(基本)理解,我认为您可以粗略地了解一下需要破解的是:

  • Swift编译器
    • 您需要向它介绍 LLVM 使用的 Wasm“三元组”,以便它知道如何与其工具链的其余部分集成
    • 你需要建立一个 WebAssembly 平台,以便人们可以在需要条件编译的地方编写 #if os(WebAssembly)
    • 您还需要设置类似的构建时宏。 Android 文章很好地解释了这类事情。
  • Swift运行时间
    • 这是用 C++ 编写的,它需要 运行 在 Wasm
    • 由于 Wasm 是一个不寻常的平台,因此这里可能会有一些工作。您可能需要为各种系统调用等提供兼容性垫片。
    • 像 Emscripten 这样的项目已经证明了将 C++ 编译为 Wasm 的很多成功。
  • Swift 标准库
    • 理论上您可以编写 & 运行 Swift 不使用标准库的代码,但谁会想要?
    • 同样理论上,如果 运行 时间正常,这应该“正常工作”,但您可能需要在此处使用您的 #if os(WebAssembly) 功能来解决平台违规问题
  • 奖励:The Foundation 和 Dispatch 库
    • 如果您想使用现有的 Swift 代码,这两个库将是必不可少的。

Links:

看起来有商业产品支持将 Swift 编译为 WebAssembly。开发工具公司 RemObjects 拥有 just announced support for WebAssembly with their Elements compiler,可以编译 Java、Swift、C# 和 Oxygene。

截至 2019 年 5 月,有一个名为 SwiftWasm that allows you to compile Swift code to WebAssembly targeting WASI SDK. This means that binaries produced by SwiftWasm can be executed either in browsers with WASI polyfill or standalone WebAssembly runtimes supporting WASI such as wasmtime, lucet or wasmer 的 open-source 项目可用。