@@ -3039,6 +3039,60 @@ class KeyPathPattern final
30393039 }
30403040};
30413041
3042+ // / Accesses the continuation for an async task, to prepare a primitive suspend operation.
3043+ // / The continuation must be consumed by an AwaitAsyncContinuation instruction locally,
3044+ // / and must dynamically be resumed exactly once during the program's ensuing execution.
3045+ class GetAsyncContinuationInst final
3046+ : public InstructionBase<SILInstructionKind::GetAsyncContinuationInst,
3047+ SingleValueInstruction>
3048+ {
3049+ friend SILBuilder;
3050+
3051+ GetAsyncContinuationInst (SILDebugLocation Loc,
3052+ SILType ContinuationTy)
3053+ : InstructionBase(Loc, ContinuationTy)
3054+ {}
3055+
3056+ public:
3057+
3058+ // / Get the type of the value the async task receives on a resume.
3059+ CanType getFormalResumeType () const ;
3060+ SILType getLoweredResumeType () const ;
3061+
3062+ // / True if the continuation can be used to resume the task by throwing an error.
3063+ bool throws () const ;
3064+
3065+ ArrayRef<Operand> getAllOperands () const { return {}; }
3066+ MutableArrayRef<Operand> getAllOperands () { return {}; }
3067+ };
3068+
3069+ // / Accesses the continuation for an async task, to prepare a primitive suspend operation.
3070+ // / The continuation must be consumed by an AwaitAsyncContinuation instruction locally,
3071+ // / and must dynamically be resumed exactly once during the program's ensuing execution.
3072+ // /
3073+ // / This variation of the instruction additionally takes an operand for the address of the
3074+ // / buffer that receives the incoming value when the continuation is resumed.
3075+ class GetAsyncContinuationAddrInst final
3076+ : public UnaryInstructionBase<SILInstructionKind::GetAsyncContinuationAddrInst,
3077+ SingleValueInstruction>
3078+ {
3079+ friend SILBuilder;
3080+ GetAsyncContinuationAddrInst (SILDebugLocation Loc,
3081+ SILValue Operand,
3082+ SILType ContinuationTy)
3083+ : UnaryInstructionBase(Loc, Operand, ContinuationTy)
3084+ {}
3085+
3086+ public:
3087+
3088+ // / Get the type of the value the async task receives on a resume.
3089+ CanType getFormalResumeType () const ;
3090+ SILType getLoweredResumeType () const ;
3091+
3092+ // / True if the continuation can be used to resume the task by throwing an error.
3093+ bool throws () const ;
3094+ };
3095+
30423096// / Instantiates a key path object.
30433097class KeyPathInst final
30443098 : public InstructionBase<SILInstructionKind::KeyPathInst,
@@ -7231,6 +7285,7 @@ class TermInst : public NonValueInstruction {
72317285 case TermKind::DynamicMethodBranchInst:
72327286 case TermKind::CheckedCastAddrBranchInst:
72337287 case TermKind::CheckedCastValueBranchInst:
7288+ case TermKind::AwaitAsyncContinuationInst:
72347289 return false ;
72357290 case TermKind::SwitchEnumInst:
72367291 case TermKind::CheckedCastBranchInst:
@@ -7326,6 +7381,52 @@ class UnwindInst
73267381 MutableArrayRef<Operand> getAllOperands () { return {}; }
73277382};
73287383
7384+ // / Suspend execution of an async task until
7385+ // / essentially just a funny kind of return).
7386+ class AwaitAsyncContinuationInst final
7387+ : public UnaryInstructionBase<SILInstructionKind::AwaitAsyncContinuationInst,
7388+ TermInst>
7389+ {
7390+ friend SILBuilder;
7391+
7392+ std::array<SILSuccessor, 2 > Successors;
7393+
7394+ AwaitAsyncContinuationInst (SILDebugLocation Loc, SILValue Continuation,
7395+ SILBasicBlock *resumeBB,
7396+ SILBasicBlock *errorBBOrNull)
7397+ : UnaryInstructionBase(Loc, Continuation),
7398+ Successors{{{this }, {this }}}
7399+ {
7400+ Successors[0 ] = resumeBB;
7401+ if (errorBBOrNull)
7402+ Successors[1 ] = errorBBOrNull;
7403+ }
7404+
7405+ public:
7406+ // / Returns the basic block to which control is transferred when the task is
7407+ // / resumed normally.
7408+ // /
7409+ // / This basic block should take an argument of the continuation's resume type,
7410+ // / unless the continuation is formed by a \c GetAsyncContinuationAddrInst
7411+ // / that binds a specific memory location to receive the resume value.
7412+ SILBasicBlock *getResumeBB () const { return Successors[0 ].getBB (); }
7413+
7414+ // / Returns the basic block to which control is transferred when the task is
7415+ // / resumed in an error state, or `nullptr` if the continuation does not support
7416+ // / failure.
7417+ // /
7418+ // / This basic block should take an argument of Error type.
7419+ SILBasicBlock *getErrorBB () const {
7420+ return Successors[1 ].getBB ();
7421+ }
7422+
7423+ SuccessorListTy getSuccessors () {
7424+ if (getErrorBB ())
7425+ return Successors;
7426+ return SuccessorListTy (Successors.data (), 1 );
7427+ }
7428+ };
7429+
73297430// / YieldInst - Yield control temporarily to the caller of this coroutine.
73307431// /
73317432// / This is a terminator because the caller can abort the coroutine,
0 commit comments