Skip to content

[Concurrency/Runtime] Implement function/continuation type generation… #40495

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

Merged
merged 1 commit into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 45 additions & 14 deletions include/swift/ABI/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ template <class AsyncSignature>
class AsyncFunctionPointer;
template <class AsyncSignature>
struct AsyncFunctionTypeImpl;
template <class AsyncSignature>
struct AsyncContinuationTypeImpl;

/// The abstract signature for an asynchronous function.
template <class Sig, bool HasErrorResult>
Expand All @@ -163,6 +165,7 @@ struct AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult> {

using FunctionPointer = AsyncFunctionPointer<AsyncSignature>;
using FunctionType = typename AsyncFunctionTypeImpl<AsyncSignature>::type;
using ContinuationType = typename AsyncContinuationTypeImpl<AsyncSignature>::type;
};

/// A signature for a thin async function that takes no arguments
Expand All @@ -175,30 +178,58 @@ using ThinNullaryAsyncSignature =
using ThickNullaryAsyncSignature =
AsyncSignature<void(HeapObject*), false>;

/// A class which can be used to statically query whether a type
/// is a specialization of AsyncSignature.
template <class T>
struct IsAsyncSignature {
static const bool value = false;
};
template <class Signature>
struct AsyncFunctionTypeImpl;

template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
struct IsAsyncSignature<AsyncSignature<DirectResultTy(ArgTys...),
HasErrorResult>> {
static const bool value = true;
struct AsyncFunctionTypeImpl<
AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult>> {

using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
ArgTys...);
};

template <class Signature>
struct AsyncFunctionTypeImpl {
static_assert(IsAsyncSignature<Signature>::value,
"template argument is not an AsyncSignature");
struct AsyncContinuationTypeImpl;

template <class DirectResultTy, class... ArgTys>
struct AsyncContinuationTypeImpl<
AsyncSignature<DirectResultTy(ArgTys...), /*throws=*/true>> {

using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
DirectResultTy,
SWIFT_CONTEXT void *);
};

// TODO: expand and include the arguments in the parameters.
using type = TaskContinuationFunction;
template <class DirectResultTy, class... ArgTys>
struct AsyncContinuationTypeImpl<
AsyncSignature<DirectResultTy(ArgTys...), /*throws=*/false>> {

using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
DirectResultTy);
};

template <class... ArgTys>
struct AsyncContinuationTypeImpl<
AsyncSignature<void(ArgTys...), /*throws=*/true>> {

using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
SWIFT_CONTEXT void *);
};

template <class... ArgTys>
struct AsyncContinuationTypeImpl<
AsyncSignature<void(ArgTys...), /*throws=*/false>> {

using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *);
};

template <class Fn>
using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type;

template <class Fn>
using AsyncContinuationType = typename AsyncContinuationTypeImpl<Fn>::type;

/// A "function pointer" for an async function.
///
/// Eventually, this will always be signed with the data key
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Runtime/Concurrency.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ AsyncTaskAndContext swift_task_create_common(
size_t taskCreateFlags,
TaskOptionRecord *options,
const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function, void *closureContext,
TaskContinuationFunction *function, void *closureContext,
size_t initialContextSize);

/// Allocate memory in a task.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ OVERRIDE_TASK(task_create_common, AsyncTaskAndContext,
(size_t taskCreateFlags,
TaskOptionRecord *options,
const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function,
TaskContinuationFunction *function,
void *closureContext,
size_t initialContextSize),
(taskCreateFlags, options, futureResultType, function,
Expand Down
5 changes: 3 additions & 2 deletions stdlib/public/Concurrency/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
size_t rawTaskCreateFlags,
TaskOptionRecord *options,
const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function, void *closureContext,
TaskContinuationFunction *function, void *closureContext,
size_t initialContextSize) {
TaskCreateFlags taskCreateFlags(rawTaskCreateFlags);

Expand Down Expand Up @@ -745,7 +745,8 @@ AsyncTaskAndContext swift::swift_task_create(
>(closureEntry, closureContext);

return swift_task_create_common(
taskCreateFlags, options, futureResultType, taskEntry, closureContext,
taskCreateFlags, options, futureResultType,
reinterpret_cast<TaskContinuationFunction *>(taskEntry), closureContext,
initialContextSize);
}

Expand Down