Skip to content

Commit bd6d657

Browse files
committed
Get typerefs for existential type metadata
1 parent 0f05b39 commit bd6d657

File tree

5 files changed

+105
-21
lines changed

5 files changed

+105
-21
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ template <typename Runtime>
3939
using SharedTargetNominalTypeDescriptorRef
4040
= std::shared_ptr<TargetNominalTypeDescriptor<Runtime>>;
4141

42+
template <typename Runtime>
43+
using SharedProtocolDescriptorRef
44+
= std::shared_ptr<TargetProtocolDescriptor<Runtime>>;
45+
4246
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
4347
using AssociatedTypeSection = ReflectionSection<AssociatedTypeIterator>;
4448
using GenericSection = ReflectionSection<const void *>;
@@ -148,8 +152,20 @@ class ReflectionContext {
148152
return _readMetadata<TargetEnumMetadata<Runtime>>(Address);
149153
case MetadataKind::ErrorObject:
150154
return _readMetadata<TargetEnumMetadata<Runtime>>(Address);
151-
case MetadataKind::Existential:
152-
return _readMetadata<TargetExistentialTypeMetadata<Runtime>>(Address);
155+
case MetadataKind::Existential: {
156+
StoredPointer NumProtocolsAddress = Address +
157+
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
158+
StoredPointer NumProtocols;
159+
if (!Reader.readInteger(NumProtocolsAddress, &NumProtocols))
160+
return nullptr;
161+
162+
auto TotalSize = sizeof(TargetExistentialTypeMetadata<Runtime>) +
163+
NumProtocols *
164+
sizeof(ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);
165+
166+
return _readMetadata<TargetExistentialTypeMetadata<Runtime>>(Address,
167+
TotalSize);
168+
}
153169
case MetadataKind::ExistentialMetatype:
154170
return _readMetadata<
155171
TargetExistentialMetatypeMetadata<Runtime>>(Address);
@@ -216,6 +232,22 @@ class ReflectionContext {
216232
});
217233
}
218234

