mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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>
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
// TODO: expand and include the arguments in the parameters.
|
||||
using type = TaskContinuationFunction;
|
||||
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 *);
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user