@@ -137,24 +137,24 @@ static SILArgument *findFirstDistributedActorSystemArg(SILFunction &F) {
137137 auto *module = F.getModule ().getSwiftModule ();
138138 auto &C = F.getASTContext ();
139139
140- auto *transportProto = C.getProtocol (KnownProtocolKind::DistributedActorSystem );
141- Type transportTy = transportProto ->getDeclaredInterfaceType ();
140+ auto *DAS = C.getDistributedActorSystemDecl ( );
141+ Type systemTy = DAS ->getDeclaredInterfaceType ();
142142
143143 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
145145 Type argTy = arg->getType ().getASTType ();
146146 auto argDecl = arg->getDecl ();
147147
148- auto conformsToTransport =
149- module ->lookupConformance (argDecl->getInterfaceType (), transportProto );
148+ auto conformsToSystem =
149+ module ->lookupConformance (argDecl->getInterfaceType (), DAS );
150150
151151 // Is it a protocol that conforms to DistributedActorSystem?
152- if (argTy->isEqual (transportTy ) || conformsToTransport ) {
152+ if (argTy->isEqual (systemTy ) || conformsToSystem ) {
153153 return arg;
154154 }
155155
156156 // Is it some specific DistributedActorSystem?
157- auto result = module ->lookupConformance (argTy, transportProto );
157+ auto result = module ->lookupConformance (argTy, DAS );
158158 if (!result.isInvalid ()) {
159159 return arg;
160160 }
@@ -172,7 +172,8 @@ static SILArgument *findFirstDistributedActorSystemArg(SILFunction &F) {
172172static void emitActorSystemInit (SILGenFunction &SGF,
173173 ConstructorDecl *ctor,
174174 SILLocation loc,
175- ManagedValue actorSelf) {
175+ ManagedValue actorSelf,
176+ SILValue systemValue) {
176177 assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
177178 assert (ctor->isDesignatedInit ());
178179
@@ -183,11 +184,10 @@ static void emitActorSystemInit(SILGenFunction &SGF,
183184 // By construction, automatically generated distributed actor ctors have
184185 // exactly one ActorSystem-conforming argument to the constructor,
185186 // so we grab the first one from the params.
186- SILValue systemArg = findFirstDistributedActorSystemArg (SGF.F );
187187 VarDecl *var = lookupProperty (classDecl, C.Id_actorSystem );
188188 assert (var);
189189
190- initializeProperty (SGF, loc, actorSelf.getValue (), var, systemArg );
190+ initializeProperty (SGF, loc, actorSelf.getValue (), var, systemValue );
191191}
192192
193193// / Emits the distributed actor's identity (`id`) initialization.
@@ -196,72 +196,98 @@ static void emitActorSystemInit(SILGenFunction &SGF,
196196// / \verbatim
197197// / self.id = system.assignID(Self.self)
198198// / \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) {
202203 assert (ctor->isDesignatedInit ());
203204
204205 auto &C = ctor->getASTContext ();
205- auto &B = SGF.B ;
206- auto &F = SGF.F ;
207206
208207 auto *dc = ctor->getDeclContext ();
209208 auto classDecl = dc->getSelfClassDecl ();
210209
210+ assert (classDecl->isDistributedActor ());
211+
211212 // --- prepare `Self.self` metatype
212213 auto *selfTyDecl = ctor->getParent ()->getSelfNominalTypeDecl ();
213214 auto selfTy = F.mapTypeIntoContext (selfTyDecl->getDeclaredInterfaceType ());
214- auto selfMetatype = SGF. getLoweredType (MetatypeType::get (selfTy));
215+ auto selfMetatype = getLoweredType (MetatypeType::get (selfTy));
215216 SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
216217
217- // since we're doing this only for the implicitly defined ctors, grab from arg
218- SILValue actorSystem = findFirstDistributedActorSystemArg (SGF.F );
219-
220218 // --- create a temporary storage for the result of the call
221219 // it will be deallocated automatically as we exit this scope
222220 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);
226223
227224 // --- emit the call itself.
228225 emitDistributedActorSystemWitnessCall (
229226 B, loc, C.Id_assignID ,
230- actorSystem, SGF. getLoweredType (selfTy),
227+ actorSystem, getLoweredType (selfTy),
231228 { temp, selfMetatypeValue });
232229
233230 // --- initialize the property.
234- initializeProperty (SGF , loc, borrowedSelfArg. getValue () , var, temp);
231+ initializeProperty (* this , loc, borrowedSelfArg, var, temp);
235232}
236233
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+ }
247243
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 ());
254276 }
255277
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 {
257285#ifndef NDEBUG
258- llvm::errs () << " ResignIdentity "
259- << " State:" << getState () << " "
260- << " Self: " << self << " \n " ;
286+ llvm::errs () << " InitializeDistActorIdentity \n "
287+ << " State: " << getState ()
288+ << " \n " ;
261289#endif
262- }
263- };
264- } // end anonymous namespace
290+ }
265291
266292void SILGenFunction::emitDistributedActorImplicitPropertyInits (
267293 ConstructorDecl *ctor, ManagedValue selfArg) {
@@ -273,18 +299,18 @@ void SILGenFunction::emitDistributedActorImplicitPropertyInits(
273299
274300 selfArg = selfArg.borrow (*this , loc);
275301
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);
283308 return ;
309+ }
284310
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);
288314}
289315
290316void SILGenFunction::emitDistributedActorReady (
@@ -505,7 +531,7 @@ SILGenFunction::emitConditionalResignIdentityCall(SILLocation loc,
505531 ManagedValue actorSelf,
506532 SILBasicBlock *continueBB) {
507533 assert (actorDecl->isDistributedActor () &&
508- " only distributed actors have transport lifecycle hooks in deinit" );
534+ " only distributed actors have actorSystem lifecycle hooks in deinit" );
509535
510536 auto selfTy = actorDecl->getDeclaredInterfaceType ();
511537
0 commit comments