Skip to content

Commit c49f7d0

Browse files
kavonktoso
authored andcommitted
[distributed] synthesize factory resolve func
1 parent 89629fe commit c49f7d0

File tree

5 files changed

+67
-54
lines changed

5 files changed

+67
-54
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6127,6 +6127,14 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
61276127
&& getSILSynthesizeKind() == SILSynthesizeKind::MemberwiseInitializer;
61286128
}
61296129

6130+
/// Determines whether this function represents a distributed actor
6131+
/// initialization factory. Such functions do not have a body that is
6132+
/// representable in the AST, so it must be synthesized during SILGen.
6133+
bool isDistributedActorFactory() const {
6134+
return getBodyKind() == BodyKind::SILSynthesize
6135+
&& getSILSynthesizeKind() == SILSynthesizeKind::DistributedActorFactory;
6136+
}
6137+
61306138
/// For a method of a class, checks whether it will require a new entry in the
61316139
/// vtable.
61326140
bool needsNewVTableEntry() const;

lib/SILGen/SILGenConstructor.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,3 +1196,11 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
11961196

11971197
emitEpilog(loc);
11981198
}
1199+
1200+
1201+
void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
1202+
/// NOTE: this will only be reached if the resolve function is actually
1203+
/// demanded. For example, by declaring the actor as `public` or
1204+
/// having at least one call to the resolve init.
1205+
llvm_unreachable("TODO: implement emitDistributedActorFactory");
1206+
}

lib/SILGen/SILGenFunction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,11 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
510510
void SILGenFunction::emitFunction(FuncDecl *fd) {
511511
MagicFunctionName = SILGenModule::getMagicFunctionName(fd);
512512

513+
if (fd->isDistributedActorFactory()) {
514+
emitDistributedActorFactory(fd);
515+
return;
516+
}
517+
513518
auto captureInfo = SGM.M.Types.getLoweredLocalCaptures(SILDeclRef(fd));
514519
emitProfilerIncrement(fd->getTypecheckedBody());
515520
emitProlog(captureInfo, fd->getParameters(), fd->getImplicitSelfDecl(), fd,

lib/SILGen/SILGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
625625
/// destructor, then implicitly releases the elements of the class.
626626
void emitDestroyingDestructor(DestructorDecl *dd);
627627

628+
/// Given a function representing a distributed actor factory, emits the
629+
/// corresponding SIL function for it.
630+
void emitDistributedActorFactory(FuncDecl *fd);
631+
628632
/// Generates code for an artificial top-level function that starts an
629633
/// application based on a main type and optionally a main type.
630634
void emitArtificialTopLevel(Decl *mainDecl);

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -47,61 +47,49 @@ using namespace swift;
4747
/// expected to be filled-in during SILGen.
4848
static void addFactoryResolveFunction(ClassDecl *decl) {
4949
assert(decl->isDistributedActor());
50-
auto &ctx = decl->getASTContext();
50+
auto &C = decl->getASTContext();
5151

52-
{
53-
auto &C = ctx;
54-
auto conformanceDC = decl;
55-
56-
// Expected type: (Self) -> (ActorAddress, ActorTransport) -> (Self)
57-
//
58-
// Param: (resolve address: AnyActorAddress)
59-
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
60-
auto *idParamDecl = new (C) ParamDecl(
61-
SourceLoc(), SourceLoc(), C.Id_resolve,
62-
SourceLoc(), C.Id_id, conformanceDC);
63-
idParamDecl->setImplicit();
64-
idParamDecl->setSpecifier(ParamSpecifier::Default);
65-
idParamDecl->setInterfaceType(addressType);
66-
67-
// Param: (using transport: ActorTransport)
68-
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
69-
auto *transportParamDecl = new (C) ParamDecl(
70-
SourceLoc(), SourceLoc(), C.Id_using,
71-
SourceLoc(), C.Id_transport, conformanceDC);
72-
transportParamDecl->setImplicit();
73-
transportParamDecl->setSpecifier(ParamSpecifier::Default);
74-
transportParamDecl->setInterfaceType(transportType);
75-
76-
auto *paramList = ParameterList::create(
77-
C,
78-
/*LParenLoc=*/SourceLoc(),
79-
/*params=*/{idParamDecl, transportParamDecl},
80-
/*RParenLoc=*/SourceLoc()
81-
);
82-
83-
// Func name: init(resolve:using:)
84-
DeclName name(C, DeclBaseName::createConstructor(), paramList);
85-
86-
auto *initDecl =
87-
new (C) ConstructorDecl(name, SourceLoc(),
88-
/*Failable=*/false, SourceLoc(),
89-
/*Async=*/false, SourceLoc(),
90-
/*Throws=*/true, SourceLoc(),
91-
paramList,
92-
/*GenericParams=*/nullptr, conformanceDC);
93-
initDecl->setImplicit();
94-
// TODO: determine how to mark this as being synthesized by SILGen.
95-
// initDecl->setSynthesized();
96-
// initDecl->setBodySynthesizer(&createDistributedActor_init_resolve_body);
97-
98-
auto *nonIsoAttr = new (C) NonisolatedAttr(/*IsImplicit*/true);
99-
initDecl->getAttrs().add(nonIsoAttr);
100-
101-
initDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
102-
103-
decl->addMember(initDecl);
104-
}
52+
auto mkParam = [&](Identifier argName, Identifier paramName, Type ty) -> ParamDecl* {
53+
auto *param = new (C) ParamDecl(SourceLoc(),
54+
SourceLoc(), argName,
55+
SourceLoc(), paramName, decl);
56+
param->setImplicit();
57+
param->setSpecifier(ParamSpecifier::Default);
58+
param->setInterfaceType(ty);
59+
return param;
60+
};
61+
62+
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
63+
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
64+
65+
// (_ id: AnyActorAddress, using transport: ActorTransport)
66+
auto *params = ParameterList::create(
67+
C,
68+
/*LParenLoc=*/SourceLoc(),
69+
/*params=*/{ mkParam(Identifier(), C.Id_id, addressType),
70+
mkParam(C.Id_using, C.Id_transport, transportType)
71+
},
72+
/*RParenLoc=*/SourceLoc()
73+
);
74+
75+
// Func name: resolve(_:using:)
76+
DeclName name(C, C.Id_resolve, params);
77+
78+
// Expected type: (Self) -> (ActorAddress, ActorTransport) throws -> (Self)
79+
auto *factoryDecl =
80+
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
81+
name, SourceLoc(),
82+
/*async=*/false,
83+
/*throws=*/true,
84+
/*genericParams=*/nullptr,
85+
params,
86+
/*returnType*/decl->getDeclaredInterfaceType(),
87+
decl);
88+
89+
factoryDecl->setDistributedActorFactory();
90+
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
91+
92+
decl->addMember(factoryDecl);
10593
}
10694

10795
/// Synthesizes an empty body of the `init(transport:)` initializer as:

0 commit comments

Comments
 (0)