Skip to content

Commit 325ca87

Browse files
authored
Merge pull request swiftlang#37789 from DougGregor/global-actor-function-types-abi-5.5
Concurrency ABI for global-actor-qualified function types
2 parents e263ff0 + 4fb68fb commit 325ca87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+606
-141
lines changed

docs/ABI/Mangling.rst

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ Types
466466
KNOWN-TYPE-KIND ::= 'a' // Swift.Array
467467
KNOWN-TYPE-KIND ::= 'B' // Swift.BinaryFloatingPoint
468468
KNOWN-TYPE-KIND ::= 'b' // Swift.Bool
469+
KNOWN-TYPE-KIND ::= 'c' KNOWN-TYPE-KIND-2 // Second set of standard types
469470
KNOWN-TYPE-KIND ::= 'D' // Swift.Dictionary
470471
KNOWN-TYPE-KIND ::= 'd' // Swift.Float64
471472
KNOWN-TYPE-KIND ::= 'E' // Swift.Encodable
@@ -511,6 +512,25 @@ Types
511512
KNOWN-TYPE-KIND ::= 'Z' // Swift.SignedInteger
512513
KNOWN-TYPE-KIND ::= 'z' // Swift.BinaryInteger
513514

515+
KNOWN-TYPE-KIND-2 ::= 'A' // Swift.Actor
516+
KNOWN-TYPE-KIND-2 ::= 'C' // Swift.CheckedContinuation
517+
KNOWN-TYPE-KIND-2 ::= 'c' // Swift.UnsafeContinuation
518+
KNOWN-TYPE-KIND-2 ::= 'E' // Swift.CancellationError
519+
KNOWN-TYPE-KIND-2 ::= 'e' // Swift.UnownedSerialExecutor
520+
KNOWN-TYPE-KIND-2 ::= 'F' // Swift.Executor
521+
KNOWN-TYPE-KIND-2 ::= 'f' // Swift.SerialExecutor
522+
KNOWN-TYPE-KIND-2 ::= 'G' // Swift.TaskGroup
523+
KNOWN-TYPE-KIND-2 ::= 'g' // Swift.ThrowingTaskGroup
524+
KNOWN-TYPE-KIND-2 ::= 'I' // Swift.AsyncIteratorProtocol
525+
KNOWN-TYPE-KIND-2 ::= 'i' // Swift.AsyncSequence
526+
KNOWN-TYPE-KIND-2 ::= 'J' // Swift.UnownedJob
527+
KNOWN-TYPE-KIND-2 ::= 'M' // Swift.MainActor
528+
KNOWN-TYPE-KIND-2 ::= 'P' // Swift.TaskPriority
529+
KNOWN-TYPE-KIND-2 ::= 'S' // Swift.AsyncStream
530+
KNOWN-TYPE-KIND-2 ::= 's' // Swift.AsyncThrowingStream
531+
KNOWN-TYPE-KIND-2 ::= 'T' // Swift.Task
532+
KNOWN-TYPE-KIND-2 ::= 't' // Swift.UnsafeCurrentTask
533+
514534
protocol ::= context decl-name
515535
protocol ::= standard-substitutions
516536

@@ -569,7 +589,7 @@ Types
569589
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
570590
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
571591

572-
function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
592+
function-signature ::= params-type params-type async? sendable? throws? differentiable? global-actor? // results and parameters
573593

574594
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
575595
// with optional inout convention, shared convention. parameters don't have labels,
@@ -579,6 +599,7 @@ Types
579599
#if SWIFT_RUNTIME_VERSION >= 5.5
580600
async ::= 'Ya' // 'async' annotation on function types
581601
sendable ::= 'Yb' // @Sendable on function types
602+
global-actor :: = type 'Yc' // Global actor on function type
582603
#endif
583604
throws ::= 'K' // 'throws' annotation on function types
584605
differentiable ::= 'Yjf' // @differentiable(_forward) on function type

include/swift/ABI/Metadata.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,7 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
16651665
bool isDifferentiable() const { return Flags.isDifferentiable(); }
16661666
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
16671667
bool isEscaping() const { return Flags.isEscaping(); }
1668+
bool hasGlobalActor() const { return Flags.hasGlobalActor(); }
16681669