235+
SharedProtocolDescriptorRef<Runtime>
236+
readProtocolDescriptor(StoredPointer Address) {
237+
auto Size = sizeof(TargetProtocolDescriptor<Runtime>);
238+
auto Buffer = (uint8_t *)malloc(Size);
239+
if (!Reader.readBytes(Address, Buffer, Size)) {
240+
free(Buffer);
241+
return nullptr;
242+
}
243+
auto Casted
244+
= reinterpret_cast<TargetProtocolDescriptor<Runtime> *>(Buffer);
245+
return SharedProtocolDescriptorRef<Runtime>(Casted,
246+
[](void *PD){
247+
free(PD);
248+
});
249+
}
250+
219251
TypeRefVector
220252
getGenericArguments(StoredPointer MetadataAddress,
221253
SharedTargetNominalTypeDescriptorRef<Runtime> Descriptor){
@@ -360,7 +392,21 @@ class ReflectionContext {
360392
case MetadataKind::Existential: {
361393
auto Exist = cast<TargetExistentialTypeMetadata<Runtime>>(Meta.get());
362394
TypeRefVector Protocols;
363-
llvm_unreachable("todo");
395+
for (size_t i = 0; i < Exist->Protocols.NumProtocols; ++i) {
396+
auto ProtocolAddress = Exist->Protocols[i];
397+
auto ProtocolDescriptor = readProtocolDescriptor(ProtocolAddress);
398+
if (!ProtocolDescriptor)
399+
return nullptr;
400+
auto MangledName = Reader.readString(ProtocolDescriptor->Name);
401+
if (MangledName.empty())
402+
return nullptr;
403+
auto Demangled = Demangle::demangleSymbolAsNode(MangledName);
404+
auto Protocol = TypeRef::fromDemangleNode(Demangled);
405+
if (!llvm::isa<ProtocolTypeRef>(Protocol.get()))
406+
return nullptr;
407+
408+
Protocols.push_back(Protocol);
409+
}
364410
return ProtocolCompositionTypeRef::create(Protocols);
365411
}
366412
case MetadataKind::Metatype: {

include/swift/Runtime/Metadata.h

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,7 +1773,7 @@ using HeapLocalVariableMetadata
17731773
/// Swift-compiled.
17741774
template <typename Runtime>
17751775
struct TargetObjCClassWrapperMetadata : public TargetMetadata<Runtime> {
1776-
const TargetClassMetadata<Runtime> *Class;
1776+
ConstTargetMetadataPointer<Runtime, TargetClassMetadata> Class;
17771777

17781778
static bool classof(const TargetMetadata<Runtime> *metadata) {
17791779
return metadata->getKind() == MetadataKind::ObjCClassWrapper;
@@ -2141,19 +2141,27 @@ struct TargetProtocolDescriptorList {
21412141
using StoredPointer = typename Runtime::StoredPointer;
21422142
StoredPointer NumProtocols;
21432143

2144-
const TargetProtocolDescriptor<Runtime> **getProtocols() {
2145-
return reinterpret_cast<const TargetProtocolDescriptor<Runtime> **>(this + 1);
2144+
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor> *
2145+
getProtocols() {
2146+
return reinterpret_cast<
2147+
ConstTargetMetadataPointer<
2148+
Runtime, TargetProtocolDescriptor> *>(this + 1);
21462149
}
21472150

2148-
const TargetProtocolDescriptor<Runtime> * const *getProtocols() const {
2149-
return reinterpret_cast<const TargetProtocolDescriptor<Runtime> * const *>(this + 1);
2151+
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor> const *
2152+
getProtocols() const {
2153+
return reinterpret_cast<
2154+
ConstTargetMetadataPointer<
2155+
Runtime, TargetProtocolDescriptor> const *>(this + 1);
21502156
}
21512157

2152-
const TargetProtocolDescriptor<Runtime> *operator[](size_t i) const {
2158+
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor> const &
2159+
operator[](size_t i) const {
21532160
return getProtocols()[i];
21542161
}
21552162

2156-
const TargetProtocolDescriptor<Runtime> *&operator[](size_t i) {
2163+
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor> &
2164+
operator[](size_t i) {
21572165
return getProtocols()[i];
21582166
}
21592167

@@ -2173,29 +2181,36 @@ struct TargetLiteralProtocolDescriptorList
21732181

21742182
template<typename...DescriptorPointers>
21752183
constexpr TargetLiteralProtocolDescriptorList(DescriptorPointers...elements)
2176-
: TargetProtocolDescriptorList<Runtime>(NUM_PROTOCOLS), Protocols{elements...}
2184+
: TargetProtocolDescriptorList<Runtime>(NUM_PROTOCOLS),
2185+
Protocols{elements...}
21772186
{}
21782187
};
2188+
using LiteralProtocolDescriptorList = TargetProtocolDescriptorList<InProcess>;
21792189

21802190
/// A protocol descriptor. This is not type metadata, but is referenced by
21812191
/// existential type metadata records to describe a protocol constraint.
21822192
/// Its layout is compatible with the Objective-C runtime's 'protocol_t' record
21832193
/// layout.
21842194
template <typename Runtime>
21852195
struct TargetProtocolDescriptor {
2196+
using StoredPointer = typename Runtime::StoredPointer;
21862197
/// Unused by the Swift runtime.
2187-
const void *_ObjC_Isa;
2198+
TargetPointer<Runtime, const void> _ObjC_Isa;
21882199

21892200
/// The mangled name of the protocol.
2190-
const char *Name;
2201+
TargetPointer<Runtime, const char> Name;
21912202

21922203
/// The list of protocols this protocol refines.
2193-
const TargetProtocolDescriptorList<Runtime> *InheritedProtocols;
2204+
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptorList>
2205+
InheritedProtocols;
21942206

21952207
/// Unused by the Swift runtime.
2196-
const void *_ObjC_InstanceMethods, *_ObjC_ClassMethods,
2197-
*_ObjC_OptionalInstanceMethods, *_ObjC_OptionalClassMethods,
2198-
*_ObjC_InstanceProperties;
2208+
TargetPointer<Runtime, const void>
2209+
_ObjC_InstanceMethods,
2210+
_ObjC_ClassMethods,
2211+
_ObjC_OptionalInstanceMethods,
2212+
_ObjC_OptionalClassMethods,
2213+
_ObjC_InstanceProperties;
21992214

22002215
/// Size of the descriptor record.
22012216
uint32_t DescriptorSize;
@@ -2229,8 +2244,8 @@ struct TargetProtocolDescriptor {
22292244
}
22302245

22312246
constexpr TargetProtocolDescriptor<Runtime>(const char *Name,
2232-
const TargetProtocolDescriptorList<Runtime> *Inherited,
2233-
ProtocolDescriptorFlags Flags)
2247+
const TargetProtocolDescriptorList<Runtime> *Inherited,
2248+
ProtocolDescriptorFlags Flags)
22342249
: _ObjC_Isa(nullptr), Name(Name), InheritedProtocols(Inherited),
22352250
_ObjC_InstanceMethods(nullptr), _ObjC_ClassMethods(nullptr),
22362251
_ObjC_OptionalInstanceMethods(nullptr),
@@ -2304,6 +2319,7 @@ enum class ExistentialTypeRepresentation {
23042319
/// The structure of existential type metadata.
23052320
template <typename Runtime>
23062321
struct TargetExistentialTypeMetadata : public TargetMetadata<Runtime> {
2322+
using StoredPointer = typename Runtime::StoredPointer;
23072323
/// The number of witness tables and class-constrained-ness of the type.
23082324
ExistentialTypeFlags Flags;
23092325
/// The protocol constraints.
@@ -2354,6 +2370,10 @@ struct TargetExistentialTypeMetadata : public TargetMetadata<Runtime> {
23542370
static bool classof(const TargetMetadata<Runtime> *metadata) {
23552371
return metadata->getKind() == MetadataKind::Existential;
23562372
}
2373+
2374+
static constexpr StoredPointer
2375+
OffsetToNumProtocols = sizeof(TargetMetadata<Runtime>) + sizeof(Flags);
2376+
23572377
};
23582378
using ExistentialTypeMetadata
23592379
= TargetExistentialTypeMetadata<InProcess>;

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/SIL/FormalLinkage.h"
2626
#include "swift/SIL/SILModule.h"
2727
#include "swift/SIL/TypeLowering.h"
28+
#include "swift/Runtime/Metadata.h"
2829
#include "swift/ABI/MetadataValues.h"
2930
#include "llvm/IR/InlineAsm.h"
3031
#include "llvm/IR/DerivedTypes.h"

lib/IRGen/IRGenModule.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ namespace swift {
8888
class IRGenOptions;
8989
class NormalProtocolConformance;
9090
class ProtocolConformance;
91-
class TypeMetadataRecord;
9291
class ProtocolCompositionType;
9392
class ProtocolDecl;
9493
struct SILDeclRef;

lib/Reflection/TypeRef.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void TypeRef::dump() const {
3535

3636
void TypeRef::dump(std::ostream &OS, unsigned Indent) const {
3737
PrintTypeRef(OS, Indent).visit(this);
38-
OS << "\n";
38+
OS << std::endl;
3939
}
4040

4141
TypeRefPointer TypeRef::substituteGenerics(ConstTypeRefVector &Substitutions) {
@@ -45,6 +45,10 @@ TypeRefPointer TypeRef::substituteGenerics(ConstTypeRefVector &Substitutions) {
4545
TypeRefPointer TypeRef::fromDemangleNode(Demangle::NodePointer Node) {
4646
using NodeKind = Demangle::Node::Kind;
4747
switch (Node->getKind()) {
48+
case NodeKind::Global:
49+
return fromDemangleNode(Node->getChild(0));
50+
case NodeKind::TypeMangling:
51+
return fromDemangleNode(Node->getChild(0));
4852
case NodeKind::Type:
4953
return fromDemangleNode(Node->getChild(0));
5054
case NodeKind::BoundGenericClass:
@@ -76,6 +80,20 @@ TypeRefPointer TypeRef::fromDemangleNode(Demangle::NodePointer Node) {
7680
auto instance = fromDemangleNode(Node->getChild(0));
7781
return MetatypeTypeRef::create(instance);
7882
}
83+
case NodeKind::ProtocolList: {
84+
TypeRefVector Protocols;
85+
auto TypeList = Node->getChild(0);
86+
for (auto Type : *TypeList) {
87+
if (auto Protocol = fromDemangleNode(Type))
88+
Protocols.push_back(Protocol);
89+
else
90+
return nullptr;
91+
}
92+
if (Protocols.size() == 1)
93+
return Protocols.front();
94+
else
95+
return ProtocolCompositionTypeRef::create(Protocols);
96+
}
7997
case NodeKind::Protocol: {
8098
auto moduleName = Node->getChild(0)->getText();
8199
auto name = Node->getChild(1)->getText();

0 commit comments

Comments
 (0)