Skip to content

Commit 7966da9

Browse files
committed
[WIP] Implement reflection support for Symbolic Extended Existential types.
1 parent 31a9b79 commit 7966da9

File tree

5 files changed

+211
-2
lines changed

5 files changed

+211
-2
lines changed

include/swift/RemoteInspection/TypeRef.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,71 @@ class ConstrainedExistentialTypeRef final : public TypeRef {
731731
}
732732
};
733733

734+
class SymbolicExtendedExistentialTypeRef final : public TypeRef {
735+
remote::RemoteAbsolutePointer Shape;
736+
const ProtocolCompositionTypeRef *Protocol;
737+
std::vector<TypeRefRequirement> Requirements;
738+
std::vector<const TypeRef *> Arguments;
739+
ExtendedExistentialTypeShapeFlags Flags;
740+
741+
static TypeRefID Profile(const remote::RemoteAbsolutePointer Shape,
742+
const ProtocolCompositionTypeRef *Protocol,
743+
llvm::ArrayRef<TypeRefRequirement> Requirements,
744+
llvm::ArrayRef<const TypeRef *> Arguments,
745+
ExtendedExistentialTypeShapeFlags Flags) {
746+
TypeRefID ID;
747+
ID.addString(Shape.getSymbol());
748+
ID.addPointer(Protocol);
749+
for (auto reqt : Requirements) {
750+
ID.addPointer(reqt.getFirstType());
751+
if (reqt.getKind() != RequirementKind::Layout)
752+
ID.addPointer(reqt.getSecondType());
753+
else
754+
ID.addInteger(
755+
unsigned(0)); // FIXME: Layout constraints aren't implemented yet
756+
ID.addInteger(unsigned(reqt.getKind()));
757+
}
758+
759+
for (auto &Arg : Arguments)
760+
ID.addPointer(Arg);
761+
return ID;
762+
}
763+
764+
public:
765+
SymbolicExtendedExistentialTypeRef(
766+
remote::RemoteAbsolutePointer Shape,
767+
const ProtocolCompositionTypeRef *Protocol,
768+
llvm::ArrayRef<TypeRefRequirement> Requirements,
769+
llvm::ArrayRef<const TypeRef *> Args,
770+
ExtendedExistentialTypeShapeFlags Flags)
771+
: TypeRef(TypeRefKind::SymbolicExtendedExistential), Shape(Shape),
772+
Protocol(Protocol), Requirements(Requirements), Arguments(Args),
773+
Flags(Flags) {}
774+
775+
template <typename Allocator>
776+
static const SymbolicExtendedExistentialTypeRef *
777+
create(Allocator &A, remote::RemoteAbsolutePointer Shape,
778+
const ProtocolCompositionTypeRef *Protocol,
779+
llvm::ArrayRef<TypeRefRequirement> Requirements,
780+
llvm::ArrayRef<const TypeRef *> Args,
781+
ExtendedExistentialTypeShapeFlags Flags) {
782+
FIND_OR_CREATE_TYPEREF(A, SymbolicExtendedExistentialTypeRef, Shape,
783+
Protocol, Requirements, Args, Flags);
784+
}
785+
786+
//const remote::RemoteAbsolutePointer getShape() const { return Shape; }
787+
const ProtocolCompositionTypeRef *getProtocol() const { return Protocol; }
788+
llvm::ArrayRef<TypeRefRequirement> getRequirements() const {
789+
return Requirements;
790+
}
791+
llvm::ArrayRef<const TypeRef *> getArguments() const { return Arguments; }
792+
ExtendedExistentialTypeShapeFlags getFlags() const { return Flags; }
793+
794+
static bool classof(const TypeRef *TR) {
795+
return TR->getKind() == TypeRefKind::SymbolicExtendedExistential;
796+
}
797+
};
798+
734799
class MetatypeTypeRef final : public TypeRef {
735800
const TypeRef *InstanceType;
736801
bool WasAbstract;

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,56 @@ class TypeRefBuilder {
12841284
createSymbolicExtendedExistentialType(NodePointer shapeNode,
12851285
llvm::ArrayRef<const TypeRef *> args) {
12861286
// Can't handle this here.
1287-
return nullptr;
1287+
1288+
remote::RemoteAddress shape(shapeNode->getIndex());
1289+
auto symbol = OpaquePointerSymbolResolver(shape);
1290+
if (!symbol)
1291+
return nullptr;
1292+
auto bytes = OpaqueByteReader(shape, 4);
1293+
if (!bytes)
1294+
return nullptr;
1295+
ExtendedExistentialTypeShapeFlags flags(*(const uint32_t *)bytes.get());
1296+
1297+
Demangler Dem;
1298+
auto *Node = Dem.demangleSymbol(symbol->getSymbol());
1299+
if (Node->getKind() != Node::Kind::Global || Node->getNumChildren() != 1)
1300+
return nullptr;
1301+
Node = Node->getChild(0);
1302+
if ((Node->getKind() == Node::Kind::Uniquable) &&
1303+
Node->getNumChildren() == 1)
1304+
Node = Node->getChild(0);
1305+
if (Node->getKind() != Node::Kind::ExtendedExistentialTypeShape ||
1306+
Node->getNumChildren() != 2)
1307+
return nullptr;
1308+
Node = Node->getChild(1);
1309+
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
1310+
return nullptr;
1311+
Node = Node->getChild(0);
1312+
if (Node->getKind() != Node::Kind::ConstrainedExistential ||
1313+
Node->getNumChildren() != 2)
1314+
return nullptr;
1315+
auto ReqNode = Node->getChild(1);
1316+
Node = Node->getChild(0);
1317+
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
1318+
return nullptr;
1319+
auto protocol = llvm::dyn_cast_or_null<ProtocolCompositionTypeRef>(
1320+
decodeMangledType(Node));
1321+
if (!protocol)
1322+
return nullptr;
1323+
1324+
if (!ReqNode ||
1325+
ReqNode->getKind() != Node::Kind::ConstrainedExistentialRequirementList)
1326+
return nullptr;
1327+
1328+
llvm::SmallVector<BuiltRequirement, 8> requirements;
1329+
llvm::SmallVector<BuiltInverseRequirement, 8> inverseRequirements;
1330+
1331+
decodeRequirement<BuiltType, BuiltRequirement, BuiltInverseRequirement,
1332+
BuiltLayoutConstraint, TypeRefBuilder>(
1333+
ReqNode, requirements, inverseRequirements, *this);
1334+
1335+
return SymbolicExtendedExistentialTypeRef::create(
1336+
*this, *symbol, protocol, requirements, args, flags);
12881337
}
12891338

12901339
const ExistentialMetatypeTypeRef *createExistentialMetatypeType(
@@ -1312,6 +1361,7 @@ class TypeRefBuilder {
13121361

13131362
const DependentMemberTypeRef *
13141363
createDependentMemberType(const std::string &member, const TypeRef *base) {
1364+
return DependentMemberTypeRef::create(*this, member, base, "");
13151365
// Should not have unresolved dependent member types here.
13161366
return nullptr;
13171367
}
@@ -1479,6 +1529,9 @@ class TypeRefBuilder {
14791529
using PointerReader =
14801530
std::function<std::optional<remote::RemoteAbsolutePointer>(
14811531
remote::RemoteAddress, unsigned)>;
1532+
using PointerSymbolResolver =
1533+
std::function<std::optional<remote::RemoteAbsolutePointer>(
1534+
remote::RemoteAddress)>;
14821535
using DynamicSymbolResolver =
14831536
std::function<std::optional<remote::RemoteAbsolutePointer>(
14841537
remote::RemoteAddress)>;
@@ -1511,6 +1564,7 @@ class TypeRefBuilder {
15111564
ByteReader OpaqueByteReader;
15121565
StringReader OpaqueStringReader;
15131566
PointerReader OpaquePointerReader;
1567+
PointerSymbolResolver OpaquePointerSymbolResolver;
15141568
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
15151569
IntVariableReader OpaqueIntVariableReader;
15161570

@@ -1549,6 +1603,11 @@ class TypeRefBuilder {
15491603
-> std::optional<remote::RemoteAbsolutePointer> {
15501604
return reader.Reader->readPointer(address, size);
15511605
}),
1606+
OpaquePointerSymbolResolver(
1607+
[&reader](remote::RemoteAddress address)
1608+
-> std::optional<remote::RemoteAbsolutePointer> {
1609+
return reader.Reader->resolvePointerAsSymbol(address);
1610+
}),
15521611
OpaqueDynamicSymbolResolver(
15531612
[&reader](remote::RemoteAddress address)
15541613
-> std::optional<remote::RemoteAbsolutePointer> {

include/swift/RemoteInspection/TypeRefs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TYPEREF(Tuple, TypeRef)
2323
TYPEREF(Function, TypeRef)
2424
TYPEREF(ProtocolComposition, TypeRef)
2525
TYPEREF(ConstrainedExistential, TypeRef)
26+
TYPEREF(SymbolicExtendedExistential, TypeRef)
2627
TYPEREF(Metatype, TypeRef)
2728
TYPEREF(ExistentialMetatype, TypeRef)
2829
TYPEREF(GenericTypeParameter, TypeRef)

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ class ExistentialTypeInfoBuilder {
11541154
TypeConverter &TC;
11551155
std::vector<const TypeRef *> Protocols;
11561156
const TypeRef *Superclass = nullptr;
1157+
remote::RemoteAbsolutePointer Shape;
11571158
ExistentialTypeRepresentation Representation;
11581159
ReferenceCounting Refcounting;
11591160
bool ObjC;
@@ -1258,6 +1259,10 @@ class ExistentialTypeInfoBuilder {
12581259
}
12591260
}
12601261

1262+
void examineShape() {
1263+
1264+
}
1265+
12611266
public:
12621267
ExistentialTypeInfoBuilder(TypeConverter &TC)
12631268
: TC(TC), Representation(ExistentialTypeRepresentation::Opaque),
@@ -1321,8 +1326,27 @@ class ExistentialTypeInfoBuilder {
13211326
Representation = ExistentialTypeRepresentation::Class;
13221327
}
13231328

1329+
void addShape(const ProtocolCompositionTypeRef *Protocol,
1330+
ExtendedExistentialTypeShapeFlags Flags) {
1331+
switch (Flags.getSpecialKind()) {
1332+
case ExtendedExistentialTypeShapeFlags::SpecialKind::Class:
1333+
Representation = ExistentialTypeRepresentation::Class;
1334+
break;
1335+
case ExtendedExistentialTypeShapeFlags::SpecialKind::Metatype:
1336+
case ExtendedExistentialTypeShapeFlags::SpecialKind::ExplicitLayout:
1337+
case ExtendedExistentialTypeShapeFlags::SpecialKind::None:
1338+
Representation = ExistentialTypeRepresentation::Opaque;
1339+
break;
1340+
}
1341+
1342+
if (Protocol)
1343+
for (auto *Protocol : Protocol->getProtocols())
1344+
addProtocol(Protocol);
1345+
}
1346+
13241347
const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
13251348
examineProtocols();
1349+
examineShape();
13261350

13271351
if (Invalid)
13281352
return nullptr;
@@ -1780,6 +1804,11 @@ class HasFixedSize
17801804
return true;
17811805
}
17821806

1807+
bool visitSymbolicExtendedExistentialTypeRef(
1808+
const SymbolicExtendedExistentialTypeRef *SEET) {
1809+
return true;
1810+
}
1811+
17831812
bool
17841813
visitSILBoxTypeRef(const SILBoxTypeRef *SB) {
17851814
return true;
@@ -1923,6 +1952,11 @@ class HasSingletonMetatype
19231952
return MetatypeRepresentation::Thin;
19241953
}
19251954

1955+
MetatypeRepresentation visitSymbolicExtendedExistentialTypeRef(
1956+
const SymbolicExtendedExistentialTypeRef *SEET) {
1957+
return MetatypeRepresentation::Thin;
1958+
}
1959+
19261960
MetatypeRepresentation visitMetatypeTypeRef(const MetatypeTypeRef *M) {
19271961
if (M->wasAbstract())
19281962
return MetatypeRepresentation::Thick;
@@ -2520,6 +2554,13 @@ class LowerType
25202554
return builder.buildMetatype(ExternalTypeInfo);
25212555
}
25222556

2557+
const TypeInfo *visitSymbolicExtendedExistentialTypeRef(
2558+
const SymbolicExtendedExistentialTypeRef *SEET) {
2559+
ExistentialTypeInfoBuilder builder(TC);
2560+
builder.addShape(SEET->getProtocol(), SEET->getFlags());
2561+
return builder.build(ExternalTypeInfo);
2562+
}
2563+
25232564
const TypeInfo *
25242565
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
25252566
DEBUG_LOG(fprintf(stderr, "Unresolved generic TypeRef: "); GTP->dump());
@@ -2736,7 +2777,7 @@ const RecordTypeInfo *TypeConverter::getClassInstanceTypeInfo(
27362777
swift_unreachable("Unhandled FieldDescriptorKind in switch.");
27372778
}
27382779

2739-
} // namespace reflection
2780+
} // namespace reflection
27402781
} // namespace swift
27412782

27422783
#endif

stdlib/public/RemoteInspection/TypeRef.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,16 @@ class PrintTypeRef : public TypeRefVisitor<PrintTypeRef, void> {
289289
stream << ")";
290290
}
291291

292+
void visitSymbolicExtendedExistentialTypeRef(
293+
const SymbolicExtendedExistentialTypeRef *CET) {
294+
printHeader("symbolic_extended_existential_type");
295+
// printRec(CET->getShape());
296+
printRec(CET->getProtocol());
297+
for (auto &arg : CET->getArguments())
298+
printRec(arg);
299+
stream << ")";
300+
}
301+
292302
void visitMetatypeTypeRef(const MetatypeTypeRef *M) {
293303
printHeader("metatype");
294304
if (M->wasAbstract())
@@ -513,6 +523,15 @@ struct TypeRefIsConcrete
513523
return visit(CET->getBase());
514524
}
515525

526+
bool visitSymbolicExtendedExistentialTypeRef(
527+
const SymbolicExtendedExistentialTypeRef *SEET) {
528+
visit(SEET->getProtocol());
529+
for (auto &Arg : SEET->getArguments())
530+
if (!visit(Arg))
531+
return false;
532+
return true;
533+
}
534+
516535
bool visitMetatypeTypeRef(const MetatypeTypeRef *M) {
517536
return visit(M->getInstanceType());
518537
}
@@ -952,6 +971,19 @@ class DemanglingForTypeRef
952971
return node;
953972
}
954973

974+
Demangle::NodePointer visitSymbolicExtendedExistentialTypeRef(
975+
const SymbolicExtendedExistentialTypeRef *SEET) {
976+
auto node = Dem.createNode(Node::Kind::ConstrainedExistential);
977+
node->addChild(visit(SEET->getProtocol()), Dem);
978+
auto constraintList =
979+
Dem.createNode(Node::Kind::ConstrainedExistentialRequirementList);
980+
for (auto req : SEET->getRequirements())
981+
constraintList->addChild(visitTypeRefRequirement(req), Dem);
982+
node->addChild(constraintList, Dem);
983+
// FIXME: This is lossy. We're dropping the Arguments here.
984+
return node;
985+
}
986+
955987
Demangle::NodePointer visitMetatypeTypeRef(const MetatypeTypeRef *M) {
956988
auto node = Dem.createNode(Node::Kind::Metatype);
957989
// FIXME: This is lossy. @objc_metatype is also abstract.
@@ -1354,6 +1386,11 @@ class ThickenMetatype
13541386
CET->getRequirements());
13551387
}
13561388

1389+
const TypeRef *visitSymbolicExtendedExistentialTypeRef(
1390+
const SymbolicExtendedExistentialTypeRef *SEET) {
1391+
return SEET;
1392+
}
1393+
13571394
const TypeRef *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
13581395
return MetatypeTypeRef::create(Builder, visit(M->getInstanceType()),
13591396
/*WasAbstract=*/true);
@@ -1641,6 +1678,12 @@ class TypeRefSubstitution
16411678
constraints);
16421679
}
16431680

1681+
const TypeRef *visitSymbolicExtendedExistentialTypeRef(
1682+
const SymbolicExtendedExistentialTypeRef *SEET) {
1683+
assert(false);
1684+
return nullptr;
1685+
}
1686+
16441687
const TypeRef *
16451688
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
16461689
auto found = Substitutions.find({GTP->getDepth(), GTP->getIndex()});

0 commit comments

Comments
 (0)