16691670
static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);
16701671

@@ -1702,6 +1703,31 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
17021703
return TargetFunctionMetadataDifferentiabilityKind<StoredSize>
17031704
::NonDifferentiable;
17041705
}
1706+
1707+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *
1708+
getGlobalActorAddr() {
1709+
assert(hasGlobalActor());
1710+
1711+
void *endAddr =
1712+
isDifferentiable()
1713+
? reinterpret_cast<void *>(getDifferentiabilityKindAddress() + 1) :
1714+
hasParameterFlags()
1715+
? reinterpret_cast<void *>(getParameterFlags() + getNumParameters()) :
1716+
reinterpret_cast<void *>(getParameters() + getNumParameters());
1717+
return reinterpret_cast<
1718+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *>(
1719+
llvm::alignAddr(
1720+
endAddr, llvm::Align(alignof(typename Runtime::StoredPointer))));
1721+
}
1722+
1723+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>
1724+
getGlobalActor() const {
1725+
if (!hasGlobalActor())
1726+
return ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>();
1727+
1728+
return *const_cast<TargetFunctionTypeMetadata<Runtime> *>(this)
1729+
->getGlobalActorAddr();
1730+
}
17051731
};
17061732
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
17071733

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,10 @@ class TargetFunctionTypeFlags {
834834
ParamFlagsMask = 0x02000000U,
835835
EscapingMask = 0x04000000U,
836836
DifferentiableMask = 0x08000000U,
837+
GlobalActorMask = 0x10000000U,
837838
AsyncMask = 0x20000000U,
838839
SendableMask = 0x40000000U,
840+
// NOTE: The next bit will need to introduce a separate flags word.
839841
};
840842
int_type Data;
841843

@@ -891,6 +893,12 @@ class TargetFunctionTypeFlags {
891893
(isSendable ? SendableMask : 0));
892894
}
893895

896+
constexpr TargetFunctionTypeFlags<int_type>
897+
withGlobalActor(bool globalActor) const {
898+
return TargetFunctionTypeFlags<int_type>(
899+
(Data & ~GlobalActorMask) | (globalActor ? GlobalActorMask : 0));
900+
}
901+
894902
unsigned getNumParameters() const { return Data & NumParametersMask; }
895903

