[Swift language features] Improve Swift async by generating single Swift function #2950
Labels
area-SwiftBindings
Swift bindings for .NET
User Story
A single user-facing feature. Can be grouped under an epic.
Description
The existing approach generate a wrapper Swift function for each async function. The idea is to improve this by implementing a single Swift wrapper function with
action
parameter to limit the size of Swift code. This will include a single method for all Swift async functions in a module.Let’s consider a simple Swift async function with suspension point:
The Swift compiler splits the function into fragments at suspension (await) points:
To run the function asynchronously, the runtime uses
swift_task_create
to create a task instance and async context.To expose a Swift async function as C# Task, we can create a TaskCompletionSource with a callback.
Since projection tooling doesn’t have control over Swift generated fragments, a Swift wrapper can ensure the callback is invoked at the end of async execution:
As async function signatures can differ, we aim to minimize Swift wrappers by using a “template” wrapper to ensure the callback is invoked when fragments are executed. The tooling can generate closure contexts for the “template” wrapper that are heap-allocated at runtime. This approach relies on the template that implements the correct control flow logic, while actual arguments are generated and passed via context at runtime.
To do this, each time Swift async function is encountered, projection tooling can generate different closure context and invoke
swift_task_create
:The required parameters for
swift_task_create
are:taskCreateFlags
null
)The closure context is heap-allocated and structured as:
Closure context for action closure:
Closures metadata:
The
objectdestroy
is C# function that ensures proper cleanup/release of closure contexts using ARC APIs.This approach allows us to use a single Swift “template” function for handling async calls, minimizing generated Swift code. Swift Task type will be projected as a separate type which utilize similar logic.
Tasks
swift_task_create
andswift_task_alloc
to theSwift.Runtime
namespaceTaskCompletionSource
callback function that resolves the C# TaskThe text was updated successfully, but these errors were encountered: