@@ -137,24 +137,24 @@ static SILArgument *findFirstDistributedActorSystemArg(SILFunction &F) {
137
137
auto *module = F.getModule ().getSwiftModule ();
138
138
auto &C = F.getASTContext ();
139
139
140
- auto *transportProto = C.getProtocol (KnownProtocolKind::DistributedActorSystem );
141
- Type transportTy = transportProto ->getDeclaredInterfaceType ();
140
+ auto *DAS = C.getDistributedActorSystemDecl ( );
141
+ Type systemTy = DAS ->getDeclaredInterfaceType ();
142
142
143
143
for (auto arg : F.getArguments ()) {
144
- // TODO(distributed): also be able to locate a generic transport
144
+ // TODO(distributed): also be able to locate a generic system
145
145
Type argTy = arg->getType ().getASTType ();
146
146
auto argDecl = arg->getDecl ();
147
147
148
- auto conformsToTransport =
149
- module ->lookupConformance (argDecl->getInterfaceType (), transportProto );
148
+ auto conformsToSystem =
149
+ module ->lookupConformance (argDecl->getInterfaceType (), DAS );
150
150
151
151
// Is it a protocol that conforms to DistributedActorSystem?
152
- if (argTy->isEqual (transportTy ) || conformsToTransport ) {
152
+ if (argTy->isEqual (systemTy ) || conformsToSystem ) {
153
153
return arg;
154
154
}
155
155
156
156
// Is it some specific DistributedActorSystem?
157
- auto result = module ->lookupConformance (argTy, transportProto );
157
+ auto result = module ->lookupConformance (argTy, DAS );
158
158
if (!result.isInvalid ()) {
159
159
return arg;
160
160
}
@@ -172,7 +172,8 @@ static SILArgument *findFirstDistributedActorSystemArg(SILFunction &F) {
172
172
static void emitActorSystemInit (SILGenFunction &SGF,
173
173
ConstructorDecl *ctor,
174
174
SILLocation loc,
175
- ManagedValue actorSelf) {
175
+ ManagedValue actorSelf,
176
+ SILValue systemValue) {
176
177
assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
177
178
assert (ctor->isDesignatedInit ());
178
179
@@ -183,11 +184,10 @@ static void emitActorSystemInit(SILGenFunction &SGF,
183
184
// By construction, automatically generated distributed actor ctors have
184
185
// exactly one ActorSystem-conforming argument to the constructor,
185
186
// so we grab the first one from the params.
186
- SILValue systemArg = findFirstDistributedActorSystemArg (SGF.F );
187
187
VarDecl *var = lookupProperty (classDecl, C.Id_actorSystem );
188
188
assert (var);
189
189
190
- initializeProperty (SGF, loc, actorSelf.getValue (), var, systemArg );
190
+ initializeProperty (SGF, loc, actorSelf.getValue (), var, systemValue );
191
191
}
192
192
193
193
// / Emits the distributed actor's identity (`id`) initialization.
@@ -196,72 +196,98 @@ static void emitActorSystemInit(SILGenFunction &SGF,
196
196
// / \verbatim
197
197
// / self.id = system.assignID(Self.self)
198
198
// / \endverbatim
199
- static void emitIDInit (SILGenFunction &SGF, ConstructorDecl *ctor,
200
- SILLocation loc, ManagedValue borrowedSelfArg) {
201
- assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
199
+ void SILGenFunction::emitDistActorIdentityInit (ConstructorDecl *ctor,
200
+ SILLocation loc,
201
+ SILValue borrowedSelfArg,
202
+ SILValue actorSystem) {
202
203
assert (ctor->isDesignatedInit ());
203
204
204
205
auto &C = ctor->getASTContext ();
205
- auto &B = SGF.B ;
206
- auto &F = SGF.F ;
207
206
208
207
auto *dc = ctor->getDeclContext ();
209
208
auto classDecl = dc->getSelfClassDecl ();
210
209
210
+ assert (classDecl->isDistributedActor ());
211
+
211
212
// --- prepare `Self.self` metatype
212
213
auto *selfTyDecl = ctor->getParent ()->getSelfNominalTypeDecl ();
213
214
auto selfTy = F.mapTypeIntoContext (selfTyDecl->getDeclaredInterfaceType ());
214
- auto selfMetatype = SGF. getLoweredType (MetatypeType::get (selfTy));
215
+ auto selfMetatype = getLoweredType (MetatypeType::get (selfTy));
215
216
SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
216
217
217
- // since we're doing this only for the implicitly defined ctors, grab from arg
218
- SILValue actorSystem = findFirstDistributedActorSystemArg (SGF.F );
219
-
220
218
// --- create a temporary storage for the result of the call
221
219
// it will be deallocated automatically as we exit this scope
222
220
VarDecl *var = lookupProperty (classDecl, C.Id_id );
223
- auto resultTy = SGF.getLoweredType (
224
- F.mapTypeIntoContext (var->getInterfaceType ()));
225
- auto temp = SGF.emitTemporaryAllocation (loc, resultTy);
221
+ auto resultTy = getLoweredType (F.mapTypeIntoContext (var->getInterfaceType ()));
222
+ auto temp = emitTemporaryAllocation (loc, resultTy);
226
223
227
224
// --- emit the call itself.
228
225
emitDistributedActorSystemWitnessCall (
229
226
B, loc, C.Id_assignID ,
230
- actorSystem, SGF. getLoweredType (selfTy),
227
+ actorSystem, getLoweredType (selfTy),
231
228
{ temp, selfMetatypeValue });
232
229
233
230
// --- initialize the property.
234
- initializeProperty (SGF , loc, borrowedSelfArg. getValue () , var, temp);
231
+ initializeProperty (* this , loc, borrowedSelfArg, var, temp);
235
232
}
236
233
237
- namespace {
238
- // / Cleanup to resign the identity of a distributed actor if an abnormal exit happens.
239
- class ResignIdentity : public Cleanup {
240
- ClassDecl *actorDecl;
241
- SILValue self;
242
- public:
243
- ResignIdentity (ClassDecl *actorDecl, SILValue self)
244
- : actorDecl(actorDecl), self(self) {
245
- assert (actorDecl->isDistributedActor ());
246
- }
234
+ InitializeDistActorIdentity::InitializeDistActorIdentity (ConstructorDecl *ctor,
235
+ ManagedValue actorSelf)
236
+ : ctor(ctor),
237
+ actorSelf(actorSelf) {
238
+ systemVar = ctor->getDeclContext ()
239
+ ->getSelfClassDecl ()
240
+ ->getDistributedActorSystemProperty ();
241
+ assert (systemVar);
242
+ }
247
243
248
- void emit (SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
249
- if (forUnwind == IsForUnwind) {
250
- l.markAutoGenerated ();
251
- SGF.emitDistributedActorSystemResignIDCall (l, actorDecl,
252
- ManagedValue::forUnmanaged (self));
253
- }
244
+ void InitializeDistActorIdentity::emit (SILGenFunction &SGF, CleanupLocation loc,
245
+ ForUnwind_t forUnwind) {
246
+
247
+ // If we're unwinding, that must mean we're in the case where the
248
+ // evaluating the expression being assigned to the actorSystem has
249
+ // thrown an error. In that case, we cannot initialize the identity,
250
+ // since there is no actorSystem.
251
+ if (forUnwind == IsForUnwind)
252
+ return ;
253
+
254
+
255
+ // Save the current clean-up depth
256
+ auto baseDepth = SGF.getCleanupsDepth ();
257
+ {
258
+ loc.markAutoGenerated ();
259
+ auto borrowedSelf = actorSelf.borrow (SGF, loc);
260
+
261
+ // load the actorSystem value
262
+ Type formalType = SGF.F .mapTypeIntoContext (systemVar->getInterfaceType ());
263
+ SILType loweredType = SGF.getLoweredType (formalType).getAddressType ();
264
+ auto ref =
265
+ SGF.B .createRefElementAddr (loc, borrowedSelf, systemVar, loweredType);
266
+
267
+ SGFContext ctx;
268
+ auto systemVal =
269
+ SGF.emitLoad (loc, ref.getValue (),
270
+ SGF.getTypeLowering (loweredType), ctx, IsNotTake);
271
+
272
+ // Important that we mark the location as auto-generated, since the id
273
+ // is a @_compilerInitialized field.
274
+ SGF.emitDistActorIdentityInit (ctor, loc,
275
+ borrowedSelf.getValue (), systemVal.getValue ());
254
276
}
255
277
256
- void dump (SILGenFunction &SGF) const override {
278
+ // Emit any active clean-ups we just pushed.
279
+ while (SGF.getTopCleanup () != baseDepth)
280
+ SGF.Cleanups .popAndEmitCleanup (SGF.getTopCleanup (), loc, forUnwind);
281
+
282
+ }
283
+
284
+ void InitializeDistActorIdentity::dump (SILGenFunction &) const {
257
285
#ifndef NDEBUG
258
- llvm::errs () << " ResignIdentity "
259
- << " State:" << getState () << " "
260
- << " Self: " << self << " \n " ;
286
+ llvm::errs () << " InitializeDistActorIdentity \n "
287
+ << " State: " << getState ()
288
+ << " \n " ;
261
289
#endif
262
- }
263
- };
264
- } // end anonymous namespace
290
+ }
265
291
266
292
void SILGenFunction::emitDistributedActorImplicitPropertyInits (
267
293
ConstructorDecl *ctor, ManagedValue selfArg) {
@@ -273,18 +299,18 @@ void SILGenFunction::emitDistributedActorImplicitPropertyInits(
273
299
274
300
selfArg = selfArg.borrow (*this , loc);
275
301
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.
278
- auto *actorDecl = cast<ClassDecl>(ctor->getParent ()->getAsDecl ());
279
- Cleanups.pushCleanup <ResignIdentity>(actorDecl, selfArg.getValue ());
280
-
281
- // Users must initialize the actorSystem property explicitly in their ctors
282
- if (!ctor->isImplicit ())
302
+ // implicit ctors initialize the system and identity from
303
+ // its ActorSystem parameter.
304
+ if (ctor->isImplicit ()) {
305
+ SILValue actorSystem = findFirstDistributedActorSystemArg (F);
306
+ emitActorSystemInit (*this , ctor, loc, selfArg, actorSystem);
307
+ emitDistActorIdentityInit (ctor, loc, selfArg.getValue (), actorSystem);
283
308
return ;
309
+ }
284
310
285
- // implicit ctors initialize these from the ActorSystem parameter.
286
- emitActorSystemInit (* this , ctor, loc, selfArg);
287
- emitIDInit (* this , ctor, loc , selfArg);
311
+ // for explicit ctors, store (but do not push) a clean-up that will
312
+ // initialize the identity in whichever scope it's pushed to.
313
+ DistActorCtorContext = InitializeDistActorIdentity (ctor , selfArg);
288
314
}
289
315
290
316
void SILGenFunction::emitDistributedActorReady (
@@ -505,7 +531,7 @@ SILGenFunction::emitConditionalResignIdentityCall(SILLocation loc,
505
531
ManagedValue actorSelf,
506
532
SILBasicBlock *continueBB) {
507
533
assert (actorDecl->isDistributedActor () &&
508
- " only distributed actors have transport lifecycle hooks in deinit" );
534
+ " only distributed actors have actorSystem lifecycle hooks in deinit" );
509
535
510
536
auto selfTy = actorDecl->getDeclaredInterfaceType ();
511
537
0 commit comments