mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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.
This commit is contained in:
@@ -1357,8 +1357,11 @@ public:
|
||||
const ::ParameterFlags *ParameterFlags;
|
||||
const Metadata *Result;
|
||||
const Metadata *GlobalActor;
|
||||
const ExtendedFunctionTypeFlags ExtFlags;
|
||||
const Metadata *ThrownError;
|
||||
|
||||
FunctionTypeFlags getFlags() const { return Flags; }
|
||||
ExtendedFunctionTypeFlags getExtFlags() const { return ExtFlags; }
|
||||
|
||||
FunctionMetadataDifferentiabilityKind getDifferentiabilityKind() const {
|
||||
return DifferentiabilityKind;
|
||||
@@ -1380,12 +1383,14 @@ public:
|
||||
}
|
||||
|
||||
const Metadata *getGlobalActor() const { return GlobalActor; }
|
||||
const Metadata *getThrownError() const { return ThrownError; }
|
||||
|
||||
friend llvm::hash_code hash_value(const Key &key) {
|
||||
auto hash = llvm::hash_combine(
|
||||
key.Flags.getIntValue(),
|
||||
key.DifferentiabilityKind.getIntValue(),
|
||||
key.Result, key.GlobalActor);
|
||||
key.Result, key.GlobalActor,
|
||||
key.ExtFlags.getIntValue(), key.ThrownError);
|
||||
for (unsigned i = 0, e = key.getFlags().getNumParameters(); i != e; ++i) {
|
||||
hash = llvm::hash_combine(hash, key.getParameter(i));
|
||||
hash = llvm::hash_combine(hash, key.getParameterFlags(i).getIntValue());
|
||||
@@ -1410,6 +1415,10 @@ public:
|
||||
return false;
|
||||
if (key.getGlobalActor() != Data.getGlobalActor())
|
||||
return false;
|
||||
if (key.getExtFlags().getIntValue() != Data.getExtendedFlags().getIntValue())
|
||||
return false;
|
||||
if (key.getThrownError() != Data.getThrownError())
|
||||
return false;
|
||||
for (unsigned i = 0, e = key.getFlags().getNumParameters(); i != e; ++i) {
|
||||
if (key.getParameter(i) != Data.getParameter(i))
|
||||
return false;
|
||||
@@ -1423,29 +1432,31 @@ public:
|
||||
friend llvm::hash_code hash_value(const FunctionCacheEntry &value) {
|
||||
Key key = {value.Data.Flags, value.Data.getDifferentiabilityKind(),
|
||||
value.Data.getParameters(), value.Data.getParameterFlags(),
|
||||
value.Data.ResultType, value.Data.getGlobalActor()};
|
||||
value.Data.ResultType, value.Data.getGlobalActor(),
|
||||
value.Data.getExtendedFlags(), value.Data.getThrownError()};
|
||||
return hash_value(key);
|
||||
}
|
||||
|
||||
static size_t getExtraAllocationSize(const Key &key) {
|
||||
return getExtraAllocationSize(key.Flags);
|
||||
return getExtraAllocationSize(key.Flags, key.ExtFlags);
|
||||
}
|
||||
|
||||
size_t getExtraAllocationSize() const {
|
||||
return getExtraAllocationSize(Data.Flags);
|
||||
return getExtraAllocationSize(Data.Flags, Data.getExtendedFlags());
|
||||
}
|
||||
|
||||
static size_t getExtraAllocationSize(const FunctionTypeFlags &flags) {
|
||||
static size_t getExtraAllocationSize(const FunctionTypeFlags &flags,
|
||||
const ExtendedFunctionTypeFlags &extFlags) {
|
||||
const auto numParams = flags.getNumParameters();
|
||||
auto size = numParams * sizeof(FunctionTypeMetadata::Parameter);
|
||||
if (flags.hasParameterFlags())
|
||||
size += numParams * sizeof(uint32_t);
|
||||
if (flags.isDifferentiable())
|
||||
size = roundUpToAlignment(size, sizeof(void *)) +
|
||||
sizeof(FunctionMetadataDifferentiabilityKind);
|
||||
if (flags.hasGlobalActor())
|
||||
size = roundUpToAlignment(size, sizeof(void *)) + sizeof(Metadata *);
|
||||
return roundUpToAlignment(size, sizeof(void *));
|
||||
return FunctionTypeMetadata::additionalSizeToAlloc<
|
||||
const Metadata *, ParameterFlags, FunctionMetadataDifferentiabilityKind,
|
||||
FunctionGlobalActorMetadata, ExtendedFunctionTypeFlags,
|
||||
FunctionThrownErrorMetadata>(numParams,
|
||||
flags.hasParameterFlags() ? numParams : 0,
|
||||
flags.isDifferentiable() ? 1 : 0,
|
||||
flags.hasGlobalActor() ? 1 : 0,
|
||||
flags.hasExtendedFlags() ? 1 : 0,
|
||||
extFlags.isTypedThrows() ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1506,9 +1517,13 @@ swift::swift_getFunctionTypeMetadata(FunctionTypeFlags flags,
|
||||
assert(!flags.hasGlobalActor()
|
||||
&& "Global actor function type metadata should be obtained using "
|
||||
"'swift_getFunctionTypeMetadataGlobalActor'");
|
||||
assert(!flags.hasExtendedFlags()
|
||||
&& "Extended flags function type metadata should be obtained using "
|
||||
"'swift_getExtendedFunctionTypeMetadata'");
|
||||
FunctionCacheEntry::Key key = {
|
||||
flags, FunctionMetadataDifferentiabilityKind::NonDifferentiable, parameters,
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result, nullptr
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result, nullptr,
|
||||
ExtendedFunctionTypeFlags(), nullptr
|
||||
};
|
||||
return &FunctionTypes.getOrInsert(key).first->Data;
|
||||
}
|
||||
@@ -1521,11 +1536,15 @@ swift::swift_getFunctionTypeMetadataDifferentiable(
|
||||
assert(!flags.hasGlobalActor()
|
||||
&& "Global actor function type metadata should be obtained using "
|
||||
"'swift_getFunctionTypeMetadataGlobalActor'");
|
||||
assert(!flags.hasExtendedFlags()
|
||||
&& "Extended flags function type metadata should be obtained using "
|
||||
"'swift_getExtendedFunctionTypeMetadata'");
|
||||
assert(flags.isDifferentiable());
|
||||
assert(diffKind.isDifferentiable());
|
||||
FunctionCacheEntry::Key key = {
|
||||
flags, diffKind, parameters,
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result, nullptr
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result, nullptr,
|
||||
ExtendedFunctionTypeFlags(), nullptr
|
||||
};
|
||||
return &FunctionTypes.getOrInsert(key).first->Data;
|
||||
}
|
||||
@@ -1535,10 +1554,29 @@ swift::swift_getFunctionTypeMetadataGlobalActor(
|
||||
FunctionTypeFlags flags, FunctionMetadataDifferentiabilityKind diffKind,
|
||||
const Metadata *const *parameters, const uint32_t *parameterFlags,
|
||||
const Metadata *result, const Metadata *globalActor) {
|
||||
assert(flags.hasGlobalActor());
|
||||
assert(!flags.hasExtendedFlags()
|
||||
&& "Extended flags function type metadata should be obtained using "
|
||||
"'swift_getExtendedFunctionTypeMetadata'");
|
||||
FunctionCacheEntry::Key key = {
|
||||
flags, diffKind, parameters,
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result, globalActor
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result,
|
||||
globalActor, ExtendedFunctionTypeFlags(), nullptr
|
||||
};
|
||||
return &FunctionTypes.getOrInsert(key).first->Data;
|
||||
}
|
||||
|
||||
const FunctionTypeMetadata *
|
||||
swift::swift_getExtendedFunctionTypeMetadata(
|
||||
FunctionTypeFlags flags, FunctionMetadataDifferentiabilityKind diffKind,
|
||||
const Metadata *const *parameters, const uint32_t *parameterFlags,
|
||||
const Metadata *result, const Metadata *globalActor,
|
||||
ExtendedFunctionTypeFlags extFlags, const Metadata *thrownError) {
|
||||
assert(flags.hasExtendedFlags() || extFlags.getIntValue() == 0);
|
||||
assert(flags.hasExtendedFlags() || thrownError == nullptr);
|
||||
FunctionCacheEntry::Key key = {
|
||||
flags, diffKind, parameters,
|
||||
reinterpret_cast<const ParameterFlags *>(parameterFlags), result,
|
||||
globalActor, extFlags, thrownError
|
||||
};
|
||||
return &FunctionTypes.getOrInsert(key).first->Data;
|
||||
}
|
||||
@@ -1592,6 +1630,13 @@ FunctionCacheEntry::FunctionCacheEntry(const Key &key) {
|
||||
*Data.getGlobalActorAddr() = key.getGlobalActor();
|
||||
if (flags.isDifferentiable())
|
||||
*Data.getDifferentiabilityKindAddress() = key.getDifferentiabilityKind();
|
||||
if (flags.hasExtendedFlags()) {
|
||||
auto extFlags = key.getExtFlags();
|
||||
*Data.getExtendedFlagsAddr() = extFlags;
|
||||
|
||||
if (extFlags.isTypedThrows())
|
||||
*Data.getThrownErrorAddr() = key.getThrownError();
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < numParameters; ++i) {
|
||||
Data.getParameters()[i] = key.getParameter(i);
|
||||
|
||||
Reference in New Issue
Block a user