mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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.
132 lines
4.0 KiB
C++
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
|