Skip to content

Commit ddf3aee

Browse files
ktosoxedin
authored andcommitted
wip
1 parent 7ba07ae commit ddf3aee

17 files changed

+179
-12
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class ASTMangler : public Mangler {
197197
Type GlobalActorBound,
198198
ModuleDecl *Module);
199199

200-
std::string mangleDistributedThunk(const FuncDecl *thunk);
200+
std::string mangleDistributedThunk(const AbstractFunctionDecl *thunk);
201201

202202
/// Mangle a completion handler block implementation function, used for importing ObjC
203203
/// APIs as async.

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ SIMPLE_DECL_ATTR(_inheritActorContext, InheritActorContext,
664664
// 117 was 'spawn' and is now unused
665665

666666
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,
667-
DeclModifier | OnClass | OnFunc | OnVar |
667+
DeclModifier | OnClass | OnFunc | OnAccessor | OnVar |
668668
ABIBreakingToAdd | ABIBreakingToRemove |
669669
APIBreakingToAdd | APIBreakingToRemove,
670670
118)

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,6 +4798,9 @@ ERROR(distributed_property_cannot_be_static,none,
47984798
ERROR(distributed_property_can_only_be_computed,none,
47994799
"%0 %1 cannot be 'distributed', only computed properties can",
48004800
(DescriptiveDeclKind, DeclName))
4801+
ERROR(distributed_property_accessor_only_get_can_be_distributed,none,
4802+
"only 'get' accessors may be 'distributed'",
4803+
())
48014804
NOTE(distributed_actor_isolated_property,none,
48024805
"access to %0 %1 is only permitted within distributed actor %2",
48034806
(DescriptiveDeclKind, DeclName, DeclName))

include/swift/AST/Expr.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ class alignas(8) Expr : public ASTAllocated<Expr> {
155155

156156
SWIFT_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
157157
SWIFT_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
158-
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1+1+1,
158+
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1+1+1+1,
159159
IsSuper : 1,
160160
IsImplicitlyAsync : 1,
161-
IsImplicitlyThrows : 1
161+
IsImplicitlyThrows : 1,
162+
ShouldApplyDistributedThunk: 1
162163
);
163164
SWIFT_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);
164165

@@ -1655,6 +1656,18 @@ class LookupExpr : public Expr {
16551656
Bits.LookupExpr.IsImplicitlyThrows = isImplicitlyThrows;
16561657
}
16571658

