@@ -5000,14 +5000,16 @@ class CallEmission {
50005000 FormalEvaluationScope initialWritebackScope;
50015001 std::optional<ActorIsolation> implicitActorHopTarget;
50025002 bool implicitlyThrows;
5003+ bool canUnwind;
50035004
50045005public:
50055006 // / Create an emission for a call of the given callee.
50065007 CallEmission (SILGenFunction &SGF, Callee &&callee,
50075008 FormalEvaluationScope &&writebackScope)
50085009 : SGF(SGF), callee(std::move(callee)),
50095010 initialWritebackScope (std::move(writebackScope)),
5010- implicitActorHopTarget(std::nullopt ), implicitlyThrows(false ) {}
5011+ implicitActorHopTarget(std::nullopt ), implicitlyThrows(false ),
5012+ canUnwind(false ) {}
50115013
50125014 // / A factory method for decomposing the apply expr \p e into a call
50135015 // / emission.
@@ -5058,6 +5060,8 @@ class CallEmission {
50585060 // / function can throw or not.
50595061 void setImplicitlyThrows (bool flag) { implicitlyThrows = flag; }
50605062
5063+ void setCanUnwind (bool flag) { canUnwind = flag; }
5064+
50615065 CleanupHandle applyCoroutine (SmallVectorImpl<ManagedValue> &yields);
50625066
50635067 RValue apply (SGFContext C = SGFContext()) {
@@ -5115,9 +5119,11 @@ namespace {
51155119// / Cleanup to end a coroutine application.
51165120class EndCoroutineApply : public Cleanup {
51175121 SILValue ApplyToken;
5122+ bool CanUnwind;
51185123 std::vector<BeginBorrowInst *> BorrowedMoveOnlyValues;
51195124public:
5120- EndCoroutineApply (SILValue applyToken) : ApplyToken(applyToken) {}
5125+ EndCoroutineApply (SILValue applyToken, bool CanUnwind)
5126+ : ApplyToken(applyToken), CanUnwind(CanUnwind) {}
51215127
51225128 void setBorrowedMoveOnlyValues (ArrayRef<BeginBorrowInst *> values) {
51235129 BorrowedMoveOnlyValues.insert (BorrowedMoveOnlyValues.end (),
@@ -5130,14 +5136,7 @@ class EndCoroutineApply : public Cleanup {
51305136 SGF.B .createEndBorrow (l, *i);
51315137 SGF.B .createDestroyValue (l, (*i)->getOperand ());
51325138 }
5133- auto *beginApply =
5134- cast<BeginApplyInst>(ApplyToken->getDefiningInstruction ());
5135- auto isCalleeAllocated = beginApply->isCalleeAllocated ();
5136- auto unwindOnCallerError =
5137- !isCalleeAllocated ||
5138- SGF.SGM .getASTContext ().LangOpts .hasFeature (
5139- Feature::CoroutineAccessorsUnwindOnCallerError);
5140- if (forUnwind && unwindOnCallerError) {
5139+ if (forUnwind && CanUnwind) {
51415140 SGF.B .createAbortApply (l, ApplyToken);
51425141 } else {
51435142 SGF.B .createEndApply (l, ApplyToken,
@@ -5180,18 +5179,15 @@ CallEmission::applyCoroutine(SmallVectorImpl<ManagedValue> &yields) {
51805179
51815180 auto fnValue = callee.getFnValue (SGF, borrowedSelf);
51825181
5183- return SGF.emitBeginApply (uncurriedLoc.value (), fnValue,
5182+ return SGF.emitBeginApply (uncurriedLoc.value (), fnValue, canUnwind,
51845183 callee.getSubstitutions (), uncurriedArgs,
51855184 calleeTypeInfo.substFnType , options, yields);
51865185}
51875186
5188- CleanupHandle
5189- SILGenFunction::emitBeginApply (SILLocation loc, ManagedValue fn,
5190- SubstitutionMap subs,
5191- ArrayRef<ManagedValue> args,
5192- CanSILFunctionType substFnType,
5193- ApplyOptions options,
5194- SmallVectorImpl<ManagedValue> &yields) {
5187+ CleanupHandle SILGenFunction::emitBeginApply (
5188+ SILLocation loc, ManagedValue fn, bool canUnwind, SubstitutionMap subs,
5189+ ArrayRef<ManagedValue> args, CanSILFunctionType substFnType,
5190+ ApplyOptions options, SmallVectorImpl<ManagedValue> &yields) {
51955191 // Emit the call.
51965192 SmallVector<SILValue, 4 > rawResults;
51975193 emitRawApply (*this , loc, fn, subs, args, substFnType, options,
@@ -5207,7 +5203,7 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
52075203
52085204 // Push a cleanup to end the application.
52095205 // TODO: destroy all the arguments at exactly this point?
5210- Cleanups.pushCleanup <EndCoroutineApply>(token);
5206+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
52115207 auto endApplyHandle = getTopCleanup ();
52125208
52135209 // Manage all the yielded values.
@@ -6184,7 +6180,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
61846180std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
61856181 CleanupHandle>
61866182SILGenFunction::emitBeginApplyWithRethrow (SILLocation loc, SILValue fn,
6187- SILType substFnType,
6183+ SILType substFnType, bool canUnwind,
61886184 SubstitutionMap subs,
61896185 ArrayRef<SILValue> args,
61906186 SmallVectorImpl<SILValue> &yields) {
@@ -6209,7 +6205,7 @@ SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
62096205 deallocCleanup = enterDeallocStackCleanup (allocation);
62106206 }
62116207
6212- Cleanups.pushCleanup <EndCoroutineApply>(token);
6208+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
62136209 auto abortCleanup = Cleanups.getTopCleanup ();
62146210
62156211 return {token, abortCleanup, allocation, deallocCleanup};
@@ -7562,6 +7558,21 @@ ManagedValue SILGenFunction::emitAddressorAccessor(
75627558 return ManagedValue::forLValue (address);
75637559}
75647560
7561+ bool SILGenFunction::canUnwindAccessorDeclRef (SILDeclRef accessorRef) {
7562+ auto *accessor =
7563+ dyn_cast_or_null<AccessorDecl>(accessorRef.getAbstractFunctionDecl ());
7564+ ASSERT (accessor && " only accessors can unwind" );
7565+ auto kind = accessor->getAccessorKind ();
7566+ ASSERT (isYieldingAccessor (kind) && " only yielding accessors can unwind" );
7567+ if (!requiresFeatureCoroutineAccessors (kind)) {
7568+ // _read and _modify can unwind
7569+ return true ;
7570+ }
7571+ // Coroutine accessors can only unwind with the experimental feature.
7572+ return getASTContext ().LangOpts .hasFeature (
7573+ Feature::CoroutineAccessorsUnwindOnCallerError);
7574+ }
7575+
75657576CleanupHandle
75667577SILGenFunction::emitCoroutineAccessor (SILLocation loc, SILDeclRef accessor,
75677578 SubstitutionMap substitutions,
@@ -7597,6 +7608,8 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
75977608
75987609 emission.addCallSite (loc, std::move (subscriptIndices));
75997610
7611+ emission.setCanUnwind (canUnwindAccessorDeclRef (accessor));
7612+
76007613 auto endApplyHandle = emission.applyCoroutine (yields);
76017614
76027615 return endApplyHandle;
0 commit comments