Skip to content

Commit e4b6f8b

Browse files
committed
More feedback: ownership of bbargs, begin -> get_async_continuation
1 parent e2dfe3a commit e4b6f8b

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

docs/SIL.rst

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -641,16 +641,18 @@ otherwise can be invoked with the normal ``apply`` and ``try_apply``
641641
instructions (or ``begin_apply`` if they are coroutines).
642642

643643
In Swift, the ``withUnsafeContinuation`` primitive is used to implement
644-
primitive suspend points. In SIL, ``@async`` functions represent this abstraction
645-
``begin_async_continuation[_addr]`` and ``await_async_continuation``
646-
instructions. ``begin_async_continuation[_addr]`` creates a *continuation*
647-
value that can be used to resume the coroutine when it suspends, feeding a
648-
value back into the currently-running function or causing it to fail with an
649-
error when it resumes. The resulting continuation value can then be passed
650-
into a completion handler, registered with an event loop, or scheduled by
651-
some other mechanism. The ``await_async_continuation`` instruction suspends
652-
execution of the coroutine until the continuation is invoked to resume it.
653-
A use of ``withUnsafeContinuation`` in Swift::
644+
primitive suspend points. In SIL, ``@async`` functions represent this
645+
abstraction using the ``get_async_continuation[_addr]`` and
646+
``await_async_continuation`` instructions. ``get_async_continuation[_addr]``
647+
accesses a *continuation* value that can be used to resume the coroutine after
648+
it suspends. The resulting continuation value can then be passed into a
649+
completion handler, registered with an event loop, or scheduled by some other
650+
mechanism. Operations on the continuation can resume the async function's
651+
execution by passing a value back to the async function, or passing in an error
652+
that propagates as an error in the async function's context.
653+
The ``await_async_continuation`` instruction suspends execution of
654+
the coroutine until the continuation is invoked to resume it. A use of
655+
``withUnsafeContinuation`` in Swift::
654656

