@@ -76,8 +76,11 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
76
76
resultSelfValue = selfValue;
77
77
}
78
78
79
+
79
80
if (cd->isDistributedActor ()) {
80
- injectDistributedActorDestructorLifecycleCall (dd, selfValue);
81
+ SILBasicBlock *continueBB = createBasicBlock ();
82
+ injectDistributedActorDestructorLifecycleCall (dd, selfValue, continueBB);
83
+ B.emitBlock (continueBB);
81
84
}
82
85
83
86
ArgumentScope S (*this , Loc);
@@ -106,19 +109,8 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
106
109
B.createReturn (returnLoc, resultSelfValue);
107
110
}
108
111
109
- static AccessorDecl *getActorTransportGetter (ASTContext &ctx,
110
- ProtocolDecl *distributedActorProtocol) {
111
- for (auto member: distributedActorProtocol->getAllMembers ()) {
112
- if (auto var = dyn_cast<VarDecl>(member)) {
113
- if (var->getName () == ctx.Id_unownedExecutor )
114
- return var->getAccessor (AccessorKind::Get);
115
- }
116
- }
117
- return nullptr ;
118
- }
119
-
120
112
void SILGenFunction::injectDistributedActorDestructorLifecycleCall (
121
- DestructorDecl *dd, SILValue selfValue) {
113
+ DestructorDecl *dd, SILValue selfValue, SILBasicBlock *continueBB ) {
122
114
ASTContext &ctx = getASTContext ();
123
115
124
116
auto cd = cast<ClassDecl>(dd->getDeclContext ());
@@ -129,6 +121,10 @@ void SILGenFunction::injectDistributedActorDestructorLifecycleCall(
129
121
if (dd->isImplicit ())
130
122
Loc.markAutoGenerated ();
131
123
124
+ auto selfDecl = dd->getImplicitSelfDecl ();
125
+ auto selfManagedValue = ManagedValue::forUnmanaged (selfValue);
126
+ auto selfType = selfDecl->getType ();
127
+
132
128
// ==== locate: self.actorAddress
133
129
auto addressVarDeclRefs = cd->lookupDirect (ctx.Id_actorAddress );
134
130
assert (addressVarDeclRefs.size () == 1 );
@@ -142,43 +138,82 @@ void SILGenFunction::injectDistributedActorDestructorLifecycleCall(
142
138
auto transportVarDeclRefs = cd->lookupDirect (ctx.Id_actorTransport );
143
139
assert (transportVarDeclRefs.size () == 1 );
144
140
auto *transportVarDeclRef = dyn_cast<VarDecl>(transportVarDeclRefs.front ());
145
- assert (transportVarDeclRef);
146
141
auto transportRef =
147
142
B.createRefElementAddr (Loc, selfValue, transportVarDeclRef,
148
143
getLoweredType (transportVarDeclRef->getType ()));
149
- assert (transportRef);
150
144
151
145
// locate: self.transport.resignAddress(...)
152
146
auto *transportDecl = ctx.getActorTransportDecl ();
153
147
auto resignFnDecls = transportDecl->lookupDirect (ctx.Id_resignAddress );
154
148
assert (resignFnDecls.size () == 1 );
155
- ValueDecl *resignFnDecl = resignFnDecls.front ();
156
- assert (resignFnDecl && " Unable to find 'resignAddress' on ActorTransport" );
149
+ auto *resignFnDecl = resignFnDecls.front ();
157
150
auto resignFnRef = SILDeclRef (resignFnDecl);
158
151
159
- auto openedTransport =
160
- OpenedArchetypeType::get (transportVarDeclRef->getType ());
152
+ // we only transport.resignAddress if we are a local actor,
153
+ // and thus the address was created by transport.assignAddress.
154
+ auto isRemoteBB = createBasicBlock ();
155
+ auto isLocalBB = createBasicBlock ();
161
156
162
- auto transportAddr = B.createOpenExistentialAddr (
163
- Loc, /* operand=*/ transportRef, getLoweredType (openedTransport),
164
- OpenedExistentialAccess::Immutable);
157
+ // if __isRemoteActor(self) {
158
+ // ...
159
+ // } else {
160
+ // ...
161
+ // }
162
+ {
163
+ FuncDecl *isRemoteFn = ctx.getIsRemoteDistributedActor ();
164
+ assert (isRemoteFn && " Could not find 'is remote' function, is the "
165
+ " '_Distributed' module available?" );
166
+
167
+ ManagedValue selfAnyObject =
168
+ B.createInitExistentialRef (Loc, getLoweredType (ctx.getAnyObjectType ()),
169
+ CanType (selfType), selfManagedValue, {});
170
+ auto result = emitApplyOfLibraryIntrinsic (
171
+ Loc, isRemoteFn, SubstitutionMap (), {selfAnyObject}, SGFContext ());
172
+
173
+ SILValue isRemoteResult =
174
+ std::move (result).forwardAsSingleValue (*this , Loc);
175
+ SILValue isRemoteResultUnwrapped =
176
+ emitUnwrapIntegerResult (Loc, isRemoteResult);
177
+
178
+ B.createCondBranch (Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB);
179
+ }
165
180
166
- auto resignFnType = SGM.M .Types .getConstantFunctionType (
167
- TypeExpansionContext::minimal (), resignFnRef);
181
+ // if remote
182
+ // === <noop>
183
+ {
184
+ B.emitBlock (isRemoteBB);
185
+ // noop, remote actors don't do anything in their deinit
186
+ B.createBranch (Loc, continueBB);
187
+ }
168
188
169
- auto witness = B.createWitnessMethod (
170
- Loc, openedTransport, ProtocolConformanceRef (transportDecl), resignFnRef,
171
- SILType::getPrimitiveObjectType (resignFnType));
189
+ // if local
190
+ // === self.transport.resignAddress(self.address)
191
+ {
192
+ B.emitBlock (isLocalBB);
172
193
173
- auto subs = SubstitutionMap::getProtocolSubstitutions (
174
- transportDecl, openedTransport, ProtocolConformanceRef (transportDecl));
194
+ auto openedTransport =
195
+ OpenedArchetypeType::get (transportVarDeclRef->getType ());
196
+ auto transportAddr = B.createOpenExistentialAddr (
197
+ Loc, /* operand=*/ transportRef, getLoweredType (openedTransport),
198
+ OpenedExistentialAccess::Immutable);
175
199
176
- SmallVector<SILValue, 2 > params;
177
- params.push_back (addressRef);
178
- params.push_back (transportAddr); // self for the call, as last param
200
+ auto resignFnType = SGM.M .Types .getConstantFunctionType (
201
+ TypeExpansionContext::minimal (), resignFnRef);
179
202
180
- // === self.transport.resignAddress(self.address)
181
- B.createApply (Loc, witness, subs, params);
203
+ auto witness = B.createWitnessMethod (
204
+ Loc, openedTransport, ProtocolConformanceRef (transportDecl),
205
+ resignFnRef, SILType::getPrimitiveObjectType (resignFnType));
206
+
207
+ auto subs = SubstitutionMap::getProtocolSubstitutions (
208
+ transportDecl, openedTransport, ProtocolConformanceRef (transportDecl));
209
+
210
+ SmallVector<SILValue, 2 > params;
211
+ params.push_back (addressRef);
212
+ params.push_back (transportAddr); // self for the call, as last param
213
+
214
+ B.createApply (Loc, witness, subs, params);
215
+ B.createBranch (Loc, continueBB);
216
+ }
182
217
}
183
218
184
219
void SILGenFunction::emitDeallocatingDestructor (DestructorDecl *dd) {
0 commit comments