Skip to content

Commit 5ed6739

Browse files
authored
Merge pull request #2911 from swiftwasm/main
[pull] swiftwasm from main
2 parents e982743 + 360e32b commit 5ed6739

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+932
-328
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ Types
517517
type ::= 'BB' // Builtin.UnsafeValueBuffer
518518
type ::= 'Bc' // Builtin.RawUnsafeContinuation
519519
type ::= 'BD' // Builtin.DefaultActorStorage
520+
type ::= 'Be' // Builtin.ExecutorRef
520521
type ::= 'Bf' NATURAL '_' // Builtin.Float<n>
521522
type ::= 'Bi' NATURAL '_' // Builtin.Int<n>
522523
type ::= 'BI' // Builtin.IntLiteral

include/swift/ABI/MetadataValues.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,9 @@ enum class AsyncContextKind {
20522052
/// A context which can yield to its caller.
20532053
Yielding = 1,
20542054

2055+
/// A continuation context.
2056+
Continuation = 2,
2057+
20552058
// Other kinds are reserved for interesting special
20562059
// intermediate contexts.
20572060

@@ -2096,6 +2099,55 @@ class AsyncContextFlags : public FlagSet<uint32_t> {
20962099
setShouldNotDeallocateInCallee)
20972100
};
20982101

2102+
/// Flags passed to swift_continuation_init.
2103+
class AsyncContinuationFlags : public FlagSet<size_t> {
2104+
public:
2105+
enum {
2106+
CanThrow = 0,
2107+
HasExecutorOverride = 1,
2108+
IsPreawaited = 2,
2109+
};
2110+
2111+
explicit AsyncContinuationFlags(size_t bits) : FlagSet(bits) {}
2112+
constexpr AsyncContinuationFlags() {}
2113+
2114+
/// Whether the continuation is permitted to throw.
2115+
FLAGSET_DEFINE_FLAG_ACCESSORS(CanThrow, canThrow, setCanThrow)
2116+
2117+
/// Whether the continuation should be resumed on a different
2118+
/// executor than the current one. swift_continuation_init
2119+
/// will not initialize ResumeToExecutor if this is set.
2120+
FLAGSET_DEFINE_FLAG_ACCESSORS(HasExecutorOverride,
2121+
hasExecutorOverride,
2122+
setHasExecutorOverride)
2123+
2124+
/// Whether the continuation is "pre-awaited". If so, it should
2125+
/// be set up in the already-awaited state, and so resumptions
2126+
/// will immediately schedule the continuation to begin
2127+
/// asynchronously.
2128+
FLAGSET_DEFINE_FLAG_ACCESSORS(IsPreawaited,
2129+
isPreawaited,
2130+
setIsPreawaited)
2131+
};
2132+
2133+
/// Status values for a continuation. Note that the "not yet"s in
2134+
/// the description below aren't quite right because the system
2135+
/// does not actually promise to update the status before scheduling
2136+
/// the task. This is because the continuation context is immediately
2137+
/// invalidated once the task starts running again, so the window in
2138+
/// which we can usefully protect against (say) double-resumption may
2139+
/// be very small.
2140+
enum class ContinuationStatus : size_t {
2141+
/// The continuation has not yet been awaited or resumed.
2142+
Pending = 0,
2143+
2144+
/// The continuation has already been awaited, but not yet resumed.
2145+
Awaited = 1,
2146+
2147+
/// The continuation has already been resumed, but not yet awaited.
2148+
Resumed = 2
2149+
};
2150+
20992151
} // end namespace swift
21002152

21012153
#endif // SWIFT_ABI_METADATAVALUES_H

include/swift/ABI/Task.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,31 @@ class YieldingAsyncContext : public AsyncContext {
536536
}
537537
};
538538

