@@ -4999,14 +4999,16 @@ class CallEmission {
4999
4999
FormalEvaluationScope initialWritebackScope;
5000
5000
std::optional<ActorIsolation> implicitActorHopTarget;
5001
5001
bool implicitlyThrows;
5002
+ bool canUnwind;
5002
5003
5003
5004
public:
5004
5005
// / Create an emission for a call of the given callee.
5005
5006
CallEmission (SILGenFunction &SGF, Callee &&callee,
5006
5007
FormalEvaluationScope &&writebackScope)
5007
5008
: SGF(SGF), callee(std::move(callee)),
5008
5009
initialWritebackScope (std::move(writebackScope)),
5009
- implicitActorHopTarget(std::nullopt), implicitlyThrows(false ) {}
5010
+ implicitActorHopTarget(std::nullopt), implicitlyThrows(false ),
5011
+ canUnwind(false ) {}
5010
5012
5011
5013
// / A factory method for decomposing the apply expr \p e into a call
5012
5014
// / emission.
@@ -5057,6 +5059,8 @@ class CallEmission {
5057
5059
// / function can throw or not.
5058
5060
void setImplicitlyThrows (bool flag) { implicitlyThrows = flag; }
5059
5061
5062
+ void setCanUnwind (bool flag) { canUnwind = flag; }
5063
+
5060
5064
CleanupHandle applyCoroutine (SmallVectorImpl<ManagedValue> &yields);
5061
5065
5062
5066
RValue apply (SGFContext C = SGFContext()) {
@@ -5114,9 +5118,11 @@ namespace {
5114
5118
// / Cleanup to end a coroutine application.
5115
5119
class EndCoroutineApply : public Cleanup {
5116
5120
SILValue ApplyToken;
5121
+ bool CanUnwind;
5117
5122
std::vector<BeginBorrowInst *> BorrowedMoveOnlyValues;
5118
5123
public:
5119
- EndCoroutineApply (SILValue applyToken) : ApplyToken(applyToken) {}
5124
+ EndCoroutineApply (SILValue applyToken, bool CanUnwind)
5125
+ : ApplyToken(applyToken), CanUnwind(CanUnwind) {}
5120
5126
5121
5127
void setBorrowedMoveOnlyValues (ArrayRef<BeginBorrowInst *> values) {
5122
5128
BorrowedMoveOnlyValues.insert (BorrowedMoveOnlyValues.end (),
@@ -5129,14 +5135,7 @@ class EndCoroutineApply : public Cleanup {
5129
5135
SGF.B .createEndBorrow (l, *i);
5130
5136
SGF.B .createDestroyValue (l, (*i)->getOperand ());
5131
5137
}
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) {
5140
5139
SGF.B .createAbortApply (l, ApplyToken);
5141
5140
} else {
5142
5141
SGF.B .createEndApply (l, ApplyToken,
@@ -5179,18 +5178,15 @@ CallEmission::applyCoroutine(SmallVectorImpl<ManagedValue> &yields) {
5179
5178
5180
5179
auto fnValue = callee.getFnValue (SGF, borrowedSelf);
5181
5180
5182
- return SGF.emitBeginApply (uncurriedLoc.value (), fnValue,
5181
+ return SGF.emitBeginApply (uncurriedLoc.value (), fnValue, canUnwind,
5183
5182
callee.getSubstitutions (), uncurriedArgs,
5184
5183
calleeTypeInfo.substFnType , options, yields);
5185
5184
}
5186
5185
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) {
5194
5190
// Emit the call.
5195
5191
SmallVector<SILValue, 4 > rawResults;
5196
5192
emitRawApply (*this , loc, fn, subs, args, substFnType, options,
@@ -5206,7 +5202,7 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
5206
5202
5207
5203
// Push a cleanup to end the application.
5208
5204
// TODO: destroy all the arguments at exactly this point?
5209
- Cleanups.pushCleanup <EndCoroutineApply>(token);
5205
+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
5210
5206
auto endApplyHandle = getTopCleanup ();
5211
5207
5212
5208
// Manage all the yielded values.
@@ -6183,7 +6179,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
6183
6179
std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
6184
6180
CleanupHandle>
6185
6181
SILGenFunction::emitBeginApplyWithRethrow (SILLocation loc, SILValue fn,
6186
- SILType substFnType,
6182
+ SILType substFnType, bool canUnwind,
6187
6183
SubstitutionMap subs,
6188
6184
ArrayRef<SILValue> args,
6189
6185
SmallVectorImpl<SILValue> &yields) {
@@ -6208,7 +6204,7 @@ SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
6208
6204
deallocCleanup = enterDeallocStackCleanup (allocation);
6209
6205
}
6210
6206
6211
- Cleanups.pushCleanup <EndCoroutineApply>(token);
6207
+ Cleanups.pushCleanup <EndCoroutineApply>(token, canUnwind );
6212
6208
auto abortCleanup = Cleanups.getTopCleanup ();
6213
6209
6214
6210
return {token, abortCleanup, allocation, deallocCleanup};
@@ -7561,6 +7557,21 @@ ManagedValue SILGenFunction::emitAddressorAccessor(
7561
7557
return ManagedValue::forLValue (address);
7562
7558
}
7563
7559
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
+
7564
7575
CleanupHandle
7565
7576
SILGenFunction::emitCoroutineAccessor (SILLocation loc, SILDeclRef accessor,
7566
7577
SubstitutionMap substitutions,
@@ -7596,6 +7607,8 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
7596
7607
7597
7608
emission.addCallSite (loc, std::move (subscriptIndices));
7598
7609
7610
+ emission.setCanUnwind (canUnwindAccessorDeclRef (accessor));
7611
+
7599
7612
auto endApplyHandle = emission.applyCoroutine (yields);
7600
7613
7601
7614
return endApplyHandle;
0 commit comments