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.
|
||||
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,
|
||||
"initializeDistributedRemoteActor", "", Special)
|
||||
|
||||
|
||||
@@ -258,6 +258,7 @@ IDENTIFIER(assignIdentity)
|
||||
IDENTIFIER(resignIdentity)
|
||||
IDENTIFIER(resolve)
|
||||
IDENTIFIER(id)
|
||||
IDENTIFIER(identity)
|
||||
IDENTIFIER(identifier)
|
||||
IDENTIFIER(_distributedActorRemoteInitialize)
|
||||
IDENTIFIER(_distributedActorDestroy)
|
||||
|
||||
@@ -716,18 +716,9 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||
void swift_defaultActor_deallocateResilient(HeapObject *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)
|
||||
void swift_distributedActor_remote_initialize(DefaultActor *actor);
|
||||
|
||||
/// 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
|
||||
);
|
||||
OpaqueValue*
|
||||
swift_distributedActor_remote_initialize(const Metadata *actorType);
|
||||
|
||||
/// Destroy the runtime storage for a default actor.
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||
|
||||
@@ -1687,7 +1687,9 @@ FUNCTION(DefaultActorDeallocateResilient,
|
||||
ARGS(RefCountedPtrTy),
|
||||
ATTRS(NoUnwind))
|
||||
|
||||
// void swift_distributedActor_remote_initialize(const Metadata *actorType);
|
||||
// OpaqueValue* swift_distributedActor_remote_initialize(
|
||||
// const Metadata *actorType
|
||||
// );
|
||||
FUNCTION(DistributedActorInitializeRemote,
|
||||
swift_distributedActor_remote_initialize, SwiftCC,
|
||||
ConcurrencyAvailability,
|
||||
|
||||
@@ -1462,7 +1462,14 @@ static ValueDecl *getDefaultActorInitDestroy(ASTContext &ctx,
|
||||
_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) {
|
||||
return getBuiltinFunction(ctx, id, _thin,
|
||||
_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);
|
||||
|
||||
case BuiltinValueKind::InitializeDistributedRemoteActor:
|
||||
return getDistributedActorInitializeRemote(Context, Id);
|
||||
|
||||
case BuiltinValueKind::DestroyDistributedActor:
|
||||
return getDistributedActorInitDestroy(Context, Id);
|
||||
return getDistributedActorDestroy(Context, Id);
|
||||
|
||||
case BuiltinValueKind::StartAsyncLet:
|
||||
case BuiltinValueKind::StartAsyncLetWithLocalBuffer:
|
||||
|
||||
@@ -1197,29 +1197,3 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
|
||||
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:
|
||||
///
|
||||
/// \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) {
|
||||
|
||||
@@ -510,17 +510,17 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
|
||||
void SILGenFunction::emitFunction(FuncDecl *fd) {
|
||||
MagicFunctionName = SILGenModule::getMagicFunctionName(fd);
|
||||
|
||||
if (fd->isDistributedActorFactory()) {
|
||||
emitDistributedActorFactory(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
auto captureInfo = SGM.M.Types.getLoweredLocalCaptures(SILDeclRef(fd));
|
||||
emitProfilerIncrement(fd->getTypecheckedBody());
|
||||
emitProlog(captureInfo, fd->getParameters(), fd->getImplicitSelfDecl(), fd,
|
||||
fd->getResultInterfaceType(), fd->hasThrows(), fd->getThrowsLoc());
|
||||
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(
|
||||
*fd->getParameters(),
|
||||
[](ParamDecl *p){ return p->hasAttachedPropertyWrapper(); })) {
|
||||
@@ -542,10 +542,17 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
|
||||
} else {
|
||||
emitStmt(fd->getTypecheckedBody());
|
||||
}
|
||||
}
|
||||
|
||||
emitEpilog(fd);
|
||||
|
||||
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) {
|
||||
|
||||
@@ -625,10 +625,6 @@ public:
|
||||
/// destructor, then implicitly releases the elements of the class.
|
||||
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
|
||||
/// application based on a main type and optionally a main type.
|
||||
void emitArtificialTopLevel(Decl *mainDecl);
|
||||
@@ -686,9 +682,6 @@ public:
|
||||
/// new task.
|
||||
SILFunction *emitNativeAsyncToForeignThunk(SILDeclRef thunk);
|
||||
|
||||
/// Generates a thunk from an actor function
|
||||
void emitDistributedThunk(SILDeclRef thunk);
|
||||
|
||||
/// Generate a nullary function that returns the given value.
|
||||
/// If \p emitProfilerIncrement is set, emit a profiler increment for
|
||||
/// \p value.
|
||||
@@ -2004,6 +1997,13 @@ public:
|
||||
void initializeDistributedActorImplicitStorageInit(
|
||||
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,
|
||||
/// and is ready to receive messages.
|
||||
void emitDistributedActorReady(
|
||||
|
||||
@@ -31,19 +31,19 @@
|
||||
using namespace swift;
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************* INITIALIZERS *********************************/
|
||||
/******************************* RESOLVE FUNCTION *****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/// Synthesizes the
|
||||
///
|
||||
/// \verbatim
|
||||
/// actor A {
|
||||
/// static resolve(_ address: ActorAddress,
|
||||
/// using transport: ActorTransport) throws -> Self
|
||||
/// using transport: ActorTransport) throws -> Self {
|
||||
/// <filled in by SILGenDistributed>
|
||||
/// }
|
||||
/// \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.
|
||||
static void addFactoryResolveFunction(ClassDecl *decl) {
|
||||
assert(decl->isDistributedActor());
|
||||
@@ -62,11 +62,11 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
||||
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
|
||||
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
|
||||
|
||||
// (_ id: AnyActorAddress, using transport: ActorTransport)
|
||||
// (_ identity: AnyActorIdentity, using transport: ActorTransport)
|
||||
auto *params = ParameterList::create(
|
||||
C,
|
||||
/*LParenLoc=*/SourceLoc(),
|
||||
/*params=*/{ mkParam(Identifier(), C.Id_id, addressType),
|
||||
/*params=*/{ mkParam(Identifier(), C.Id_identity, addressType),
|
||||
mkParam(C.Id_using, C.Id_transport, transportType)
|
||||
},
|
||||
/*RParenLoc=*/SourceLoc()
|
||||
@@ -75,7 +75,7 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
||||
// Func name: resolve(_:using:)
|
||||
DeclName name(C, C.Id_resolve, params);
|
||||
|
||||
// Expected type: (Self) -> (ActorAddress, ActorTransport) throws -> (Self)
|
||||
// Expected type: (Self) -> (AnyActorIdentity, ActorTransport) throws -> (Self)
|
||||
auto *factoryDecl =
|
||||
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
|
||||
name, SourceLoc(),
|
||||
@@ -86,12 +86,16 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
|
||||
/*returnType*/decl->getDeclaredInterfaceType(),
|
||||
decl);
|
||||
|
||||
factoryDecl->setDistributedActorFactory();
|
||||
factoryDecl->setDistributedActorFactory(); // TODO(distributed): should we mark this specifically as the resolve factory?
|
||||
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
|
||||
|
||||
decl->addMember(factoryDecl);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/***************************** DEFAULT INITIALIZER ****************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/// 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.
|
||||
if (auto classDecl = dyn_cast<ClassDecl>(member->getDeclContext())) {
|
||||
if (classDecl->isDistributedActor()) {
|
||||
fprintf(stderr, "[%s:%d] (%s) HERE\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
ctx.Diags.diagnose(memberLoc, diag::distributed_actor_isolated_method);
|
||||
noteIsolatedActorMember(member, context);
|
||||
return true;
|
||||
|
||||
@@ -1752,33 +1752,23 @@ void swift::swift_defaultActor_deallocateResilient(HeapObject *actor) {
|
||||
metadata->getInstanceAlignMask());
|
||||
}
|
||||
|
||||
// TODO: rename initialize to allocate throughout htis built-in. Delete `swift_distributedActor_remote_create` throughout.
|
||||
OpaqueValue* swift::swift_distributedActor_remote_initialize(Metadata *actorType) {
|
||||
OpaqueValue*
|
||||
swift::swift_distributedActor_remote_initialize(const Metadata *actorType) {
|
||||
auto *classMetadata = actorType->getClassObject();
|
||||
|
||||
// TODOs:
|
||||
// 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.
|
||||
|
||||
// TODO(distributed): make this allocation smaller
|
||||
HeapObject *alloc = swift_allocObject(classMetadata,
|
||||
classMetadata->getInstanceSize(),
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO: missing implementation of creating a proxy for the remote actor
|
||||
OpaqueValue* swift::swift_distributedActor_remote_create(OpaqueValue *identity,
|
||||
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.
|
||||
void swift::swift_distributedActor_destroy(DefaultActor *_actor) {
|
||||
// FIXME(distributed): 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
|
||||
}
|
||||
|
||||
@@ -1786,7 +1776,7 @@ bool swift::swift_distributed_actor_is_remote(DefaultActor *_actor) {
|
||||
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 {
|
||||
Metadata* MainActorMetadata = nullptr;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public protocol ActorTransport: Sendable {
|
||||
///
|
||||
/// Detecting liveness of such remote actors shall be offered / by transport libraries
|
||||
/// 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
|
||||
|
||||
// ==== ---------------------------------------------------------------------
|
||||
|
||||
@@ -48,8 +48,11 @@ public protocol DistributedActor:
|
||||
///
|
||||
/// - 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
|
||||
static func resolve<Identity>(_ identity: Identity, using transport: ActorTransport)
|
||||
throws -> Self where Identity: ActorIdentity
|
||||
// FIXME: move to generic identity here; depends on
|
||||
// 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.
|
||||
/// It is immutable and equal to the transport passed in the local/resolve
|
||||
|
||||
Reference in New Issue
Block a user