Skip to content

Commit 58f4969

Browse files
committed
Add mangling, metadata, and reflection support for "isolated" parameters.
Isolated parameters are part of function types. Encode them in function type manglings and metadata, and ensure that they round-trip through the various mangling and metadata facilities. This nails down the ABI for isolated parameters.
1 parent 4afa371 commit 58f4969

File tree

17 files changed

+86
-3
lines changed

17 files changed

+86
-3
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ Types
611611
type-list ::= empty-list
612612

613613
// FIXME: Consider replacing 'h' with a two-char code
614-
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, and variadic specifier
614+
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'Yi'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, actor 'isolated', and variadic specifier
615615

616616
METATYPE-REPR ::= 't' // Thin metatype representation
617617
METATYPE-REPR ::= 'T' // Thick metatype representation

include/swift/ABI/MetadataValues.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ class TargetParameterTypeFlags {
950950
ValueOwnershipMask = 0x7F,
951951
VariadicMask = 0x80,
952952
AutoClosureMask = 0x100,
953-
NoDerivativeMask = 0x200
953+
NoDerivativeMask = 0x200,
954+
IsolatedMask = 0x400,
954955
};
955956
int_type Data;
956957

@@ -983,10 +984,17 @@ class TargetParameterTypeFlags {
983984
(Data & ~NoDerivativeMask) | (isNoDerivative ? NoDerivativeMask : 0));
984985
}
985986

987+
constexpr TargetParameterTypeFlags<int_type>
988+
withIsolated(bool isIsolated) const {
989+
return TargetParameterTypeFlags<int_type>(
990+
(Data & ~IsolatedMask) | (isIsolated ? IsolatedMask : 0));
991+
}
992+
986993
bool isNone() const { return Data == 0; }
987994
bool isVariadic() const { return Data & VariadicMask; }
988995
bool isAutoClosure() const { return Data & AutoClosureMask; }
989996
bool isNoDerivative() const { return Data & NoDerivativeMask; }
997+
bool isIsolated() const { return Data & IsolatedMask; }
990998

