Skip to content

[WIP] Implement reflection support for Symbolic Extended Existential #82389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions include/swift/RemoteInspection/TypeRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,71 @@ class ConstrainedExistentialTypeRef final : public TypeRef {
}
};

class SymbolicExtendedExistentialTypeRef final : public TypeRef {
remote::RemoteAbsolutePointer Shape;
const ProtocolCompositionTypeRef *Protocol;
std::vector<TypeRefRequirement> Requirements;
std::vector<const TypeRef *> Arguments;
ExtendedExistentialTypeShapeFlags Flags;

static TypeRefID Profile(const remote::RemoteAbsolutePointer Shape,
const ProtocolCompositionTypeRef *Protocol,
llvm::ArrayRef<TypeRefRequirement> Requirements,
llvm::ArrayRef<const TypeRef *> Arguments,
ExtendedExistentialTypeShapeFlags Flags) {
TypeRefID ID;
ID.addString(Shape.getSymbol());
ID.addPointer(Protocol);
for (auto reqt : Requirements) {
ID.addPointer(reqt.getFirstType());
if (reqt.getKind() != RequirementKind::Layout)
ID.addPointer(reqt.getSecondType());
else
ID.addInteger(
unsigned(0)); // FIXME: Layout constraints aren't implemented yet
ID.addInteger(unsigned(reqt.getKind()));
}

for (auto &Arg : Arguments)
ID.addPointer(Arg);
return ID;
}

public:
SymbolicExtendedExistentialTypeRef(
remote::RemoteAbsolutePointer Shape,
const ProtocolCompositionTypeRef *Protocol,
llvm::ArrayRef<TypeRefRequirement> Requirements,
llvm::ArrayRef<const TypeRef *> Args,
ExtendedExistentialTypeShapeFlags Flags)
: TypeRef(TypeRefKind::SymbolicExtendedExistential), Shape(Shape),
Protocol(Protocol), Requirements(Requirements), Arguments(Args),
Flags(Flags) {}

template <typename Allocator>
static const SymbolicExtendedExistentialTypeRef *
create(Allocator &A, remote::RemoteAbsolutePointer Shape,
const ProtocolCompositionTypeRef *Protocol,
llvm::ArrayRef<TypeRefRequirement> Requirements,
llvm::ArrayRef<const TypeRef *> Args,
ExtendedExistentialTypeShapeFlags Flags) {
FIND_OR_CREATE_TYPEREF(A, SymbolicExtendedExistentialTypeRef, Shape,
Protocol, Requirements, Args, Flags);
}

//const remote::RemoteAbsolutePointer getShape() const { return Shape; }
const ProtocolCompositionTypeRef *getProtocol() const { return Protocol; }
llvm::ArrayRef<TypeRefRequirement> getRequirements() const {
return Requirements;
}
llvm::ArrayRef<const TypeRef *> getArguments() const { return Arguments; }
ExtendedExistentialTypeShapeFlags getFlags() const { return Flags; }

static bool classof(const TypeRef *TR) {
return TR->getKind() == TypeRefKind::SymbolicExtendedExistential;
}
};

