Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A Vision for WebAssembly Support in Swift #2358

Closed
wants to merge 17 commits into from

Conversation

MaxDesiatov
Copy link
Contributor

@MaxDesiatov MaxDesiatov commented Mar 9, 2024

For now this contains an introduction section which doesn't assume any prior knowledge of the Wasm ecosystem. It provides overview of properties of Wasm useful when applied to Swift developer tools specifically. A list of high-level goals is provided, with a short subsection for specific language features that can be proposed in the near term.

@MaxDesiatov MaxDesiatov added the vision Prospective vision document label Mar 9, 2024
@MaxDesiatov MaxDesiatov self-assigned this Mar 9, 2024
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Show resolved Hide resolved
Comment on lines +44 to +45
This means that adoption of Wasm in developer tools does not imply unavoidable performance overhead. In fact, with
security guarantees that virtualization brings there's no longer a need to spawn a separate process for each
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this sentence :)

@MaxDesiatov MaxDesiatov marked this pull request as ready for review March 14, 2024 10:43
@MaxDesiatov MaxDesiatov changed the title Initial draft of "A Vision for WebAssembly Support in Swift" A Vision for WebAssembly Support in Swift Mar 14, 2024
Co-authored-by: Yuta Saito <[email protected]>
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
@MaxDesiatov MaxDesiatov marked this pull request as draft March 15, 2024 09:29
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
visions/webassembly.md Show resolved Hide resolved
visions/webassembly.md Outdated Show resolved Hide resolved
Co-authored-by: Alastair Houghton <[email protected]>
@rjmccall
Copy link
Contributor

rjmccall commented Apr 1, 2024

I see this primarily as a topic for the new Platform Steering Group, but we'll look it over on the LSG as well.

@rjmccall rjmccall added the PSG Contains topics under the domain of the Platform Steering Group label Apr 1, 2024
@al45tair
Copy link
Contributor

Could this also talk a little about the story re. debugging? How do we debug Swift code built on WASM? Does it matter whether we're debugging in the browser or using a separate WASM interpreter like wasmtime? Do we support attaching LLDB somehow? How are we going to deal with metadata?

@MaxDesiatov
Copy link
Contributor Author

Could this also talk a little about the story re. debugging? How do we debug Swift code built on WASM? Does it matter whether we're debugging in the browser or using a separate WASM interpreter like wasmtime? Do we support attaching LLDB somehow? How are we going to deal with metadata?

There's no debugging story, unfortunately. Some browsers had some support for source maps at some point, some rely on DWARF, some have no support for debugging other then stepping through disassembly. I'm not aware of Wasm runtimes that have special support for debugging, other than @kateinoigakukun's wasminspect. There's apparently a WebAssembly Debugging Subgroup, but they have no meeting minutes posted since 2020.

@al45tair
Copy link
Contributor

There's no debugging story, unfortunately.

I think, since this is a vision document, it should probably expand on what debugging should look like, or what our goal is here in that regard, and maybe a summary of what is presently possible would be useful along with some ideas about how we might make progress towards the end goal (which, presumably, is some kind of support for source-level debugging of Swift programs running on WASM)?

