Skip to content

Commit 99fb23c

Browse files
committed
Add Extended Existential Vaulue Projection Utilities
1 parent a918648 commit 99fb23c

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

include/swift/ABI/Metadata.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,16 @@ struct TargetExtendedExistentialTypeMetadata
21252125
return this->template getTrailingObjects<ConstTargetPointer<Runtime, void>>();
21262126
}
21272127

2128+
public:
2129+
/// Project the value pointer from an extended existential container of the
2130+
/// type described by this metadata.
2131+
const OpaqueValue *projectValue(const OpaqueValue *container) const;
2132+
2133+
OpaqueValue *projectValue(OpaqueValue *container) const {
2134+
return const_cast<OpaqueValue *>(
2135+
projectValue((const OpaqueValue *)container));
2136+
}
2137+
21282138
public:
21292139
static bool classof(const TargetMetadata<Runtime> *metadata) {
21302140
return metadata->getKind() == MetadataKind::ExtendedExistential;

include/swift/ABI/MetadataValues.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,7 @@ class ExtendedExistentialTypeShapeFlags {
899899
SpecialKind getSpecialKind() const {
900900
return SpecialKind((Data & SpecialKindMask) >> SpecialKindShift);
901901
}
902+
bool isOpaque() const { return getSpecialKind() == SpecialKind::None; }
902903
bool isClassConstrained() const {
903904
return getSpecialKind() == SpecialKind::Class;
904905
}

stdlib/public/runtime/Metadata.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3977,6 +3977,32 @@ ExistentialTypeMetadata::projectValue(const OpaqueValue *container) const {
39773977
"Unhandled ExistentialTypeRepresentation in switch.");
39783978
}
39793979

3980+
template <>
3981+
const OpaqueValue *ExtendedExistentialTypeMetadata::projectValue(
3982+
const OpaqueValue *container) const {
3983+
switch (Shape->Flags.getSpecialKind()) {
3984+
case ExtendedExistentialTypeShape::SpecialKind::None: {
3985+
auto *opaqueContainer =
3986+
reinterpret_cast<const OpaqueExistentialContainer *>(container);
3987+
return opaqueContainer->projectValue();
3988+
}
3989+
case ExtendedExistentialTypeShape::SpecialKind::Class: {
3990+
auto classContainer =
3991+
reinterpret_cast<const ClassExistentialContainer *>(container);
3992+
return reinterpret_cast<const OpaqueValue *>(&classContainer->Value);
3993+
}
3994+
case ExtendedExistentialTypeShape::SpecialKind::Metatype: {
3995+
auto *metatypeContainer =
3996+
reinterpret_cast<const ExistentialMetatypeContainer *>(container);
3997+
return reinterpret_cast<const OpaqueValue *>(&metatypeContainer->Value);
3998+
}
3999+
case ExtendedExistentialTypeShape::SpecialKind::ExplicitLayout:
4000+
swift_unreachable("ExplicitLayout not yet handled.");
4001+
}
4002+
4003+
swift_unreachable("Unhandled ExistentialTypeRepresentation in switch.");
4004+
}
4005+
39804006
template<> const Metadata *
39814007
ExistentialTypeMetadata::getDynamicType(const OpaqueValue *container) const {
39824008
switch (getRepresentation()) {

0 commit comments

Comments
 (0)