896904
FunctionMetadataConvention getConvention() const {
@@ -915,6 +923,10 @@ class TargetFunctionTypeFlags {
915923
return bool (Data & DifferentiableMask);
916924
}
917925

926+
bool hasGlobalActor() const {
927+
return bool (Data & GlobalActorMask);
928+
}
929+
918930
int_type getIntValue() const {
919931
return Data;
920932
}

include/swift/AST/ASTDemangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class ASTBuilder {
9898
Type createFunctionType(
9999
ArrayRef<Demangle::FunctionParam<Type>> params,
100100
Type output, FunctionTypeFlags flags,
101-
FunctionMetadataDifferentiabilityKind diffKind);
101+
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor);
102102

103103
Type createImplFunctionType(
104104
Demangle::ImplParameterConvention calleeConvention,

include/swift/AST/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,9 @@ class ModuleDecl : public DeclContext, public TypeDecl {
713713
/// \returns true if this module is the "swift" standard library module.
714714
bool isStdlibModule() const;
715715

716+
/// \returns true if this module has standard substitutions for mangling.
717+
bool hasStandardSubstitutions() const;
718+
716719
/// \returns true if this module is the "SwiftShims" module;
717720
bool isSwiftShimsModule() const;
718721

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ NODE(ErrorType)
8282
NODE(EscapingAutoClosureType)
8383
NODE(NoEscapeFunctionType)
8484
NODE(ConcurrentFunctionType)
85+
NODE(GlobalActorFunctionType)
8586
NODE(DifferentiableFunctionType)
8687
NODE(ExistentialMetatype)
8788
CONTEXT_NODE(ExplicitClosure)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ class Demangler : public NodeFactory {
494494
NodePointer pushMultiSubstitutions(int RepeatCount, size_t SubstIdx);
495495
NodePointer createSwiftType(Node::Kind typeKind, const char *name);
496496
NodePointer demangleStandardSubstitution();
497-
NodePointer createStandardSubstitution(char Subst);
497+
NodePointer createStandardSubstitution(char Subst, bool SecondLevel);
498498
NodePointer demangleLocalIdentifier();
499499

500500
NodePointer popModule();

include/swift/Demangling/ManglingUtils.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ char translateOperatorChar(char op);
9999
std::string translateOperator(StringRef Op);
100100

101101
/// Returns the standard type kind for an 'S' substitution, e.g. 'i' for "Int".
102-
char getStandardTypeSubst(StringRef TypeName);
102+
llvm::Optional<StringRef> getStandardTypeSubst(StringRef TypeName);
103103

104104
/// Mangles an identifier using a generic Mangler class.
105105
///
@@ -274,8 +274,9 @@ class SubstitutionMerging {
274274
/// *) getBufferStr(): Returns a StringRef of the current content of Buffer.
275275
/// *) resetBuffer(size_t): Resets the buffer to an old position.
276276
template <typename Mangler>
277-
bool tryMergeSubst(Mangler &M, char Subst, bool isStandardSubst) {
278-
assert(isUpperLetter(Subst) || (isStandardSubst && isLowerLetter(Subst)));
277+
bool tryMergeSubst(Mangler &M, StringRef Subst, bool isStandardSubst) {
278+
assert(isUpperLetter(Subst.back()) ||
279+
(isStandardSubst && isLowerLetter(Subst.back())));
279280
StringRef BufferStr = M.getBufferStr();
280281
if (lastNumSubsts > 0 && lastNumSubsts < MaxRepeatCount
281282
&& BufferStr.size() == lastSubstPosition + lastSubstSize
@@ -284,17 +285,20 @@ class SubstitutionMerging {
284285
// The last mangled thing is a substitution.
285286
assert(lastSubstPosition > 0 && lastSubstPosition < BufferStr.size());
286287
assert(lastSubstSize > 0);
287-
char lastSubst = BufferStr.back();
288-
assert(isUpperLetter(lastSubst)
289-
|| (isStandardSubst && isLowerLetter(lastSubst)));
288+
StringRef lastSubst = BufferStr.take_back(lastSubstSize)
289+
.drop_while([](char c) {
290+
return isDigit(c);
291+
});
292+
assert(isUpperLetter(lastSubst.back())
293+
|| (isStandardSubst && isLowerLetter(lastSubst.back())));
290294
if (lastSubst != Subst && !isStandardSubst) {
291295
// We can merge with a different 'A' substitution,
292296
// e.g. 'AB' -> 'AbC'.
293297
lastSubstPosition = BufferStr.size();
294298
lastNumSubsts = 1;
295299
M.resetBuffer(BufferStr.size() - 1);
296-
assert(isUpperLetter(lastSubst));
297-
M.Buffer << (char)(lastSubst - 'A' + 'a') << Subst;
300+
assert(isUpperLetter(lastSubst.back()));
301+
M.Buffer << (char)(lastSubst.back() - 'A' + 'a') << Subst;
298302
lastSubstSize = 1;
299303
return true;
300304
}
@@ -312,7 +316,7 @@ class SubstitutionMerging {
312316
// We can't merge with the previous substitution, but let's remember this
313317
// substitution which will be mangled by the caller.
314318
lastSubstPosition = BufferStr.size() + 1;
315-
lastSubstSize = 1;
319+
lastSubstSize = Subst.size();
316320
lastNumSubsts = 1;
317321
lastSubstIsStandardSubst = isStandardSubst;
318322
return false;

include/swift/Demangling/StandardTypesMangling.def

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212

1313
/// STANDARD_TYPE(KIND, MANGLING, TYPENAME)
1414
/// The 1-character MANGLING for a known TYPENAME of KIND.
15-
15+
///
16+
/// STANDARD_TYPE_2(KIND, MANGLING, TYPENAME)
17+
/// The 1-character MANGLING for a known TYPENAME of KIND that is in the
18+
/// second level of standard types, all of which are mangled with the form
19+
/// Sc<MANGLING>.
20+
///
1621
/// OBJC_INTEROP_STANDARD_TYPE(KIND, MANGLING, TYPENAME)
1722
/// The 1-character MANGLING for a known TYPENAME of KIND, for a type that's
1823
/// only available with ObjC interop enabled.
@@ -22,6 +27,7 @@
2227
STANDARD_TYPE(KIND, MANGLING, TYPENAME)
2328
#endif
2429

30+
2531
OBJC_INTEROP_STANDARD_TYPE(Structure, A, AutoreleasingUnsafeMutablePointer)
2632
STANDARD_TYPE(Structure, a, Array)
2733
STANDARD_TYPE(Structure, b, Bool)
@@ -73,5 +79,25 @@ STANDARD_TYPE(Protocol, y, StringProtocol)
7379
STANDARD_TYPE(Protocol, Z, SignedInteger)
7480
STANDARD_TYPE(Protocol, z, BinaryInteger)
7581

82+
STANDARD_TYPE_2(Protocol, A, Actor)
83+
STANDARD_TYPE_2(Structure, C, CheckedContinuation)
84+
STANDARD_TYPE_2(Structure, c, UnsafeContinuation)
85+
STANDARD_TYPE_2(Structure, E, CancellationError)
86+
STANDARD_TYPE_2(Structure, e, UnownedSerialExecutor)
87+
STANDARD_TYPE_2(Protocol, F, Executor)
88+
STANDARD_TYPE_2(Protocol, f, SerialExecutor)
89+
STANDARD_TYPE_2(Structure, G, TaskGroup)
90+
STANDARD_TYPE_2(Structure, g, ThrowingTaskGroup)
91+
STANDARD_TYPE_2(Protocol, I, AsyncIteratorProtocol)
92+
STANDARD_TYPE_2(Protocol, i, AsyncSequence)
93+
STANDARD_TYPE_2(Structure, J, UnownedJob)
94+
STANDARD_TYPE_2(Class, M, MainActor)
95+
STANDARD_TYPE_2(Structure, P, TaskPriority)
96+
STANDARD_TYPE_2(Structure, S, AsyncStream)
97+
STANDARD_TYPE_2(Structure, s, AsyncThrowingStream)
98+
STANDARD_TYPE_2(Structure, T, Task)
99+
STANDARD_TYPE_2(Structure, t, UnsafeCurrentTask)
100+
76101
#undef STANDARD_TYPE
77102
#undef OBJC_INTEROP_STANDARD_TYPE
103+
#undef STANDARD_TYPE_2

include/swift/Demangling/TypeDecoder.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,23 @@ class TypeDecoder {
738738
++firstChildIdx;
739739
}
740740

741+
BuiltType globalActorType = BuiltType();
742+
if (Node->getChild(firstChildIdx)->getKind() ==
743+
NodeKind::GlobalActorFunctionType) {
744+
auto child = Node->getChild(firstChildIdx);
745+
if (child->getNumChildren() < 1) {
746+
return MAKE_NODE_TYPE_ERROR0(child,
747+
"Global actor node is missing child");
748+
}
749+
750+
auto globalActorResult = decodeMangledType(child->getChild(0));
751+
if (globalActorResult.isError())
752+
return globalActorResult;
753+
754+
globalActorType = globalActorResult.getType();
755+
++firstChildIdx;
756+
}
757+
741758
FunctionMetadataDifferentiabilityKind diffKind;
742759
if (Node->getChild(firstChildIdx)->getKind() ==
743760
NodeKind::DifferentiableFunctionType) {
@@ -811,7 +828,7 @@ class TypeDecoder {
811828
if (result.isError())
812829
return result;
813830
return Builder.createFunctionType(
814-
parameters, result.getType(), flags, diffKind);
831+
parameters, result.getType(), flags, diffKind, globalActorType);
815832
}
816833
case NodeKind::ImplFunctionType: {
817834
auto calleeConvention = ImplParameterConvention::Direct_Unowned;

0 commit comments

Comments
 (0)