@@ -4999,14 +4999,16 @@ class CallEmission {
49994999 FormalEvaluationScope initialWritebackScope;
50005000 std::optional<ActorIsolation> implicitActorHopTarget;
50015001 bool implicitlyThrows;
5002+ bool canUnwind;
50025003
50035004public:
50045005 // / Create an emission for a call of the given callee.
50055006 CallEmission (SILGenFunction &SGF, Callee &&callee,
50065007 FormalEvaluationScope &&writebackScope)
50075008 : SGF(SGF), callee(std::move(callee)),
50085009 initialWritebackScope (std::move(writebackScope)),
5009- implicitActorHopTarget(std::nullopt ), implicitlyThrows(false ) {}
5010+ implicitActorHopTarget(std::nullopt ), implicitlyThrows(false ),
5011+ canUnwind(false ) {}
50105012
50115013 // / A factory method for decomposing the apply expr \p e into a call
50125014 // / emission.
@@ -5057,6 +5059,8 @@ class CallEmission {
50575059 // / function can throw or not.
50585060 void setImplicitlyThrows (bool flag) { implicitlyThrows = flag; }
50595061
5062+ void setCanUnwind (bool flag) { canUnwind = flag; }
5063+
50605064 CleanupHandle applyCoroutine (SmallVectorImpl<ManagedValue> &yields);
50615065
50625066 RValue apply (SGFContext C = SGFContext()) {
@@ -5114,9 +5118,11 @@ namespace {
51145118// / Cleanup to end a coroutine application.
51155119class EndCoroutineApply : public Cleanup {
51165120 SILValue ApplyToken;
5121+ bool CanUnwind;
51175122 std::vector<BeginBorrowInst *> BorrowedMoveOnlyValues;
51185123public:
5119- EndCoroutineApply (SILValue applyToken) : ApplyToken(applyToken) {}
5124+ EndCoroutineApply (SILValue applyToken, bool CanUnwind)
5125+ : ApplyToken(applyToken), CanUnwind(CanUnwind) {}
51205126
51215127 void setBorrowedMoveOnlyValues (ArrayRef<BeginBorrowInst *> values) {
51225128 BorrowedMoveOnlyValues.insert (BorrowedMoveOnlyValues.end (),
@@ -5129,14 +5135,7 @@ class EndCoroutineApply : public Cleanup {
51295135 SGF.B .createEndBorrow (l, *i);
51305136 SGF.B .createDestroyValue (l, (*i)->getOperand ());
51315137 }
5132- auto *beginApply =
5133- cast<BeginApplyInst>(ApplyToken->getDefiningInstruction ());
5134- auto isCalleeAllocated = beginApply->isCalleeAllocated ();
5135- auto unwindOnCallerError =
5136- !isCalleeAllocated ||
5137- SGF.SGM .getASTContext ().LangOpts .hasFeature (
5138- Feature::CoroutineAccessorsUnwindOnCallerError);
5139- if (forUnwind && unwindOnCallerError) {
5138+ if (forUnwind && CanUnwind) {
51405139 SGF.B .createAbortApply (l, ApplyToken);
51415140 } else {
51425141 SGF.B .createEndApply (l, ApplyToken,
@@ -5179,18 +5178,15 @@ CallEmission::applyCoroutine(SmallVectorImpl<ManagedValue> &yields) {
51795178
51805179 auto fnValue = callee.getFnValue (SGF, borrowedSelf);
51815180
5182- return SGF.emitBeginApply (uncurriedLoc.value (), fnValue,
5181+ return SGF.emitBeginApply (uncurriedLoc.value (), fnValue, canUnwind,
51835182 callee.getSubstitutions (), uncurriedArgs,
51845183 calleeTypeInfo.substFnType , options, yields);
51855184}
51865185
5187- CleanupHandle
5188- SILGenFunction::emitBeginApply (SILLocation loc, ManagedValue fn,
5189- SubstitutionMap subs,
5190- ArrayRef<ManagedValue> args,
5191- CanSILFunctionType substFnType,
5192- ApplyOptions options,
5193- SmallVectorImpl<ManagedValue> &yields) {
5186+ CleanupHandle SILGenFunction::emitBeginApply (
5187+ SILLocation loc, ManagedValue fn, bool canUnwind, SubstitutionMap subs,
5188+ ArrayRef<ManagedValue> args, CanSILFunctionType substFnType,
5189+ ApplyOptions options, SmallVectorImpl<ManagedValue> &yields) {
51945190 // Emit the call.
51955191 SmallVector<SILValue, 4 > rawResults;
51965192 emitRawApply (*this , loc, fn, subs, args, substFnType, options,
@@ -5206,7 +5202,7 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
52065202
52075203 // Push a cleanup to end the application.
52085204 // TODO: destroy all the arguments at exactly this point?
5209- Cleanups.pushCleanup <EndCoroutineApply>(token);
5205+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
52105206 auto endApplyHandle = getTopCleanup ();
52115207
52125208 // Manage all the yielded values.
@@ -6183,7 +6179,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
61836179std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
61846180 CleanupHandle>
61856181SILGenFunction::emitBeginApplyWithRethrow (SILLocation loc, SILValue fn,
6186- SILType substFnType,
6182+ SILType substFnType, bool canUnwind,
61876183 SubstitutionMap subs,
61886184 ArrayRef<SILValue> args,
61896185 SmallVectorImpl<SILValue> &yields) {
@@ -6208,7 +6204,7 @@ SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
62086204 deallocCleanup = enterDeallocStackCleanup (allocation);
62096205 }
62106206
6211- Cleanups.pushCleanup <EndCoroutineApply>(token);
6207+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
62126208 auto abortCleanup = Cleanups.getTopCleanup ();
62136209
62146210 return {token, abortCleanup, allocation, deallocCleanup};
@@ -7561,6 +7557,21 @@ ManagedValue SILGenFunction::emitAddressorAccessor(
75617557 return ManagedValue::forLValue (address);
75627558}
75637559
7560+ bool SILGenFunction::canUnwindAccessorDeclRef (SILDeclRef accessorRef) {
7561+ auto *accessor =
7562+ dyn_cast_or_null<AccessorDecl>(accessorRef.getAbstractFunctionDecl ());
7563+ ASSERT (accessor && " only accessors can unwind" );
7564+ auto kind = accessor->getAccessorKind ();
7565+ ASSERT (isYieldingAccessor (kind) && " only yielding accessors can unwind" );
7566+ if (!requiresFeatureCoroutineAccessors (kind)) {
7567+ // _read and _modify can unwind
7568+ return true ;
7569+ }
7570+ // Coroutine accessors can only unwind with the experimental feature.
7571+ return getASTContext ().LangOpts .hasFeature (
7572+ Feature::CoroutineAccessorsUnwindOnCallerError);
7573+ }
7574+
75647575CleanupHandle
75657576SILGenFunction::emitCoroutineAccessor (SILLocation loc, SILDeclRef accessor,
75667577 SubstitutionMap substitutions,
@@ -7596,6 +7607,8 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
75967607
75977608 emission.addCallSite (loc, std::move (subscriptIndices));
75987609
7610+ emission.setCanUnwind (canUnwindAccessorDeclRef (accessor));
7611+
75997612 auto endApplyHandle = emission.applyCoroutine (yields);
76007613
76017614 return endApplyHandle;
0 commit comments