34

The LLVM infrastructure now supports compiling from LLVM IR to WebAssembly (at least experimentally). Swift uses the LLVM compiler infrastructure and can easily be compiled to LLVM IR. So I thought it would be straightforward to compile some Swift code to LLVM IR and then to WebAssembly.

It turned out not to be that easy, however. It looks like LLVM IR is not entirely platform independent? Whatever the reason behind the scenes, when compiling Swift to LLVM IR, a target architecture must be specified and WebAssembly is not available.

I have two questions then:

1) Am I correct that there is currently (as of October 2017) no way to compile Swift to WebAssembly?

2) What would it take to make WebAssembly a supported target for Swift to LLVM IR compilation?

Rob Mecham
  • 593
  • 7
  • 9
  • I believe you need to build LLVM yourself, because it doesn't come with support for webm by default. – Rakete1111 Oct 04 '17 at 19:26
  • 2
    Yes, that's correct. I have a custom of build of LLVM with support for WebAssembly turned on. I have successfully used that to compile C code to WebAssembly. But now I would like to compile Swift code to WebAssembly and for that, the correct build of LLVM seems to be necessary but not sufficient. Some support for WebAssembly needs to be in Swift itself, as far as I can tell. – Rob Mecham Oct 04 '17 at 22:28
  • 1
    watch this space - https://github.com/kripken/emscripten/issues/2427 – johndpope Sep 26 '18 at 12:20

5 Answers5

26

1) To the best of my knowledge as of early Nov, 2017 you are correct: there is no commonly available way to compile Swift to WebAssembly. Maybe some enterprising hacker somewhere has made it happen but if so she hasn't shared her code with us yet.

2) In order to enable Wasm support you will probably need to hack on a few different parts. I think you could do it without knowing much of anything about the internals of the compiler (e.g. the parser & optimizers), but you'd need to learn about how the toolchain works and how it integrates with the platform at runtime.

You can learn a ton about what you'd need to do by studying how Swift was ported to Android. Luckily, Brian Gesiak posted a really detailed blog post about exactly how that port worked (warning: small Patreon donation required):

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

Seriously, you would be nuts to embark on this project without reading that article.

Though I'm NOT an expert, based on that port and my (basic) understanding of Swift, I think the rough overview of where you'd need to hack would be:

  • The Swift compiler
    • You'll need to teach it about the Wasm "triple" used by LLVM, so it knows how to integrate with the rest of its toolchain
    • You'll need to set up a WebAssembly platform so that people can write #if os(WebAssembly) in places that require conditional compilation
    • You'll also need to set up similar build-time macros. The Android article explains this sort of thing really well.
  • The Swift runtime
    • This is written in C++ and it needs to run on Wasm
    • Since Wasm is an unusual platform there will probably be some work here. You might need to provide compatibility shims for various system calls and the like.
    • Projects like Emscripten have demonstrated lots of success compiling C++ to Wasm.
  • The Swift standard library
    • In theory you can write & run Swift code that doesn't use the standard library, but who would want to?
    • Also in theory this should "just work" if the runtime works, but you will likely need to use your #if os(WebAssembly) feature here to work around platform irregularities
  • Bonus: The Foundation and Dispatch libraries
    • If you want to use existing Swift code these two libraries will be essential.

Links:

Max Desiatov
  • 5,087
  • 3
  • 48
  • 56
n8gray
  • 4,939
  • 3
  • 36
  • 33
  • 5
    Also progress on this thing is being tracked mostly in this Github issue: https://github.com/kripken/emscripten/issues/2427 – Alper Nov 16 '17 at 08:44
12

It looks like there is a commercial offering that supports compilation of Swift to WebAssembly. RemObjects, the developer tooling company, has just announced support for WebAssembly with their Elements compiler, which can compile Java, Swift, C# and Oxygene.

ColinE
  • 68,894
  • 15
  • 164
  • 232
5

As of May 2019 there's an open-source project available called 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.

Max Desiatov
  • 5,087
  • 3
  • 48
  • 56
1

I was looking for a way to convert Swift code to web assembly, and I found this.

https://swiftwasm.org/

I do not know how mature this platform is (October 2022) and if it can flourish, but having the capability is exciting. Also, it provides means for writing JavaScript in Swift directly.

EricandWeb
  • 25
  • 6
-4

WebAssembly target would be like a generic unix target for llvm, so I think someone needs develop that port.

Please note that Swift -> Wasm in browser would be pretty much useless because Wasm has no DOM or DOM API access so you still need JavaScript to do anything meaningful, thus the question: why would anyone bother to make the port? It looks like JavaScript remains the only web language. If you don't like JavaScript you better forget the web development.

Chances are that Swift will run on Android before it runs on the web so stick with Swift/iOS and then make the port to Android whenever that becomes possible. People don't use the web/browser that much anyway.

Max Desiatov
  • 5,087
  • 3
  • 48
  • 56
mike
  • 533
  • 1
  • 7
  • 24
  • 3
    Yes, it seems clear that support for WASM as a target for Swift will require additional development. The point of question #2 was to ask for pointers on where to get started on that. It’s not difficult to imagine scenarios in which WASM code can be useful for web development even without direct DOM access. Validation functions, for example, could be written in Swift, used server-side and client-side, with some JavaScript code on the client-side to call the validation functions. That said, WASM would certainly be _more_ useful if it did have DOM access, but one step at a time, no? – Rob Mecham Nov 01 '17 at 16:26