@@ -351,24 +351,11 @@ bool swift_taskGroup_isCancelled(TaskGroup *group);
351351SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swift)
352352bool swift_taskGroup_isEmpty (TaskGroup *group);
353353
354- // / DEPRECATED. swift_asyncLet_begin is used instead.
355- // / Its Swift signature is
354+ // / Enter the scope of an async let binding, creating a child task of the
355+ // / current task to run the given function.
356356// /
357- // / \code
358- // / func swift_asyncLet_start<T>(
359- // / asyncLet: Builtin.RawPointer,
360- // / options: Builtin.RawPointer?,
361- // / operation: __owned @Sendable () async throws -> T
362- // / )
363- // / \endcode
364- SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swift)
365- void swift_asyncLet_start (AsyncLet *alet,
366- TaskOptionRecord *options,
367- const Metadata *futureResultType,
368- void *closureEntryPoint, HeapObject *closureContext);
369-
370- // / Begin an async let child task.
371- // / Its Swift signature is
357+ // / Behaves approximately like a Swift function with the following
358+ // / signature, except the generic argument is in a different position:
372359// /
373360// / \code
374361// / func swift_asyncLet_start<T>(
@@ -378,64 +365,24 @@ void swift_asyncLet_start(AsyncLet *alet,
378365// / resultBuffer: Builtin.RawPointer
379366// / )
380367// / \endcode
368+ // /
369+ // / Previous versions of the concurrency runtime also provided a
370+ // / \c swift_asyncLet_start which did not take a result buffer. This
371+ // / function was never used by a released version of the compiler,
372+ // / and it has been removed.
381373SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swift)
382374void swift_asyncLet_begin (AsyncLet *alet,
383375 TaskOptionRecord *options,
384376 const Metadata *futureResultType,
385377 void *closureEntryPoint, HeapObject *closureContext,
386378 void *resultBuffer);
387379
388- // / This matches the ABI of a closure `<T>(Builtin.RawPointer) async -> T`
389- using AsyncLetWaitSignature =
390- SWIFT_CC (swiftasync)
391- void (OpaqueValue *,
392- SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *, Metadata *);
393-
394- // / DEPRECATED. swift_asyncLet_get is used instead.
395- // / Wait for a non-throwing async-let to complete.
380+ // / Get the value of a non-throwing async let, awaiting the result
381+ // / if necessary.
396382// /
397- // / This can be called from any thread. Its Swift signature is
383+ // / This must be called from the parent task of the async let.
398384// /
399- // / \code
400- // / func swift_asyncLet_wait(
401- // / _ asyncLet: _owned Builtin.RawPointer
402- // / ) async -> Success
403- // / \endcode
404- SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
405- void swift_asyncLet_wait (OpaqueValue *,
406- SWIFT_ASYNC_CONTEXT AsyncContext *,
407- AsyncLet *, TaskContinuationFunction *,
408- AsyncContext *);
409-
410- // / DEPRECATED. swift_asyncLet_get_throwing is used instead.
411- // / Wait for a potentially-throwing async-let to complete.
412- // /
413- // / This can be called from any thread. Its Swift signature is
414- // /
415- // / \code
416- // / func swift_asyncLet_wait_throwing(
417- // / _ asyncLet: _owned Builtin.RawPointer
418- // / ) async throws -> Success
419- // / \endcode
420- SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
421- void swift_asyncLet_wait_throwing (OpaqueValue *,
422- SWIFT_ASYNC_CONTEXT AsyncContext *,
423- AsyncLet *,
424- ThrowingTaskFutureWaitContinuationFunction *,
425- AsyncContext *);
426-
427- // / DEPRECATED. swift_asyncLet_finish is used instead.
428- // / Its Swift signature is
429- // /
430- // / \code
431- // / func swift_asyncLet_end(_ alet: Builtin.RawPointer)
432- // / \endcode
433- SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swift)
434- void swift_asyncLet_end (AsyncLet *alet);
435-
436- // / Get the value of a non-throwing async-let, awaiting the result if necessary.
437- // /
438- // / This can be called from any thread. Its Swift signature is
385+ // / Behaves like a Swift async function with the signature:
439386// /
440387// / \code
441388// / func swift_asyncLet_get(
@@ -444,21 +391,31 @@ void swift_asyncLet_end(AsyncLet *alet);
444391// / ) async
445392// / \endcode
446393// /
447- // / \c result points at the variable storage for the binding. It is
448- // / uninitialized until the first call to \c swift_asyncLet_get or
449- // / \c swift_asyncLet_get_throwing. That first call initializes the storage
450- // / with the result of the child task. Subsequent calls do nothing and leave
451- // / the value in place.
394+ // / except that it uses the special calling convention in which the
395+ // / continuation function, parent context, and child context are all
396+ // / passed in separately rather than being stored in the child context.
397+ // / The child async context has a fixed size of 5 * sizeof(void*).
398+ // /
399+ // / \c resultBuffer must be the same result buffer that was passed to
400+ // / swift_asyncLet_begin. After asynchronous return, it is guaranteed
401+ // / to be initialized.
402+ // /
403+ // / Previous versions of the concurrency runtime also provided a
404+ // / \c swift_asyncLet_wait which was meant to be paired with
405+ // / \c swift_asyncLet_start. This function was never used by
406+ // / a released version of the compiler, and it has been removed.
452407SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
453- void swift_asyncLet_get (SWIFT_ASYNC_CONTEXT AsyncContext *,
454- AsyncLet *,
455- void *,
456- TaskContinuationFunction *,
457- AsyncContext *);
408+ void swift_asyncLet_get (SWIFT_ASYNC_CONTEXT AsyncContext *parentContext ,
409+ AsyncLet *alet ,
410+ void *resultBuffer ,
411+ TaskContinuationFunction *continuation ,
412+ AsyncContext *childContext );
458413
459- // / Get the value of a throwing async- let, awaiting the result if necessary.
414+ // / Get the value of a throwing async let, awaiting the result if necessary.
460415// /
461- // / This can be called from any thread. Its Swift signature is
416+ // / This must be called from the parent task of the async let.
417+ // /
418+ // / Behaves like a Swift async function with the signature:
462419// /
463420// / \code
464421// / func swift_asyncLet_get_throwing(
@@ -467,42 +424,75 @@ void swift_asyncLet_get(SWIFT_ASYNC_CONTEXT AsyncContext *,
467424// / ) async throws
468425// / \endcode
469426// /
470- // / \c result points at the variable storage for the binding. It is
471- // / uninitialized until the first call to \c swift_asyncLet_get or
472- // / \c swift_asyncLet_get_throwing. That first call initializes the storage
473- // / with the result of the child task. Subsequent calls do nothing and leave
474- // / the value in place. A pointer to the storage inside the child task is
475- // / returned if the task completes successfully, otherwise the error from the
476- // / child task is thrown.
427+ // / except that it uses the special calling convention in which the
428+ // / continuation function, parent context, and child context are all
429+ // / passed in separately rather than being stored in the child context.
430+ // / The child async context has a fixed size of 5 * sizeof(void*).
431+ // /
432+ // / \c resultBuffer must be the same result buffer that was passed to
433+ // / swift_asyncLet_begin. After asynchronous return, it is guaranteed
434+ // / to be initialized unless the operation throws by passing an error
435+ // / to the continuation function.
436+ // /
437+ // / Previous versions of the concurrency runtime also provided a
438+ // / \c swift_asyncLet_wait_throwing which was meant to be paired with
439+ // / \c swift_asyncLet_start. This function was never used by
440+ // / a released version of the compiler, and it has been removed.
477441SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
478- void swift_asyncLet_get_throwing (SWIFT_ASYNC_CONTEXT AsyncContext *,
479- AsyncLet *,
480- void *,
481- ThrowingTaskFutureWaitContinuationFunction *,
482- AsyncContext *);
442+ void swift_asyncLet_get_throwing (SWIFT_ASYNC_CONTEXT AsyncContext *parentContext,
443+ AsyncLet *alet,
444+ void *resultBuffer,
445+ ThrowingTaskFutureWaitContinuationFunction *
446+ continuation,
447+ AsyncContext *childContext);
483448
484- // / Exit the scope of an async- let binding. If the task is still running, it
485- // / is cancelled, and we await its completion; otherwise, we destroy the
486- // / value in the variable storage .
449+ // / Exit the scope of an async let binding that was created with
450+ // / swift_asyncLet_begin. If the child task is still running, it is
451+ // / cancelled, and the current task is suspended to await its completion .
487452// /
488- // / Its Swift signature is
453+ // / This must be called from the parent task of the async let.
454+ // /
455+ // / Behaves like a Swift async function with the signature:
489456// /
490457// / \code
491458// / func swift_asyncLet_finish(_ asyncLet: Builtin.RawPointer,
492459// / _ resultBuffer: Builtin.RawPointer) async
493460// / \endcode
461+ // /
462+ // / except that it uses the special calling convention in which the
463+ // / continuation function, parent context, and child context are all
464+ // / passed in separately rather than being stored in the child context.
465+ // / The child async context has a fixed size of 5 * sizeof(void*).
466+ // /
467+ // / \c resultBuffer must be the same result buffer that was passed to
468+ // / swift_asyncLet_begin.
469+ // /
470+ // / Prior to asynchronous return, the value in the result buffer is
471+ // / destroyed (if present) and any memory initially allocated for the
472+ // / task is deallocated. Because swift_asyncLet_begin potentially
473+ // / allocates memory on the parent task's task allocator, the call to
474+ // / this function must be properly paired with the begin.
475+ // /
476+ // / The async let is invalid after this call and cannot be used again.
477+ // /
478+ // / Previous versions of the concurrency runtime also provided a
479+ // / \c swift_asyncLet_end which was not asynchronous and was meant
480+ // / to be paired with \c swift_asyncLet_start. This function was never
481+ // / used by a released version of the compiler, and it has been removed.
494482SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
495483void swift_asyncLet_finish (SWIFT_ASYNC_CONTEXT AsyncContext *,
496484 AsyncLet *,
497485 void *,
498486 TaskContinuationFunction *,
499487 AsyncContext *);
500488
501- // / Get the value of a non-throwing async- let, awaiting the result if necessary,
502- // / and then destroy the child task. The result buffer is left initialized after
503- // / returning .
489+ // / Get the value of a non-throwing async let binding that was created
490+ // / with \c swift_asyncLet_begin, awaiting the task's completion if
491+ // / necessary, and then destroy the task and the binding .
504492// /
505- // / This can be called from any thread. Its Swift signature is
493+ // / This must be called from the parent task of the async let.
494+ // /
495+ // / Behaves like a Swift async function with the signature:
506496// /
507497// / \code
508498// / func swift_asyncLet_get(
@@ -511,22 +501,34 @@ void swift_asyncLet_finish(SWIFT_ASYNC_CONTEXT AsyncContext *,
511501// / ) async
512502// / \endcode
513503// /
514- // / \c result points at the variable storage for the binding. It is
515- // / uninitialized until the first call to \c swift_asyncLet_get or
516- // / \c swift_asyncLet_get_throwing. The child task will be invalidated after
517- // / this call, so the `async let` can not be gotten or finished afterward.
504+ // / except that it uses the special calling convention in which the
505+ // / continuation function, parent context, and child context are all
506+ // / passed in separately rather than being stored in the child context.
507+ // / The child async context has a fixed size of 5 * sizeof(void*).
508+ // /
509+ // / \c resultBuffer must be the same result buffer that was passed to
510+ // / swift_asyncLet_begin. After asynchronous return, this is guaranteed
511+ // / to be initialized.
512+ // /
513+ // / The async let is invalid after this call and cannot be used again.
514+ // / Any memory initially allocated for the task is deallocated. Because
515+ // / \c swift_asyncLet_begin potentially allocates memory on the parent
516+ // / task's task allocator, the call to this function must be properly
517+ // / paired with the begin.
518518SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
519- void swift_asyncLet_consume (SWIFT_ASYNC_CONTEXT AsyncContext *,
520- AsyncLet *,
521- void *,
522- TaskContinuationFunction *,
523- AsyncContext *);
519+ void swift_asyncLet_consume (SWIFT_ASYNC_CONTEXT AsyncContext *callerContext ,
520+ AsyncLet *alet ,
521+ void *resultBuffer ,
522+ TaskContinuationFunction *continuation ,
523+ AsyncContext *callContext );
524524
525- // / Get the value of a throwing async- let, awaiting the result if necessary,
526- // / and then destroy the child task. The result buffer is left initialized after
527- // / returning .
525+ // / Get the value of a throwing async let binding that was created
526+ // / with \c swift_asyncLet_begin, awaiting the task's completion if
527+ // / necessary, and then destroy the task and the binding .
528528// /
529- // / This can be called from any thread. Its Swift signature is
529+ // / This must be called from the parent task of the async let.
530+ // /
531+ // / Behaves like a Swift async function with the signature:
530532// /
531533// / \code
532534// / func swift_asyncLet_get_throwing(
@@ -535,18 +537,28 @@ void swift_asyncLet_consume(SWIFT_ASYNC_CONTEXT AsyncContext *,
535537// / ) async throws
536538// / \endcode
537539// /
538- // / \c result points at the variable storage for the binding. It is
539- // / uninitialized until the first call to \c swift_asyncLet_get or
540- // / \c swift_asyncLet_get_throwing. That first call initializes the storage
541- // / with the result of the child task. Subsequent calls do nothing and leave
542- // / the value in place. The child task will be invalidated after
543- // / this call, so the `async let` can not be gotten or finished afterward.
540+ // / except that it uses the special calling convention in which the
541+ // / continuation function, parent context, and child context are all
542+ // / passed in separately rather than being stored in the child context.
543+ // / The child async context has a fixed size of 5 * sizeof(void*).
544+ // /
545+ // / \c resultBuffer must be the same result buffer that was passed to
546+ // / swift_asyncLet_begin. After asynchronous return, it is guaranteed
547+ // / to be initialized unless the operation throws by passing an error
548+ // / to the continuation function.
549+ // /
550+ // / The async let is invalid after this call and cannot be used again.
551+ // / Any memory initially allocated for the task is deallocated. Because
552+ // / \c swift_asyncLet_begin potentially allocates memory on the parent
553+ // / task's task allocator, the call to this function must be properly
554+ // / paired with the begin.
544555SWIFT_EXPORT_FROM (swift_Concurrency) SWIFT_CC(swiftasync)
545- void swift_asyncLet_consume_throwing (SWIFT_ASYNC_CONTEXT AsyncContext *,
546- AsyncLet *,
547- void *,
548- ThrowingTaskFutureWaitContinuationFunction *,
549- AsyncContext *);
556+ void swift_asyncLet_consume_throwing (SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
557+ AsyncLet *alet,
558+ void *resultBuffer,
559+ ThrowingTaskFutureWaitContinuationFunction *
560+ continuation,
561+ AsyncContext *callContext);
550562
551563// / Returns true if the currently executing AsyncTask has a
552564// / 'TaskGroupTaskStatusRecord' present.
0 commit comments