@@ -70,6 +70,34 @@ static void emitDistributedIfRemoteBranch(SILGenFunction &SGF,
70
70
B.createCondBranch (Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB);
71
71
}
72
72
73
+ static AbstractFunctionDecl *lookupActorTransportResolveFunc (ASTContext &C) {
74
+ auto transportDecl = C.getActorTransportDecl ();
75
+
76
+ for (auto decl : transportDecl->lookupDirect (DeclName (C.Id_resolve )))
77
+ if (auto funcDecl = dyn_cast<AbstractFunctionDecl>(decl))
78
+ return funcDecl;
79
+
80
+ llvm_unreachable (" Missing ActorTransport.resolve function" );
81
+ }
82
+
83
+ static VarDecl *lookupActorTransportProperty (ASTContext &C, ClassDecl *cd,
84
+ SILValue selfValue) {
85
+ auto transportVarDeclRefs = cd->lookupDirect (C.Id_actorTransport );
86
+ assert (transportVarDeclRefs.size () == 1 );
87
+ return dyn_cast<VarDecl>(transportVarDeclRefs.front ());
88
+ }
89
+
90
+ static EnumElementDecl *lookupEnumCase (ASTContext &C, EnumDecl *target,
91
+ Identifier identifier) {
92
+ auto elementDecls = target->lookupDirect (DeclName (identifier));
93
+ if (elementDecls.empty ())
94
+ return nullptr ;
95
+
96
+ auto *elementDecl = elementDecls.front ();
97
+
98
+ return dyn_cast<EnumElementDecl>(elementDecl);
99
+ }
100
+
73
101
/* *****************************************************************************/
74
102
/* ***************** DISTRIBUTED ACTOR STORAGE INITIALIZATION ******************/
75
103
/* *****************************************************************************/
@@ -120,6 +148,7 @@ static void emitDistributedActorStore_transport(
120
148
SILValue actorSelf, AbstractFunctionDecl *func,
121
149
SILArgument *transportArg) {
122
150
auto &B = SGF.B ;
151
+
123
152
auto &SGM = SGF.SGM ;
124
153
SILGenFunctionBuilder builder (SGM);
125
154
@@ -135,6 +164,7 @@ static void emitDistributedActorStore_transport(
135
164
auto *var = dyn_cast<VarDecl>(vars.front ());
136
165
137
166
// ----
167
+
138
168
auto fieldAddr = B.createRefElementAddr (
139
169
loc, actorSelf, var,
140
170
SGF.getLoweredType (var->getInterfaceType ()));
@@ -166,6 +196,7 @@ emitDistributedActor_init_transportStore(
166
196
SILValue transportArgValue = getActorTransportArgument (C, F, ctor);
167
197
168
198
// ----
199
+
169
200
auto transportFieldAddr = B.createRefElementAddr (
170
201
loc, borrowedSelfArg.getValue (), var,
171
202
SGF.getLoweredType (var->getInterfaceType ()));
@@ -187,6 +218,7 @@ static void emitDistributedActorStore_id(
187
218
SILValue actorSelf, AbstractFunctionDecl *func,
188
219
SILArgument *identityArg) {
189
220
auto &B = SGF.B ;
221
+
190
222
auto &SGM = SGF.SGM ;
191
223
SILGenFunctionBuilder builder (SGM);
192
224
@@ -237,7 +269,9 @@ static void emitDistributedActorStore_init_assignIdentity(
237
269
238
270
// --- Prepare the arguments
239
271
SILValue transportArgValue = getActorTransportArgument (C, F, ctor);
272
+
240
273
ProtocolDecl *distributedActorProto = C.getProtocol (KnownProtocolKind::DistributedActor);
274
+
241
275
assert (distributedActorProto);
242
276
assert (transportProto);
243
277
@@ -382,6 +416,7 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
382
416
383
417
void SILGenFunction::emitDistributedActorReady (
384
418
ConstructorDecl *ctor, ManagedValue selfArg) {
419
+
385
420
auto *dc = ctor->getDeclContext ();
386
421
auto classDecl = dc->getSelfClassDecl ();
387
422
auto &C = classDecl->getASTContext ();
@@ -462,6 +497,86 @@ void SILGenFunction::emitDistributedActorReady(
462
497
/* ****************** DISTRIBUTED ACTOR RESOLVE FUNCTION ***********************/
463
498
/* *****************************************************************************/
464
499
500
+ // / Synthesize the distributed actor's identity (`id`) initialization:
501
+ // /
502
+ // / \verbatim
503
+ // / transport.resolve(_, as:)
504
+ // / \endverbatim
505
+ static void createDistributedActorFactory_resolve (
506
+ SILGenFunction &SGF, ASTContext &C, FuncDecl *fd, SILValue identityValue,
507
+ SILValue transportValue, Type selfTy, SILValue selfMetatypeValue,
508
+ SILType resultTy, SILBasicBlock *normalBB, SILBasicBlock *errorBB) {
509
+ auto &B = SGF.B ;
510
+ auto &SGM = SGF.SGM ;
511
+ auto &F = SGF.F ;
512
+ SILGenFunctionBuilder builder (SGM);
513
+
514
+ auto loc = SILLocation (fd);
515
+ loc.markAutoGenerated ();
516
+
517
+ ProtocolDecl *distributedActorProto =
518
+ C.getProtocol (KnownProtocolKind::DistributedActor);
519
+ ProtocolDecl *transportProto =
520
+ C.getProtocol (KnownProtocolKind::ActorTransport);
521
+ assert (distributedActorProto);
522
+ assert (transportProto);
523
+
524
+ // // --- Open the transport existential
525
+ OpenedArchetypeType *Opened;
526
+ auto transportASTType = transportValue->getType ().getASTType ();
527
+ auto openedTransportType =
528
+ transportASTType->openAnyExistentialType (Opened)->getCanonicalType ();
529
+ auto openedTransportSILType = F.getLoweredType (openedTransportType);
530
+ auto transportArchetypeValue =
531
+ B.createOpenExistentialAddr (loc, transportValue, openedTransportSILType,
532
+ OpenedExistentialAccess::Immutable);
533
+
534
+ // --- prepare the witness_method
535
+ // Note: it does not matter on what module we perform the lookup,
536
+ // it is currently ignored. So the Stdlib module is good enough.
537
+ auto *module = SGF.getModule ().getSwiftModule ();
538
+
539
+ // the conformance here is just an abstract thing so we can simplify
540
+ auto transportConfRef = ProtocolConformanceRef (transportProto);
541
+ assert (!transportConfRef.isInvalid () &&
542
+ " Missing conformance to `ActorTransport`" );
543
+
544
+ auto distributedActorConfRef =
545
+ module->lookupConformance (selfTy, distributedActorProto);
546
+ assert (!distributedActorConfRef.isInvalid () &&
547
+ " Missing conformance to `DistributedActor`" );
548
+
549
+ auto resolveMethod =
550
+ cast<FuncDecl>(transportProto->getSingleRequirement (C.Id_resolve ));
551
+ auto resolveRef = SILDeclRef (resolveMethod, SILDeclRef::Kind::Func);
552
+ auto constantInfo =
553
+ SGF.getConstantInfo (SGF.getTypeExpansionContext (), resolveRef);
554
+ auto resolveSILTy = constantInfo.getSILType ();
555
+
556
+ auto resolveWitnessMethod =
557
+ B.createWitnessMethod (loc,
558
+ /* lookupTy*/ openedTransportType,
559
+ /* Conformance*/ transportConfRef,
560
+ /* member*/ resolveRef,
561
+ /* methodTy*/ resolveSILTy);
562
+
563
+ // // --- prepare conformance subs
564
+ auto genericSig = resolveMethod->getGenericSignature ();
565
+
566
+ SubstitutionMap subs =
567
+ SubstitutionMap::get (genericSig, {openedTransportType, selfTy},
568
+ {transportConfRef, distributedActorConfRef});
569
+
570
+ // // ---- actually call transport.resolve(id, as: Self.self)
571
+
572
+ SmallVector<SILValue, 3 > params;
573
+ params.push_back (identityValue);
574
+ params.push_back (selfMetatypeValue);
575
+ params.push_back (transportArchetypeValue); // self for the call, as last param
576
+
577
+ B.createTryApply (loc, resolveWitnessMethod, subs, params, normalBB, errorBB);
578
+ }
579
+
465
580
// / Function body of:
466
581
// / \verbatim
467
582
// / DistributedActor.resolve(
@@ -487,28 +602,66 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
487
602
assert (
488
603
transportArg->getType ().getASTType ()->isEqual (C.getActorTransportType ()));
489
604
490
- // --- Parameter: self
605
+ SILValue selfArgValue = F.getSelfArgument ();
606
+ ManagedValue selfArg = ManagedValue::forUnmanaged (selfArgValue);
607
+
608
+ // type: SpecificDistributedActor.Type
609
+ auto selfArgType = F.mapTypeIntoContext (selfArg.getType ().getASTType ());
610
+ auto selfMetatype = getLoweredType (selfArgType);
611
+ SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
612
+
613
+ // type: SpecificDistributedActor
491
614
auto *selfTyDecl = fd->getParent ()->getSelfNominalTypeDecl ();
492
615
assert (selfTyDecl->isDistributedActor ());
616
+ auto selfTy = F.mapTypeIntoContext (selfTyDecl->getDeclaredInterfaceType ());
617
+ auto returnTy = getLoweredType (selfTy);
493
618
494
- SILValue selfArgValue = F.getSelfArgument ();
495
- ManagedValue selfArg = ManagedValue::forUnmanaged (selfArgValue);
619
+ // ==== Prepare all the basic blocks
620
+ auto returnBB = createBasicBlock ();
621
+ auto resolvedBB = createBasicBlock ();
622
+ auto makeProxyBB = createBasicBlock ();
623
+ auto switchBB = createBasicBlock ();
624
+ auto errorBB = createBasicBlock ();
625
+
626
+ SILFunctionConventions fnConv = F.getConventions (); // TODO: no idea?
627
+
628
+ // --- get the uninitialized allocation from the runtime system.
629
+ FullExpr scope (Cleanups, CleanupLocation (fd));
630
+
631
+ auto optionalReturnTy = SILType::getOptionalType (returnTy);
496
632
497
- // ==== Case 'remote') Create the remote instance
633
+ // ==== Call `try transport.resolve(id, as: Self.self)`
498
634
{
499
- // ==== Create 'remote' distributed actor instance
500
- // --- Prepare param: Self.self
501
- // type: SpecificDistributedActor
502
- auto returnTy = getLoweredType (
503
- F.mapTypeIntoContext (selfTyDecl->getDeclaredInterfaceType ()));
635
+ createDistributedActorFactory_resolve (
636
+ *this , C, fd, identityArg, transportArg, selfTy, selfMetatypeValue,
637
+ optionalReturnTy, switchBB, errorBB);
638
+ }
639
+
640
+ // ==== switch resolved { ... }
641
+ {
642
+ B.emitBlock (switchBB);
643
+ auto resolve =
644
+ switchBB->createPhiArgument (optionalReturnTy, OwnershipKind::Owned);
645
+
646
+ B.createSwitchEnum (
647
+ loc, resolve, nullptr ,
648
+ {{C.getOptionalSomeDecl (), resolvedBB},
649
+ {std::make_pair (C.getOptionalNoneDecl (), makeProxyBB)}});
650
+ }
504
651
505
- // type: SpecificDistributedActor.Type
506
- auto selfMetatype =
507
- getLoweredType (F.mapTypeIntoContext (selfArg.getType ().getASTType ()));
508
- SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
652
+ // ==== Case 'some') return the resolved instance
653
+ {
654
+ B.emitBlock (resolvedBB);
655
+
656
+ auto local = resolvedBB->createPhiArgument (returnTy, OwnershipKind::Owned);
657
+
658
+ B.createBranch (loc, returnBB, {local});
659
+ }
509
660
510
- // --- get the uninitialized allocation from the runtime system.
511
- FullExpr scope (Cleanups, CleanupLocation (fd));
661
+ // ==== Case 'none') Create the remote instance
662
+ {
663
+ B.emitBlock (makeProxyBB);
664
+ // ==== Create 'remote' distributed actor instance
512
665
513
666
// --- Call: _distributedActorRemoteInitialize(Self.self)
514
667
auto builtinName = C.getIdentifier (
@@ -528,8 +681,32 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
528
681
emitDistributedActorStore_transport (
529
682
C, *this , /* actorSelf*/ remote, fd, transportArg);
530
683
531
- // ==== Return the fully initialized remote instance
532
- B.createReturn (loc, remote);
684
+ // ==== Branch to return the fully initialized remote instance
685
+ B.createBranch (loc, returnBB, {remote});
686
+ }
687
+
688
+ // --- Emit return logic
689
+ // return <remote>
690
+ {
691
+ B.emitBlock (returnBB);
692
+
693
+ auto local = returnBB->createPhiArgument (returnTy, OwnershipKind::Owned);
694
+
695
+ Cleanups.emitCleanupsForReturn (CleanupLocation (loc), NotForUnwind);
696
+ B.createReturn (loc, local);
697
+ }
698
+
699
+ // --- Emit rethrow logic
700
+ // throw error
701
+ {
702
+ B.emitBlock (errorBB);
703
+
704
+ auto error = errorBB->createPhiArgument (
705
+ fnConv.getSILErrorType (F.getTypeExpansionContext ()),
706
+ OwnershipKind::Owned);
707
+
708
+ Cleanups.emitCleanupsForReturn (CleanupLocation (loc), IsForUnwind);
709
+ B.createThrow (loc, error);
533
710
}
534
711
}
535
712
@@ -563,9 +740,8 @@ void SILGenFunction::emitDistributedActor_resignAddress(
563
740
getLoweredType (idVarDeclRef->getType ()));
564
741
565
742
// ==== locate: self.actorTransport
566
- auto transportVarDeclRefs = cd->lookupDirect (ctx.Id_actorTransport );
567
- assert (transportVarDeclRefs.size () == 1 );
568
- auto *transportVarDeclRef = dyn_cast<VarDecl>(transportVarDeclRefs.front ());
743
+ auto transportVarDeclRef = lookupActorTransportProperty (ctx, cd, selfValue);
744
+
569
745
auto transportRef =
570
746
B.createRefElementAddr (Loc, selfValue, transportVarDeclRef,
571
747
getLoweredType (transportVarDeclRef->getType ()));
0 commit comments