Skip to content

Commit 59a2201

Browse files
committed
Register and look up field descriptors using TypeInfoProvider
1 parent bd10966 commit 59a2201

File tree

7 files changed

+177
-65
lines changed

7 files changed

+177
-65
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ class ReflectionContext
228228
}
229229

230230
template <typename T>
231-
bool readMachOSections(
231+
llvm::Optional<uint64_t>
232+
readMachOSections(
232233
RemoteAddress ImageStart,
233234
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
234235
auto Buf =
@@ -350,7 +351,7 @@ class ReflectionContext
350351
{MPEnumMdSec.first, MPEnumMdSec.second},
351352
PotentialModuleNames};
352353

353-
this->addReflectionInfo(info);
354+
auto InfoID = this->addReflectionInfo(info);
354355

355356
// Find the __DATA segment.
356357
for (unsigned I = 0; I < NumCommands; ++I) {
@@ -374,10 +375,10 @@ class ReflectionContext
374375

375376
savedBuffers.push_back(std::move(Buf));
376377
savedBuffers.push_back(std::move(Sections));
377-
return true;
378+
return InfoID;
378379
}
379380

380-
bool readPECOFFSections(
381+
llvm::Optional<uint64_t> readPECOFFSections(
381382
RemoteAddress ImageStart,
382383
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
383384
auto DOSHdrBuf = this->getReader().readBytes(
@@ -477,11 +478,10 @@ class ReflectionContext
477478
{ConformMdSec.first, ConformMdSec.second},
478479
{MPEnumMdSec.first, MPEnumMdSec.second},
479480
PotentialModuleNames};
480-
this->addReflectionInfo(Info);
481-
return true;
481+
return this->addReflectionInfo(Info);
482482
}
483483

484-
bool readPECOFF(RemoteAddress ImageStart,
484+
llvm::Optional<uint64_t> readPECOFF(RemoteAddress ImageStart,
485485
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
486486
auto Buf = this->getReader().readBytes(ImageStart,
487487
sizeof(llvm::object::dos_header));
@@ -505,7 +505,7 @@ class ReflectionContext
505505
}
506506

507507
template <typename T>
508-
bool readELFSections(
508+
llvm::Optional<uint64_t> readELFSections(
509509
RemoteAddress ImageStart,
510510
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
511511
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
@@ -673,8 +673,7 @@ class ReflectionContext
673673
{MPEnumMdSec.first, MPEnumMdSec.second},
674674
PotentialModuleNames};
675675

676-
this->addReflectionInfo(info);
677-
return true;
676+
return this->addReflectionInfo(info);
678677
}
679678

680679
/// Parses metadata information from an ELF image. Because the Section
@@ -693,22 +692,22 @@ class ReflectionContext
693692
/// instance's memory reader.
694693
///
695694
/// \return
696-
/// /b True if the metadata information was parsed successfully,
697-
/// /b false otherwise.
698-
bool
695+
/// \b The newly added reflection info ID if successful,
696+
/// \b llvm::None otherwise.
697+
llvm::Optional<uint64_t>
699698
readELF(RemoteAddress ImageStart,
700699
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
701700
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
702701
auto Buf =
703702
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
704703
if (!Buf)
705-
return false;
704+
return llvm::None;
706705

707706
// Read the header.
708707
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
709708

710709
if (!Hdr->checkMagic())
711-
return false;
710+
return llvm::None;
712711

713712
// Check if we have a ELFCLASS32 or ELFCLASS64
714713
unsigned char FileClass = Hdr->getFileClass();
@@ -719,11 +718,11 @@ class ReflectionContext
719718
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS32>>(
720719
ImageStart, FileBuffer, PotentialModuleNames);
721720
} else {
722-
return false;
721+
return llvm::None;
723722
}
724723
}
725724

726-
bool
725+
llvm::Optional<uint64_t>
727726
addImage(RemoteAddress ImageStart,
728727
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
729728
// Read the first few bytes to look for a magic header.
@@ -761,7 +760,7 @@ class ReflectionContext
761760
}
762761

763762
// We don't recognize the format.
764-
return false;
763+
return llvm::None;
765764
}
766765

767766
/// Adds an image using the FindSection closure to find the swift metadata
@@ -770,9 +769,9 @@ class ReflectionContext
770769
/// of freeing the memory buffer in the RemoteRef return value.
771770
/// process.
772771
/// \return
773-
/// \b True if any of the reflection sections were registered,
774-
/// \b false otherwise.
775-
bool
772+
/// \b The newly added reflection info ID if successful,
773+
/// \b llvm::None otherwise.
774+
llvm::Optional<uint64_t>
776775
addImage(llvm::function_ref<
777776
std::pair<RemoteRef<void>, uint64_t>(ReflectionSectionKind)>
778777
FindSection,
@@ -798,7 +797,7 @@ class ReflectionContext
798797

799798
// If we didn't find any sections, return.
800799
if (llvm::all_of(Pairs, [](const auto &Pair) { return !Pair.first; }))
801-
return false;
800+
return {};
802801

803802
ReflectionInfo Info = {{Pairs[0].first, Pairs[0].second},
804803
{Pairs[1].first, Pairs[1].second},
@@ -809,12 +808,11 @@ class ReflectionContext
809808
{Pairs[6].first, Pairs[6].second},
810809
{Pairs[7].first, Pairs[7].second},
811810
PotentialModuleNames};
812-
this->addReflectionInfo(Info);
813-
return true;
811+
return addReflectionInfo(Info);
814812
}
815813

816-
void addReflectionInfo(ReflectionInfo I) {
817-
getBuilder().addReflectionInfo(I);
814+
llvm::Optional<uint64_t> addReflectionInfo(ReflectionInfo I) {
815+
return getBuilder().addReflectionInfo(I);
818816
}
819817

820818
bool ownsObject(RemoteAddress ObjectAddress) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,10 +915,13 @@ class TypeRefBuilder {
915915
/// Parsing reflection metadata
916916
///
917917

918-
void addReflectionInfo(ReflectionInfo I) {
918+
/// Add the ReflectionInfo and return a unique ID for the reflection image
919+
/// added. Since we only add reflection infos, the ID can be its index.
920+
llvm::Optional<uint64_t> addReflectionInfo(ReflectionInfo I) {
919921
ReflectionInfos.push_back(I);
922+
return ReflectionInfos.size() - 1;
920923
}
921-
924+
922925
const std::vector<ReflectionInfo> &getReflectionInfos() {
923926
return ReflectionInfos;
924927
}
@@ -939,9 +942,15 @@ class TypeRefBuilder {
939942
llvm::Optional<std::string> normalizeReflectionName(RemoteRef<char> name);
940943
bool reflectionNameMatches(RemoteRef<char> reflectionName,
941944
StringRef searchName);
942-
void populateFieldTypeInfoCacheWithReflectionAtIndex(size_t Index);
945+
void populateFieldTypeInfoCacheWithReflectionAtIndex(
946+
size_t Index, remote::TypeInfoProvider *ExternalTypeInfo);
947+
llvm::Optional<RemoteRef<FieldDescriptor>>
948+
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName,
949+
remote::TypeInfoProvider *ExternalTypeInfo);
950+
943951
llvm::Optional<RemoteRef<FieldDescriptor>>
944-
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName);
952+
getFieldDescriptorFromProvider(const std::string &MangledName,
953+
remote::TypeInfoProvider *ExternalTypeInfo);
945954

946955
public:
947956
RemoteRef<char> readTypeRef(uint64_t remoteAddr);
@@ -1052,10 +1061,13 @@ class TypeRefBuilder {
10521061
const std::string &Member,
10531062
StringRef Protocol);
10541063

1055-
const TypeRef *lookupSuperclass(const TypeRef *TR);
1064+
const TypeRef *lookupSuperclass(const TypeRef *TR,
1065+
remote::TypeInfoProvider *ExternalTypeInfo);
10561066

10571067
/// Load unsubstituted field types for a nominal type.
1058-
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
1068+
RemoteRef<FieldDescriptor>
1069+
getFieldTypeInfo(const TypeRef *TR,
1070+
remote::TypeInfoProvider *ExternalTypeInfo);
10591071

10601072
/// Get the parsed and substituted field types for a nominal type.
10611073
bool getFieldTypeRefs(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,

include/swift/Remote/TypeInfoProvider.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,33 @@
1717
#ifndef SWIFT_REMOTE_TYPEINFOPROVIDER_H
1818
#define SWIFT_REMOTE_TYPEINFOPROVIDER_H
1919

20+
#include "llvm/ADT/ArrayRef.h"
21+
#include "llvm/ADT/StringRef.h"
22+
#include "llvm/ADT/Optional.h"
23+
24+
#include <vector>
25+
#include <string>
26+
2027
namespace swift {
2128
namespace reflection {
2229
class TypeInfo;
30+
31+
template <typename T>
32+
class ReflectionSection;
33+
class FieldDescriptorIterator;
34+
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
2335
}
2436
namespace remote {
2537

38+
/// A struct with the information to locate a specific field descriptor.
39+
struct FieldDescriptorLocator {
40+
/// The reflection info ID the field descriptor belongs to.
41+
uint64_t InfoID;
42+
43+
/// The offset of the field descriptor in the FieldSection buffer.
44+
uint64_t Offset;
45+
};
46+
2647
/// An abstract interface for providing external type layout information.
2748
struct TypeInfoProvider {
2849
virtual ~TypeInfoProvider() = default;
@@ -32,6 +53,26 @@ struct TypeInfoProvider {
3253
/// info, for example.
3354
virtual const reflection::TypeInfo *
3455
getTypeInfo(llvm::StringRef mangledName) = 0;
56+
57+
/// Register the field descriptors of a reflection info with a given id with
58+
/// their corresponding mangled names. The amount of field descriptors and
59+
/// mangled names must be the same. If a field descriptor does not have a
60+
/// mangled name a corresponding empty string must be in the mangled_names
61+
/// vector.
62+
virtual void registerFieldDescriptors(
63+
uint64_t InfoID,
64+
const swift::reflection::FieldSection &FieldDescriptors,
65+
const llvm::ArrayRef<std::string> &MangledNames) = 0;
66+
67+
/// Retrieve a pair representing the reflection info id and the offset of a
68+
/// field descriptor in the field section buffer, if available.
69+
virtual llvm::Optional<FieldDescriptorLocator>
70+
getFieldDescriptorLocator(const std::string &Name) = 0;
71+
72+
/// Returns whether looking for a mangled name in reflection info with a given
73+
/// id could possibly return information that couldn't be provided by the
74+
/// TypeInfoProvider.
75+
virtual bool shouldParseReflectionInfoWithId(uint64_t InfoID) = 0;
3576
};
3677

3778
} // namespace remote

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ class ExistentialTypeInfoBuilder {
12011201
return false;
12021202
}
12031203

1204-
void examineProtocols() {
1204+
void examineProtocols(remote::TypeInfoProvider *ExternalTypeInfo) {
12051205
if (isSingleError()) {
12061206
Representation = ExistentialTypeRepresentation::Error;
12071207
// No extra witness table for protocol<Error>
@@ -1223,7 +1223,7 @@ class ExistentialTypeInfoBuilder {
12231223
continue;
12241224
}
12251225

1226-
auto FD = TC.getBuilder().getFieldTypeInfo(P);
1226+
auto FD = TC.getBuilder().getFieldTypeInfo(P, ExternalTypeInfo);
12271227
if (FD == nullptr) {
12281228
DEBUG_LOG(fprintf(stderr, "No field descriptor: "); P->dump())
12291229
Invalid = true;
@@ -1239,7 +1239,8 @@ class ExistentialTypeInfoBuilder {
12391239
Representation = ExistentialTypeRepresentation::Class;
12401240
++WitnessTableCount;
12411241

1242-
if (auto *Superclass = TC.getBuilder().lookupSuperclass(P)) {
1242+
if (auto *Superclass =
1243+
TC.getBuilder().lookupSuperclass(P, ExternalTypeInfo)) {
12431244
// ObjC class info should be available in the metadata, so it's safe
12441245
// to not pass an external provider here. This helps preserving the
12451246
// layering.
@@ -1290,7 +1291,8 @@ class ExistentialTypeInfoBuilder {
12901291
Protocols.push_back(P);
12911292
}
12921293

1293-
void addProtocolComposition(const ProtocolCompositionTypeRef *PC) {
1294+
void addProtocolComposition(const ProtocolCompositionTypeRef *PC,
1295+
remote::TypeInfoProvider *ExternalTypeInfo) {
12941296
for (auto *T : PC->getProtocols()) {
12951297
addProtocol(T);
12961298
}
@@ -1301,8 +1303,7 @@ class ExistentialTypeInfoBuilder {
13011303
if (auto *T = PC->getSuperclass()) {
13021304
// Anything else should either be a superclass constraint, or
13031305
// we have an invalid typeref.
1304-
if (!isa<NominalTypeRef>(T) &&
1305-
!isa<BoundGenericTypeRef>(T) &&
1306+
if (!isa<NominalTypeRef>(T) && !isa<BoundGenericTypeRef>(T) &&
13061307
!isa<ObjCClassTypeRef>(T)) {
13071308
DEBUG_LOG(fprintf(stderr, "Bad existential member: "); T->dump())
13081309
Invalid = true;
@@ -1315,7 +1316,7 @@ class ExistentialTypeInfoBuilder {
13151316
return;
13161317
}
13171318

1318-
const auto &FD = TC.getBuilder().getFieldTypeInfo(T);
1319+
const auto &FD = TC.getBuilder().getFieldTypeInfo(T, ExternalTypeInfo);
13191320
if (FD == nullptr) {
13201321
DEBUG_LOG(fprintf(stderr, "No field descriptor: "); T->dump())
13211322
Invalid = true;
@@ -1350,7 +1351,7 @@ class ExistentialTypeInfoBuilder {
13501351
}
13511352

13521353
const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
1353-
examineProtocols();
1354+
examineProtocols(ExternalTypeInfo);
13541355

13551356
if (Invalid)
13561357
return nullptr;
@@ -1421,7 +1422,7 @@ class ExistentialTypeInfoBuilder {
14211422
}
14221423

14231424
const TypeInfo *buildMetatype(remote::TypeInfoProvider *ExternalTypeInfo) {
1424-
examineProtocols();
1425+
examineProtocols(ExternalTypeInfo);
14251426

14261427
if (Invalid)
14271428
return nullptr;
@@ -2226,7 +2227,7 @@ class LowerType
22262227
}
22272228

22282229
const TypeInfo *visitAnyNominalTypeRef(const TypeRef *TR) {
2229-
auto FD = TC.getBuilder().getFieldTypeInfo(TR);
2230+
auto FD = TC.getBuilder().getFieldTypeInfo(TR, ExternalTypeInfo);
22302231
if (FD == nullptr || FD->isStruct()) {
22312232
// Maybe this type is opaque -- look for a builtin
22322233
// descriptor to see if we at least know its size
@@ -2325,7 +2326,7 @@ class LowerType
23252326
const TypeInfo *
23262327
visitProtocolCompositionTypeRef(const ProtocolCompositionTypeRef *PC) {
23272328
ExistentialTypeInfoBuilder builder(TC);
2328-
builder.addProtocolComposition(PC);
2329+
builder.addProtocolComposition(PC, ExternalTypeInfo);
23292330
return builder.build(ExternalTypeInfo);
23302331
}
23312332

@@ -2354,7 +2355,7 @@ class LowerType
23542355
auto *TR = EM->getInstanceType();
23552356

23562357
if (auto *PC = dyn_cast<ProtocolCompositionTypeRef>(TR)) {
2357-
builder.addProtocolComposition(PC);
2358+
builder.addProtocolComposition(PC, ExternalTypeInfo);
23582359
} else {
23592360
DEBUG_LOG(fprintf(stderr, "Invalid existential metatype: "); EM->dump());
23602361
return nullptr;
@@ -2515,7 +2516,7 @@ TypeConverter::getTypeInfo(const TypeRef *TR,
25152516
const TypeInfo *TypeConverter::getClassInstanceTypeInfo(
25162517
const TypeRef *TR, unsigned start,
25172518
remote::TypeInfoProvider *ExternalTypeInfo) {
2518-
auto FD = getBuilder().getFieldTypeInfo(TR);
2519+
auto FD = getBuilder().getFieldTypeInfo(TR, ExternalTypeInfo);
25192520
if (FD == nullptr) {
25202521
DEBUG_LOG(fprintf(stderr, "No field descriptor: "); TR->dump());
25212522
return nullptr;

stdlib/public/Reflection/TypeRef.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,7 @@ class TypeRefSubstitution
13651365
break;
13661366

13671367
// If we didn't find the member type, check the superclass.
1368-
auto *Superclass = Builder.lookupSuperclass(SubstBase);
1368+
auto *Superclass = Builder.lookupSuperclass(SubstBase, nullptr);
13691369
if (Superclass == nullptr)
13701370
break;
13711371

0 commit comments

Comments
 (0)