Skip to content

Commit 40e07cf

Browse files
committed
[Typed throws] IR generation and runtime support for function type metadata
Extend function type metadata with an entry for the thrown error type, so that thrown error types are represented at runtime as well. Note that this required the introduction of "extended" function type flags into function type metadata, because we would have used the last bit. Do so, and define one extended flag bit as representing typed throws. Add `swift_getExtendedFunctionTypeMetadata` to the runtime to build function types that have the extended flags and a thrown error type. Teach IR generation to call this function to form the metadata, when appropriate. Introduce all of the runtime mangling/demangling support needed for thrown error types.
1 parent e82854d commit 40e07cf

File tree

18 files changed

+369
-49
lines changed

18 files changed

+369
-49
lines changed

include/swift/ABI/Metadata.h

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,13 @@ template <typename Runtime>
14631463
struct TargetFunctionGlobalActorMetadata {
14641464
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> GlobalActorType;
14651465
};
1466+
using FunctionGlobalActorMetadata = TargetFunctionGlobalActorMetadata<InProcess>;
1467+
1468+
template <typename Runtime>
1469+
struct TargetFunctionThrownErrorMetadata {
1470+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> ThrownErrorType;
1471+
};
1472+
using FunctionThrownErrorMetadata = TargetFunctionThrownErrorMetadata<InProcess>;
14661473

14671474
/// The structure of function type metadata.
14681475
template <typename Runtime>
@@ -1472,7 +1479,9 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
14721479
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>,
14731480
ParameterFlags,
14741481
TargetFunctionMetadataDifferentiabilityKind<typename Runtime::StoredSize>,
1475-
TargetFunctionGlobalActorMetadata<Runtime>> {
1482+
TargetFunctionGlobalActorMetadata<Runtime>,
1483+
ExtendedFunctionTypeFlags,
1484+
TargetFunctionThrownErrorMetadata<Runtime>> {
14761485
using StoredSize = typename Runtime::StoredSize;
14771486
using Parameter = ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>;
14781487

@@ -1483,7 +1492,9 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
14831492
Parameter,
14841493
ParameterFlags,
14851494
TargetFunctionMetadataDifferentiabilityKind<StoredSize>,
1486-
TargetFunctionGlobalActorMetadata<Runtime>>;
1495+
TargetFunctionGlobalActorMetadata<Runtime>,
1496+
ExtendedFunctionTypeFlags,
1497+
TargetFunctionThrownErrorMetadata<Runtime>>;
14871498
friend TrailingObjects;
14881499

14891500
template<typename T>
@@ -1516,6 +1527,16 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
15161527
return hasGlobalActor() ? 1 : 0;
15171528
}
15181529

1530+
size_t numTrailingObjects(OverloadToken<ExtendedFunctionTypeFlags>) const {
1531+
return hasExtendedFlags() ? 1 : 0;
1532+
}
1533+
1534+
size_t numTrailingObjects(
1535+
OverloadToken<TargetFunctionThrownErrorMetadata<Runtime>>
1536+
) const {
1537+
return hasThrownError() ? 1 : 0;
1538+
}
1539+
15191540
public:
15201541
Parameter *getParameters() {
15211542
return this->template getTrailingObjects<Parameter>();
@@ -1548,6 +1569,13 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
15481569
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
15491570
bool isEscaping() const { return Flags.isEscaping(); }
15501571
bool hasGlobalActor() const { return Flags.hasGlobalActor(); }
1572+
bool hasExtendedFlags() const { return Flags.hasExtendedFlags(); }
1573+
bool hasThrownError() const {
1574+
if (!Flags.hasExtendedFlags())
1575+
return false;
1576+
1577+
return getExtendedFlags().isTypedThrows();
1578+
}
15511579

15521580
static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);
15531581

@@ -1594,6 +1622,35 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime>,
15941622
this->template getTrailingObjects<TargetFunctionGlobalActorMetadata<Runtime>>();
15951623
return globalActorAddr->GlobalActorType;
15961624
}
1625+
1626+
ExtendedFunctionTypeFlags *getExtendedFlagsAddr() {
1627+
assert(hasExtendedFlags());
1628+
return this->template getTrailingObjects<ExtendedFunctionTypeFlags>();
1629+
}
1630+
1631+
ExtendedFunctionTypeFlags getExtendedFlags() const {
1632+
if (!hasExtendedFlags())
1633+
return ExtendedFunctionTypeFlags();
1634+
1635+
return this->template getTrailingObjects<ExtendedFunctionTypeFlags>()[0];
1636+
}
1637+
1638+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> *
1639+
getThrownErrorAddr() {
1640+
assert(hasThrownError());
1641+
auto thrownErrorAddr =
1642+
this->template getTrailingObjects<TargetFunctionThrownErrorMetadata<Runtime>>();
1643+
return &thrownErrorAddr->ThrownErrorType;
1644+
}
1645+
1646+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>
1647+
getThrownError() const {
1648+
if (!hasThrownError())
1649+
return ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>();
1650+
auto thrownErrorAddr =
1651+
this->template getTrailingObjects<TargetFunctionThrownErrorMetadata<Runtime>>();
1652+
return thrownErrorAddr->ThrownErrorType;
1653+
}
15971654
};
15981655
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
15991656

