Files
swift-mirror/include/swift/Reflection/ReflectionContext.h
Slava Pestov 1d5b9b09ac Reflection: Add instance-specific layout entry point, and do some refactoring
Closure context layout will depend on the instance itself as well
as the isa pointer, because instead of instantiating metadata for
closures that capture generic parameters, we store the substitutions
inside the context itself.

For classes, this entry point just reads the isa pointer, applies
the isa mask and proceeds down the metadata path.

For now, the only the latter is hooked up.
2016-04-29 15:39:49 -07:00

132 lines
4.0 KiB
C++

//===--- ReflectionContext.h - Swift Type Reflection Context ----*- 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 context for reflection of values in the address space of a
// remote process.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REFLECTION_REFLECTIONCONTEXT_H
#define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
#include "swift/Remote/MemoryReader.h"
#include "swift/Remote/MetadataReader.h"
#include "swift/Reflection/Records.h"
#include "swift/Reflection/TypeLowering.h"
#include "swift/Reflection/TypeRef.h"
#include "swift/Reflection/TypeRefBuilder.h"
#include <iostream>
#include <vector>
#include <unordered_map>
namespace swift {
namespace reflection {
using swift::remote::MemoryReader;
using swift::remote::RemoteAddress;
template <typename Runtime>
class ReflectionContext
: public remote::MetadataReader<Runtime, TypeRefBuilder> {
using super = remote::MetadataReader<Runtime, TypeRefBuilder>;
std::unordered_map<typename super::StoredPointer, const TypeInfo *> Cache;
public:
using super::getBuilder;
using super::readIsaMask;
using super::readTypeFromMetadata;
using super::readMetadataFromInstance;
using typename super::StoredPointer;
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
: super(std::move(reader)) {}
ReflectionContext(const ReflectionContext &other) = delete;
ReflectionContext &operator=(const ReflectionContext &other) = delete;
MemoryReader &getReader() {
return *this->Reader;
}
void dumpAllSections(std::ostream &OS) {
getBuilder().dumpAllSections();
}
void addReflectionInfo(ReflectionInfo I) {
getBuilder().addReflectionInfo(I);
}
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {
// See if we cached the layout already
auto found = Cache.find(MetadataAddress);
if (found != Cache.end())
return found->second;
auto &TC = getBuilder().getTypeConverter();
const TypeInfo *TI = nullptr;
auto TR = readTypeFromMetadata(MetadataAddress);
auto kind = this->readKindFromMetadata(MetadataAddress);
if (TR != nullptr && kind.first) {
switch (kind.second) {
case MetadataKind::Class: {
// Figure out where the stored properties of this class begin
// by looking at the size of the superclass
bool valid;
unsigned size, align;
auto super =
this->readSuperClassFromClassMetadata(MetadataAddress);
if (super) {
std::tie(valid, size, align) =
this->readInstanceSizeAndAlignmentFromClassMetadata(super);
// Perform layout
if (valid)
TI = TC.getClassInstanceTypeInfo(TR, size, align);
}
break;
}
default:
break;
}
}
// Cache the result for future lookups
Cache[MetadataAddress] = TI;
return TI;
}
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const TypeInfo *getInstanceTypeInfo(StoredPointer ObjectAddress) {
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
if (!MetadataAddress.first)
return nullptr;
return getMetadataTypeInfo(MetadataAddress.second);
}
/// Return a description of the layout of a value with the given type.
const TypeInfo *getTypeInfo(const TypeRef *TR) {
return getBuilder().getTypeConverter().getTypeInfo(TR);
}
};
} // end namespace reflection
} // end namespace swift
#endif // SWIFT_REFLECTION_REFLECTIONCONTEXT_H