539+
/// An async context that can be resumed as a continuation.
540+
class ContinuationAsyncContext : public AsyncContext {
541+
public:
542+
/// An atomic object used to ensure that a continuation is not
543+
/// scheduled immediately during a resume if it hasn't yet been
544+
/// awaited by the function which set it up.
545+
std::atomic<ContinuationStatus> AwaitSynchronization;
546+
547+
/// The error result value of the continuation.
548+
/// This should be null-initialized when setting up the continuation.
549+
/// Throwing resumers must overwrite this with a non-null value.
550+
SwiftError *ErrorResult;
551+
552+
/// A pointer to the normal result value of the continuation.
553+
/// Normal resumers must initialize this before resuming.
554+
OpaqueValue *NormalResult;
555+
556+
/// The executor that should be resumed to.
557+
ExecutorRef ResumeToExecutor;
558+
559+
static bool classof(const AsyncContext *context) {
560+
return context->Flags.getKind() == AsyncContextKind::Continuation;
561+
}
562+
};
563+
539564
/// An asynchronous context within a task that describes a general "Future".
540565
/// task.
541566
///

include/swift/AST/ASTSynthesis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ enum SingletonTypeSynthesizer {
4141
_any,
4242
_bridgeObject,
4343
_error,
44+
_executor,
4445
_job,
4546
_nativeObject,
4647
_never,
4748
_rawPointer,
49+
_rawUnsafeContinuation,
4850
_void,
4951
_word,
5052
};
@@ -54,10 +56,12 @@ inline Type synthesizeType(SynthesisContext &SC,
5456
case _any: return SC.Context.TheAnyType;
5557
case _bridgeObject: return SC.Context.TheBridgeObjectType;
5658
case _error: return SC.Context.getExceptionType();
59+
case _executor: return SC.Context.TheExecutorType;
5760
case _job: return SC.Context.TheJobType;
5861
case _nativeObject: return SC.Context.TheNativeObjectType;
5962
case _never: return SC.Context.getNeverType();
6063
case _rawPointer: return SC.Context.TheRawPointerType;
64+
case _rawUnsafeContinuation: return SC.Context.TheRawUnsafeContinuationType;
6165
case _void: return SC.Context.TheEmptyTupleType;
6266
case _word: return BuiltinIntegerType::get(BuiltinIntegerWidth::pointer(),
6367
SC.Context);

include/swift/AST/Builtins.def

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,18 @@ BUILTIN_MISC_OPERATION(InitializeDefaultActor, "initializeDefaultActor", "", Spe
723723
/// Destroy the default-actor instance in a default actor object.
724724
BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
725725

726+
/// Resume a non-throwing continuation normally with the given result.
727+
BUILTIN_MISC_OPERATION(ResumeNonThrowingContinuationReturning,
728+
"resumeNonThrowingContinuationReturning", "", Special)
729+
730+
/// Resume a throwing continuation normally with the given result.
731+
BUILTIN_MISC_OPERATION(ResumeThrowingContinuationReturning,
732+
"resumeThrowingContinuationReturning", "", Special)
733+
734+
/// Resume a throwing continuation abnormally with the given error.
735+
BUILTIN_MISC_OPERATION(ResumeThrowingContinuationThrowing,
736+
"resumeThrowingContinuationThrowing", "", Special)
737+
726738
// BUILTIN_MISC_OPERATION_WITH_SILGEN - Miscellaneous operations that are
727739
// specially emitted during SIL generation.
728740
//
@@ -736,7 +748,7 @@ BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
736748
BUILTIN_MISC_OPERATION(Id, Name, Attrs, Overload)
737749
#endif
738750

739-
// getCurrentExecutor: () async -> Builtin.Word
751+
// getCurrentExecutor: () async -> Builtin.Executor
740752
//
741753
// Retrieve the ExecutorRef on which the current asynchronous
742754
// function is executing.

include/swift/AST/RequirementBase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class RequirementBase {
6363
: FirstTypeAndKind(first, kind), SecondType(second) {
6464
assert(first);
6565
assert(second);
66+
assert(kind != RequirementKind::Layout);
6667
}
6768

6869
/// Create a layout constraint requirement.
@@ -71,6 +72,7 @@ class RequirementBase {
7172
: FirstTypeAndKind(first, kind), SecondLayout(second) {
7273
assert(first);
7374
assert(second);
75+
assert(kind == RequirementKind::Layout);
7476
}
7577

7678
/// Determine the kind of requirement.

include/swift/AST/TypeNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ ABSTRACT_TYPE(Builtin, Type)
103103
BUILTIN_TYPE(BuiltinInteger, AnyBuiltinIntegerType)
104104
BUILTIN_TYPE(BuiltinIntegerLiteral, AnyBuiltinIntegerType)
105105
TYPE_RANGE(AnyBuiltinInteger, BuiltinInteger, BuiltinIntegerLiteral)
106+
BUILTIN_TYPE(BuiltinExecutor, BuiltinType)
106107
BUILTIN_TYPE(BuiltinFloat, BuiltinType)
107108
BUILTIN_TYPE(BuiltinJob, BuiltinType)
108109
BUILTIN_TYPE(BuiltinRawPointer, BuiltinType)
@@ -181,6 +182,7 @@ LAST_TYPE(Dictionary) // Sugared types are last to make isa<SugarType>() fast.
181182
#ifdef SINGLETON_TYPE
182183
SINGLETON_TYPE(IntegerLiteral, BuiltinIntegerLiteral)
183184
SINGLETON_TYPE(Job, BuiltinJob)
185+
SINGLETON_TYPE(Executor, BuiltinExecutor)
184186
SINGLETON_TYPE(RawPointer, BuiltinRawPointer)
185187
SINGLETON_TYPE(RawUnsafeContinuation, BuiltinRawUnsafeContinuation)
186188
SINGLETON_TYPE(NativeObject, BuiltinNativeObject)

include/swift/AST/Types.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,19 @@ class BuiltinRawUnsafeContinuationType : public BuiltinType {
14161416
};
14171417
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinRawUnsafeContinuationType, BuiltinType);
14181418

1419+
/// BuiltinExecutorType - The builtin executor-ref type. In C, this
1420+
/// is the ExecutorRef struct type.
1421+
class BuiltinExecutorType : public BuiltinType {
1422+
friend class ASTContext;
1423+
BuiltinExecutorType(const ASTContext &C)
1424+
: BuiltinType(TypeKind::BuiltinExecutor, C) {}
1425+
public:
1426+
static bool classof(const TypeBase *T) {
1427+
return T->getKind() == TypeKind::BuiltinExecutor;
1428+
}
1429+
};
1430+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinExecutorType, BuiltinType);
1431+
14191432
/// BuiltinJobType - The builtin job type. In C, this is a
14201433
/// non-null Job*. This pointer is completely unmanaged (the unscheduled
14211434
/// job is self-owning), but has more spare bits than Builtin.RawPointer.

include/swift/Basic/SourceLoc.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ class SourceLoc {
4444

4545
bool isValid() const { return Value.isValid(); }
4646
bool isInvalid() const { return !isValid(); }
47-
47+
48+
/// An explicit bool operator so one can check if a SourceLoc is valid in an
49+
/// if statement:
50+
///
51+
/// if (auto x = getSourceLoc()) { ... }
52+
explicit operator bool() const { return isValid(); }
53+
4854
bool operator==(const SourceLoc &RHS) const { return RHS.Value == Value; }
4955
bool operator!=(const SourceLoc &RHS) const { return !operator==(RHS); }
5056

@@ -107,6 +113,12 @@ class SourceRange {
107113
bool isValid() const { return Start.isValid(); }
108114
bool isInvalid() const { return !isValid(); }
109115

116+
/// An explicit bool operator so one can check if a SourceRange is valid in an
117+
/// if statement:
118+
///
119+
/// if (auto x = getSourceRange()) { ... }
120+
explicit operator bool() const { return isValid(); }
121+
110122
/// Extend this SourceRange to the smallest continuous SourceRange that
111123
/// includes both this range and the other one.
112124
void widen(SourceRange Other);

include/swift/Runtime/Concurrency.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -523,23 +523,35 @@ void swift_defaultActor_destroy(DefaultActor *actor);
523523
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
524524
void swift_defaultActor_enqueue(Job *job, DefaultActor *actor);
525525

526-
/// Resume a task from its continuation, given a normal result value.
526+
/// Prepare a continuation in the current task.
527+
///
528+
/// The caller should initialize the Parent, ResumeParent,
529+
/// and NormalResult fields. This function will initialize the other
530+
/// fields with appropriate defaaults; the caller may then overwrite
531+
/// them if desired.
532+
///
533+
/// This function is provided as a code-size and runtime-usage
534+
/// optimization; calling it is not required if code is willing to
535+
/// do all its work inline.
536+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
537+
AsyncTask *swift_continuation_init(ContinuationAsyncContext *context,
538+
AsyncContinuationFlags flags);
539+
540+
/// Resume a task from a non-throwing continuation, given a normal
541+
/// result which has already been stored into the continuation.
527542
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
528-
void swift_continuation_resume(/* +1 */ OpaqueValue *result,
529-
void *continuation,
530-
const Metadata *resumeType);
543+
void swift_continuation_resume(AsyncTask *continuation);
531544

532-
/// Resume a task from its throwing continuation, given a normal result value.
545+
/// Resume a task from a potentially-throwing continuation, given a
546+
/// normal result which has already been stored into the continuation.
533547
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
534-
void swift_continuation_throwingResume(/* +1 */ OpaqueValue *result,
535-
void *continuation,
536-
const Metadata *resumeType);
548+
void swift_continuation_throwingResume(AsyncTask *continuation);
537549

538-
/// Resume a task from its throwing continuation by throwing an error.
550+
/// Resume a task from a potentially-throwing continuation by throwing
551+
/// an error.
539552
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
540-
void swift_continuation_throwingResumeWithError(/* +1 */ SwiftError *error,
541-
void *continuation,
542-
const Metadata *resumeType);
553+
void swift_continuation_throwingResumeWithError(AsyncTask *continuation,
554+
/* +1 */ SwiftError *error);
543555

544556
/// SPI helper to log a misuse of a `CheckedContinuation` to the appropriate places in the OS.
545557
extern "C" SWIFT_CC(swift)

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,40 @@ FUNCTION(TaskSwitchFunc,
15811581
ARGS(SwiftContextPtrTy, Int8PtrTy, SwiftExecutorPtrTy),
15821582
ATTRS(NoUnwind))
15831583

1584+
// AsyncTask *swift_continuation_init(AsyncContext *continuationContext,
1585+
// AsyncContinuationFlags);
1586+
FUNCTION(ContinuationInit,
1587+
swift_continuation_init, SwiftCC,
1588+
ConcurrencyAvailability,
1589+
RETURNS(SwiftTaskPtrTy),
1590+
ARGS(ContinuationAsyncContextPtrTy, SizeTy),
1591+
ATTRS(NoUnwind))
1592+
1593+
// void swift_continuation_resume(AsyncTask *continuation);
1594+
FUNCTION(ContinuationResume,
1595+
swift_continuation_resume, SwiftCC,
1596+
ConcurrencyAvailability,
1597+
RETURNS(VoidTy),
1598+
ARGS(SwiftTaskPtrTy),
1599+
ATTRS(NoUnwind))
1600+
1601+
// void swift_continuation_throwingResume(AsyncTask *continuation);
1602+
FUNCTION(ContinuationThrowingResume,
1603+
swift_continuation_throwingResume, SwiftCC,
1604+
ConcurrencyAvailability,
1605+
RETURNS(VoidTy),
1606+
ARGS(SwiftTaskPtrTy),
1607+
ATTRS(NoUnwind))
1608+
1609+
// void swift_continuation_throwingResumeWithError(AsyncTask *continuation,
1610+
// SwiftError *error);
1611+
FUNCTION(ContinuationThrowingResumeWithError,
1612+
swift_continuation_throwingResumeWithError, SwiftCC,
1613+
ConcurrencyAvailability,
1614+
RETURNS(VoidTy),
1615+
ARGS(SwiftTaskPtrTy, ErrorPtrTy),
1616+
ATTRS(NoUnwind))
1617+
15841618
// ExecutorRef swift_task_getCurrentExecutor();
15851619
FUNCTION(TaskGetCurrentExecutor,
15861620
swift_task_getCurrentExecutor, SwiftCC,

0 commit comments

Comments
 (0)