include/swift/ABI/MetadataValues.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,8 @@ class TargetFunctionTypeFlags {
10371037
GlobalActorMask = 0x10000000U,
10381038
AsyncMask = 0x20000000U,
10391039
SendableMask = 0x40000000U,
1040-
// NOTE: The next bit will need to introduce a separate flags word.
1040+
ExtendedFlagsMask = 0x80000000U,
1041+
// NOTE: No more room for flags here. Use TargetExtendedFunctionTypeFlags.
10411042
};
10421043
int_type Data;
10431044

@@ -1099,6 +1100,12 @@ class TargetFunctionTypeFlags {
10991100
(Data & ~GlobalActorMask) | (globalActor ? GlobalActorMask : 0));
11001101
}
11011102

1103+
constexpr TargetFunctionTypeFlags<int_type>
1104+
withExtendedFlags(bool extendedFlags) const {
1105+
return TargetFunctionTypeFlags<int_type>(
1106+
(Data & ~ExtendedFlagsMask) | (extendedFlags ? ExtendedFlagsMask : 0));
1107+
}
1108+
11021109
unsigned getNumParameters() const { return Data & NumParametersMask; }
11031110

11041111
FunctionMetadataConvention getConvention() const {
@@ -1127,6 +1134,10 @@ class TargetFunctionTypeFlags {
11271134
return bool (Data & GlobalActorMask);
11281135
}
11291136

1137+
bool hasExtendedFlags() const {
1138+
return bool (Data & ExtendedFlagsMask);
1139+
}
1140+
11301141
int_type getIntValue() const {
11311142
return Data;
11321143
}
@@ -1144,6 +1155,43 @@ class TargetFunctionTypeFlags {
11441155
};
11451156
using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
11461157

1158+
/// Extended flags in a function type metadata record.
1159+
template <typename int_type>
1160+
class TargetExtendedFunctionTypeFlags {
1161+
enum : int_type {
1162+
TypedThrowsMask = 0x00000001U,
1163+
};
1164+
int_type Data;
1165+
1166+
constexpr TargetExtendedFunctionTypeFlags(int_type Data) : Data(Data) {}
1167+
public:
1168+
constexpr TargetExtendedFunctionTypeFlags() : Data(0) {}
1169+
1170+
constexpr TargetExtendedFunctionTypeFlags<int_type>
1171+
withTypedThrows(bool typedThrows) const {
1172+
return TargetExtendedFunctionTypeFlags<int_type>(
1173+
(Data & ~TypedThrowsMask) | (typedThrows ? TypedThrowsMask : 0));
1174+
}
1175+
1176+
bool isTypedThrows() const { return bool(Data & TypedThrowsMask); }
1177+
1178+
int_type getIntValue() const {
1179+
return Data;
1180+
}
1181+
1182+
static TargetExtendedFunctionTypeFlags<int_type> fromIntValue(int_type Data) {
1183+
return TargetExtendedFunctionTypeFlags(Data);
1184+
}
1185+
1186+
bool operator==(TargetExtendedFunctionTypeFlags<int_type> other) const {
1187+
return Data == other.Data;
1188+
}
1189+
bool operator!=(TargetExtendedFunctionTypeFlags<int_type> other) const {
1190+
return Data != other.Data;
1191+
}
1192+
};
1193+
using ExtendedFunctionTypeFlags = TargetExtendedFunctionTypeFlags<uint32_t>;
1194+
11471195
template <typename int_type>
11481196
class TargetParameterTypeFlags {
11491197
enum : int_type {

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,9 @@ class ASTContext final {
914914
/// Get the runtime availability of support for differentiation.
915915
AvailabilityContext getDifferentiationAvailability();
916916

917+
/// Get the runtime availability of support for typed throws.
918+
AvailabilityContext getTypedThrowsAvailability();
919+
917920
/// Get the runtime availability of getters and setters of multi payload enum
918921
/// tag single payloads.
919922
AvailabilityContext getMultiPayloadEnumTagSinglePayload();
@@ -982,6 +985,10 @@ class ASTContext final {
982985
/// compiler for the target platform.
983986
AvailabilityContext getSwift59Availability();
984987

988+
/// Get the runtime availability of features introduced in the Swift 5.9
989+
/// compiler for the target platform.
990+
AvailabilityContext getSwift511Availability();
991+
985992
// Note: Update this function if you add a new getSwiftXYAvailability above.
986993
/// Get the runtime availability for a particular version of Swift (5.0+).
987994
AvailabilityContext

include/swift/Remote/MetadataReader.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,10 @@ class MetadataReader {
10021002
}
10031003

10041004
BuiltType thrownError = BuiltType();
1005-
// FIXME: Read from metadata.
1005+
if (Function->hasThrownError()) {
1006+
thrownError = readTypeFromMetadata(Function->getThrownError(), false,
1007+
recursion_limit);
1008+
}
10061009

10071010
auto BuiltFunction = Builder.createFunctionType(
10081011
Parameters, Result, flags, diffKind, globalActor, thrownError);

include/swift/Runtime/Metadata.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,14 @@ swift_getFunctionTypeMetadataGlobalActor(
504504
const Metadata *const *parameters, const uint32_t *parameterFlags,
505505
const Metadata *result, const Metadata *globalActor);
506506

507+
SWIFT_RUNTIME_EXPORT
508+
const FunctionTypeMetadata *
509+
swift_getExtendedFunctionTypeMetadata(
510+
FunctionTypeFlags flags, FunctionMetadataDifferentiabilityKind diffKind,
511+
const Metadata *const *parameters, const uint32_t *parameterFlags,
512+
const Metadata *result, const Metadata *globalActor,
513+
ExtendedFunctionTypeFlags extFlags, const Metadata *thrownError);
514+
507515
SWIFT_RUNTIME_EXPORT
508516
const FunctionTypeMetadata *
509517
swift_getFunctionTypeMetadata0(FunctionTypeFlags flags,

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,31 @@ FUNCTION(GetFunctionMetadataDifferentiable,
786786
EFFECT(MetaData),
787787
MEMEFFECTS(ReadOnly))
788788

789+
// Metadata *
790+
// swift_getExtendedFunctionTypeMetadata(unsigned long flags,
791+
// unsigned long diffKind,
792+
// const Metadata **parameters,
793+
// const uint32_t *parameterFlags,
794+
// const Metadata *result,
795+
// const Metadata *globalActor,
796+
// uint32_t extendedflags,
797+
// const Metadata *thrownError);
798+
FUNCTION(GetFunctionMetadataExtended,
799+
swift_getExtendedFunctionTypeMetadata,
800+
C_CC, TypedThrowsAvailability,
801+
RETURNS(TypeMetadataPtrTy),
802+
ARGS(SizeTy,
803+
SizeTy,
804+
TypeMetadataPtrTy->getPointerTo(0),
805+
Int32Ty->getPointerTo(0),
806+
TypeMetadataPtrTy,
807+
TypeMetadataPtrTy,
808+
Int32Ty,
809+
TypeMetadataPtrTy),
810+
ATTRS(NoUnwind),
811+
EFFECT(MetaData),
812+
MEMEFFECTS(ReadOnly))
813+
789814
// Metadata *
790815
// swift_getFunctionTypeMetadataGlobalActor(unsigned long flags,
791816
// unsigned long diffKind,

lib/AST/Availability.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ AvailabilityContext ASTContext::getDifferentiationAvailability() {
545545
return getSwiftFutureAvailability();
546546
}
547547

548+
AvailabilityContext ASTContext::getTypedThrowsAvailability() {
549+
return getSwift511Availability();
550+
}
551+
548552
AvailabilityContext ASTContext::getMultiPayloadEnumTagSinglePayload() {
549553
return getSwift56Availability();
550554
}
@@ -752,6 +756,11 @@ AvailabilityContext ASTContext::getSwift59Availability() {
752756
}
753757
}
754758

759+
AvailabilityContext ASTContext::getSwift511Availability() {
760+
// Placeholder
761+
return getSwiftFutureAvailability();
762+
}
763+
755764
AvailabilityContext ASTContext::getSwiftFutureAvailability() {
756765
auto target = LangOpts.Target;
757766

lib/Driver/DarwinToolChains.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
378378
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
379379
} else if (value.equals("5.8")) {
380380
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
381+
} else if (value.equals("5.11")) {
382+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 11);
381383
} else if (value.equals("none")) {
382384
runtimeCompatibilityVersion = llvm::None;
383385
} else {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2811,6 +2811,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
28112811
runtimeCompatibilityVersion = llvm::VersionTuple(5, 6);
28122812
} else if (version.equals("5.8")) {
28132813
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
2814+
} else if (version.equals("5.11")) {
2815+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 11);
28142816
} else {
28152817
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
28162818
versionArg->getAsString(Args), version);

lib/IRGen/GenReflection.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,20 @@ class PrintMetadataSource
176176

177177
llvm::Optional<llvm::VersionTuple>
178178
getRuntimeVersionThatSupportsDemanglingType(CanType type) {
179+
// The Swift 5.11 runtime is the first version able to demangle types
180+
// that involve typed throws.
181+
bool usesTypedThrows = type.findIf([](CanType t) -> bool {
182+
if (auto fn = dyn_cast<AnyFunctionType>(t)) {
183+
if (!fn.getThrownError().isNull())
184+
return true;
185+
}
186+
187+
return false;
188+
});
189+
if (usesTypedThrows) {
190+
return llvm::VersionTuple(5, 11);
191+
}
192+
179193
// The Swift 5.5 runtime is the first version able to demangle types
180194
// related to concurrency.
181195
bool needsConcurrency = type.findIf([](CanType t) -> bool {

0 commit comments

Comments
 (0)