class MetatypeTypeRef final : public TypeRef {
const TypeRef *InstanceType;
bool WasAbstract;
Expand Down
61 changes: 60 additions & 1 deletion include/swift/RemoteInspection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1284,7 +1284,56 @@ class TypeRefBuilder {
createSymbolicExtendedExistentialType(NodePointer shapeNode,
llvm::ArrayRef<const TypeRef *> args) {
// Can't handle this here.
return nullptr;

remote::RemoteAddress shape(shapeNode->getIndex());
auto symbol = OpaquePointerSymbolResolver(shape);
if (!symbol)
return nullptr;
auto bytes = OpaqueByteReader(shape, 4);
if (!bytes)
return nullptr;
ExtendedExistentialTypeShapeFlags flags(*(const uint32_t *)bytes.get());

Demangler Dem;
auto *Node = Dem.demangleSymbol(symbol->getSymbol());
if (Node->getKind() != Node::Kind::Global || Node->getNumChildren() != 1)
return nullptr;
Node = Node->getChild(0);
if ((Node->getKind() == Node::Kind::Uniquable) &&
Node->getNumChildren() == 1)
Node = Node->getChild(0);
if (Node->getKind() != Node::Kind::ExtendedExistentialTypeShape ||
Node->getNumChildren() != 2)
return nullptr;
Node = Node->getChild(1);
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
return nullptr;
Node = Node->getChild(0);
if (Node->getKind() != Node::Kind::ConstrainedExistential ||
Node->getNumChildren() != 2)
return nullptr;
auto ReqNode = Node->getChild(1);
Node = Node->getChild(0);
if (Node->getKind() != Node::Kind::Type || Node->getNumChildren() != 1)
return nullptr;
auto protocol = llvm::dyn_cast_or_null<ProtocolCompositionTypeRef>(
decodeMangledType(Node));
if (!protocol)
return nullptr;

if (!ReqNode ||
ReqNode->getKind() != Node::Kind::ConstrainedExistentialRequirementList)
return nullptr;

llvm::SmallVector<BuiltRequirement, 8> requirements;
llvm::SmallVector<BuiltInverseRequirement, 8> inverseRequirements;

decodeRequirement<BuiltType, BuiltRequirement, BuiltInverseRequirement,
BuiltLayoutConstraint, TypeRefBuilder>(
ReqNode, requirements, inverseRequirements, *this);

return SymbolicExtendedExistentialTypeRef::create(
*this, *symbol, protocol, requirements, args, flags);
}

const ExistentialMetatypeTypeRef *createExistentialMetatypeType(
Expand Down Expand Up @@ -1312,6 +1361,7 @@ class TypeRefBuilder {

const DependentMemberTypeRef *
createDependentMemberType(const std::string &member, const TypeRef *base) {
return DependentMemberTypeRef::create(*this, member, base, "");
// Should not have unresolved dependent member types here.
return nullptr;
}
Expand Down Expand Up @@ -1479,6 +1529,9 @@ class TypeRefBuilder {
using PointerReader =
std::function<std::optional<remote::RemoteAbsolutePointer>(
remote::RemoteAddress, unsigned)>;
using PointerSymbolResolver =
std::function<std::optional<remote::RemoteAbsolutePointer>(
remote::RemoteAddress)>;
using DynamicSymbolResolver =
std::function<std::optional<remote::RemoteAbsolutePointer>(
remote::RemoteAddress)>;
Expand Down Expand Up @@ -1511,6 +1564,7 @@ class TypeRefBuilder {
ByteReader OpaqueByteReader;
StringReader OpaqueStringReader;
PointerReader OpaquePointerReader;
PointerSymbolResolver OpaquePointerSymbolResolver;
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
IntVariableReader OpaqueIntVariableReader;

Expand Down Expand Up @@ -1549,6 +1603,11 @@ class TypeRefBuilder {
-> std::optional<remote::RemoteAbsolutePointer> {
return reader.Reader->readPointer(address, size);
}),
OpaquePointerSymbolResolver(
[&reader](remote::RemoteAddress address)
-> std::optional<remote::RemoteAbsolutePointer> {
return reader.Reader->resolvePointerAsSymbol(address);
}),
OpaqueDynamicSymbolResolver(
[&reader](remote::RemoteAddress address)
-> std::optional<remote::RemoteAbsolutePointer> {
Expand Down
1 change: 1 addition & 0 deletions include/swift/RemoteInspection/TypeRefs.def
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ TYPEREF(Tuple, TypeRef)
TYPEREF(Function, TypeRef)
TYPEREF(ProtocolComposition, TypeRef)
TYPEREF(ConstrainedExistential, TypeRef)
TYPEREF(SymbolicExtendedExistential, TypeRef)
TYPEREF(Metatype, TypeRef)
TYPEREF(ExistentialMetatype, TypeRef)
TYPEREF(GenericTypeParameter, TypeRef)
Expand Down
44 changes: 42 additions & 2 deletions stdlib/public/RemoteInspection/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,7 @@ class ExistentialTypeInfoBuilder {
TypeConverter &TC;
std::vector<const TypeRef *> Protocols;
const TypeRef *Superclass = nullptr;
remote::RemoteAbsolutePointer Shape;
ExistentialTypeRepresentation Representation;
ReferenceCounting Refcounting;
bool ObjC;
Expand Down Expand Up @@ -1258,6 +1259,10 @@ class ExistentialTypeInfoBuilder {
}
}

void examineShape() {

}

public:
ExistentialTypeInfoBuilder(TypeConverter &TC)
: TC(TC), Representation(ExistentialTypeRepresentation::Opaque),
Expand Down Expand Up @@ -1321,8 +1326,26 @@ class ExistentialTypeInfoBuilder {
Representation = ExistentialTypeRepresentation::Class;
}

void addShape(const ProtocolCompositionTypeRef *Protocol,
ExtendedExistentialTypeShapeFlags Flags) {
switch (Flags.getSpecialKind()) {
case ExtendedExistentialTypeShapeFlags::SpecialKind::Class:
Representation = ExistentialTypeRepresentation::Class;
break;
case ExtendedExistentialTypeShapeFlags::SpecialKind::Metatype:
case ExtendedExistentialTypeShapeFlags::SpecialKind::ExplicitLayout:
case ExtendedExistentialTypeShapeFlags::SpecialKind::None:
Representation = ExistentialTypeRepresentation::Opaque;
break;
}

for (auto *Protocol : Protocols)
addProtocol(Protocol);
}

const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
examineProtocols();
examineShape();

if (Invalid)
return nullptr;
Expand Down Expand Up @@ -1415,7 +1438,7 @@ class ExistentialTypeInfoBuilder {

return builder.build();
}
};
};

unsigned RecordTypeInfoBuilder::addField(unsigned fieldSize,
unsigned fieldAlignment,
Expand Down Expand Up @@ -1780,6 +1803,11 @@ class HasFixedSize
return true;
}

bool visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
return true;
}

bool
visitSILBoxTypeRef(const SILBoxTypeRef *SB) {
return true;
Expand Down Expand Up @@ -1923,6 +1951,11 @@ class HasSingletonMetatype
return MetatypeRepresentation::Thin;
}

MetatypeRepresentation visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
return MetatypeRepresentation::Thin;
}

MetatypeRepresentation visitMetatypeTypeRef(const MetatypeTypeRef *M) {
if (M->wasAbstract())
return MetatypeRepresentation::Thick;
Expand Down Expand Up @@ -2520,6 +2553,13 @@ class LowerType
return builder.buildMetatype(ExternalTypeInfo);
}

const TypeInfo *visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
ExistentialTypeInfoBuilder builder(TC);
builder.addShape(SEET->getProtocol(), SEET->getFlags());
return builder.build(ExternalTypeInfo);
}

const TypeInfo *
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
DEBUG_LOG(fprintf(stderr, "Unresolved generic TypeRef: "); GTP->dump());
Expand Down Expand Up @@ -2733,7 +2773,7 @@ const RecordTypeInfo *TypeConverter::getClassInstanceTypeInfo(
swift_unreachable("Unhandled FieldDescriptorKind in switch.");
}

} // namespace reflection
} // namespace reflection
} // namespace swift

