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?
Binaryen. Binaryen is a compiler toolchain infrastructure library for WebAssembly. Written in C++, Binaryen is intended to make compiling to WebAssembly easy, effective, and fast. It has a C API in a single header, and it can be used from JavaScript.
WebAssembly can be compiled by Golang itself or with TinyGo. At the time of writing Go version 1.18 is the latest version and does not support WASI, if you wish to compile to WASI you need to use TinyGo.
Since it's a well-defined format, any language can have Wasm as a compilation target. Consequently, there are now around 40 high-level programming languages that support WebAssembly, including C and C++, Python, Go, Rust, Java, and PHP.
You can use WebAssembly in Safari, Chrome, Firefox, Edge and in mobile browsers like iOS Safari, Firefox for Android, and Chrome.
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:
#if os(WebAssembly)
in places that require conditional compilation#if os(WebAssembly)
feature here to work around platform irregularitiesIt 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With