[Concurrency/Runtime] Implement function/continuation type generation for AsyncSignature

`AsyncFunctionTypeImpl` has its `type` defaulted to `TaskContinuationFunction`
which is incorrect because it has to append arguments, result type and account
for throws bit.

These changes expand `AsyncSignature` with `ContinuationType` and expand `FunctionType`
to include all of the appropriate information.
This commit is contained in:
Pavel Yaskevich
2021-12-09 16:49:48 -08:00
parent efb47510b8
commit 9a00b33378
4 changed files with 50 additions and 18 deletions

View File

@@ -149,6 +149,8 @@ template <class AsyncSignature>
class AsyncFunctionPointer; class AsyncFunctionPointer;
template <class AsyncSignature> template <class AsyncSignature>
struct AsyncFunctionTypeImpl; struct AsyncFunctionTypeImpl;
template <class AsyncSignature>
struct AsyncContinuationTypeImpl;
/// The abstract signature for an asynchronous function. /// The abstract signature for an asynchronous function.
template <class Sig, bool HasErrorResult> template <class Sig, bool HasErrorResult>
@@ -163,6 +165,7 @@ struct AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult> {
using FunctionPointer = AsyncFunctionPointer<AsyncSignature>; using FunctionPointer = AsyncFunctionPointer<AsyncSignature>;
using FunctionType = typename AsyncFunctionTypeImpl<AsyncSignature>::type; using FunctionType = typename AsyncFunctionTypeImpl<AsyncSignature>::type;
using ContinuationType = typename AsyncContinuationTypeImpl<AsyncSignature>::type;
}; };
/// A signature for a thin async function that takes no arguments /// A signature for a thin async function that takes no arguments
@@ -175,30 +178,58 @@ using ThinNullaryAsyncSignature =
using ThickNullaryAsyncSignature = using ThickNullaryAsyncSignature =
AsyncSignature<void(HeapObject*), false>; AsyncSignature<void(HeapObject*), false>;
/// A class which can be used to statically query whether a type template <class Signature>
/// is a specialization of AsyncSignature. struct AsyncFunctionTypeImpl;
template <class T>
struct IsAsyncSignature {
static const bool value = false;
};
template <class DirectResultTy, class... ArgTys, bool HasErrorResult> template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
struct IsAsyncSignature<AsyncSignature<DirectResultTy(ArgTys...), struct AsyncFunctionTypeImpl<
HasErrorResult>> { AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult>> {
static const bool value = true;
using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
ArgTys...);
}; };
template <class Signature> template <class Signature>
struct AsyncFunctionTypeImpl { struct AsyncContinuationTypeImpl;
static_assert(IsAsyncSignature<Signature>::value,
"template argument is not an AsyncSignature");
// TODO: expand and include the arguments in the parameters. template <class DirectResultTy, class... ArgTys>
using type = TaskContinuationFunction; struct AsyncContinuationTypeImpl<
AsyncSignature<DirectResultTy(ArgTys...), /*throws=*/true>> {
using type = SWIFT_CC(swiftasync) void(SWIFT_ASYNC_CONTEXT AsyncContext *,
DirectResultTy,
SWIFT_CONTEXT void *);
};
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> template <class Fn>
using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type; using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type;
template <class Fn>
using AsyncContinuationType = typename AsyncContinuationTypeImpl<Fn>::type;
/// A "function pointer" for an async function. /// A "function pointer" for an async function.
/// ///
/// Eventually, this will always be signed with the data key /// Eventually, this will always be signed with the data key

View File

@@ -71,7 +71,7 @@ AsyncTaskAndContext swift_task_create_common(
size_t taskCreateFlags, size_t taskCreateFlags,
TaskOptionRecord *options, TaskOptionRecord *options,
const Metadata *futureResultType, const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function, void *closureContext, TaskContinuationFunction *function, void *closureContext,
size_t initialContextSize); size_t initialContextSize);
/// Allocate memory in a task. /// Allocate memory in a task.

View File

@@ -97,7 +97,7 @@ OVERRIDE_TASK(task_create_common, AsyncTaskAndContext,
(size_t taskCreateFlags, (size_t taskCreateFlags,
TaskOptionRecord *options, TaskOptionRecord *options,
const Metadata *futureResultType, const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function, TaskContinuationFunction *function,
void *closureContext, void *closureContext,
size_t initialContextSize), size_t initialContextSize),
(taskCreateFlags, options, futureResultType, function, (taskCreateFlags, options, futureResultType, function,

View File

@@ -432,7 +432,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
size_t rawTaskCreateFlags, size_t rawTaskCreateFlags,
TaskOptionRecord *options, TaskOptionRecord *options,
const Metadata *futureResultType, const Metadata *futureResultType,
FutureAsyncSignature::FunctionType *function, void *closureContext, TaskContinuationFunction *function, void *closureContext,
size_t initialContextSize) { size_t initialContextSize) {
TaskCreateFlags taskCreateFlags(rawTaskCreateFlags); TaskCreateFlags taskCreateFlags(rawTaskCreateFlags);
@@ -745,7 +745,8 @@ AsyncTaskAndContext swift::swift_task_create(
>(closureEntry, closureContext); >(closureEntry, closureContext);
return swift_task_create_common( return swift_task_create_common(
taskCreateFlags, options, futureResultType, taskEntry, closureContext, taskCreateFlags, options, futureResultType,
reinterpret_cast<TaskContinuationFunction *>(taskEntry), closureContext,
initialContextSize); initialContextSize);
} }