#endif
43 changes: 43 additions & 0 deletions stdlib/public/RemoteInspection/TypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ class PrintTypeRef : public TypeRefVisitor<PrintTypeRef, void> {
stream << ")";
}

void visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *CET) {
printHeader("symbolic_extended_existential_type");
// printRec(CET->getShape());
printRec(CET->getProtocol());
for (auto &arg : CET->getArguments())
printRec(arg);
stream << ")";
}

void visitMetatypeTypeRef(const MetatypeTypeRef *M) {
printHeader("metatype");
if (M->wasAbstract())
Expand Down Expand Up @@ -513,6 +523,15 @@ struct TypeRefIsConcrete
return visit(CET->getBase());
}

bool visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
visit(SEET->getProtocol());
for (auto &Arg : SEET->getArguments())
if (!visit(Arg))
return false;
return true;
}

bool visitMetatypeTypeRef(const MetatypeTypeRef *M) {
return visit(M->getInstanceType());
}
Expand Down Expand Up @@ -952,6 +971,19 @@ class DemanglingForTypeRef
return node;
}

Demangle::NodePointer visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
auto node = Dem.createNode(Node::Kind::ConstrainedExistential);
node->addChild(visit(SEET->getProtocol()), Dem);
auto constraintList =
Dem.createNode(Node::Kind::ConstrainedExistentialRequirementList);
for (auto req : SEET->getRequirements())
constraintList->addChild(visitTypeRefRequirement(req), Dem);
node->addChild(constraintList, Dem);
// FIXME: This is lossy. We're dropping the Arguments here.
return node;
}

Demangle::NodePointer visitMetatypeTypeRef(const MetatypeTypeRef *M) {
auto node = Dem.createNode(Node::Kind::Metatype);
// FIXME: This is lossy. @objc_metatype is also abstract.
Expand Down Expand Up @@ -1354,6 +1386,11 @@ class ThickenMetatype
CET->getRequirements());
}

const TypeRef *visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
return SEET;
}

const TypeRef *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
return MetatypeTypeRef::create(Builder, visit(M->getInstanceType()),
/*WasAbstract=*/true);
Expand Down Expand Up @@ -1641,6 +1678,12 @@ class TypeRefSubstitution
constraints);
}

const TypeRef *visitSymbolicExtendedExistentialTypeRef(
const SymbolicExtendedExistentialTypeRef *SEET) {
assert(false);
return nullptr;
}

const TypeRef *
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
auto found = Substitutions.find({GTP->getDepth(), GTP->getIndex()});
Expand Down