1659+
/// Informs IRGen to that this expression should be applied as its distributed
1660+
/// thunk, rather than invoking the function directly.
1661+
///
1662+
/// Only intended to be set on distributed get-only computed properties.
1663+
bool shouldApplyLookupDistributedThunk() const {
1664+
return Bits.LookupExpr.ShouldApplyDistributedThunk;
1665+
}
1666+
1667+
void setShouldApplyLookupDistributedThunk(bool flag) {
1668+
Bits.LookupExpr.ShouldApplyDistributedThunk = flag;
1669+
}
1670+
16581671
static bool classof(const Expr *E) {
16591672
return E->getKind() >= ExprKind::First_LookupExpr &&
16601673
E->getKind() <= ExprKind::Last_LookupExpr;

include/swift/AST/StorageImpl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ class AccessStrategy {
110110
/// separately performing a Read into a temporary variable followed by
111111
/// a Write access back into the storage.
112112
MaterializeToTemporary,
113+
114+
/// The access is to a computed distributed property, and thus the
115+
/// get-accessor is a distributed thunk which may perform a remote call.
116+
DirectToDistributedThunkAccessor,
113117
};
114118

115119
private:
@@ -149,6 +153,10 @@ class AccessStrategy {
149153
return { dispatched ? DispatchToAccessor : DirectToAccessor, accessor };
150154
}
151155

156+
static AccessStrategy getDistributedGetAccessor(AccessorKind accessor) {
157+
assert(accessor == AccessorKind::Get);
158+
return { DirectToDistributedThunkAccessor, accessor };
159+
}
152160
static AccessStrategy getMaterializeToTemporary(AccessStrategy read,
153161
AccessStrategy write) {
154162
return { read, write };

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,8 @@ namespace {
745745

746746
void visitVarDecl(VarDecl *VD) {
747747
printCommon(VD, "var_decl");
748+
if (VD->isDistributed())
749+
PrintWithColorRAII(OS, DeclModifierColor) << " distributed";
748750
if (VD->isLet())
749751
PrintWithColorRAII(OS, DeclModifierColor) << " let";
750752
if (VD->getAttrs().hasAttribute<LazyAttr>())
@@ -2033,6 +2035,9 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
20332035

20342036
void visitMemberRefExpr(MemberRefExpr *E) {
20352037
printCommon(E, "member_ref_expr");
2038+
if (E->shouldApplyLookupDistributedThunk()) {
2039+
OS << " distributed";
2040+
}
20362041
PrintWithColorRAII(OS, DeclColor) << " decl=";
20372042
printDeclRef(E->getMember());
20382043
if (E->getAccessSemantics() != AccessSemantics::Ordinary)

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3486,7 +3486,7 @@ ASTMangler::mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl) {
34863486
return finalize();
34873487
}
34883488

3489-
std::string ASTMangler::mangleDistributedThunk(const FuncDecl *thunk) {
3489+
std::string ASTMangler::mangleDistributedThunk(const AbstractFunctionDecl *thunk) {
34903490
// Marker protocols cannot be checked at runtime, so there is no point
34913491
// in recording them for distributed thunks.
34923492
llvm::SaveAndRestore<bool> savedAllowMarkerProtocols(AllowMarkerProtocols,

lib/AST/Decl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,17 @@ getDirectReadAccessStrategy(const AbstractStorageDecl *storage) {
21512151
llvm_unreachable("bad impl kind");
21522152
}
21532153

2154+
static AccessStrategy
2155+
getDirectToDistributedThunkAccessorStrategy(const AbstractStorageDecl *storage) {
2156+
switch (storage->getReadImpl()) {
2157+
case ReadImplKind::Get:
2158+
return AccessStrategy::getDistributedGetAccessor(AccessorKind::Get);
2159+
default:
2160+
llvm_unreachable("bad impl kind for distributed property accessor");
2161+
}
2162+
llvm_unreachable("bad impl kind for distributed property accessor");
2163+
}
2164+
21542165
static AccessStrategy
21552166
getDirectWriteAccessStrategy(const AbstractStorageDecl *storage) {
21562167
switch (storage->getWriteImpl()) {
@@ -2284,6 +2295,14 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
22842295
if (shouldUseNativeDynamicDispatch())
22852296
return getOpaqueAccessStrategy(this, accessKind, /*dispatch*/ false);
22862297

2298+
if (auto var = dyn_cast<VarDecl>(this)) {
2299+
if (var->isDistributed()) {
2300+
fprintf(stderr, "[%s:%d] (%s) DIST STRATEGY!!\n", __FILE__, __LINE__, __FUNCTION__);
2301+
var->dump();
2302+
return getDirectToDistributedThunkAccessorStrategy(this);
2303+
}
2304+
}
2305+
22872306
// If the storage is resilient from the given module and resilience
22882307
// expansion, we cannot use direct access.
22892308
//

lib/SILGen/SILGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,9 @@ void SILGenModule::visitVarDecl(VarDecl *vd) {
17641764
if (vd->hasStorage())
17651765
addGlobalVariable(vd);
17661766

1767+
fprintf(stderr, "[%s:%d] (%s) VISIT VAR DECL\n", __FILE__, __LINE__, __FUNCTION__);
1768+
vd->dump();
1769+
17671770
vd->visitEmittedAccessors([&](AccessorDecl *accessor) {
17681771
emitFunction(accessor);
17691772
});
@@ -1830,6 +1833,7 @@ SILGenModule::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
18301833
case AccessStrategy::DirectToAccessor:
18311834
case AccessStrategy::DispatchToAccessor:
18321835
case AccessStrategy::MaterializeToTemporary:
1836+
case AccessStrategy::DirectToDistributedThunkAccessor:
18331837
return false;
18341838
}
18351839
llvm_unreachable("unhandled strategy");

lib/SILGen/SILGenApply.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
10901090

10911091
// If this is a direct reference to a vardecl, just emit its value directly.
10921092
// Recursive references to callable declarations are allowed.
1093-
if (isa<VarDecl>(e->getDecl())) {
1093+
if (auto var = dyn_cast<VarDecl>(e->getDecl())) {
10941094
visitExpr(e);
10951095
return;
10961096
}
@@ -1126,6 +1126,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11261126

11271127
/// Some special handling may be necessary for thunks:
11281128
if (callSite && callSite->shouldApplyDistributedThunk()) {
1129+
fprintf(stderr, "[%s:%d] (%s) SHOULD APPLY DIST THUNK\n", __FILE__, __LINE__, __FUNCTION__);
1130+
11291131
if (auto distributedThunk = cast<AbstractFunctionDecl>(e->getDecl())->getDistributedThunk()) {
11301132
constant = SILDeclRef(distributedThunk).asDistributed();
11311133
}
@@ -5773,12 +5775,20 @@ RValue SILGenFunction::emitGetAccessor(SILLocation loc, SILDeclRef get,
57735775
ArgumentSource &&selfValue, bool isSuper,
57745776
bool isDirectUse,
57755777
PreparedArguments &&subscriptIndices,
5776-
SGFContext c, bool isOnSelfParameter) {
5778+
SGFContext c,
5779+
bool isOnSelfParameter,
5780+
bool shouldUseDistributedThunk) {
57775781
// Scope any further writeback just within this operation.
57785782
FormalEvaluationScope writebackScope(*this);
57795783

5784+
auto constant = get;
5785+
if (shouldUseDistributedThunk) {
5786+
get.dump();
5787+
assert(false && "should use dist thunk");
5788+
}
5789+
57805790
Callee getter = emitSpecializedAccessorFunctionRef(
5781-
*this, loc, get, substitutions, selfValue, isSuper, isDirectUse,
5791+
*this, loc, constant, substitutions, selfValue, isSuper, isDirectUse,
57825792
isOnSelfParameter);
57835793
bool hasSelf = (bool)selfValue;
57845794
CanAnyFunctionType accessType = getter.getSubstFormalType();

lib/SILGen/SILGenDistributed.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ void SILGenFunction::emitDistActorIdentityInit(ConstructorDecl *ctor,
212212
initializeProperty(*this, loc, borrowedSelfArg, var, temp);
213213
}
214214

215+
// TODO(distributed): rename to DistributedActorID
215216
InitializeDistActorIdentity::InitializeDistActorIdentity(ConstructorDecl *ctor,
216217
ManagedValue actorSelf)
217218
: ctor(ctor),

lib/SILGen/SILGenExpr.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3504,6 +3504,23 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
35043504
// stable identifier.
35053505
return SGM.getFunction(getterRef, NotForDefinition);
35063506
}
3507+
case AccessStrategy::DirectToDistributedThunkAccessor: {
3508+
assert(false && "dont need this");
3509+
// Locate the distributed thunk for the getter of this property
3510+
fprintf(stderr, "[%s:%d] (%s) CHECKING.... DirectToDistributedThunkAccessor\n", __FILE__, __LINE__, __FUNCTION__);
3511+
auto representativeDecl = getRepresentativeAccessorForKeyPath(storage);
3512+
assert(representativeDecl->isDistributed());
3513+
fprintf(stderr, "[%s:%d] (%s) OK, representative is DIST\n", __FILE__, __LINE__, __FUNCTION__);
3514+
3515+
auto getterThunkRef = SILDeclRef(representativeDecl->getDistributedThunk(),
3516+
SILDeclRef::Kind::Func,
3517+
/*isForeign=*/false,
3518+
/*isDistributed=*/true);
3519+
fprintf(stderr, "[%s:%d] (%s) THUNK\n", __FILE__, __LINE__, __FUNCTION__);
3520+
getterThunkRef.dump();
3521+
3522+
return SGM.getFunction(getterThunkRef, NotForDefinition);
3523+
}
35073524
case AccessStrategy::DispatchToAccessor: {
35083525
// Identify the property by its vtable or wtable slot.
35093526
return SGM.getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage));

lib/SILGen/SILGenFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
14441444
ArgumentSource &&optionalSelfValue, bool isSuper,
14451445
bool isDirectAccessorUse,
14461446
PreparedArguments &&optionalSubscripts, SGFContext C,
1447-
bool isOnSelfParameter);
1447+
bool isOnSelfParameter,
1448+
bool shouldUseDistributedThunk);
14481449

14491450
void emitSetAccessor(SILLocation loc, SILDeclRef setter,
14501451
SubstitutionMap substitutions,

lib/SILGen/SILGenLValue.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ namespace {
12921292
bool IsSuper;
12931293
bool IsDirectAccessorUse;
12941294
bool IsOnSelfParameter;
1295+
bool IsDistributedAccessor;
12951296
SubstitutionMap Substitutions;
12961297
Optional<ActorIsolation> ActorIso;
12971298

@@ -1304,12 +1305,15 @@ namespace {
13041305
ArgumentList *argListForDiagnostics,
13051306
PreparedArguments &&indices,
13061307
bool isOnSelfParameter = false,
1308+
bool isDistributedAccessor = false,
13071309
Optional<ActorIsolation> actorIso = None)
13081310
: super(kind, decl, baseFormalType, typeData, argListForDiagnostics,
13091311
std::move(indices)),
13101312
Accessor(accessor), IsSuper(isSuper),
13111313
IsDirectAccessorUse(isDirectAccessorUse),
1312-
IsOnSelfParameter(isOnSelfParameter), Substitutions(substitutions),
1314+
IsOnSelfParameter(isOnSelfParameter),
1315+
IsDistributedAccessor(isDistributedAccessor),
1316+
Substitutions(substitutions),
13131317
ActorIso(actorIso) {}
13141318

13151319
AccessorBasedComponent(const AccessorBasedComponent &copied,
@@ -1320,6 +1324,7 @@ namespace {
13201324
IsSuper(copied.IsSuper),
13211325
IsDirectAccessorUse(copied.IsDirectAccessorUse),
13221326
IsOnSelfParameter(copied.IsOnSelfParameter),
1327+
IsDistributedAccessor(copied.IsDistributedAccessor),
13231328
Substitutions(copied.Substitutions),
13241329
ActorIso(copied.ActorIso) {}
13251330

@@ -1341,11 +1346,13 @@ namespace {
13411346
ArgumentList *subscriptArgList,
13421347
PreparedArguments &&indices,
13431348
bool isOnSelfParameter,
1349+
bool isDistributedAccessor,
13441350
Optional<ActorIsolation> actorIso)
13451351
: AccessorBasedComponent(GetterSetterKind, decl, accessor, isSuper,
13461352
isDirectAccessorUse, substitutions,
13471353
baseFormalType, typeData, subscriptArgList,
1348-
std::move(indices), isOnSelfParameter, actorIso)
1354+
std::move(indices), isOnSelfParameter,
1355+
isDistributedAccessor, actorIso)
13491356
{
13501357
assert(getAccessorDecl()->isGetterOrSetter());
13511358
}
@@ -1650,7 +1657,8 @@ namespace {
16501657

16511658
rvalue = SGF.emitGetAccessor(
16521659
loc, getter, Substitutions, std::move(args.base), IsSuper,
1653-
IsDirectAccessorUse, std::move(args.Indices), c, IsOnSelfParameter);
1660+
IsDirectAccessorUse, std::move(args.Indices), c,
1661+
IsOnSelfParameter, IsDistributedAccessor);
16541662

16551663
} // End the evaluation scope before any hop back to the current executor.
16561664

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
3+
// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
4+
// RUN: %target-run %t/a.out | %FileCheck %s --color
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: concurrency
8+
// REQUIRES: distributed
9+
10+
// rdar://76038845
11+
// UNSUPPORTED: use_os_stdlib
12+
// UNSUPPORTED: back_deployment_runtime
13+
14+
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
15+
// UNSUPPORTED: windows
16+
17+
import Distributed
18+
import FakeDistributedActorSystems
19+
20+
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
21+
22+
distributed actor Greeter {
23+
distributed var theDistributedProperty: String {
24+
"Patrik the Seastar"
25+
}
26+
}
27+
28+
func test() async throws {
29+
let system = DefaultDistributedActorSystem()
30+
31+
let local = Greeter(actorSystem: system)
32+
let ref = try Greeter.resolve(id: local.id, using: system)
33+
34+
let reply = try await ref.theDistributedProperty
35+
// CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.name, invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String
36+
// CHECK: << remoteCall return: Patrick the Seastar
37+
print("reply: \(reply)")
38+
// CHECK: reply: Echo: Caplin
39+
}
40+
41+
@main struct Main {
42+
static func main() async {
43+
try! await test()
44+
}
45+
}

test/Distributed/distributed_actor_isolation.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ distributed actor DistributedActor_1 {
4242
distributed let letProperty: String = "" // expected-error{{property 'letProperty' cannot be 'distributed', only computed properties can}}
4343
distributed var varProperty: String = "" // expected-error{{property 'varProperty' cannot be 'distributed', only computed properties can}}
4444

45+
distributed var computed: String {
46+
"computed"
47+
}
48+
49+
distributed var computedNotCodable: NotCodableValue { // expected-error{{result type 'NotCodableValue' of distributed property 'computedNotCodable' does not conform to serialization requirement 'Codable'}}
50+
.init()
51+
}
52+
53+
distributed var getSet: String { // expected-error{{'distributed' computed property 'getSet' cannot have setter}}
54+
get {
55+
"computed"
56+
}
57+
set {
58+
_ = newValue
59+
}
60+
}
61+
4562
distributed static func distributedStatic() {} // expected-error{{'distributed' method cannot be 'static'}}
4663
distributed class func distributedClass() {}
4764
// expected-error@-1{{class methods are only allowed within classes; use 'static' to declare a static method}}

test/Distributed/distributed_actor_var_implicitly_async_throws.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ distributed actor D {
3333
"dist"
3434
}
3535

36+
// OK:
37+
distributed var distGet: String {
38+
distributed get {
39+
"okey"
40+
}
41+
}
42+
43+
distributed var distSetGet: String {
44+
distributed set {
45+
_ = newValue
46+
}
47+
distributed get {
48+
"okey"
49+
}
50+
}
51+
3652
// expected-error@+1{{'distributed' property 'hello' cannot be 'static'}}
3753
static distributed var hello: String {
3854
"nope!"

0 commit comments

Comments
 (0)