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:
@@ -727,7 +727,7 @@ BUILTIN_MISC_OPERATION(InitializeDefaultActor, "initializeDefaultActor", "", Spe
|
|||||||
/// Destroy the default-actor instance in a default actor object.
|
/// Destroy the default-actor instance in a default actor object.
|
||||||
BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
|
BUILTIN_MISC_OPERATION(DestroyDefaultActor, "destroyDefaultActor", "", Special)
|
||||||
|
|
||||||
/// Allocate a "proxy" for a distributed remote actor. TODO(distributed) change the naming throughout.
|
/// Allocate a "proxy" for a distributed remote actor. TODO(distributed) change the name of this to create throughout.
|
||||||
BUILTIN_MISC_OPERATION(InitializeDistributedRemoteActor,
|
BUILTIN_MISC_OPERATION(InitializeDistributedRemoteActor,
|
||||||
"initializeDistributedRemoteActor", "", Special)
|
"initializeDistributedRemoteActor", "", Special)
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ IDENTIFIER(assignIdentity)
|
|||||||
IDENTIFIER(resignIdentity)
|
IDENTIFIER(resignIdentity)
|
||||||
IDENTIFIER(resolve)
|
IDENTIFIER(resolve)
|
||||||
IDENTIFIER(id)
|
IDENTIFIER(id)
|
||||||
|
IDENTIFIER(identity)
|
||||||
IDENTIFIER(identifier)
|
IDENTIFIER(identifier)
|
||||||
IDENTIFIER(_distributedActorRemoteInitialize)
|
IDENTIFIER(_distributedActorRemoteInitialize)
|
||||||
IDENTIFIER(_distributedActorDestroy)
|
IDENTIFIER(_distributedActorDestroy)
|
||||||
|
|||||||
@@ -716,18 +716,9 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
|||||||
void swift_defaultActor_deallocateResilient(HeapObject *actor);
|
void swift_defaultActor_deallocateResilient(HeapObject *actor);
|
||||||
|
|
||||||
/// Initialize the runtime storage for a distributed remote actor.
|
/// Initialize the runtime storage for a distributed remote actor.
|
||||||
// TODO: this may end up being removed as we move to the "proxy creation" below
|
|
||||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||||
void swift_distributedActor_remote_initialize(DefaultActor *actor);
|
OpaqueValue*
|
||||||
|
swift_distributedActor_remote_initialize(const Metadata *actorType);
|
||||||
/// Create a proxy object that will serve as remote distributed actor instance.
|
|
||||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
|
||||||
OpaqueValue* swift_distributedActor_remote_create(
|
|
||||||
/* +1 */OpaqueValue *identity,
|
|
||||||
/* +1 */OpaqueValue *transport
|
|
||||||
// metadata for identity
|
|
||||||
// metadata for transport
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Destroy the runtime storage for a default actor.
|
/// Destroy the runtime storage for a default actor.
|
||||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||||
|
|||||||
@@ -1687,7 +1687,9 @@ FUNCTION(DefaultActorDeallocateResilient,
|
|||||||
ARGS(RefCountedPtrTy),
|
ARGS(RefCountedPtrTy),
|
||||||
ATTRS(NoUnwind))
|
ATTRS(NoUnwind))
|
||||||
|
|
||||||
// void swift_distributedActor_remote_initialize(const Metadata *actorType);
|
// OpaqueValue* swift_distributedActor_remote_initialize(
|
||||||
|
// const Metadata *actorType
|
||||||
|
// );
|
||||||
FUNCTION(DistributedActorInitializeRemote,
|
FUNCTION(DistributedActorInitializeRemote,
|
||||||
swift_distributedActor_remote_initialize, SwiftCC,
|
swift_distributedActor_remote_initialize, SwiftCC,
|
||||||
ConcurrencyAvailability,
|
ConcurrencyAvailability,
|
||||||
|
|||||||
@@ -1462,7 +1462,14 @@ static ValueDecl *getDefaultActorInitDestroy(ASTContext &ctx,
|
|||||||
_void);
|
_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ValueDecl *getDistributedActorInitDestroy(ASTContext &ctx,
|
static ValueDecl *getDistributedActorInitializeRemote(ASTContext &ctx,
|
||||||
|
Identifier id) {
|
||||||
|
return getBuiltinFunction(ctx, id, _thin,
|
||||||
|
_parameters(_nativeObject),
|
||||||
|
_rawPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ValueDecl *getDistributedActorDestroy(ASTContext &ctx,
|
||||||
Identifier id) {
|
Identifier id) {
|
||||||
return getBuiltinFunction(ctx, id, _thin,
|
return getBuiltinFunction(ctx, id, _thin,
|
||||||
_parameters(_nativeObject), // TODO: no idea if to pass more here?
|
_parameters(_nativeObject), // TODO: no idea if to pass more here?
|
||||||
@@ -2808,8 +2815,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
|
|||||||
return getDefaultActorInitDestroy(Context, Id);
|
return getDefaultActorInitDestroy(Context, Id);
|
||||||
|
|
||||||
case BuiltinValueKind::InitializeDistributedRemoteActor:
|
case BuiltinValueKind::InitializeDistributedRemoteActor:
|
||||||
|
return getDistributedActorInitializeRemote(Context, Id);
|
||||||
|
|
||||||
case BuiltinValueKind::DestroyDistributedActor:
|
case BuiltinValueKind::DestroyDistributedActor:
|
||||||
return getDistributedActorInitDestroy(Context, Id);
|
return getDistributedActorDestroy(Context, Id);
|
||||||
|
|
||||||
case BuiltinValueKind::StartAsyncLet:
|
case BuiltinValueKind::StartAsyncLet:
|
||||||
case BuiltinValueKind::StartAsyncLetWithLocalBuffer:
|
case BuiltinValueKind::StartAsyncLetWithLocalBuffer:
|
||||||
|
|||||||
@@ -1197,29 +1197,3 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
|
|||||||
emitEpilog(loc);
|
emitEpilog(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 init.
|
|
||||||
|
|
||||||
SILLocation loc = fd; // NOTE: forgot if this is the right one for all locs.
|
|
||||||
ClassDecl *actor = cast<ClassDecl>(fd->getDeclContext()->getAsDecl());
|
|
||||||
assert(actor->isDistributedActor());
|
|
||||||
|
|
||||||
// Step 1: get the uninitialized allocation from the runtime system.
|
|
||||||
auto &ctx = getASTContext();
|
|
||||||
auto builtinName = ctx.getIdentifier(
|
|
||||||
getBuiltinName(BuiltinValueKind::InitializeDistributedRemoteActor));
|
|
||||||
auto returnType = getLoweredType(actor->getInterfaceType());
|
|
||||||
auto *metaTypeInfo = F.getArgument(0);
|
|
||||||
|
|
||||||
FullExpr scope(Cleanups, CleanupLocation(fd));
|
|
||||||
auto *result = B.createBuiltin(loc, builtinName, returnType, /*subs*/{},
|
|
||||||
{ metaTypeInfo });
|
|
||||||
|
|
||||||
// TODO: initialize the id and transport fields
|
|
||||||
|
|
||||||
|
|
||||||
B.createReturn(loc, result);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -87,12 +87,10 @@ lookupAssignIdentityFunc(ASTContext& C) {
|
|||||||
/// Synthesize the actorTransport initialization:
|
/// Synthesize the actorTransport initialization:
|
||||||
///
|
///
|
||||||
/// \verbatim
|
/// \verbatim
|
||||||
/// // init(..., <transport>: ActorTransport) ... {
|
/// self.actorTransport = <<constructor parameter:ActorTransport>>
|
||||||
/// self.actorTransport = transport
|
|
||||||
/// // }
|
|
||||||
/// \endverbatim
|
/// \endverbatim
|
||||||
static void
|
static void
|
||||||
emitDistributedActorTransportInit(
|
emitDistributedActor_init_transportStore(
|
||||||
SILGenFunction &SGF,
|
SILGenFunction &SGF,
|
||||||
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
|
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
|
||||||
ConstructorDecl *ctor,
|
ConstructorDecl *ctor,
|
||||||
@@ -109,7 +107,6 @@ emitDistributedActorTransportInit(
|
|||||||
// ==== Prepare assignment: get the self.transport address
|
// ==== Prepare assignment: get the self.transport address
|
||||||
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
|
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
|
||||||
ManagedValue transportArgManaged = ManagedValue::forUnmanaged(transportArgValue);
|
ManagedValue transportArgManaged = ManagedValue::forUnmanaged(transportArgValue);
|
||||||
auto transportDecl = C.getActorTransportDecl();
|
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
|
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
|
||||||
@@ -124,15 +121,55 @@ emitDistributedActorTransportInit(
|
|||||||
IsNotTake, IsInitialization);
|
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:
|
/// Synthesize the distributed actor's identity (`id`) initialization:
|
||||||
///
|
///
|
||||||
/// \verbatim
|
/// \verbatim
|
||||||
/// // init(..., <transport>: ActorTransport) ... {
|
|
||||||
/// self.id = transport.assignIdentity(Self.self)
|
/// self.id = transport.assignIdentity(Self.self)
|
||||||
/// // }
|
|
||||||
/// \endverbatim
|
/// \endverbatim
|
||||||
static void
|
static void emitDistributedActorIdentity_init_assignIdentity(
|
||||||
emitDistributedActorIdentityInit(
|
|
||||||
SILGenFunction &SGF,
|
SILGenFunction &SGF,
|
||||||
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
|
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
|
||||||
ConstructorDecl *ctor,
|
ConstructorDecl *ctor,
|
||||||
@@ -198,8 +235,6 @@ emitDistributedActorIdentityInit(
|
|||||||
distributedActorProto);
|
distributedActorProto);
|
||||||
assert(!distributedActorConfRef.isInvalid() && "Missing conformance to `DistributedActor`");
|
assert(!distributedActorConfRef.isInvalid() && "Missing conformance to `DistributedActor`");
|
||||||
|
|
||||||
// auto anyActorIdentityDecl = C.getAnyActorIdentityDecl();
|
|
||||||
|
|
||||||
auto assignIdentityMethod =
|
auto assignIdentityMethod =
|
||||||
cast<FuncDecl>(transportProto->getSingleRequirement(C.Id_assignIdentity));
|
cast<FuncDecl>(transportProto->getSingleRequirement(C.Id_assignIdentity));
|
||||||
auto assignIdentityRef = SILDeclRef(assignIdentityMethod, SILDeclRef::Kind::Func);
|
auto assignIdentityRef = SILDeclRef(assignIdentityMethod, SILDeclRef::Kind::Func);
|
||||||
@@ -252,11 +287,8 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
|
|||||||
auto &C = classDecl->getASTContext();
|
auto &C = classDecl->getASTContext();
|
||||||
|
|
||||||
// Only designated initializers get the lifecycle handling injected
|
// Only designated initializers get the lifecycle handling injected
|
||||||
if (!ctor->isDesignatedInit()) {
|
if (!ctor->isDesignatedInit())
|
||||||
fprintf(stderr, "[%s:%d] (%s) NOT DESIGNATED INIT SKIP\n", __FILE__, __LINE__, __FUNCTION__);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
SILLocation prologueLoc = RegularLocation(ctor);
|
SILLocation prologueLoc = RegularLocation(ctor);
|
||||||
prologueLoc.markAsPrologue(); // TODO: no idea if this is necessary or makes sense
|
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 &&
|
if (var->getName() == C.Id_actorTransport &&
|
||||||
var->getInterfaceType()->isEqual(transportTy)) {
|
var->getInterfaceType()->isEqual(transportTy)) {
|
||||||
transportMember = var;
|
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 &&
|
} else if (var->getName() == C.Id_id &&
|
||||||
(var->getInterfaceType()->isEqual(identityProtoTy) ||
|
(var->getInterfaceType()->isEqual(identityProtoTy) ||
|
||||||
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
|
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
|
||||||
idMember = var;
|
idMember = var;
|
||||||
emitDistributedActorIdentityInit(*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
emitDistributedActorIdentity_init_assignIdentity(
|
||||||
|
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
|
||||||
}
|
}
|
||||||
if (transportMember && idMember) {
|
if (transportMember && idMember) {
|
||||||
break; // we found all properties we care about, break out of the loop early
|
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
|
// 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 ************************/
|
/******************* DISTRIBUTED DEINIT: resignAddress ************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -364,7 +538,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
|
|||||||
|
|
||||||
bindParametersForForwarding(fd->getParameters(), params);
|
bindParametersForForwarding(fd->getParameters(), params);
|
||||||
bindParameterForForwarding(selfVarDecl, 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();
|
auto selfType = selfVarDecl->getType();
|
||||||
|
|
||||||
// if __isRemoteActor(self) {
|
// if __isRemoteActor(self) {
|
||||||
|
|||||||
@@ -510,17 +510,17 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
|
|||||||
void SILGenFunction::emitFunction(FuncDecl *fd) {
|
void SILGenFunction::emitFunction(FuncDecl *fd) {
|
||||||
MagicFunctionName = SILGenModule::getMagicFunctionName(fd);
|
MagicFunctionName = SILGenModule::getMagicFunctionName(fd);
|
||||||
|
|
||||||
if (fd->isDistributedActorFactory()) {
|
|
||||||
emitDistributedActorFactory(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto captureInfo = SGM.M.Types.getLoweredLocalCaptures(SILDeclRef(fd));
|
auto captureInfo = SGM.M.Types.getLoweredLocalCaptures(SILDeclRef(fd));
|
||||||
emitProfilerIncrement(fd->getTypecheckedBody());
|
emitProfilerIncrement(fd->getTypecheckedBody());
|
||||||
emitProlog(captureInfo, fd->getParameters(), fd->getImplicitSelfDecl(), fd,
|
emitProlog(captureInfo, fd->getParameters(), fd->getImplicitSelfDecl(), fd,
|
||||||
fd->getResultInterfaceType(), fd->hasThrows(), fd->getThrowsLoc());
|
fd->getResultInterfaceType(), fd->hasThrows(), fd->getThrowsLoc());
|
||||||
prepareEpilog(true, fd->hasThrows(), CleanupLocation(fd));
|
prepareEpilog(true, fd->hasThrows(), CleanupLocation(fd));
|
||||||
|
|
||||||
|
if (fd->isDistributedActorFactory()) {
|
||||||
|
// Synthesize the factory function body
|
||||||
|
emitDistributedActorFactory(fd);
|
||||||
|
} else {
|
||||||
|
// Emit the actual function body as usual
|
||||||
if (llvm::any_of(
|
if (llvm::any_of(
|
||||||
*fd->getParameters(),
|
*fd->getParameters(),
|
||||||
[](ParamDecl *p){ return p->hasAttachedPropertyWrapper(); })) {
|
[](ParamDecl *p){ return p->hasAttachedPropertyWrapper(); })) {
|
||||||
@@ -542,10 +542,17 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
|
|||||||
} else {
|
} else {
|
||||||
emitStmt(fd->getTypecheckedBody());
|
emitStmt(fd->getTypecheckedBody());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
emitEpilog(fd);
|
emitEpilog(fd);
|
||||||
|
|
||||||
mergeCleanupBlocks();
|
mergeCleanupBlocks();
|
||||||
|
|
||||||
|
if (fd->isDistributedActorFactory()) {
|
||||||
|
fprintf(stderr, "[%s:%d] (%s) DONEDONEDONEDONEDONEDONEDONEDONEDONEDONEDONEDONE\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
|
F.dump();
|
||||||
|
fprintf(stderr, "[%s:%d] (%s) DONEDONEDONEDONEDONEDONEDONEDONEDONEDONEDONEDONE\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
|
void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
|
||||||
|
|||||||
@@ -625,10 +625,6 @@ public:
|
|||||||
/// destructor, then implicitly releases the elements of the class.
|
/// destructor, then implicitly releases the elements of the class.
|
||||||
void emitDestroyingDestructor(DestructorDecl *dd);
|
void emitDestroyingDestructor(DestructorDecl *dd);
|
||||||
|
|
||||||
/// Given a function representing a distributed actor factory, emits the
|
|
||||||
/// corresponding SIL function for it.
|
|
||||||
void emitDistributedActorFactory(FuncDecl *fd);
|
|
||||||
|
|
||||||
/// Generates code for an artificial top-level function that starts an
|
/// Generates code for an artificial top-level function that starts an
|
||||||
/// application based on a main type and optionally a main type.
|
/// application based on a main type and optionally a main type.
|
||||||
void emitArtificialTopLevel(Decl *mainDecl);
|
void emitArtificialTopLevel(Decl *mainDecl);
|
||||||
@@ -686,9 +682,6 @@ public:
|
|||||||
/// new task.
|
/// new task.
|
||||||
SILFunction *emitNativeAsyncToForeignThunk(SILDeclRef thunk);
|
SILFunction *emitNativeAsyncToForeignThunk(SILDeclRef thunk);
|
||||||
|
|
||||||
/// Generates a thunk from an actor function
|
|
||||||
void emitDistributedThunk(SILDeclRef thunk);
|
|
||||||
|
|
||||||
/// Generate a nullary function that returns the given value.
|
/// Generate a nullary function that returns the given value.
|
||||||
/// If \p emitProfilerIncrement is set, emit a profiler increment for
|
/// If \p emitProfilerIncrement is set, emit a profiler increment for
|
||||||
/// \p value.
|
/// \p value.
|
||||||
@@ -2004,6 +1997,13 @@ public:
|
|||||||
void initializeDistributedActorImplicitStorageInit(
|
void initializeDistributedActorImplicitStorageInit(
|
||||||
ConstructorDecl *ctor, ManagedValue selfArg);
|
ConstructorDecl *ctor, ManagedValue selfArg);
|
||||||
|
|
||||||
|
/// Given a function representing a distributed actor factory, emits the
|
||||||
|
/// corresponding SIL function for it.
|
||||||
|
void emitDistributedActorFactory(FuncDecl *fd);
|
||||||
|
|
||||||
|
/// Generates a thunk from an actor function
|
||||||
|
void emitDistributedThunk(SILDeclRef thunk);
|
||||||
|
|
||||||
/// Notify transport that actor has initialized successfully,
|
/// Notify transport that actor has initialized successfully,
|
||||||
/// and is ready to receive messages.
|
/// and is ready to receive messages.
|
||||||
void emitDistributedActorReady(
|
void emitDistributedActorReady(
|
||||||
|
|||||||
@@ -31,19 +31,19 @@
|
|||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************* INITIALIZERS *********************************/
|
/******************************* RESOLVE FUNCTION *****************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/// Synthesizes the
|
/// Synthesizes the
|
||||||
///
|
///
|
||||||
/// \verbatim
|
/// \verbatim
|
||||||
/// actor A {
|
|
||||||
/// static resolve(_ address: ActorAddress,
|
/// static resolve(_ address: ActorAddress,
|
||||||
/// using transport: ActorTransport) throws -> Self
|
/// using transport: ActorTransport) throws -> Self {
|
||||||
|
/// <filled in by SILGenDistributed>
|
||||||
/// }
|
/// }
|
||||||
/// \endverbatim
|
/// \endverbatim
|
||||||
///
|
///
|
||||||
/// factory function in the AST, with an empty body. It's body is
|
/// factory function in the AST, with an empty body. Its body is
|
||||||
/// expected to be filled-in during SILGen.
|
/// expected to be filled-in during SILGen.
|
||||||
static void addFactoryResolveFunction(ClassDecl *decl) {
|
static void addFactoryResolveFunction(ClassDecl *decl) {
|
||||||
assert(decl->isDistributedActor());
|
assert(decl->isDistributedActor());
|
||||||
@@ -62,11 +62,11 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
|||||||
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
|
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
|
||||||
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
|
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
|
||||||
|
|
||||||
// (_ id: AnyActorAddress, using transport: ActorTransport)
|
// (_ identity: AnyActorIdentity, using transport: ActorTransport)
|
||||||
auto *params = ParameterList::create(
|
auto *params = ParameterList::create(
|
||||||
C,
|
C,
|
||||||
/*LParenLoc=*/SourceLoc(),
|
/*LParenLoc=*/SourceLoc(),
|
||||||
/*params=*/{ mkParam(Identifier(), C.Id_id, addressType),
|
/*params=*/{ mkParam(Identifier(), C.Id_identity, addressType),
|
||||||
mkParam(C.Id_using, C.Id_transport, transportType)
|
mkParam(C.Id_using, C.Id_transport, transportType)
|
||||||
},
|
},
|
||||||
/*RParenLoc=*/SourceLoc()
|
/*RParenLoc=*/SourceLoc()
|
||||||
@@ -75,7 +75,7 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
|||||||
// Func name: resolve(_:using:)
|
// Func name: resolve(_:using:)
|
||||||
DeclName name(C, C.Id_resolve, params);
|
DeclName name(C, C.Id_resolve, params);
|
||||||
|
|
||||||
// Expected type: (Self) -> (ActorAddress, ActorTransport) throws -> (Self)
|
// Expected type: (Self) -> (AnyActorIdentity, ActorTransport) throws -> (Self)
|
||||||
auto *factoryDecl =
|
auto *factoryDecl =
|
||||||
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
|
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
|
||||||
name, SourceLoc(),
|
name, SourceLoc(),
|
||||||
@@ -86,12 +86,16 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
|||||||
/*returnType*/decl->getDeclaredInterfaceType(),
|
/*returnType*/decl->getDeclaredInterfaceType(),
|
||||||
decl);
|
decl);
|
||||||
|
|
||||||
factoryDecl->setDistributedActorFactory();
|
factoryDecl->setDistributedActorFactory(); // TODO(distributed): should we mark this specifically as the resolve factory?
|
||||||
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
|
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
|
||||||
|
|
||||||
decl->addMember(factoryDecl);
|
decl->addMember(factoryDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/***************************** DEFAULT INITIALIZER ****************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
/// Synthesizes an empty body of the `init(transport:)` initializer as:
|
/// Synthesizes an empty body of the `init(transport:)` initializer as:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -2196,7 +2196,6 @@ namespace {
|
|||||||
// distributed actor, in which case we need to diagnose it.
|
// distributed actor, in which case we need to diagnose it.
|
||||||
if (auto classDecl = dyn_cast<ClassDecl>(member->getDeclContext())) {
|
if (auto classDecl = dyn_cast<ClassDecl>(member->getDeclContext())) {
|
||||||
if (classDecl->isDistributedActor()) {
|
if (classDecl->isDistributedActor()) {
|
||||||
fprintf(stderr, "[%s:%d] (%s) HERE\n", __FILE__, __LINE__, __FUNCTION__);
|
|
||||||
ctx.Diags.diagnose(memberLoc, diag::distributed_actor_isolated_method);
|
ctx.Diags.diagnose(memberLoc, diag::distributed_actor_isolated_method);
|
||||||
noteIsolatedActorMember(member, context);
|
noteIsolatedActorMember(member, context);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1752,33 +1752,23 @@ void swift::swift_defaultActor_deallocateResilient(HeapObject *actor) {
|
|||||||
metadata->getInstanceAlignMask());
|
metadata->getInstanceAlignMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rename initialize to allocate throughout htis built-in. Delete `swift_distributedActor_remote_create` throughout.
|
OpaqueValue*
|
||||||
OpaqueValue* swift::swift_distributedActor_remote_initialize(Metadata *actorType) {
|
swift::swift_distributedActor_remote_initialize(const Metadata *actorType) {
|
||||||
auto *classMetadata = actorType->getClassObject();
|
auto *classMetadata = actorType->getClassObject();
|
||||||
|
|
||||||
// TODOs:
|
// TODO(distributed): make this allocation smaller
|
||||||
// 1. make this allocation smaller
|
|
||||||
// 2. if we are going to keep the remote flag in the header,
|
|
||||||
// allocate that header and mark / register this as being remote instance.
|
|
||||||
|
|
||||||
HeapObject *alloc = swift_allocObject(classMetadata,
|
HeapObject *alloc = swift_allocObject(classMetadata,
|
||||||
classMetadata->getInstanceSize(),
|
classMetadata->getInstanceSize(),
|
||||||
classMetadata->getInstanceAlignMask());
|
classMetadata->getInstanceAlignMask());
|
||||||
|
|
||||||
|
// TODO(distributed): if we are going to keep the remote flag in the header,
|
||||||
|
// allocate that header and mark / register this as being remote instance.
|
||||||
|
|
||||||
return reinterpret_cast<OpaqueValue*>(alloc);
|
return reinterpret_cast<OpaqueValue*>(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: missing implementation of creating a proxy for the remote actor
|
void swift::swift_distributedActor_destroy(DefaultActor *_actor) {
|
||||||
OpaqueValue* swift::swift_distributedActor_remote_create(OpaqueValue *identity,
|
// FIXME(distributed): if this is a proxy, we would destroy a bit differently I guess? less memory was allocated etc.
|
||||||
OpaqueValue *transport) {
|
|
||||||
assert(false && "swift_distributedActor_remote_create is not implemented yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void swift::swift_distributedActor_destroy(DefaultActor *_actor) { // FIXME: remove distributed C++ impl not needed?
|
|
||||||
// TODO: need to resign the address before we destroy:
|
|
||||||
// something like: actor.transport.resignIdentity(actor.address)
|
|
||||||
|
|
||||||
// FIXME: if this is a proxy, we would destroy a bit differently I guess? less memory was allocated etc.
|
|
||||||
asImpl(_actor)->destroy(); // today we just replicate what defaultActor_destroy does
|
asImpl(_actor)->destroy(); // today we just replicate what defaultActor_destroy does
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1786,7 +1776,7 @@ bool swift::swift_distributed_actor_is_remote(DefaultActor *_actor) {
|
|||||||
return asImpl(_actor)->isDistributedRemote();
|
return asImpl(_actor)->isDistributedRemote();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME: only exists for the quick-and-dirty MainActor implementation.
|
/// FIXME: only exists for the quick-and-dirtraKASASAasasy MainActor implementation.
|
||||||
namespace swift {
|
namespace swift {
|
||||||
Metadata* MainActorMetadata = nullptr;
|
Metadata* MainActorMetadata = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public protocol ActorTransport: Sendable {
|
|||||||
///
|
///
|
||||||
/// Detecting liveness of such remote actors shall be offered / by transport libraries
|
/// Detecting liveness of such remote actors shall be offered / by transport libraries
|
||||||
/// by other means, such as "watching an actor for termination" or similar.
|
/// by other means, such as "watching an actor for termination" or similar.
|
||||||
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type) throws -> ActorResolved<Act>
|
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type) throws -> ActorResolved<Act> // TODO(distributed): make just optional
|
||||||
where Act: DistributedActor
|
where Act: DistributedActor
|
||||||
|
|
||||||
// ==== ---------------------------------------------------------------------
|
// ==== ---------------------------------------------------------------------
|
||||||
|
|||||||
@@ -48,8 +48,11 @@ public protocol DistributedActor:
|
|||||||
///
|
///
|
||||||
/// - Parameter identity: identity uniquely identifying a, potentially remote, actor in the system
|
/// - Parameter identity: identity uniquely identifying a, potentially remote, actor in the system
|
||||||
/// - Parameter transport: `transport` which should be used to resolve the `identity`, and be associated with the returned actor
|
/// - Parameter transport: `transport` which should be used to resolve the `identity`, and be associated with the returned actor
|
||||||
static func resolve<Identity>(_ identity: Identity, using transport: ActorTransport)
|
// FIXME: move to generic identity here; depends on
|
||||||
throws -> Self where Identity: ActorIdentity
|
// static func resolve<Identity>(_ identity: Identity, using transport: ActorTransport)
|
||||||
|
// throws -> Self where Identity: ActorIdentity
|
||||||
|
static func resolve(_ identity: AnyActorIdentity, using transport: ActorTransport)
|
||||||
|
throws -> Self
|
||||||
|
|
||||||
/// The `ActorTransport` associated with this actor.
|
/// The `ActorTransport` associated with this actor.
|
||||||
/// It is immutable and equal to the transport passed in the local/resolve
|
/// It is immutable and equal to the transport passed in the local/resolve
|
||||||
|
|||||||
Reference in New Issue
Block a user