From 04444c44a26abf74a922b4715a2696e2eeb695d7 Mon Sep 17 00:00:00 2001 From: David Farler Date: Thu, 3 Mar 2016 18:25:09 -0800 Subject: [PATCH] Get typerefs for tuple type metadata, including their elements --- include/swift/Reflection/ReflectionContext.h | 33 +++++++++++++++++--- include/swift/Runtime/Metadata.h | 6 ++-- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h index d0aa7026f7d1b..094170d6ff3e6 100644 --- a/include/swift/Reflection/ReflectionContext.h +++ b/include/swift/Reflection/ReflectionContext.h @@ -53,6 +53,7 @@ struct ReflectionInfo { template class ReflectionContext { using StoredPointer = typename Runtime::StoredPointer; + using StoredSize = typename Runtime::StoredSize; std::vector ReflectionInfos; std::unordered_map TypeRefCache; @@ -69,8 +70,7 @@ class ReflectionContext { } template - SharedTargetMetadataRef _readMetadata(StoredPointer Address) { - auto Size = sizeof(M); + SharedTargetMetadataRef _readMetadata(StoredPointer Address, size_t Size = sizeof(M)) { uint8_t *Buffer = (uint8_t *)malloc(Size); if (!Reader.readBytes(Address, Buffer, Size)) { free(Buffer); @@ -83,6 +83,7 @@ class ReflectionContext { free((void*)Meta); }); } + public: ReflectionContext(MemoryReader &Reader) : Reader(Reader) {} @@ -167,8 +168,17 @@ class ReflectionContext { return _readMetadata>(Address); case MetadataKind::Struct: return _readMetadata>(Address); - case MetadataKind::Tuple: - return _readMetadata>(Address); + case MetadataKind::Tuple: { + auto NumElementsAddress = Address + + TargetTupleTypeMetadata::OffsetToNumElements; + StoredSize NumElements; + if (!Reader.readInteger(NumElementsAddress, &NumElements)) + return nullptr; + auto TotalSize = sizeof(TargetTupleTypeMetadata) + + NumElements * sizeof(StoredPointer); + return _readMetadata>(Address, + TotalSize); + } default: return nullptr; } @@ -302,7 +312,20 @@ class ReflectionContext { case MetadataKind::Tuple: { auto TupleMeta = cast>(Meta.get()); TypeRefVector Elements; - llvm_unreachable("todo"); + StoredPointer ElementAddress = MetadataAddress + + sizeof(TargetTupleTypeMetadata); + using Element = typename TargetTupleTypeMetadata::Element; + for (StoredPointer i = 0; i < TupleMeta->NumElements; ++i, + ElementAddress += sizeof(Element)) { + Element E; + if (!Reader.readBytes(ElementAddress, (uint8_t*)&E, sizeof(Element))) + return nullptr; + + if (auto ElementTypeRef = getTypeRef(E.Type)) + Elements.push_back(ElementTypeRef); + else + return nullptr; + } return TupleTypeRef::create(Elements); } case MetadataKind::Function: { diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h index 48cedb2383ab1..dab5d286f554e 100644 --- a/include/swift/Runtime/Metadata.h +++ b/include/swift/Runtime/Metadata.h @@ -2101,11 +2101,11 @@ struct TargetTupleTypeMetadata : public TargetMetadata { } }; - Element *getElements() { + TargetPointer getElements() { return reinterpret_cast>(this + 1); } - const Element *getElements() const { + TargetPointer getElements() const { return reinterpret_cast>(this + 1); } @@ -2117,6 +2117,8 @@ struct TargetTupleTypeMetadata : public TargetMetadata { return getElements()[i]; } + static constexpr StoredSize OffsetToNumElements = sizeof(TargetMetadata); + static bool classof(const TargetMetadata *metadata) { return metadata->getKind() == MetadataKind::Tuple; }