Skip to content

Commit 5196f5b

Browse files
committed
Get typerefs for nominal type metadata
and read their generic arguments, if there are any, too.
1 parent c451db4 commit 5196f5b

File tree

4 files changed

+67
-173
lines changed

4 files changed

+67
-173
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 52 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -204,30 +204,65 @@ class ReflectionContext {
204204
}
205205

206206
TypeRefVector
207-
getGenericSubstitutions(TypeRefPointer Unsubstituted,
208-
StoredPointer MetadataAddress) {
209-
if (!Unsubstituted || !MetadataAddress)
210-
return {};
211-
212-
if (!llvm::isa<BoundGenericTypeRef>(Unsubstituted.get()))
213-
return {};
214-
215-
auto Meta = readMetadata(MetadataAddress);
216-
if (!Meta)
217-
return {};
218-
207+
getGenericArguments(StoredPointer MetadataAddress,
208+
SharedTargetNominalTypeDescriptorRef<Runtime> Descriptor){
219209
TypeRefVector GenericArgTypeRefs;
220-
llvm_unreachable("todo");
210+
auto NumGenericParams = Descriptor->GenericParams.NumPrimaryParams;
211+
auto OffsetToGenericArgs
212+
= sizeof(StoredPointer) * (Descriptor->GenericParams.Offset);
213+
auto AddressOfGenericArgAddress = MetadataAddress + OffsetToGenericArgs;
214+
215+
using ArgIndex = decltype(Descriptor->GenericParams.NumPrimaryParams);
216+
for (ArgIndex i = 0; i < NumGenericParams; ++i,
217+
AddressOfGenericArgAddress += sizeof(StoredPointer)) {
218+
StoredPointer GenericArgAddress;
219+
if (!Reader.readInteger(AddressOfGenericArgAddress,
220+
&GenericArgAddress))
221+
return {};
222+
if (auto GenericArg = getTypeRef(GenericArgAddress))
223+
GenericArgTypeRefs.push_back(GenericArg);
224+
else
225+
return {};
226+
}
221227
return GenericArgTypeRefs;
222228
}
223229

224230
TypeRefPointer
225231
resolveDependentMembers(TypeRefPointer Unresolved,
226232
StoredPointer MetadataAddress) {
227-
llvm_unreachable("todo");
233+
// TODO: Resolve dependent members
228234
return Unresolved;
229235
}
230236

237+
TypeRefPointer
238+
getNominalTypeRef(StoredPointer MetadataAddress,
239+
StoredPointer DescriptorAddress) {
240+
auto Descriptor = readNominalTypeDescriptor(DescriptorAddress);
241+
if (!Descriptor)
242+
return nullptr;
243+
244+
auto NameAddress
245+
= resolveRelativeOffset<int32_t>(DescriptorAddress +
246+
Descriptor->offsetToNameOffset());
247+
auto MangledName = Reader.readString(NameAddress);
248+
if (MangledName.empty())
249+
return nullptr;
250+
251+
auto DemangleNode = Demangle::demangleTypeAsNode(MangledName);
252+
if (!DemangleNode)
253+
return nullptr;
254+
255+
TypeRefPointer Nominal;
256+
if (Descriptor->GenericParams.NumPrimaryParams) {
257+
auto Args = getGenericArguments(MetadataAddress, Descriptor);
258+
Nominal = BoundGenericTypeRef::create(MangledName, Args);
259+
} else {
260+
Nominal = TypeRef::fromDemangleNode(DemangleNode);
261+
}
262+
TypeRefCache.insert({MetadataAddress, Nominal});
263+
return Nominal;
264+
}
265+
231266
TypeRefPointer getTypeRef(StoredPointer MetadataAddress) {
232267
auto Cached = TypeRefCache.find(MetadataAddress);
233268
if (Cached != TypeRefCache.end())
@@ -245,84 +280,24 @@ class ReflectionContext {
245280
auto DescriptorAddress
246281
= resolveRelativeOffset<StoredPointer>(MetadataAddress +
247282
ClassMeta->offsetToDescriptorOffset());
248-
auto Descriptor = readNominalTypeDescriptor(DescriptorAddress);
249-
if (!Descriptor)
250-
return nullptr;
251-
252-
auto NameAddress
253-
= resolveRelativeOffset<int32_t>(DescriptorAddress +
254-
Descriptor->offsetToNameOffset());
255-
auto MangledName = Reader.readString(NameAddress);
256-
if (MangledName.empty())
257-
return nullptr;
258-
259-
auto DemangleNode = Demangle::demangleTypeAsNode(MangledName);
260-
if (!DemangleNode)
261-
return nullptr;
262283

263-
auto Unsubstituted = TypeRef::fromDemangleNode(DemangleNode);
264-
auto Substitutions = getGenericSubstitutions(Unsubstituted,
265-
MetadataAddress);
266-
auto Substituted = Unsubstituted->substituteGenerics(Substitutions);
267-
auto Resolved = resolveDependentMembers(Substituted, MetadataAddress);
268-
TypeRefCache.insert({MetadataAddress, Resolved});
269-
return Resolved;
284+
return getNominalTypeRef(MetadataAddress, DescriptorAddress);
270285
}
271286
case MetadataKind::Struct: {
272287
auto StructMeta = cast<TargetStructMetadata<Runtime>>(Meta.get());
273288

274289
auto DescriptorAddress
275290
= resolveRelativeOffset<StoredPointer>(MetadataAddress +
276291
StructMeta->offsetToDescriptorOffset());
277-
auto Descriptor = readNominalTypeDescriptor(DescriptorAddress);
278-
if (!Descriptor)
279-
return nullptr;
280-
281-
auto NameAddress
282-
= resolveRelativeOffset<int32_t>(DescriptorAddress +
283-
Descriptor->offsetToNameOffset());
284-
auto MangledName = Reader.readString(NameAddress);
285-
if (MangledName.empty())
286-
return nullptr;
287-
288-
auto DemangleNode = Demangle::demangleTypeAsNode(MangledName);
289-
if (!DemangleNode)
290-
return nullptr;
291-
292-
auto Unsubstituted = TypeRef::fromDemangleNode(DemangleNode);
293-
auto Substitutions = getGenericSubstitutions(Unsubstituted,
294-
MetadataAddress);
295-
auto Substituted = Unsubstituted->substituteGenerics(Substitutions);
296-
auto Resolved = resolveDependentMembers(Substituted, MetadataAddress);
297-
TypeRefCache.insert({MetadataAddress, Resolved});
298-
return Resolved;
292+
return getNominalTypeRef(MetadataAddress, DescriptorAddress);
299293
}
300294
case MetadataKind::Enum:
301295
case MetadataKind::Optional: {
302296
auto EnumMeta = cast<TargetEnumMetadata<Runtime>>(Meta.get());
303297
auto DescriptorAddress
304298
= resolveRelativeOffset<StoredPointer>(MetadataAddress +
305299
EnumMeta->offsetToDescriptorOffset());
306-
auto Descriptor = readNominalTypeDescriptor(DescriptorAddress);
307-
if (!Descriptor)
308-
return nullptr;
309-
310-
auto NameAddress
311-
= resolveRelativeOffset<int32_t>(DescriptorAddress +
312-
Descriptor->offsetToNameOffset());
313-
auto MangledName = Reader.readString(NameAddress);
314-
if (MangledName.empty()) return nullptr;
315-
316-
auto DemangleNode = Demangle::demangleTypeAsNode(MangledName);
317-
if (!DemangleNode) return nullptr;
318-
319-
auto Unsubstituted = TypeRef::fromDemangleNode(DemangleNode);
320-
auto Substitutions = getGenericSubstitutions(Unsubstituted,
321-
MetadataAddress);
322-
auto Substituted = Unsubstituted->substituteGenerics(Substitutions);
323-
auto Resolved = resolveDependentMembers(Substituted, MetadataAddress);
324-
TypeRefCache.insert({MetadataAddress, Resolved});
325-
return Resolved;
300+
return getNominalTypeRef(MetadataAddress, DescriptorAddress);
326301
}
327302
case MetadataKind::Tuple: {
328303
auto TupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta.get());

include/swift/Runtime/Metadata.h

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,9 +1222,9 @@ struct TargetMetadata {
12221222
case MetadataKind::Class: {
12231223
const auto cls = static_cast<const TargetClassMetadata<Runtime> *>(this);
12241224
if (!cls->isTypeMetadata())
1225-
return nullptr;
1225+
return 0;
12261226
if (cls->isArtificialSubclass())
1227-
return nullptr;
1227+
return 0;
12281228
return cls->getDescription();
12291229
}
12301230
case MetadataKind::Struct:
@@ -1242,7 +1242,7 @@ struct TargetMetadata {
12421242
case MetadataKind::HeapLocalVariable:
12431243
case MetadataKind::HeapGenericLocalVariable:
12441244
case MetadataKind::ErrorObject:
1245-
return nullptr;
1245+
return 0;
12461246
}
12471247
}
12481248

@@ -1379,7 +1379,7 @@ struct EnumTypeDescriptor;
13791379
template <typename Runtime>
13801380
struct TargetNominalTypeDescriptor {
13811381
using StoredPointer = typename Runtime::StoredPointer;
1382-
/// The mangled name of the nominal type, with no generic parameters.
1382+
/// The mangled name of the nominal type.
13831383
TargetRelativeDirectPointer<Runtime, const char> Name;
13841384

13851385
/// The following fields are kind-dependent.
@@ -1628,11 +1628,11 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
16281628
/// created for various dynamic purposes like KVO?
16291629
bool isArtificialSubclass() const {
16301630
assert(isTypeMetadata());
1631-
return Description == nullptr;
1631+
return Description == 0;
16321632
}
16331633
void setArtificialSubclass() {
16341634
assert(isTypeMetadata());
1635-
Description = nullptr;
1635+
Description = 0;
16361636
}
16371637

16381638
ClassFlags getFlags() const {
@@ -1914,6 +1914,7 @@ using ForeignClassMetadata = TargetForeignClassMetadata<InProcess>;
19141914
/// The common structure of metadata for structs and enums.
19151915
template <typename Runtime>
19161916
struct TargetValueMetadata : public TargetMetadata<Runtime> {
1917+
using StoredPointer = typename Runtime::StoredPointer;
19171918
TargetValueMetadata(MetadataKind Kind,
19181919
ConstTargetMetadataPointer<Runtime, TargetNominalTypeDescriptor>
19191920
description,
@@ -1948,6 +1949,12 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
19481949
ConstTargetMetadataPointer<Runtime, TargetMetadata> const *>(this);
19491950
return (asWords + Description->GenericParams.Offset);
19501951
}
1952+
1953+
StoredPointer offsetToDescriptorOffset() const {
1954+
auto DescriptionAddress = (uint8_t *)&this->Description;
1955+
auto ThisAddress = (uint8_t *)this;
1956+
return DescriptionAddress - ThisAddress;
1957+
}
19511958
};
19521959
using ValueMetadata = TargetValueMetadata<InProcess>;
19531960

@@ -1975,12 +1982,6 @@ struct TargetStructMetadata : public TargetValueMetadata<Runtime> {
19751982
return getter(this);
19761983
}
19771984

1978-
StoredPointer offsetToDescriptorOffset() const {
1979-
auto DescriptionAddress = (uint8_t *)&this->Description;
1980-
auto ThisAddress = (uint8_t *)this;
1981-
return DescriptionAddress - ThisAddress;
1982-
}
1983-
19841985
static bool classof(const TargetMetadata<Runtime> *metadata) {
19851986
return metadata->getKind() == MetadataKind::Struct;
19861987
}
@@ -2018,12 +2019,6 @@ struct TargetEnumMetadata : public TargetValueMetadata<Runtime> {
20182019
return *asWords;
20192020
}
20202021

2021-
StoredPointer offsetToDescriptorOffset() const {
2022-
auto DescriptionAddress = (uint8_t *)&this->Description;
2023-
auto ThisAddress = (uint8_t *)this;
2024-
return DescriptionAddress - ThisAddress;
2025-
}
2026-
20272022
static bool classof(const TargetMetadata<Runtime> *metadata) {
20282023
return metadata->getKind() == MetadataKind::Enum
20292024
|| metadata->getKind() == MetadataKind::Optional;

tools/swift-reflection-test/mach_helpers.h

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -28,63 +28,10 @@ static inline uint64_t extractUInt64(mach_msg_type_descriptor_t type_desc) {
2828
return (type_desc.pad1 + ((uint64_t)type_desc.pad2 << 32));
2929
}
3030

31-
static inline void packUInt64(uint64_t value,
32-
mach_msg_type_descriptor_t *type_desc) {
33-
type_desc->pad1 = (uint32_t)value;
34-
type_desc->pad2 = value >> 32;
35-
}
36-
37-
static inline mach_port_t getSelfTask() {
38-
return mach_task_self();
39-
}
40-
4131
static inline void guardMachError(kern_return_t error, const char *message) {
4232
if (error == KERN_SUCCESS) return;
4333
fprintf(stderr, "%s failed: %s\n", message, mach_error_string(error));
44-
exit(EXIT_FAILURE);
45-
}
46-
47-
/// Sends `portToSend` through `remotePort`.
48-
static inline void sendPort(mach_port_t portToSend, mach_port_t remotePort) {
49-
kern_return_t error;
50-
51-
SendPortMessage message;
52-
53-
message.header.msgh_remote_port = remotePort;
54-
message.header.msgh_local_port = MACH_PORT_NULL;
55-
message.header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0) |
56-
MACH_MSGH_BITS_COMPLEX;
57-
message.header.msgh_size = sizeof(message);
58-
59-
message.body.msgh_descriptor_count = 1;
60-
message.task_port.name = portToSend;
61-
message.task_port.disposition = MACH_MSG_TYPE_COPY_SEND;
62-
message.task_port.type = MACH_MSG_PORT_DESCRIPTOR;
63-
64-
error = mach_msg_send (&message.header);
65-
guardMachError(error, "mach_msg_send");
66-
}
67-
68-
static inline mach_port_t getSelfBootstrapPort() {
69-
mach_port_t port;
70-
kern_return_t error = task_get_bootstrap_port(mach_task_self(), &port);
71-
guardMachError(error, "task_get_bootstrap_port");
72-
return port;
73-
}
74-
75-
static inline void sendUInt64(uint64_t value, mach_port_t remotePort) {
76-
SendUInt64Message message;
77-
message.header.msgh_remote_port = remotePort;
78-
message.header.msgh_local_port = MACH_PORT_NULL;
79-
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
80-
message.header.msgh_size = sizeof(message);
81-
82-
message.body.msgh_descriptor_count = 1;
83-
message.value.pad1 = (uint32_t)value;
84-
message.value.pad2 = value >> 32;
85-
86-
kern_return_t error = mach_msg_send(&message.header);
87-
guardMachError(error, "mach_msg_send");
34+
abort();
8835
}
8936

9037
static inline uint64_t receive_uint64_t(mach_port_t from_port) {
@@ -101,29 +48,5 @@ static inline uint64_t receive_uint64_t(mach_port_t from_port) {
10148
return extractUInt64(message.value);
10249
}
10350

104-
static inline void sendReflectionInfo(RemoteReflectionInfo info,
105-
mach_port_t remotePort) {
106-
SendReflectionInfoMessage message;
107-
message.header.msgh_remote_port = remotePort;
108-
message.header.msgh_local_port = MACH_PORT_NULL;
109-
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
110-
message.header.msgh_size = sizeof(message);
111-
112-
message.body.msgh_descriptor_count = 9;
113-
114-
packUInt64(info.image_name_addr, &message.image_name_addr);
115-
packUInt64(info.fieldmd.addr, &message.fieldmd_start_addr);
116-
packUInt64(info.fieldmd.size, &message.fieldmd_size);
117-
packUInt64(info.typeref.addr, &message.typeref_start_addr);
118-
packUInt64(info.typeref.size, &message.typeref_size);
119-
packUInt64(info.reflstr.addr, &message.reflstr_start_addr);
120-
packUInt64(info.reflstr.size, &message.reflstr_size);
121-
packUInt64(info.assocty.addr, &message.assocty_start_addr);
122-
packUInt64(info.assocty.size, &message.assocty_size);
123-
124-
kern_return_t error = mach_msg_send(&message.header);
125-
guardMachError(error, "mach_msg_send");
126-
}
127-
12851
#endif // SWIFT_REFLECTION_TEST_MACH_HELPERS_H
12952

tools/swift-reflection-test/swift-reflection-test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ static bool machReadBytes(const addr_t Address, uint8_t *Dest, uint64_t Size) {
313313
mach_msg_type_number_t SizeRead = 0;
314314
vm_offset_t Data = 0;
315315
auto Result = vm_read(childTask, Address, Size, &Data, &SizeRead);
316+
guardMachError(Result, "vm_read");
316317
if (Result == KERN_SUCCESS && SizeRead == Size) {
317318
memmove(reinterpret_cast<void *>(Dest),
318319
reinterpret_cast<void *>(Data), Size);

0 commit comments

Comments
 (0)