@@ -636,45 +636,73 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
636
636
}
637
637
}
638
638
639
- /* *****************************************************************************/
640
- /* ****************** DISTRIBUTED DEINIT: resignIdentity ***********************/
641
- /* *****************************************************************************/
639
+ // MARK: transport.resignIdentity()
642
640
643
- void SILGenFunction::emitDistributedActor_resignIdentity (
644
- DestructorDecl *dd, SILValue selfValue, SILBasicBlock *continueBB) {
641
+ void SILGenFunction::emitResignIdentityCall (SILLocation loc,
642
+ ClassDecl *actorDecl,
643
+ ManagedValue actorSelf) {
645
644
ASTContext &ctx = getASTContext ();
646
-
647
- auto cd = cast<ClassDecl>(dd->getDeclContext ());
648
- assert (cd->isDistributedActor () &&
649
- " only distributed actors have transport lifecycle hooks in deinit" );
650
-
651
- RegularLocation Loc (dd);
652
- if (dd->isImplicit ())
653
- Loc.markAutoGenerated ();
654
-
655
- auto selfDecl = dd->getImplicitSelfDecl ();
656
- auto selfManagedValue = ManagedValue::forUnmanaged (selfValue);
657
- auto selfTy = selfDecl->getType ();
658
-
645
+
646
+ FormalEvaluationScope scope (*this );
647
+
659
648
// ==== locate: self.id
660
- auto *idVarDeclRef = lookupProperty (cd , ctx.Id_id );
649
+ auto *idVarDeclRef = lookupProperty (actorDecl , ctx.Id_id );
661
650
auto idRef =
662
- B.createRefElementAddr (Loc, selfValue , idVarDeclRef,
663
- getLoweredType (idVarDeclRef->getType ()));
664
-
651
+ B.createRefElementAddr (loc, actorSelf , idVarDeclRef,
652
+ getLoweredType (idVarDeclRef->getType ()));
653
+
665
654
// ==== locate: self.actorTransport
666
- auto transportVarDeclRef = lookupProperty (cd , ctx.Id_actorTransport );
655
+ auto transportVarDeclRef = lookupProperty (actorDecl , ctx.Id_actorTransport );
667
656
auto transportRef =
668
- B.createRefElementAddr (Loc, selfValue , transportVarDeclRef,
669
- getLoweredType (transportVarDeclRef->getType ()));
670
-
671
- // locate: self.transport.resignIdentity(...)
657
+ B.createRefElementAddr (loc, actorSelf , transportVarDeclRef,
658
+ getLoweredType (transportVarDeclRef->getType ()));
659
+
660
+ // ==== locate: self.transport.resignIdentity(...)
672
661
auto *transportDecl = ctx.getActorTransportDecl ();
673
662
auto resignFnDecls = transportDecl->lookupDirect (ctx.Id_resignIdentity );
674
663
assert (resignFnDecls.size () == 1 );
675
664
auto *resignFnDecl = resignFnDecls.front ();
676
665
auto resignFnRef = SILDeclRef (resignFnDecl);
666
+
667
+ // ==== perform the call
668
+ auto openedTransport =
669
+ OpenedArchetypeType::get (transportVarDeclRef->getType ());
670
+ auto transportAddr =
671
+ B.createOpenExistentialAddr (loc, /* operand=*/ transportRef.getValue (),
672
+ getLoweredType (openedTransport),
673
+ OpenedExistentialAccess::Immutable);
674
+
675
+ auto resignFnType =
676
+ SGM.M .Types .getConstantFunctionType (TypeExpansionContext::minimal (),
677
+ resignFnRef);
678
+
679
+ auto conformance = ProtocolConformanceRef (transportDecl);
680
+ auto witness =
681
+ B.createWitnessMethod (loc, openedTransport,
682
+ conformance, resignFnRef,
683
+ SILType::getPrimitiveObjectType (resignFnType));
684
+
685
+ auto subs = SubstitutionMap::getProtocolSubstitutions (transportDecl,
686
+ openedTransport,
687
+ conformance);
688
+
689
+ SmallVector<SILValue, 2 > params;
690
+ params.push_back (idRef.getValue ());
691
+ params.push_back (transportAddr); // self for the call, as last param
692
+
693
+ B.createApply (loc, witness, subs, params);
694
+ }
695
+
696
+ void
697
+ SILGenFunction::emitConditionalResignIdentityCall (SILLocation loc,
698
+ ClassDecl *actorDecl,
699
+ ManagedValue actorSelf,
700
+ SILBasicBlock *continueBB) {
701
+ assert (actorDecl->isDistributedActor () &&
702
+ " only distributed actors have transport lifecycle hooks in deinit" );
677
703
704
+ auto selfTy = actorDecl->getDeclaredInterfaceType ();
705
+
678
706
// we only transport.resignIdentity if we are a local actor,
679
707
// and thus the address was created by transport.assignIdentity.
680
708
auto isRemoteBB = createBasicBlock ();
@@ -685,46 +713,24 @@ void SILGenFunction::emitDistributedActor_resignIdentity(
685
713
// } else {
686
714
// ...
687
715
// }
688
- emitDistributedIfRemoteBranch (*this , Loc ,
689
- selfManagedValue , selfTy,
716
+ emitDistributedIfRemoteBranch (*this , loc ,
717
+ actorSelf , selfTy,
690
718
/* if remote*/ isRemoteBB,
691
719
/* if local*/ isLocalBB);
692
720
693
- // if remote
694
- // === <noop>
721
+ // if remote, do nothing.
695
722
{
696
723
B.emitBlock (isRemoteBB);
697
- // noop, remote actors don't do anything in their deinit
698
- B.createBranch (Loc, continueBB);
724
+ B.createBranch (loc, continueBB);
699
725
}
700
726
701
- // if local
702
- // === self.transport.resignIdentity(self.address)
727
+ // if local, resign identity.
703
728
{
704
729
B.emitBlock (isLocalBB);
705
730
706
- auto openedTransport =
707
- OpenedArchetypeType::get (transportVarDeclRef->getType ());
708
- auto transportAddr = B.createOpenExistentialAddr (
709
- Loc, /* operand=*/ transportRef, getLoweredType (openedTransport),
710
- OpenedExistentialAccess::Immutable);
711
-
712
- auto resignFnType = SGM.M .Types .getConstantFunctionType (
713
- TypeExpansionContext::minimal (), resignFnRef);
714
-
715
- auto witness = B.createWitnessMethod (
716
- Loc, openedTransport, ProtocolConformanceRef (transportDecl),
717
- resignFnRef, SILType::getPrimitiveObjectType (resignFnType));
718
-
719
- auto subs = SubstitutionMap::getProtocolSubstitutions (
720
- transportDecl, openedTransport, ProtocolConformanceRef (transportDecl));
721
-
722
- SmallVector<SILValue, 2 > params;
723
- params.push_back (idRef);
724
- params.push_back (transportAddr); // self for the call, as last param
725
-
726
- B.createApply (Loc, witness, subs, params);
727
- B.createBranch (Loc, continueBB);
731
+ emitResignIdentityCall (loc, actorDecl, actorSelf);
732
+
733
+ B.createBranch (loc, continueBB);
728
734
}
729
735
}
730
736
0 commit comments