mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Distributed] Implementing calling transport in resolve and assigning id/transp
This commit is contained in:
@@ -87,12 +87,10 @@ lookupAssignIdentityFunc(ASTContext& C) {
|
||||
/// Synthesize the actorTransport initialization:
|
||||
///
|
||||
/// \verbatim
|
||||
/// // init(..., <transport>: ActorTransport) ... {
|
||||
/// self.actorTransport = transport
|
||||
/// // }
|
||||
/// self.actorTransport = <<constructor parameter:ActorTransport>>
|
||||
/// \endverbatim
|
||||
static void
|
||||
emitDistributedActorTransportInit(
|
||||
emitDistributedActor_init_transportStore(
|
||||
SILGenFunction &SGF,
|
||||
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
|
||||
ConstructorDecl *ctor,
|
||||
@@ -109,7 +107,6 @@ emitDistributedActorTransportInit(
|
||||
// ==== Prepare assignment: get the self.transport address
|
||||
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
|
||||
ManagedValue transportArgManaged = ManagedValue::forUnmanaged(transportArgValue);
|
||||
auto transportDecl = C.getActorTransportDecl();
|
||||
|
||||
// ----
|
||||
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
|
||||
@@ -124,15 +121,55 @@ emitDistributedActorTransportInit(
|
||||
IsNotTake, IsInitialization);
|
||||
}
|
||||
|
||||
/// Synthesize storing the passed in managed identity to the `id` property:
|
||||
///
|
||||
/// \verbatim
|
||||
/// self.id = <<parameter:identity>>
|
||||
/// \endverbatim
|
||||
static void
|
||||
emitDistributedActorIdentityStore(
|
||||
ASTContext& C, SILGenFunction &SGF,
|
||||
SILValue actorSelf, FuncDecl *func, SILArgument *identityArg) {
|
||||
auto &B = SGF.B;
|
||||
auto &F = SGF.F;
|
||||
auto &SGM = SGF.SGM;
|
||||
SILGenFunctionBuilder builder(SGM);
|
||||
|
||||
auto *dc = func->getDeclContext();
|
||||
auto classDecl = dc->getSelfClassDecl();
|
||||
assert(classDecl->isDistributedActor());
|
||||
|
||||
auto loc = SILLocation(func);
|
||||
loc.markAutoGenerated();
|
||||
|
||||
// ==== Prepare the property reference: self.id
|
||||
auto idVars = classDecl->lookupDirect(C.Id_id);
|
||||
assert(idVars.size() == 1);
|
||||
auto *idVar = dyn_cast<VarDecl>(idVars.front());
|
||||
|
||||
// ==== Prepare assignment
|
||||
// SILValue identityArgValue = identityArg->getValue();
|
||||
fprintf(stderr, "[%s:%d] (%s) THE ACTOR SELF\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
actorSelf->dump();
|
||||
|
||||
SILValue identityArgValue = identityArg;
|
||||
auto idFieldAddr = B.createRefElementAddr(
|
||||
loc, actorSelf, idVar,
|
||||
SGF.getLoweredType(idVar->getInterfaceType()));
|
||||
|
||||
// ==== Store the transport
|
||||
B.createCopyAddr(loc,
|
||||
/*src*/identityArgValue,
|
||||
/*dest*/idFieldAddr,
|
||||
IsNotTake, IsInitialization); // TODO(distributed): should it be take?
|
||||
}
|
||||
|
||||
/// Synthesize the distributed actor's identity (`id`) initialization:
|
||||
///
|
||||
/// \verbatim
|
||||
/// // init(..., <transport>: ActorTransport) ... {
|
||||
/// self.id = transport.assignIdentity(Self.self)
|
||||
/// // }
|
||||
/// \endverbatim
|
||||
static void
|
||||
emitDistributedActorIdentityInit(
|
||||
static void emitDistributedActorIdentity_init_assignIdentity(
|
||||
SILGenFunction &SGF,
|
||||
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
|
||||
ConstructorDecl *ctor,
|
||||
@@ -198,8 +235,6 @@ emitDistributedActorIdentityInit(
|
||||
distributedActorProto);
|
||||
assert(!distributedActorConfRef.isInvalid() && "Missing conformance to `DistributedActor`");
|
||||
|
||||
// auto anyActorIdentityDecl = C.getAnyActorIdentityDecl();
|
||||
|
||||
auto assignIdentityMethod =
|
||||
cast<FuncDecl>(transportProto->getSingleRequirement(C.Id_assignIdentity));
|
||||
auto assignIdentityRef = SILDeclRef(assignIdentityMethod, SILDeclRef::Kind::Func);
|
||||
@@ -252,11 +287,8 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
|
||||
auto &C = classDecl->getASTContext();
|
||||
|
||||
// Only designated initializers get the lifecycle handling injected
|
||||
if (!ctor->isDesignatedInit()) {
|
||||
fprintf(stderr, "[%s:%d] (%s) NOT DESIGNATED INIT SKIP\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (!ctor->isDesignatedInit())
|
||||
return;
|
||||
}
|
||||
|
||||
SILLocation prologueLoc = RegularLocation(ctor);
|
||||
prologueLoc.markAsPrologue(); // TODO: no idea if this is necessary or makes sense
|
||||
@@ -284,12 +316,14 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
|
||||
if (var->getName() == C.Id_actorTransport &&
|
||||
var->getInterfaceType()->isEqual(transportTy)) {
|
||||
transportMember = var;
|
||||
emitDistributedActorTransportInit(*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
||||
emitDistributedActor_init_transportStore(
|
||||
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
||||
} else if (var->getName() == C.Id_id &&
|
||||
(var->getInterfaceType()->isEqual(identityProtoTy) ||
|
||||
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
|
||||
idMember = var;
|
||||
emitDistributedActorIdentityInit(*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
||||
emitDistributedActorIdentity_init_assignIdentity(
|
||||
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
||||
}
|
||||
if (transportMember && idMember) {
|
||||
break; // we found all properties we care about, break out of the loop early
|
||||
@@ -305,6 +339,146 @@ void SILGenFunction::emitDistributedActorReady(
|
||||
// TODO(distributed): implement actorReady call
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************* DISTRIBUTED ACTOR RESOLVE FUNCTION ***********************/
|
||||
/******************************************************************************/
|
||||
|
||||
/// Function body of:
|
||||
/// \verbatim
|
||||
/// DistributedActor.resolve(
|
||||
/// _ identity: Identity,
|
||||
/// using transport: ActorTransport
|
||||
/// ) throws -> Self where Identity: ActorIdentity
|
||||
/// \endverbatim
|
||||
void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
|
||||
/// NOTE: this will only be reached if the resolve function is actually
|
||||
/// demanded. For example, by declaring the actor as `public` or
|
||||
/// having at least one call to the resolve function.
|
||||
|
||||
auto &C = getASTContext();
|
||||
SILLocation loc = fd;
|
||||
|
||||
fd->dump();
|
||||
F.dump();
|
||||
|
||||
// ==== Prepare argument references
|
||||
// --- Parameter: identity
|
||||
SILArgument *identityArg = F.getArgument(0);
|
||||
assert(identityArg->getType().getASTType()->isEqual(C.getAnyActorIdentityType()));
|
||||
|
||||
// --- Parameter: transport
|
||||
SILArgument *transportArg = F.getArgument(1); // existential
|
||||
assert(
|
||||
transportArg->getType().getASTType()->isEqual(C.getActorTransportType()));
|
||||
|
||||
// --- Parameter: self
|
||||
// ClassDecl *selfDecl = cast<ClassDecl>(fd->getDeclContext()->getAsDecl());
|
||||
auto *selfTyDecl = fd->getParent()->getSelfNominalTypeDecl();
|
||||
assert(selfTyDecl->isDistributedActor());
|
||||
auto selfTy = F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()); // TODO: thats just self var devl getType
|
||||
|
||||
// ManagedValue selfArg = B.createInputFunctionArgument(selfTy, selfDecl);
|
||||
VarDecl *selfVarDecl = fd->getImplicitSelfDecl();
|
||||
|
||||
SILValue selfArgValue = F.getSelfArgument();
|
||||
ManagedValue selfArg = ManagedValue::forUnmanaged(selfArgValue);
|
||||
|
||||
// // ==== Prepare all the basic blocks
|
||||
// auto returnBB = createBasicBlock();
|
||||
// auto errorBB = createBasicBlock();
|
||||
|
||||
SILFunctionConventions fnConv = F.getConventions(); // TODO: no idea?
|
||||
|
||||
// TODO(distributed): call the transport 'transport.resolve(identity)'
|
||||
// TODO(distributed): switch over result to determine if local or remote
|
||||
// NOTES: to make that call on the transport we need to open tne existential
|
||||
// but we already do such things in in the initializer synthesis (in this file)
|
||||
// so we can steal that code, it's fairly easy once we know how.
|
||||
//
|
||||
// That call is throwing, so we may need to cover it with some try?
|
||||
|
||||
// ==== Case 'local') return the resolved instance
|
||||
// {
|
||||
// auto local = ...
|
||||
// // TODO(distributed): 'case .resolved(let instance): return instance'
|
||||
// // ==== Return the fully initialized 'remote' instance
|
||||
// B.createReturn(loc, local);
|
||||
// }
|
||||
|
||||
// ==== Case 'remote') Create the remote instance
|
||||
{
|
||||
// ==== Create 'remote' distributed actor instance
|
||||
// --- Prepare arguments to remote actor initialization builtin
|
||||
// auto borrowedSelfArg = selfArg.borrow(*this, loc);
|
||||
|
||||
// --- Prepare param: Self.self
|
||||
// type: SpecificDistributedActor
|
||||
auto returnTy = getLoweredType(
|
||||
F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()));
|
||||
fprintf(stderr, "[%s:%d] (%s) auto returnTy = selfArg.getType().getDeclaredInterfaceType();\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
returnTy.dump();
|
||||
|
||||
// type: SpecificDistributedActor.Type
|
||||
auto selfMetatype =
|
||||
getLoweredType(F.mapTypeIntoContext(selfArg.getType().getASTType()));
|
||||
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);
|
||||
|
||||
// --- get the uninitialized allocation from the runtime system.
|
||||
FullExpr scope(Cleanups, CleanupLocation(fd));
|
||||
|
||||
// --- Call: _distributedActorRemoteInitialize(Self.self)
|
||||
auto builtinName = C.getIdentifier(
|
||||
getBuiltinName(BuiltinValueKind::InitializeDistributedRemoteActor));
|
||||
auto *remote = B.createBuiltin(
|
||||
loc, builtinName,
|
||||
/*returnTy*/returnTy,
|
||||
/*subs*/ {},
|
||||
{selfMetatypeValue});
|
||||
|
||||
// ==== Initialize identity and transport
|
||||
// --- Store the identity: self.id = identity
|
||||
emitDistributedActorIdentityStore(
|
||||
C, *this, /*actorSelf*/remote, fd, identityArg);
|
||||
|
||||
// --- Store the transport: self.transport = transport
|
||||
// FIXME(distributed): IMPLEMENT:
|
||||
// emitDistributedActorTransportStore(
|
||||
// *this, borrowedSelfArg, selfVarDecl, fd, transportArg);
|
||||
|
||||
// ==== Return the fully initialized remote instance
|
||||
B.createReturn(loc, remote);
|
||||
|
||||
// // ==== Branch to return the fully initialized remote instance
|
||||
// B.createBranch(loc, returnBB, {remote});
|
||||
//
|
||||
// // --- Emit return logic
|
||||
// // return <remote>
|
||||
// {
|
||||
// B.emitBlock(returnBB);
|
||||
// SILValue result = returnBB->createPhiArgument(
|
||||
// returnTy, OwnershipKind::Owned);
|
||||
//
|
||||
// B.createReturn(loc, result);
|
||||
// }
|
||||
//
|
||||
// // --- Emit rethrow logic
|
||||
// // throw error
|
||||
// {
|
||||
// B.emitBlock(errorBB);
|
||||
//
|
||||
// SILValue error = errorBB->createPhiArgument(
|
||||
// fnConv.getSILErrorType(getTypeExpansionContext()),
|
||||
// OwnershipKind::Owned);
|
||||
//
|
||||
// Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind);
|
||||
// B.createThrow(loc, error);
|
||||
// }
|
||||
}
|
||||
|
||||
fprintf(stderr, "[%s:%d] (%s) DONE HERE\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
F.dump();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************* DISTRIBUTED DEINIT: resignAddress ************************/
|
||||
/******************************************************************************/
|
||||
@@ -364,7 +538,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
|
||||
|
||||
bindParametersForForwarding(fd->getParameters(), params);
|
||||
bindParameterForForwarding(selfVarDecl, params);
|
||||
auto selfValue = ManagedValue::forUnmanaged(params[params.size() - 1]);
|
||||
auto selfValue = ManagedValue::forUnmanaged(params[params.size() - 1]); // TODO(distributed): getSelfArgument instead
|
||||
auto selfType = selfVarDecl->getType();
|
||||
|
||||
// if __isRemoteActor(self) {
|
||||
|
||||
Reference in New Issue
Block a user