655657
func waitForCallback() async -> Int {
656658
return await withUnsafeContinuation { cc in
@@ -662,7 +664,7 @@ might lower to the following SIL::
662664

663665
sil @waitForCallback : $@convention(thin) @async () -> Int {
664666
entry:
665-
%cc = begin_async_continuation $Int
667+
%cc = get_async_continuation $Int
666668
%closure = function_ref @waitForCallback_closure
667669
: $@convention(thin) (UnsafeContinuation<Int>) -> ()
668670
apply %closure(%cc)
@@ -676,7 +678,7 @@ The closure may then be inlined into the ``waitForCallback`` function::
676678

677679
sil @waitForCallback : $@convention(thin) @async () -> Int {
678680
entry:
679-
%cc = begin_async_continuation $Int
681+
%cc = get_async_continuation $Int
680682
%registerCallback = function_ref @registerCallback
681683
: $@convention(thin) (@convention(thick) () -> ()) -> ()
682684
%callback_fn = function_ref @waitForCallback_callback
@@ -2682,29 +2684,29 @@ undefined behavior if the global variable has already been initialized.
26822684

26832685
The type operand must be a lowered object type.
26842686

2685-
begin_async_continuation
2686-
````````````````````````
2687+
get_async_continuation
2688+
``````````````````````
26872689

26882690
::
26892691

2690-
sil-instruction ::= 'begin_async_continuation' '[throws]'? sil-type
2692+
sil-instruction ::= 'get_async_continuation' '[throws]'? sil-type
26912693

2692-
%0 = begin_async_continuation $T
2693-
%0 = begin_async_continuation [throws] $U
2694+
%0 = get_async_continuation $T
2695+
%0 = get_async_continuation [throws] $U
26942696

26952697
Begins a suspension of an ``@async`` function. This instruction can only be
26962698
used inside an ``@async`` function. The result of the instruction is an
26972699
``UnsafeContinuation<T>`` value, where ``T`` is the formal type argument to the
26982700
instruction, or an ``UnsafeThrowingContinuation<T>`` if the instruction
26992701
carries the ``[throws]`` attribute. ``T`` must be a loadable type.
27002702
The continuation must be consumed by a ``await_async_continuation`` terminator
2701-
on all paths. Between ``begin_async_continuation`` and
2703+
on all paths. Between ``get_async_continuation`` and
27022704
``await_async_continuation``, the following restrictions apply:
27032705

27042706
- The function cannot ``return``, ``throw``, ``yield``, or ``unwind``.
27052707
- There cannot be nested suspend points; namely, the function cannot call
27062708
another ``@async`` function, nor can it initiate another suspend point with
2707-
``begin_async_continuation``.
2709+
``get_async_continuation``.
27082710

27092711
The function suspends execution when the matching ``await_async_continuation``
27102712
terminator is reached, and resumes execution when the continuation is resumed.
@@ -2723,34 +2725,34 @@ undefined behavior to resume the continuation more than once. Conversely,
27232725
failing to resume the continuation will leave the suspended async coroutine
27242726
hung in its suspended state, leaking any resources it may be holding.
27252727

2726-
begin_async_continuation_addr
2727-
`````````````````````````````
2728+
get_async_continuation_addr
2729+
```````````````````````````
27282730

27292731
::
27302732

2731-
sil-instruction ::= 'begin_async_continuation_addr' '[throws]'? sil-type ',' sil-operand
2733+
sil-instruction ::= 'get_async_continuation_addr' '[throws]'? sil-type ',' sil-operand
27322734

2733-
%1 = begin_async_continuation_addr $T, %0 : $*T
2734-
%1 = begin_async_continuation_addr [throws] $U, %0 : $*U
2735+
%1 = get_async_continuation_addr $T, %0 : $*T
2736+
%1 = get_async_continuation_addr [throws] $U, %0 : $*U
27352737

2736-
Begins a suspension of an ``@async`` function, like ``begin_async_continuation``,
2737-
while binding a specific memory location to the resulting continuation for
2738-
receiving the value the continuation is resumed with. The operand must be an
2739-
address whose type is the maximally-abstracted lowered type of the formal
2740-
resume type. The memory must be uninitialized, and must remain valid until the
2741-
matching ``await_async_continuation`` instruction(s) consuming the result
2742-
continuation have executed. The behavior is otherwise the same as
2743-
``begin_async_continuation``, and the same restrictions apply on code appearing
2744-
between ``begin_async_continuation_addr`` and ``await_async_continuation`` as
2745-
apply between ``begin_async_continuation`` and ``await_async_continuation``.
2738+
Begins a suspension of an ``@async`` function, like ``get_async_continuation``,
2739+
additionally binding a specific memory location for receiving the value
2740+
when the result continuation is resumed. The operand must be an address whose
2741+
type is the maximally-abstracted lowered type of the formal resume type. The
2742+
memory must be uninitialized, and must remain allocated until the matching
2743+
``await_async_continuation`` instruction(s) consuming the result continuation
2744+
have executed. The behavior is otherwise the same as
2745+
``get_async_continuation``, and the same restrictions apply on code appearing
2746+
between ``get_async_continuation_addr`` and ``await_async_continuation`` as
2747+
apply between ``get_async_continuation`` and ``await_async_continuation``.
27462748
Additionally, the state of the memory referenced by the operand is indefinite
2747-
between the execution of ``begin_async_continuation_addr`` and
2749+
between the execution of ``get_async_continuation_addr`` and
27482750
``await_async_continuation``, and it is undefined behavior to read or modify
27492751
the memory during this time. After the ``await_async_continuation`` resumes
2750-
normally to its ``resume`` successor, the memory referenced by the operand
2751-
is initialized with the resume value, and that value is then owned by the
2752-
current function. If ``await_async_continuation`` instead resumes to
2753-
its ``error`` successor, then the memory remains uninitialized.
2752+
normally to its ``resume`` successor, the memory referenced by the operand is
2753+
initialized with the resume value, and that value is then owned by the current
2754+
function. If ``await_async_continuation`` instead resumes to its ``error``
2755+
successor, then the memory remains uninitialized.
27542756

27552757
dealloc_stack
27562758
`````````````
@@ -6386,33 +6388,33 @@ await_async_continuation
63866388
await_async_continuation %0 : $UnsafeContinuation<T>, resume bb1
63876389
await_async_continuation %0 : $UnsafeThrowingContinuation<T>, resume bb1, error bb2
63886390

6389-
bb1(%1 : $T):
6390-
bb2(%2 : $Error):
6391+
bb1(%1 : @owned $T):
6392+
bb2(%2 : @owned $Error):
63916393

63926394
Suspends execution of an ``@async`` function until the continuation
63936395
is resumed. The continuation must be the result of a
6394-
``begin_async_continuation`` or ``begin_async_continuation_addr``
6396+
``get_async_continuation`` or ``get_async_continuation_addr``
63956397
instruction within the same function; see the documentation for
6396-
``begin_async_continuation`` for discussion of further constraints on the
6397-
IR between ``begin_async_continuation[_addr]`` and ``await_async_continuation``.
6398+
``get_async_continuation`` for discussion of further constraints on the
6399+
IR between ``get_async_continuation[_addr]`` and ``await_async_continuation``.
63986400
This terminator can only appear inside an ``@async`` function. The
63996401
instruction must always have a ``resume`` successor, but must have an
64006402
``error`` successor if and only if the operand is an
64016403
``UnsafeThrowingContinuation<T>``.
64026404

6403-
If the operand is the result of a ``begin_async_continuation`` instruction,
6405+
If the operand is the result of a ``get_async_continuation`` instruction,
64046406
then the ``resume`` successor block must take an argument whose type is the
64056407
maximally-abstracted lowered type of ``T``, matching the type argument of the
64066408
``Unsafe[Throwing]Continuation<T>`` operand. The value of the ``resume``
64076409
argument is owned by the current function. If the operand is the result of a
6408-
``begin_async_continuation_addr`` instruction, then the ``resume`` successor
6410+
``get_async_continuation_addr`` instruction, then the ``resume`` successor
64096411
block must *not* take an argument; the resume value will be written to the
6410-
memory referenced by the operand to the ``begin_async_continuation_addr``
6412+
memory referenced by the operand to the ``get_async_continuation_addr``
64116413
instruction, after which point the value in that memory becomes owned by the
64126414
current function. With either variant, if the ``await_async_continuation``
64136415
instruction has an ``error`` successor block, the ``error`` block must take a
64146416
single ``Error`` argument, and that argument is owned by the enclosing
6415-
function. The memory referenced by a ``begin_async_continuation_addr``
6417+
function. The memory referenced by a ``get_async_continuation_addr``
64166418
instruction remains uninitialized when ``await_async_continuation`` resumes on
64176419
the ``error`` successor.
64186420

0 commit comments

Comments
 (0)