[`__attribute__((export_name("name")))`](https://clang.llvm.org/docs/AttributeReference.html#export-name), which
is the counterpart of `@_extern(wasm)` working in the opposite direction. This explicitly makes a Swift declaration
available outside of the current module, added to its exports section under a given name. Again, the lack of
this attribute in Swift requires use of C headers as a workaround.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added brief notes about debugging, multi-threading, 64-bit, and shared library directions. Feel free to ignore or amend this if it's too implementation details :)

Suggested change
this attribute in Swift requires use of C headers as a workaround.
this attribute in Swift requires use of C headers as a workaround.
## Platform-specific Considerations
### Debugging
Debugging Wasm modules is challenging because Wasm does not expose ways to introspect and control the execution of
the Wasm instance, so a debugger cannot be built on top of Wasm itself. Therefore, special support from the Wasm
execution engine is necessary for debugging.
The current state of debugging tools in the Wasm ecosystem is not as mature as other platforms but there are two
main directions:
1. LLDB debugger with Wasm runtime supporting GDB Remote Serial Protocol [1]
2. Wasm runtime with a built-in debugger [2]
The first approach provides an almost equivalent experience to existing debugging workflows on other platforms. It
can utilize LLDB's Swift support, remote metadata inspection and serialized Swift module information. However, since
Wasm is a Harvard architecture and has no way to allocate executable memory space at runtime, implementing expression
evaluation with JIT in user space is challenging. In other words, gdb stub in Wasm engines need tricky implementations
or need to extend the GDB Remote Serial Protocol.
The second approach embeds the debugger within the Wasm engine. In scenarios where the Wasm engine is embedded as a guest
language in another host language engine (e.g. within a Web Browser), this approach allows seamless debugging experiences
with the host language by integrating with the host debugger. For example, in cases where JavaScript and Wasm call frames
are interleaved, the debugger works well in both contexts without switching tools. Debugging tools like Chrome DevTools
can use DWARF information embedded in Wasm file to provide debugging support. However, supporting Swift-specific
metadata information and JIT-based expression evaluation will require integrating LLDB's Swift plugin with these debuggers
in some way.
Given that both approaches can utilize DWARF information, the Swift toolchain should generate as much DWARF information as possible
for statically known things. Also, making Swift type information DWARF-friendly is desirable because the current debug
information generated by the Swift compiler assumes that debuggers can understand certain Swift primitives (e.g. `Swift.Int`
is currently represented as a `DW_TAG_structure_type` node without any member but ideally such types should be represented
as `DW_TAG_base_type` nodes with `DW_AT_encoding` attribute or provide a debug summary string by LLDB Summary Strings)
[1]: https://github.com/llvm/llvm-project/pull/77949
[2]: https://github.com/ChromeDevTools/devtools-frontend/blob/main/extensions/cxx_debugging
### Multi-threading and Concurrency
WebAssembly has [atomic operations in the instruction set](https://github.com/WebAssembly/threads) (only sequential
consistency is supported), but it does not have a built-in way to create threads. Instead, it relies on the host
environment to provide multi-threading support. This means that multi-threading in Wasm is dependent on the Wasm runtime
that executes the module. There are two proposals to standardize ways to create threads in Wasm: (1) [wasi-threads](https://github.com/WebAssembly/wasi-threads),
which is already supported by some toolchains, runtimes, and libraries but has been superseded by the new one. (2) The
new proposal [shared-everything-threads](https://github.com/WebAssembly/shared-everything-threads) is still in the
early stages of spec development but is expected to be the future of multi-threading in Wasm.
Swift currently supports two threading models in Wasm: single-threaded (`wasm32-unknown-wasi`) and multi-threaded
using wasi-threads (`wasm32-unknown-wasip1-threads`). Despite the latter supporting multi-threading, Swift Concurrency defaults
to a cooperative single-threaded executor due to the lack of wasi-threads support in libdispatch. Preparing for the
shared-everything-threads proposal is crucial to ensure that Swift Concurrency can adapt to future multi-threading
standards in Wasm.
### 64-bit address space
WebAssembly currently uses a 32-bit address space, but the specification is going to support [64-bit address space](https://github.com/WebAssembly/memory64/).
Swift already has support on 64-bit for other platforms, however, WebAssembly is the first platform where relative reference
from data to code is not allowed. Alternative solutions like image-base relative addressing or small "code model" for fitting
64-bit pointer in 32-bit are unavailable, at least for now. This means that we need cooperation from the WebAssembly toolchain
side or different memory layout in Swift metadata to support 64-bit in WebAssembly.
### Shared libraries
There are two approaches to using shared libraries in WebAssembly ecosystem:
1. [Emscripten-style dynamic linking](https://emscripten.org/docs/compiling/Dynamic-Linking.html)
2. [Component Model-based "ahead-of-time" linking](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Linking.md)
Emscripten-style dynamic linking is a traditional way to use shared libraries in WebAssembly, where the host environment provides
non-standard dynamic loading capabilities.
Component Model-based AOT linking is a new way that transforms shared library WebAssembly Core modules compiled with
Emscripten's dynamic linking ABI into a single WebAssembly Component at build time. The latter approach cannot fully replace the former,
as it is not able to handle dynamic loading of shared libraries at runtime, but it is more portable way to distribute programs linked
with shared libraries because it does not require the host environment to provide any special capabilities except for Component Model
support.
From the Swift toolchain perspective, they both use the Emscripten's dynamic linking ABI, so the support for shared libraries in
Swift is mostly about making sure that Swift programs can be compiled in position-independent code mode and linked with shared
libraries by following the dynamic linking ABI.

@MaxDesiatov
Copy link
Contributor Author

Closing this, since after migration to swiftlang I no longer have access to this branch to update anything in the PR.

@MaxDesiatov MaxDesiatov closed this Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PSG Contains topics under the domain of the Platform Steering Group vision Prospective vision document
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants