[Reflection] Adopt the MemoryReader in swift-reflection-test

Also do a little bit of gardening of the various headers.
This commit is contained in:
David Farler
2016-02-12 14:58:44 -08:00
parent 69bb6235fa
commit c7d4d25d53
5 changed files with 392 additions and 311 deletions

View File

@@ -0,0 +1,96 @@
//===--- Buffer.h - Swift Type Reflection Buffers ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Abstracts indirecting pointers in the current address space or a remote
// address space.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REFLECTION_BUFFER_H
#define SWIFT_REFLECTION_BUFFER_H
#include "swift/Reflection/Reader.h"
namespace swift {
namespace reflection {
/// An abstract impl interface for getting the head of what may be a buffer
/// copied from an external address space.
class BufferImpl {
public:
virtual const void *getPointer() = 0;
virtual ~BufferImpl() {}
};
/// A trivial wrapper for pointers in the current address space.
template <typename T>
class InternalBuffer final : public BufferImpl {
const T *Source;
public:
InternalBuffer(const T *Source) : Source(Source) {}
virtual const void *getPointer() override {
return reinterpret_cast<const void *>(Source);
}
};
/// A buffer of data copied out of an external address space.
template <typename T>
class ExternalBuffer final : public BufferImpl {
uint8_t Buf[sizeof(T)] = {0};
public:
virtual const void *getPointer() override {
return reinterpret_cast<const void *>(Buf);
}
};
/// An abstraction over a pointer which may be in another
/// address space.
///
/// These will always be backed by real data, but it is
/// important not to indirect twice out of this type.
/// Ask the MemoryReader to read each pointer. For example:
/// Buffer<MyStruct> MS = Reader.read(APointer);
/// int i = MS->i; // OK.
///
/// If MyStruct has a nested MyStruct *, you read it like so:
/// Buffer<MyStruct> MS = Reader.read(MS->nestedMyStruct);
template <typename T>
class Buffer {
friend class MemoryReader;
std::unique_ptr<BufferImpl> Impl;
Buffer() : Impl(nullptr) {}
Buffer(std::unique_ptr<BufferImpl> Impl)
: Impl(std::move(Impl)) {}
public:
const T& operator*() {
return *reinterpret_cast<const T*>(Impl->getPointer());
}
const T* operator->() {
return reinterpret_cast<const T*>(Impl->getPointer());
}
operator bool() const {
return bool(Impl);
}
};
} // end namespace reflection
} // end namespace swift
#endif // SWIFT_REFLECTION_BUFFER_H

View File

