@@ -3039,6 +3039,60 @@ class KeyPathPattern final
3039
3039
}
3040
3040
};
3041
3041
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
+
3042
3096
// / Instantiates a key path object.
3043
3097
class KeyPathInst final
3044
3098
: public InstructionBase<SILInstructionKind::KeyPathInst,
@@ -7231,6 +7285,7 @@ class TermInst : public NonValueInstruction {
7231
7285
case TermKind::DynamicMethodBranchInst:
7232
7286
case TermKind::CheckedCastAddrBranchInst:
7233
7287
case TermKind::CheckedCastValueBranchInst:
7288
+ case TermKind::AwaitAsyncContinuationInst:
7234
7289
return false ;
7235
7290
case TermKind::SwitchEnumInst:
7236
7291
case TermKind::CheckedCastBranchInst:
@@ -7326,6 +7381,52 @@ class UnwindInst
7326
7381
MutableArrayRef<Operand> getAllOperands () { return {}; }
7327
7382
};
7328
7383
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
+
7329
7430
// / YieldInst - Yield control temporarily to the caller of this coroutine.
7330
7431
// /
7331
7432
// / This is a terminator because the caller can abort the coroutine,
0 commit comments