Skip to content

Commit 7e0a3eb

Browse files
committed
[Distributed] Implementing calling transport in resolve and assigning id/transp
1 parent a965abd commit 7e0a3eb

15 files changed

+276
-122
lines changed

include/swift/AST/Builtins.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ BUILTIN_MISC_OPERATION(InitializeDefaultActor, "initializeDefaultActor", "", Spe
727727
/// Destroy the default-actor instance in a default actor object.
728728
BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
729729

730-
/// Allocate a "proxy" for a distributed remote actor. TODO(distributed) change the naming throughout.
730+
/// Allocate a "proxy" for a distributed remote actor. TODO(distributed) change the name of this to create throughout.
731731
BUILTIN_MISC_OPERATION(InitializeDistributedRemoteActor,
732732
"initializeDistributedRemoteActor", "", Special)
733733

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ IDENTIFIER(assignIdentity)
258258
IDENTIFIER(resignIdentity)
259259
IDENTIFIER(resolve)
260260
IDENTIFIER(id)
261+
IDENTIFIER(identity)
261262
IDENTIFIER(identifier)
262263
IDENTIFIER(_distributedActorRemoteInitialize)
263264
IDENTIFIER(_distributedActorDestroy)

include/swift/Runtime/Concurrency.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -716,18 +716,9 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
716716
void swift_defaultActor_deallocateResilient(HeapObject *actor);
717717

718718
/// Initialize the runtime storage for a distributed remote actor.
719-
// TODO: this may end up being removed as we move to the "proxy creation" below
720719
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
721-
void swift_distributedActor_remote_initialize(DefaultActor *actor);
722-
723-
/// Create a proxy object that will serve as remote distributed actor instance.
724-
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
725-
OpaqueValue* swift_distributedActor_remote_create(
726-
/* +1 */OpaqueValue *identity,
727-
/* +1 */OpaqueValue *transport
728-
// metadata for identity
729-
// metadata for transport
730-
);
720+
OpaqueValue*
721+
swift_distributedActor_remote_initialize(const Metadata *actorType);
731722

732723
/// Destroy the runtime storage for a default actor.
733724
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,9 @@ FUNCTION(DefaultActorDeallocateResilient,
16871687
ARGS(RefCountedPtrTy),
16881688
ATTRS(NoUnwind))
16891689

1690-
// void swift_distributedActor_remote_initialize(const Metadata *actorType);
1690+
// OpaqueValue* swift_distributedActor_remote_initialize(
1691+
// const Metadata *actorType
1692+
// );
16911693
FUNCTION(DistributedActorInitializeRemote,
16921694
swift_distributedActor_remote_initialize, SwiftCC,
16931695
ConcurrencyAvailability,

lib/AST/Builtins.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,14 @@ static ValueDecl *getDefaultActorInitDestroy(ASTContext &ctx,
14621462
_void);
14631463
}
14641464

1465-
static ValueDecl *getDistributedActorInitDestroy(ASTContext &ctx,
1465+
static ValueDecl *getDistributedActorInitializeRemote(ASTContext &ctx,
1466+
Identifier id) {
1467+
return getBuiltinFunction(ctx, id, _thin,
1468+
_parameters(_nativeObject),
1469+
_rawPointer);
1470+
}
1471+
1472+
static ValueDecl *getDistributedActorDestroy(ASTContext &ctx,
14661473
Identifier id) {
14671474
return getBuiltinFunction(ctx, id, _thin,
14681475
_parameters(_nativeObject), // TODO: no idea if to pass more here?
@@ -2808,8 +2815,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
28082815
return getDefaultActorInitDestroy(Context, Id);
28092816

28102817
case BuiltinValueKind::InitializeDistributedRemoteActor:
2818+
return getDistributedActorInitializeRemote(Context, Id);
2819+
28112820
case BuiltinValueKind::DestroyDistributedActor:
2812-
return getDistributedActorInitDestroy(Context, Id);
2821+
return getDistributedActorDestroy(Context, Id);
28132822

28142823
case BuiltinValueKind::StartAsyncLet:
28152824
case BuiltinValueKind::StartAsyncLetWithLocalBuffer:

lib/SILGen/SILGenConstructor.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,29 +1197,3 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
11971197
emitEpilog(loc);
11981198
}
11991199

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-
1206-
SILLocation loc = fd; // NOTE: forgot if this is the right one for all locs.
1207-
ClassDecl *actor = cast<ClassDecl>(fd->getDeclContext()->getAsDecl());
1208-
assert(actor->isDistributedActor());
1209-
1210-
// Step 1: get the uninitialized allocation from the runtime system.
1211-
auto &ctx = getASTContext();
1212-
auto builtinName = ctx.getIdentifier(
1213-
getBuiltinName(BuiltinValueKind::InitializeDistributedRemoteActor));
1214-
auto returnType = getLoweredType(actor->getInterfaceType());
1215-
auto *metaTypeInfo = F.getArgument(0);
1216-
1217-
FullExpr scope(Cleanups, CleanupLocation(fd));
1218-
auto *result = B.createBuiltin(loc, builtinName, returnType, /*subs*/{},
1219-
{ metaTypeInfo });
1220-
1221-
// TODO: initialize the id and transport fields
1222-
1223-
1224-
B.createReturn(loc, result);
1225-
}

lib/SILGen/SILGenDistributed.cpp

Lines changed: 192 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,10 @@ lookupAssignIdentityFunc(ASTContext& C) {
8787
/// Synthesize the actorTransport initialization:
8888
///
8989
/// \verbatim
90-
/// // init(..., <transport>: ActorTransport) ... {
91-
/// self.actorTransport = transport
92-
/// // }
90+
/// self.actorTransport = <<constructor parameter:ActorTransport>>
9391
/// \endverbatim
9492
static void
95-
emitDistributedActorTransportInit(
93+
emitDistributedActor_init_transportStore(
9694
SILGenFunction &SGF,
9795
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
9896
ConstructorDecl *ctor,
@@ -109,7 +107,6 @@ emitDistributedActorTransportInit(
109107
// ==== Prepare assignment: get the self.transport address
110108
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
111109
ManagedValue transportArgManaged = ManagedValue::forUnmanaged(transportArgValue);
112-
auto transportDecl = C.getActorTransportDecl();
113110

114111
// ----
115112
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
@@ -124,15 +121,55 @@ emitDistributedActorTransportInit(
124121
IsNotTake, IsInitialization);
125122
}
126123

124+
/// Synthesize storing the passed in managed identity to the `id` property:
125+
///
126+
/// \verbatim
127+
/// self.id = <<parameter:identity>>
128+
/// \endverbatim
129+
static void
130+
emitDistributedActorIdentityStore(
131+
ASTContext& C, SILGenFunction &SGF,
132+
SILValue actorSelf, FuncDecl *func, SILArgument *identityArg) {
133+
auto &B = SGF.B;
134+
auto &F = SGF.F;
135+
auto &SGM = SGF.SGM;
136+
SILGenFunctionBuilder builder(SGM);
137+
138+
auto *dc = func->getDeclContext();
139+
auto classDecl = dc->getSelfClassDecl();
140+
assert(classDecl->isDistributedActor());
141+
142+
auto loc = SILLocation(func);
143+
loc.markAutoGenerated();
144+
145+
// ==== Prepare the property reference: self.id
146+
auto idVars = classDecl->lookupDirect(C.Id_id);
147+
assert(idVars.size() == 1);
148+
auto *idVar = dyn_cast<VarDecl>(idVars.front());
149+
150+
// ==== Prepare assignment
151+
// SILValue identityArgValue = identityArg->getValue();
152+
fprintf(stderr, "[%s:%d] (%s) THE ACTOR SELF\n", __FILE__, __LINE__, __FUNCTION__);
153+
actorSelf->dump();
154+
155+
SILValue identityArgValue = identityArg;
156+
auto idFieldAddr = B.createRefElementAddr(
157+
loc, actorSelf, idVar,
158+
SGF.getLoweredType(idVar->getInterfaceType()));
159+
160+
// ==== Store the transport
161+
B.createCopyAddr(loc,
162+
/*src*/identityArgValue,
163+
/*dest*/idFieldAddr,
164+
IsNotTake, IsInitialization); // TODO(distributed): should it be take?
165+
}
166+
127167
/// Synthesize the distributed actor's identity (`id`) initialization:
128168
///
129169
/// \verbatim
130-
/// // init(..., <transport>: ActorTransport) ... {
131170
/// self.id = transport.assignIdentity(Self.self)
132-
/// // }
133171
/// \endverbatim
134-
static void
135-
emitDistributedActorIdentityInit(
172+
static void emitDistributedActorIdentity_init_assignIdentity(
136173
SILGenFunction &SGF,
137174
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
138175
ConstructorDecl *ctor,
@@ -198,8 +235,6 @@ emitDistributedActorIdentityInit(
198235
distributedActorProto);
199236
assert(!distributedActorConfRef.isInvalid() && "Missing conformance to `DistributedActor`");
200237

201-
// auto anyActorIdentityDecl = C.getAnyActorIdentityDecl();
202-
203238
auto assignIdentityMethod =
204239
cast<FuncDecl>(transportProto->getSingleRequirement(C.Id_assignIdentity));
205240
auto assignIdentityRef = SILDeclRef(assignIdentityMethod, SILDeclRef::Kind::Func);
@@ -252,11 +287,8 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
252287
auto &C = classDecl->getASTContext();
253288

254289
// Only designated initializers get the lifecycle handling injected
255-
if (!ctor->isDesignatedInit()) {
256-
fprintf(stderr, "[%s:%d] (%s) NOT DESIGNATED INIT SKIP\n", __FILE__, __LINE__, __FUNCTION__);
257-
290+
if (!ctor->isDesignatedInit())
258291
return;
259-
}
260292

261293
SILLocation prologueLoc = RegularLocation(ctor);
262294
prologueLoc.markAsPrologue(); // TODO: no idea if this is necessary or makes sense
@@ -284,12 +316,14 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
284316
if (var->getName() == C.Id_actorTransport &&
285317
var->getInterfaceType()->isEqual(transportTy)) {
286318
transportMember = var;
287-
emitDistributedActorTransportInit(*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
319+
emitDistributedActor_init_transportStore(
320+
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
288321
} else if (var->getName() == C.Id_id &&
289322
(var->getInterfaceType()->isEqual(identityProtoTy) ||
290323
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
291324
idMember = var;
292-
emitDistributedActorIdentityInit(*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
325+
emitDistributedActorIdentity_init_assignIdentity(
326+
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
293327
}
294328
if (transportMember && idMember) {
295329
break; // we found all properties we care about, break out of the loop early
@@ -305,6 +339,146 @@ void SILGenFunction::emitDistributedActorReady(
305339
// TODO(distributed): implement actorReady call
306340
}
307341

342+
/******************************************************************************/
343+
/******************* DISTRIBUTED ACTOR RESOLVE FUNCTION ***********************/
344+
/******************************************************************************/
345+
346+
/// Function body of:
347+
/// \verbatim
348+
/// DistributedActor.resolve(
349+
/// _ identity: Identity,
350+
/// using transport: ActorTransport
351+
/// ) throws -> Self where Identity: ActorIdentity
352+
/// \endverbatim
353+
void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
354+
/// NOTE: this will only be reached if the resolve function is actually
355+
/// demanded. For example, by declaring the actor as `public` or
356+
/// having at least one call to the resolve function.
357+
358+
auto &C = getASTContext();
359+
SILLocation loc = fd;
360+
361+
fd->dump();
362+
F.dump();
363+
364+
// ==== Prepare argument references
365+
// --- Parameter: identity
366+
SILArgument *identityArg = F.getArgument(0);
367+
assert(identityArg->getType().getASTType()->isEqual(C.getAnyActorIdentityType()));
368+
369+
// --- Parameter: transport
370+
SILArgument *transportArg = F.getArgument(1); // existential
371+
assert(
372+
transportArg->getType().getASTType()->isEqual(C.getActorTransportType()));
373+
374+
// --- Parameter: self
375+
// ClassDecl *selfDecl = cast<ClassDecl>(fd->getDeclContext()->getAsDecl());
376+
auto *selfTyDecl = fd->getParent()->getSelfNominalTypeDecl();
377+
assert(selfTyDecl->isDistributedActor());
378+
auto selfTy = F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()); // TODO: thats just self var devl getType
379+
380+
// ManagedValue selfArg = B.createInputFunctionArgument(selfTy, selfDecl);
381+
VarDecl *selfVarDecl = fd->getImplicitSelfDecl();
382+
383+
SILValue selfArgValue = F.getSelfArgument();
384+
ManagedValue selfArg = ManagedValue::forUnmanaged(selfArgValue);
385+
386+
// // ==== Prepare all the basic blocks
387+
// auto returnBB = createBasicBlock();
388+
// auto errorBB = createBasicBlock();
389+
390+
SILFunctionConventions fnConv = F.getConventions(); // TODO: no idea?
391+
392+
// TODO(distributed): call the transport 'transport.resolve(identity)'
393+
// TODO(distributed): switch over result to determine if local or remote
394+
// NOTES: to make that call on the transport we need to open tne existential
395+
// but we already do such things in in the initializer synthesis (in this file)
396+
// so we can steal that code, it's fairly easy once we know how.
397+
//
398+
// That call is throwing, so we may need to cover it with some try?
399+
400+
// ==== Case 'local') return the resolved instance
401+
// {
402+
// auto local = ...
403+
// // TODO(distributed): 'case .resolved(let instance): return instance'
404+
// // ==== Return the fully initialized 'remote' instance
405+
// B.createReturn(loc, local);
406+
// }
407+
408+
// ==== Case 'remote') Create the remote instance
409+
{
410+
// ==== Create 'remote' distributed actor instance
411+
// --- Prepare arguments to remote actor initialization builtin
412+
// auto borrowedSelfArg = selfArg.borrow(*this, loc);
413+
414+
// --- Prepare param: Self.self
415+
// type: SpecificDistributedActor
416+
auto returnTy = getLoweredType(
417+
F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()));
418+
fprintf(stderr, "[%s:%d] (%s) auto returnTy = selfArg.getType().getDeclaredInterfaceType();\n", __FILE__, __LINE__, __FUNCTION__);
419+
returnTy.dump();
420+
421+
// type: SpecificDistributedActor.Type
422+
auto selfMetatype =
423+
getLoweredType(F.mapTypeIntoContext(selfArg.getType().getASTType()));
424+
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);
425+
426+
// --- get the uninitialized allocation from the runtime system.
427+
FullExpr scope(Cleanups, CleanupLocation(fd));
428+
429+
// --- Call: _distributedActorRemoteInitialize(Self.self)
430+
auto builtinName = C.getIdentifier(
431+
getBuiltinName(BuiltinValueKind::InitializeDistributedRemoteActor));
432+
auto *remote = B.createBuiltin(
433+
loc, builtinName,
434+
/*returnTy*/returnTy,
435+
/*subs*/ {},
436+
{selfMetatypeValue});
437+
438+
// ==== Initialize identity and transport
439+
// --- Store the identity: self.id = identity
440+
emitDistributedActorIdentityStore(
441+
C, *this, /*actorSelf*/remote, fd, identityArg);
442+
443+
// --- Store the transport: self.transport = transport
444+
// FIXME(distributed): IMPLEMENT:
445+
// emitDistributedActorTransportStore(
446+
// *this, borrowedSelfArg, selfVarDecl, fd, transportArg);
447+
448+
// ==== Return the fully initialized remote instance
449+
B.createReturn(loc, remote);
450+
451+
// // ==== Branch to return the fully initialized remote instance
452+
// B.createBranch(loc, returnBB, {remote});
453+
//
454+
// // --- Emit return logic
455+
// // return <remote>
456+
// {
457+
// B.emitBlock(returnBB);
458+
// SILValue result = returnBB->createPhiArgument(
459+
// returnTy, OwnershipKind::Owned);
460+
//
461+
// B.createReturn(loc, result);
462+
// }
463+
//
464+
// // --- Emit rethrow logic
465+
// // throw error
466+
// {
467+
// B.emitBlock(errorBB);
468+
//
469+
// SILValue error = errorBB->createPhiArgument(
470+
// fnConv.getSILErrorType(getTypeExpansionContext()),
471+
// OwnershipKind::Owned);
472+
//
473+
// Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind);
474+
// B.createThrow(loc, error);
475+
// }
476+
}
477+
478+
fprintf(stderr, "[%s:%d] (%s) DONE HERE\n", __FILE__, __LINE__, __FUNCTION__);
479+
F.dump();
480+
}
481+
308482
/******************************************************************************/
309483
/******************* DISTRIBUTED DEINIT: resignAddress ************************/
310484
/******************************************************************************/
@@ -364,7 +538,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
364538

365539
bindParametersForForwarding(fd->getParameters(), params);
366540
bindParameterForForwarding(selfVarDecl, params);
367-
auto selfValue = ManagedValue::forUnmanaged(params[params.size() - 1]);
541+
auto selfValue = ManagedValue::forUnmanaged(params[params.size() - 1]); // TODO(distributed): getSelfArgument instead
368542
auto selfType = selfVarDecl->getType();
369543

370544
// if __isRemoteActor(self) {

0 commit comments

Comments
 (0)