@@ -1,9 +1,29 @@
//===--- Reader.h - Swift Type Reflection Memory Reader ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implements reading memory from the current or external process
// for reflection.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REFLECTION_READER_H
#define SWIFT_REFLECTION_READER_H
#include "swift/Reflection/Buffer.h"
#include "swift/Reflection/Records.h"
#include <cstdint>
#include <memory>
#include <vector>
class BufferImpl;
@@ -12,79 +32,45 @@ namespace reflection {
using CopyFunction = size_t (*)(uintptr_t Source, void *Dest, size_t Size);
/// An abstract impl interface for getting the head of what may be a buffer
/// copied from an external address space.
class BufferImpl {
public:
virtual const void *getPointer() = 0;
virtual ~BufferImpl() {}
};
/// A trivial wrapper for pointers in the current address space.
template <typename T>
class InternalBuffer final : public BufferImpl {
const T *Source;
template <typename Iterator>
class ReflectionSection {
using const_iterator = Iterator;
const std::string ImageFilename;
const void * const Begin;
const void * const End;
public:
InternalBuffer(const T *Source) : Source(Source) {}
virtual const void *getPointer() override {
return reinterpret_cast<const void *>(Source);
ReflectionSection(const char *ImageFilename, const void * const Begin,
const void * const End)
: ImageFilename(ImageFilename), Begin(Begin), End(End) {}
const_iterator begin() const {
return const_iterator(Begin, End);
}
const_iterator end() const {
return const_iterator(End, End);
}
const std::string getImageFilename() const {
return ImageFilename;
}
};
/// A buffer of data copied out of an external address space.
template <typename T>
class ExternalBuffer final : public BufferImpl {
uint8_t Buf[sizeof(T)] = {0};
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
using AssociatedTypeSection = ReflectionSection<AssociatedTypeIterator>;
public:
virtual const void *getPointer() override {
return reinterpret_cast<const void *>(Buf);
}
};
/// An abstraction over a pointer which may be in another
/// address space.
///
/// These will always be backed by real data, but it is
/// important not to indirect twice out of this type.
/// Ask the MemoryReader to read each pointer. For example:
/// Buffer<MyStruct> MS = Reader.read(APointer);
/// int i = MS->i; // OK.
///
/// If MyStruct has a nested MyStruct *, you read it like so:
/// Buffer<MyStruct> MS = Reader.read(MS->nestedMyStruct);
template <typename T>
class Buffer {
friend class MemoryReader;
std::unique_ptr<BufferImpl> Impl;
Buffer() : Impl(nullptr) {}
Buffer(std::unique_ptr<BufferImpl> Impl)
: Impl(std::move(Impl)) {}
public:
const T& operator*() {
return *reinterpret_cast<const T*>(Impl->getPointer());
}
const T* operator->() {
return reinterpret_cast<const T*>(Impl->getPointer());
}
operator bool() const {
return bool(Impl);
}
struct ReflectionInfo {
FieldSection Fields;
AssociatedTypeSection AssociatedTypes;
};
class MemoryReader {
CopyFunction copy;
std::vector<ReflectionInfo> Info;
public:
MemoryReader() : copy(nullptr) {}
MemoryReader(CopyFunction copy) : copy(copy) {}
template <typename T>
Buffer<T> read(const T *Source) {
@@ -105,6 +91,14 @@ public:
return Buffer<T>(std::unique_ptr<Internal>(internal));
}
}
void addReflectionInfo(ReflectionInfo I) {
Info.push_back(I);
}
const std::vector<ReflectionInfo> &getInfo() const {
return Info;
}
};
} // end namespace reflection

View File

@@ -0,0 +1,231 @@
//===--- Records.h - Swift Type Reflection Records --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implements the structures of type reflection records.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REFLECTION_RECORDS_H
#define SWIFT_REFLECTION_RECORDS_H
#include "swift/Basic/RelativePointer.h"
namespace swift {
namespace reflection {
class FieldRecord {
const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> FieldName;
public:
std::string getMangledTypeName() const {
return MangledTypeName.get();
}
std::string getFieldName() const {
return FieldName.get();
}
};
struct FieldRecordIterator {
const FieldRecord *Cur;
const FieldRecord * const End;
FieldRecordIterator(const FieldRecord *Cur, const FieldRecord * const End)
: Cur(Cur), End(End) {}
const FieldRecord &operator*() const {
return *Cur;
}
FieldRecordIterator &operator++() {
++Cur;
return *this;
}
bool operator==(const FieldRecordIterator &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(const FieldRecordIterator &other) const {
return !(*this == other);
}
};
struct FieldDescriptor {
const FieldRecord *getFieldRecordBuffer() const {
return reinterpret_cast<const FieldRecord *>(this + 1);
}
const RelativeDirectPointer<const char> MangledTypeName;
public:
const uint32_t NumFields;
const uint32_t FieldRecordSize;
using const_iterator = FieldRecordIterator;
const_iterator begin() const {
auto Begin = getFieldRecordBuffer();
auto End = Begin + NumFields;
return const_iterator { Begin, End };
}
const_iterator end() const {
auto Begin = getFieldRecordBuffer();
auto End = Begin + NumFields;
return const_iterator { End, End };
}
std::string getMangledTypeName() const {
return MangledTypeName.get();
}
};
class AssociatedTypeRecord {
const RelativeDirectPointer<const char> Name;
const RelativeDirectPointer<const char> SubstitutedTypeName;
public:
std::string getName() const {
return Name.get();
}
std::string getMangledSubstitutedTypeName() const {
return SubstitutedTypeName.get();
}
};
struct AssociatedTypeRecordIterator {
const AssociatedTypeRecord *Cur;
const AssociatedTypeRecord * const End;
AssociatedTypeRecordIterator(const AssociatedTypeRecord *Cur,
const AssociatedTypeRecord * const End)
: Cur(Cur), End(End) {}
const AssociatedTypeRecord &operator*() const {
return *Cur;
}
AssociatedTypeRecordIterator &operator++() {
++Cur;
return *this;
}
bool operator==(const AssociatedTypeRecordIterator &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(const AssociatedTypeRecordIterator &other) const {
return !(*this == other);
}
};
struct AssociatedTypeDescriptor {
const RelativeDirectPointer<const char> ConformingTypeName;
const RelativeDirectPointer<const char> ProtocolTypeName;
uint32_t NumAssociatedTypes;
uint32_t AssociatedTypeRecordSize;
const AssociatedTypeRecord *getAssociatedTypeRecordBuffer() const {
return reinterpret_cast<const AssociatedTypeRecord *>(this + 1);
}
public:
using const_iterator = AssociatedTypeRecordIterator;
const_iterator begin() const {
auto Begin = getAssociatedTypeRecordBuffer();
auto End = Begin + NumAssociatedTypes;
return const_iterator { Begin, End };
}
const_iterator end() const {
auto Begin = getAssociatedTypeRecordBuffer();
auto End = Begin + NumAssociatedTypes;
return const_iterator { End, End };
}
std::string getMangledProtocolTypeName() const {
return ProtocolTypeName.get();
}
std::string getMangledConformingTypeName() const {
return ConformingTypeName.get();
}
};
class AssociatedTypeIterator
: public std::iterator<std::forward_iterator_tag, AssociatedTypeDescriptor> {
public:
const void *Cur;
const void * const End;
AssociatedTypeIterator(const void *Cur, const void * const End)
: Cur(Cur), End(End) {}
const AssociatedTypeDescriptor &operator*() const {
return *reinterpret_cast<const AssociatedTypeDescriptor *>(Cur);
}
AssociatedTypeIterator &operator++() {
const auto &ATR = this->operator*();
size_t Size = sizeof(AssociatedTypeDescriptor) +
ATR.NumAssociatedTypes * ATR.AssociatedTypeRecordSize;
const void *Next = reinterpret_cast<const char *>(Cur) + Size;
Cur = Next;
return *this;
}
bool operator==(AssociatedTypeIterator const &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(AssociatedTypeIterator const &other) const {
return !(*this == other);
}
};
class FieldDescriptorIterator
: public std::iterator<std::forward_iterator_tag, FieldDescriptor> {
public:
const void *Cur;
const void * const End;
FieldDescriptorIterator(const void *Cur, const void * const End)
: Cur(Cur), End(End) {}
const FieldDescriptor &operator*() const {
return *reinterpret_cast<const FieldDescriptor *>(Cur);
}
FieldDescriptorIterator &operator++() {
const auto &FR = this->operator*();
const void *Next = reinterpret_cast<const char *>(Cur)
+ sizeof(FieldDescriptor) + FR.NumFields * FR.FieldRecordSize;
Cur = Next;
return *this;
}
bool operator==(FieldDescriptorIterator const &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(FieldDescriptorIterator const &other) const {
return !(*this == other);
}
};
} // end namespace reflection
} // end namespace swift
#endif // SWIFT_REFLECTION_RECORDS_H

View File

@@ -18,8 +18,8 @@
#ifndef SWIFT_REFLECTION_REFLECTIONCONTEXT_H
#define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
#include "swift/Reflection/Reader.h"
#include "swift/Reflection/TypeRef.h"
#include "swift/Runtime/Metadata.h"
#include <iostream>
@@ -28,249 +28,8 @@ class NodePointer;
namespace swift {
namespace reflection {
class FieldRecord {
const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> FieldName;
public:
std::string getMangledTypeName() const {
return MangledTypeName.get();
}
std::string getFieldName() const {
return FieldName.get();
}
};
struct FieldRecordIterator {
const FieldRecord *Cur;
const FieldRecord * const End;
FieldRecordIterator(const FieldRecord *Cur, const FieldRecord * const End)
: Cur(Cur), End(End) {}
const FieldRecord &operator*() const {
return *Cur;
}
FieldRecordIterator &operator++() {
++Cur;
return *this;
}
bool operator==(const FieldRecordIterator &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(const FieldRecordIterator &other) const {
return !(*this == other);
}
};
struct FieldDescriptor {
const FieldRecord *getFieldRecordBuffer() const {
return reinterpret_cast<const FieldRecord *>(this + 1);
}
const RelativeDirectPointer<const char> MangledTypeName;
public:
const uint32_t NumFields;
const uint32_t FieldRecordSize;
using const_iterator = FieldRecordIterator;
const_iterator begin() const {
auto Begin = getFieldRecordBuffer();
auto End = Begin + NumFields;
return const_iterator { Begin, End };
}
const_iterator end() const {
auto Begin = getFieldRecordBuffer();
auto End = Begin + NumFields;
return const_iterator { End, End };
}
std::string getMangledTypeName() const {
return MangledTypeName.get();
}
};
class AssociatedTypeRecord {
const RelativeDirectPointer<const char> Name;
const RelativeDirectPointer<const char> SubstitutedTypeName;
public:
std::string getName() const {
return Name.get();
}
std::string getMangledSubstitutedTypeName() const {
return SubstitutedTypeName.get();
}
};
struct AssociatedTypeRecordIterator {
const AssociatedTypeRecord *Cur;
const AssociatedTypeRecord * const End;
AssociatedTypeRecordIterator(const AssociatedTypeRecord *Cur,
const AssociatedTypeRecord * const End)
: Cur(Cur), End(End) {}
const AssociatedTypeRecord &operator*() const {
return *Cur;
}
AssociatedTypeRecordIterator &operator++() {
++Cur;
return *this;
}
bool operator==(const AssociatedTypeRecordIterator &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(const AssociatedTypeRecordIterator &other) const {
return !(*this == other);
}
};
struct AssociatedTypeDescriptor {
const RelativeDirectPointer<const char> ConformingTypeName;
const RelativeDirectPointer<const char> ProtocolTypeName;
uint32_t NumAssociatedTypes;
uint32_t AssociatedTypeRecordSize;
const AssociatedTypeRecord *getAssociatedTypeRecordBuffer() const {
return reinterpret_cast<const AssociatedTypeRecord *>(this + 1);
}
public:
using const_iterator = AssociatedTypeRecordIterator;
const_iterator begin() const {
auto Begin = getAssociatedTypeRecordBuffer();
auto End = Begin + NumAssociatedTypes;
return const_iterator { Begin, End };
}
const_iterator end() const {
auto Begin = getAssociatedTypeRecordBuffer();
auto End = Begin + NumAssociatedTypes;
return const_iterator { End, End };
}
std::string getMangledProtocolTypeName() const {
return ProtocolTypeName.get();
}
std::string getMangledConformingTypeName() const {
return ConformingTypeName.get();
}
};
class AssociatedTypeIterator
: public std::iterator<std::forward_iterator_tag, AssociatedTypeDescriptor> {
public:
const void *Cur;
const void * const End;
AssociatedTypeIterator(const void *Cur, const void * const End)
: Cur(Cur), End(End) {}
const AssociatedTypeDescriptor &operator*() const {
return *reinterpret_cast<const AssociatedTypeDescriptor *>(Cur);
}
AssociatedTypeIterator &operator++() {
const auto &ATR = this->operator*();
size_t Size = sizeof(AssociatedTypeDescriptor) +
ATR.NumAssociatedTypes * ATR.AssociatedTypeRecordSize;
const void *Next = reinterpret_cast<const char *>(Cur) + Size;
Cur = Next;
return *this;
}
bool operator==(AssociatedTypeIterator const &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(AssociatedTypeIterator const &other) const {
return !(*this == other);
}
};
class FieldDescriptorIterator
: public std::iterator<std::forward_iterator_tag, FieldDescriptor> {
public:
const void *Cur;
const void * const End;
FieldDescriptorIterator(const void *Cur, const void * const End)
: Cur(Cur), End(End) {}
const FieldDescriptor &operator*() const {
return *reinterpret_cast<const FieldDescriptor *>(Cur);
}
FieldDescriptorIterator &operator++() {
const auto &FR = this->operator*();
const void *Next = reinterpret_cast<const char *>(Cur)
+ sizeof(FieldDescriptor) + FR.NumFields * FR.FieldRecordSize;
Cur = Next;
return *this;
}
bool operator==(FieldDescriptorIterator const &other) const {
return Cur == other.Cur && End == other.End;
}
bool operator!=(FieldDescriptorIterator const &other) const {
return !(*this == other);
}
};
template <typename Iterator>
class ReflectionSection {
using const_iterator = Iterator;
const std::string ImageFilename;
const void * const Begin;
const void * const End;
public:
ReflectionSection(const char *ImageFilename, const void * const Begin,
const void * const End)
: ImageFilename(ImageFilename), Begin(Begin), End(End) {}
const_iterator begin() const {
return const_iterator(Begin, End);
}
const_iterator end() const {
return const_iterator(End, End);
}
const std::string getImageFilename() const {
return ImageFilename;
}
};
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
using AssociatedTypeSection = ReflectionSection<AssociatedTypeIterator>;
struct ReflectionSectionReader {
std::vector<FieldSection> FieldSections;
std::vector<AssociatedTypeSection> AssociatedTypeSections;
ReflectionSectionReader(std::vector<FieldSection> FieldSections,
std::vector<AssociatedTypeSection>
AssociatedTypeSections)
: FieldSections(FieldSections),
AssociatedTypeSections(AssociatedTypeSections) {}
};
class ReflectionContext {
ReflectionSectionReader &Reader;
MemoryReader &Reader;
void dumpTypeRef(const std::string &MangledName,
std::ostream &OS, bool printTypeName = false) const {
@@ -283,11 +42,11 @@ class ReflectionContext {
}
public:
ReflectionContext(ReflectionSectionReader &Reader) : Reader(Reader) {}
ReflectionContext(MemoryReader &Reader) : Reader(Reader) {}
void dumpFieldSection(std::ostream &OS) const {
for (const auto &section : Reader.FieldSections) {
for (const auto &descriptor : section) {
for (const auto &sections : Reader.getInfo()) {
for (const auto &descriptor : sections.Fields) {
dumpTypeRef(descriptor.getMangledTypeName(), OS);
for (auto &field : descriptor) {
OS << field.getFieldName() << ": ";
@@ -298,8 +57,8 @@ public:
}
void dumpAssociatedTypeSection(std::ostream &OS) const {
for (const auto &section : Reader.AssociatedTypeSections) {
for (const auto &descriptor : section) {
for (const auto &sections : Reader.getInfo()) {
for (const auto &descriptor : sections.AssociatedTypes) {
auto conformingTypeName = Demangle::demangleTypeAsString(
descriptor.getMangledConformingTypeName());
auto protocolName = Demangle::demangleTypeAsString(