991999
ValueOwnership getValueOwnership() const {
9921000
return (ValueOwnership)(Data & ValueOwnershipMask);

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ NODE(ImplErrorResult)
133133
NODE(InOut)
134134
NODE(InfixOperator)
135135
CONTEXT_NODE(Initializer)
136+
NODE(Isolated)
136137
NODE(KeyPathGetterThunkHelper)
137138
NODE(KeyPathSetterThunkHelper)
138139
NODE(KeyPathEqualsThunkHelper)

include/swift/Demangling/TypeDecoder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class FunctionParam {
7373
Flags = Flags.withValueOwnership(ownership);
7474
}
7575
void setNoDerivative() { Flags = Flags.withNoDerivative(true); }
76+
void setIsolated() { Flags = Flags.withIsolated(true); }
7677
void setFlags(ParameterFlags flags) { Flags = flags; };
7778

7879
FunctionParam withLabel(StringRef label) const {
@@ -1415,6 +1416,12 @@ class TypeDecoder {
14151416
hasParamFlags = true;
14161417
break;
14171418

1419+
case NodeKind::Isolated:
1420+
param.setIsolated();
1421+
node = node->getFirstChild();
1422+
hasParamFlags = true;
1423+
break;
1424+
14181425
case NodeKind::AutoClosureType:
14191426
case NodeKind::EscapingAutoClosureType:
14201427
param.setAutoClosure();

lib/AST/ASTMangler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,6 +2571,9 @@ void ASTMangler::appendTypeListElement(Identifier name, Type elementType,
25712571
appendOperator("n");
25722572
break;
25732573
}
2574+
if (flags.isIsolated())
2575+
appendOperator("Yi");
2576+
25742577
if (!name.empty())
25752578
appendIdentifier(name.str());
25762579
if (flags.isVariadic())

lib/Demangling/Demangler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ NodePointer Demangler::demangleTypeAnnotation() {
739739
case 'c':
740740
return createWithChild(
741741
Node::Kind::GlobalActorFunctionType, popTypeAndGetChild());
742+
case 'i':
743+
return createType(
744+
createWithChild(Node::Kind::Isolated, popTypeAndGetChild()));
742745
case 'j':
743746
return demangleDifferentiableFunctionType();
744747
case 'k':

lib/Demangling/NodePrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ class NodePrinter {
416416
case Node::Kind::InOut:
417417
case Node::Kind::InfixOperator:
418418
case Node::Kind::Initializer:
419+
case Node::Kind::Isolated:
419420
case Node::Kind::PropertyWrapperBackingInitializer:
420421
case Node::Kind::PropertyWrapperInitFromProjectedValue:
421422
case Node::Kind::KeyPathGetterThunkHelper:
@@ -1423,6 +1424,10 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
14231424
Printer << "inout ";
14241425
print(Node->getChild(0));
14251426
return nullptr;
1427+
case Node::Kind::Isolated:
1428+
Printer << "isolated ";
1429+
print(Node->getChild(0));
1430+
return nullptr;
14261431
case Node::Kind::Shared:
14271432
Printer << "__shared ";
14281433
print(Node->getChild(0));

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,11 @@ void Remangler::mangleInOut(Node *node) {
14941494
mangleSingleChildNode(node); // type
14951495
}
14961496

1497+
void Remangler::mangleIsolated(Node *node) {
1498+
Buffer << "Yi";
1499+
mangleSingleChildNode(node); // type
1500+
}
1501+
14971502
void Remangler::mangleNoDerivative(Node *node) {
14981503
Buffer << 'k';
14991504
mangleSingleChildNode(node); // type

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,11 @@ void Remangler::mangleInOut(Node *node) {
16701670
Buffer << 'z';
16711671
}
16721672

1673+
void Remangler::mangleIsolated(Node *node) {
1674+
mangleSingleChildNode(node);
1675+
Buffer << "Yi";
1676+
}
1677+
16731678
void Remangler::mangleShared(Node *node) {
16741679
mangleSingleChildNode(node);
16751680
Buffer << 'h';

lib/IRGen/MetadataRequest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,8 @@ namespace {
13831383
.withValueOwnership(flags.getValueOwnership())
13841384
.withVariadic(flags.isVariadic())
13851385
.withAutoClosure(flags.isAutoClosure())
1386-
.withNoDerivative(flags.isNoDerivative());
1386+
.withNoDerivative(flags.isNoDerivative())
1387+
.withIsolated(flags.isIsolated());
13871388
};
13881389

13891390
bool hasParameterFlags = false;

stdlib/public/Reflection/TypeRef.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ class PrintTypeRef : public TypeRefVisitor<PrintTypeRef, void> {
199199
break;
200200
}
201201

202+
if (flags.isIsolated())
203+
printHeader("isolated");
204+
202205
if (flags.isVariadic())
203206
printHeader("variadic");
204207

@@ -633,6 +636,9 @@ class DemanglingForTypeRef
633636
wrapInput(Node::Kind::Owned);
634637
break;
635638
}
639+
if (flags.isIsolated()) {
640+
wrapInput(Node::Kind::Isolated);
641+
}
636642

637643
inputs.push_back({input, flags.isVariadic()});
638644
}

stdlib/public/runtime/Demangle.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
499499
wrapInput(Node::Kind::Owned);
500500
break;
501501
}
502+
if (flags.isIsolated()) {
503+
wrapInput(Node::Kind::Isolated);
504+
}
502505

503506
inputs.push_back({input, flags.isVariadic()});
504507
}

test/Demangle/Inputs/manglings.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,5 @@ $sScA ---> Swift.Actor
407407
$sScGySiG ---> Swift.TaskGroup<Swift.Int>
408408
$s4test10returnsOptyxycSgxyScMYccSglF ---> test.returnsOpt<A>((@Swift.MainActor () -> A)?) -> (() -> A)?
409409
$sSvSgA3ASbIetCyyd_SgSbIetCyyyd_SgD ---> (@escaping @convention(thin) @convention(c) (@unowned Swift.UnsafeMutableRawPointer?, @unowned Swift.UnsafeMutableRawPointer?, @unowned (@escaping @convention(thin) @convention(c) (@unowned Swift.UnsafeMutableRawPointer?, @unowned Swift.UnsafeMutableRawPointer?) -> (@unowned Swift.Bool))?) -> (@unowned Swift.Bool))?
410+
$s4test10returnsOptyxycSgxyScMYccSglF ---> test.returnsOpt<A>(@Swift.MainActor () -> A?) -> () -> A?
411+
$s1t10globalFuncyyAA7MyActorCYiF ---> t.globalFunc(isolated t.MyActor) -> ()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
@available(SwiftStdlib 5.5, *)
2+
public actor SomeActor {
3+
}
4+
5+
@available(SwiftStdlib 5.5, *)
16
public struct UsesConcurrency {
27
public var mainActorFunction: @MainActor () -> Void
8+
public var actorIsolatedFunction: (isolated SomeActor) -> Void
39
}

test/Reflection/typeref_decoding_concurrency.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@
2323
// CHECK: (function
2424
// CHECK: (global-actor
2525
// CHECK: (class Swift.MainActor))
26+
27+
// CHECK: actorIsolatedFunction: (isolated TypesToReflect.SomeActor) -> ()
28+
// CHECK: (function
29+
// CHECK: (parameters
30+
// CHECK: isolated
31+
// CHECK: (class TypesToReflect.SomeActor))

test/Runtime/demangleToMetadata.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ func globalActorMetatypeFn<T>(_: T.Type) -> Any.Type {
6060
return Fn.self
6161
}
6262

63+
@available(SwiftStdlib 5.5, *)
64+
func f1_actor(_: (isolated Actor) -> Void) { }
65+
6366
DemangleToMetadataTests.test("function types") {
6467
// Conventions
6568
expectEqual(type(of: f0), _typeByName("yyc")!)
@@ -114,6 +117,13 @@ DemangleToMetadataTests.test("function types") {
114117
typealias MainActorFn = @MainActor () -> Float
115118
expectEqual(MainActorFn.self, _typeByName("SfyScMYcc")!)
116119
expectEqual(MainActorFn.self, globalActorMetatypeFn(Float.self))
120+
121+
// isolated parameters
122+
if #available(SwiftStdlib 5.5, *) {
123+
expectEqual(type(of: f1_actor), _typeByName("yyScA_pYiXEc")!)
124+
typealias IsolatedFn = ((isolated Actor) -> Void) -> Void
125+
expectEqual(IsolatedFn.self, type(of: f1_actor))
126+
}
117127
}
118128

119129
DemangleToMetadataTests.test("metatype types") {

test/SILGen/isolated_parameters.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 | %FileCheck %s
2+
// REQUIRES: concurrency
3+
4+
@available(SwiftStdlib 5.5, *)
5+
public actor A {
6+
// CHECK: sil {{.*}} [ossa] @$s4test1AC6methodyyF
7+
public func method() { }
8+
}
9+
10+
// CHECK: sil {{.*}} [ossa] @$s4test13takesIsolatedyyAA1ACYiF
11+
@available(SwiftStdlib 5.5, *)
12+
public func takesIsolated(_: isolated A) { }

0 commit comments

Comments
 (0)