Skip to content

Commit 1628798

Browse files
committed
Add Extended Existential Vaulue Projection Utilities
1 parent 66d7133 commit 1628798

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
@@ -3980,6 +3980,32 @@ ExistentialTypeMetadata::projectValue(const OpaqueValue *container) const {
39803980
"Unhandled ExistentialTypeRepresentation in switch.");
39813981
}
39823982

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

0 commit comments

Comments
 (0)