@@ -133,18 +133,56 @@ static void emitDistributedIfRemoteBranch(SILGenFunction &SGF, SILLocation Loc,
133
133
// ==== ------------------------------------------------------------------------
134
134
// MARK: local instance initialization
135
135
136
+ static SILArgument *findFirstDistributedActorSystemArg (SILFunction &F) {
137
+ auto *module = F.getModule ().getSwiftModule ();
138
+ auto &C = F.getASTContext ();
139
+
140
+ auto *transportProto = C.getProtocol (KnownProtocolKind::DistributedActorSystem);
141
+ Type transportTy = transportProto->getDeclaredInterfaceType ();
142
+
143
+ for (auto arg : F.getArguments ()) {
144
+ // TODO(distributed): also be able to locate a generic transport
145
+ Type argTy = arg->getType ().getASTType ();
146
+ auto argDecl = arg->getDecl ();
147
+
148
+ auto conformsToTransport =
149
+ module ->lookupConformance (argDecl->getInterfaceType (), transportProto);
150
+
151
+ // Is it a protocol that conforms to DistributedActorSystem?
152
+ if (argTy->isEqual (transportTy) || conformsToTransport) {
153
+ return arg;
154
+ }
155
+
156
+ // Is it some specific DistributedActorSystem?
157
+ auto result = module ->lookupConformance (argTy, transportProto);
158
+ if (!result.isInvalid ()) {
159
+ return arg;
160
+ }
161
+ }
162
+
163
+ #ifndef NDEBUG
164
+ llvm_unreachable (" Missing required DistributedActorSystem argument!" );
165
+ #endif
166
+
167
+ return nullptr ;
168
+ }
169
+
136
170
// / For the initialization of a local distributed actor instance, emits code to
137
171
// / initialize the instance's stored property corresponding to the system.
138
172
static void emitActorSystemInit (SILGenFunction &SGF,
139
173
ConstructorDecl *ctor,
140
174
SILLocation loc,
141
175
ManagedValue actorSelf) {
176
+ assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
177
+ assert (ctor->isDesignatedInit ());
178
+
142
179
auto *dc = ctor->getDeclContext ();
143
180
auto classDecl = dc->getSelfClassDecl ();
144
181
auto &C = ctor->getASTContext ();
145
182
146
- // Sema has already guaranteed that there is exactly one DistributedActorSystem
147
- // argument to the constructor, so we grab the first one from the params.
183
+ // By construction, automatically generated distributed actor ctors have
184
+ // exactly one ActorSystem-conforming argument to the constructor,
185
+ // so we grab the first one from the params.
148
186
SILValue systemArg = findFirstDistributedActorSystemArg (SGF.F );
149
187
VarDecl *var = lookupProperty (classDecl, C.Id_actorSystem );
150
188
assert (var);
@@ -160,6 +198,9 @@ static void emitActorSystemInit(SILGenFunction &SGF,
160
198
// / \endverbatim
161
199
static void emitIDInit (SILGenFunction &SGF, ConstructorDecl *ctor,
162
200
SILLocation loc, ManagedValue borrowedSelfArg) {
201
+ assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
202
+ assert (ctor->isDesignatedInit ());
203
+
163
204
auto &C = ctor->getASTContext ();
164
205
auto &B = SGF.B ;
165
206
auto &F = SGF.F ;
@@ -173,7 +214,8 @@ static void emitIDInit(SILGenFunction &SGF, ConstructorDecl *ctor,
173
214
auto selfMetatype = SGF.getLoweredType (MetatypeType::get (selfTy));
174
215
SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
175
216
176
- SILValue actorSystem = findFirstDistributedActorSystemArg (F);
217
+ // since we're doing this only for the implicitly defined ctors, grab from arg
218
+ SILValue actorSystem = findFirstDistributedActorSystemArg (SGF.F );
177
219
178
220
// --- create a temporary storage for the result of the call
179
221
// it will be deallocated automatically as we exit this scope
@@ -230,12 +272,19 @@ void SILGenFunction::emitDistributedActorImplicitPropertyInits(
230
272
loc.markAutoGenerated ();
231
273
232
274
selfArg = selfArg.borrow (*this , loc);
233
- emitActorSystemInit (*this , ctor, loc, selfArg);
234
- emitIDInit (*this , ctor, loc, selfArg);
235
275
236
276
// register a clean-up to resign the identity upon abnormal exit
277
+ // we do this regardless of initializer kind, since it's easy to do in SILGen.
237
278
auto *actorDecl = cast<ClassDecl>(ctor->getParent ()->getAsDecl ());
238
279
Cleanups.pushCleanup <ResignIdentity>(actorDecl, selfArg.getValue ());
280
+
281
+ // Users must initialize the actorSystem property explicitly in their ctors
282
+ if (!ctor->isImplicit ())
283
+ return ;
284
+
285
+ // implicit ctors initialize these from the ActorSystem parameter.
286
+ emitActorSystemInit (*this , ctor, loc, selfArg);
287
+ emitIDInit (*this , ctor, loc, selfArg);
239
288
}
240
289
241
290
void SILGenFunction::emitDistributedActorReady (
@@ -244,12 +293,27 @@ void SILGenFunction::emitDistributedActorReady(
244
293
// Only designated initializers get the lifecycle handling injected
245
294
assert (ctor->isDesignatedInit ());
246
295
247
- SILValue transport = findFirstDistributedActorSystemArg (F);
296
+ auto &C = ctor->getASTContext ();
297
+ auto *dc = ctor->getDeclContext ();
298
+ auto classDecl = dc->getSelfClassDecl ();
248
299
249
300
FullExpr scope (Cleanups, CleanupLocation (loc));
250
301
auto borrowedSelf = actorSelf.borrow (*this , loc);
251
302
252
- emitActorReadyCall (B, loc, borrowedSelf.getValue (), transport);
303
+ // --- load the actor system from the actor instance
304
+ ManagedValue actorSystem;
305
+ SGFContext sgfCxt; // TODO: is this right?
306
+ {
307
+ VarDecl *property = lookupProperty (classDecl, C.Id_actorSystem );
308
+ Type formalType = F.mapTypeIntoContext (property->getInterfaceType ());
309
+ SILType loweredType = getLoweredType (formalType).getAddressType ();
310
+ SILValue actorSystemRef = emitActorPropertyReference (
311
+ *this , loc, borrowedSelf.getValue (), property);
312
+ actorSystem = emitLoad (loc, actorSystemRef,
313
+ getTypeLowering (loweredType), sgfCxt, IsNotTake);
314
+ }
315
+
316
+ emitActorReadyCall (B, loc, borrowedSelf.getValue (), actorSystem.getValue ());
253
317
}
254
318
255
319
// ==== ------------------------------------------------------------------------
0 commit comments