Skip to content

Commit 325ca87

Browse files
authored
Merge pull request #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;

include/swift/Reflection/TypeRef.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,12 @@ class FunctionTypeRef final : public TypeRef {
462462
const TypeRef *Result;
463463
FunctionTypeFlags Flags;
464464
FunctionMetadataDifferentiabilityKind DifferentiabilityKind;
465+
const TypeRef *GlobalActor;
465466

466467
static TypeRefID Profile(const std::vector<Param> &Parameters,
467468
const TypeRef *Result, FunctionTypeFlags Flags,
468-
FunctionMetadataDifferentiabilityKind DiffKind) {
469+
FunctionMetadataDifferentiabilityKind DiffKind,
470+
const TypeRef *GlobalActor) {
469471
TypeRefID ID;
470472
for (const auto &Param : Parameters) {
471473
ID.addString(Param.getLabel().str());
@@ -475,21 +477,27 @@ class FunctionTypeRef final : public TypeRef {
475477
ID.addPointer(Result);
476478
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));
477479
ID.addInteger(static_cast<uint64_t>(DiffKind.getIntValue()));
480+
ID.addPointer(GlobalActor);
481+
478482
return ID;
479483
}
480484

481485
public:
482486
FunctionTypeRef(std::vector<Param> Params, const TypeRef *Result,
483487
FunctionTypeFlags Flags,
484-
FunctionMetadataDifferentiabilityKind DiffKind)
488+
FunctionMetadataDifferentiabilityKind DiffKind,
489+
const TypeRef *GlobalActor)
485490
: TypeRef(TypeRefKind::Function), Parameters(Params), Result(Result),
486-
Flags(Flags), DifferentiabilityKind(DiffKind) {}
491+
Flags(Flags), DifferentiabilityKind(DiffKind),
492+
GlobalActor(GlobalActor) {}
487493

488494
template <typename Allocator>
489495
static const FunctionTypeRef *create(
490496
Allocator &A, std::vector<Param> Params, const TypeRef *Result,
491-
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind) {
492-
FIND_OR_CREATE_TYPEREF(A, FunctionTypeRef, Params, Result, Flags, DiffKind);
497+
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind,
498+
const TypeRef *GlobalActor) {
499+
FIND_OR_CREATE_TYPEREF(
500+
A, FunctionTypeRef, Params, Result, Flags, DiffKind, GlobalActor);
493501
}
494502

495503
const std::vector<Param> &getParameters() const { return Parameters; };
@@ -506,6 +514,10 @@ class FunctionTypeRef final : public TypeRef {
506514
return DifferentiabilityKind;
507515
}
508516

517+
const TypeRef *getGlobalActor() const {
518+
return GlobalActor;
519+
}
520+
509521
static bool classof(const TypeRef *TR) {
510522
return TR->getKind() == TypeRefKind::Function;
511523
}

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,10 @@ class TypeRefBuilder {
415415
const FunctionTypeRef *createFunctionType(
416416
llvm::ArrayRef<remote::FunctionParam<const TypeRef *>> params,
417417
const TypeRef *result, FunctionTypeFlags flags,
418-
FunctionMetadataDifferentiabilityKind diffKind) {
419-
return FunctionTypeRef::create(*this, params, result, flags, diffKind);
418+
FunctionMetadataDifferentiabilityKind diffKind,
419+
const TypeRef *globalActor) {
420+
return FunctionTypeRef::create(
421+
*this, params, result, flags, diffKind, globalActor);
420422
}
421423

422424
const FunctionTypeRef *createImplFunctionType(
@@ -472,7 +474,8 @@ class TypeRefBuilder {
472474
}
473475

474476
auto result = createTupleType({}, "");
475-
return FunctionTypeRef::create(*this, {}, result, funcFlags, diffKind);
477+
return FunctionTypeRef::create(
478+
*this, {}, result, funcFlags, diffKind, nullptr);
476479
}
477480

478481
const ProtocolCompositionTypeRef *

0 commit comments

Comments
 (0)