mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
290 lines
9.6 KiB
C++
290 lines
9.6 KiB
C++
//===--- SwiftRemoteMirror.cpp - C wrapper for Reflection API -------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/Reflection/ReflectionContext.h"
|
|
#include "swift/Reflection/TypeLowering.h"
|
|
#include "swift/Remote/CMemoryReader.h"
|
|
#include "swift/SwiftRemoteMirror/SwiftRemoteMirror.h"
|
|
|
|
using namespace swift;
|
|
using namespace swift::reflection;
|
|
using namespace swift::remote;
|
|
|
|
using NativeReflectionContext
|
|
= ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>;
|
|
|
|
SwiftReflectionContextRef
|
|
swift_reflection_createReflectionContext(void *ReaderContext,
|
|
PointerSizeFunction getPointerSize,
|
|
SizeSizeFunction getSizeSize,
|
|
ReadBytesFunction readBytes,
|
|
GetStringLengthFunction getStringLength,
|
|
GetSymbolAddressFunction getSymbolAddress) {
|
|
MemoryReaderImpl ReaderImpl {
|
|
ReaderContext,
|
|
getPointerSize,
|
|
getSizeSize,
|
|
readBytes,
|
|
getStringLength,
|
|
getSymbolAddress
|
|
};
|
|
|
|
auto Reader = std::make_shared<CMemoryReader>(ReaderImpl);
|
|
auto Context
|
|
= new ReflectionContext<External<RuntimeTarget<sizeof(uintptr_t)>>>(Reader);
|
|
return reinterpret_cast<SwiftReflectionContextRef>(Context);
|
|
}
|
|
|
|
void swift_reflection_destroyReflectionContext(SwiftReflectionContextRef ContextRef) {
|
|
auto Context = reinterpret_cast<ReflectionContext<InProcess> *>(ContextRef);
|
|
delete Context;
|
|
}
|
|
|
|
void
|
|
swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
|
|
swift_reflection_info_t Info) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
Context->addReflectionInfo(*reinterpret_cast<ReflectionInfo *>(&Info));
|
|
}
|
|
|
|
int
|
|
swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t *outIsaMask) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto isaMask = Context->readIsaMask();
|
|
*outIsaMask = isaMask.second;
|
|
return isaMask.first;
|
|
}
|
|
|
|
swift_typeref_t
|
|
swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TR = Context->readTypeFromMetadata(Metadata);
|
|
return reinterpret_cast<swift_typeref_t>(TR);
|
|
}
|
|
|
|
swift_typeref_t
|
|
swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto MetadataAddress = Context->readMetadataFromInstance(Object);
|
|
if (!MetadataAddress.first)
|
|
return 0;
|
|
auto TR = Context->readTypeFromMetadata(MetadataAddress.second);
|
|
return reinterpret_cast<swift_typeref_t>(TR);
|
|
}
|
|
|
|
swift_typeref_t
|
|
swift_reflection_genericArgumentOfTypeRef(swift_typeref_t OpaqueTypeRef,
|
|
unsigned Index) {
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
|
|
if (auto BG = dyn_cast<BoundGenericTypeRef>(TR)) {
|
|
auto &Params = BG->getGenericParams();
|
|
assert(Index < Params.size());
|
|
return reinterpret_cast<swift_typeref_t>(Params[Index]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned
|
|
swift_reflection_genericArgumentCountOfTypeRef(swift_typeref_t OpaqueTypeRef) {
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
|
|
if (auto BG = dyn_cast<BoundGenericTypeRef>(TR)) {
|
|
auto &Params = BG->getGenericParams();
|
|
return Params.size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
swift_layout_kind_t getTypeInfoKind(const TypeInfo &TI) {
|
|
switch (TI.getKind()) {
|
|
case TypeInfoKind::Builtin:
|
|
return SWIFT_BUILTIN;
|
|
case TypeInfoKind::Record: {
|
|
auto &RecordTI = cast<RecordTypeInfo>(TI);
|
|
switch (RecordTI.getRecordKind()) {
|
|
case RecordKind::Tuple:
|
|
return SWIFT_TUPLE;
|
|
case RecordKind::Struct:
|
|
return SWIFT_STRUCT;
|
|
case RecordKind::ThickFunction:
|
|
return SWIFT_THICK_FUNCTION;
|
|
case RecordKind::Existential:
|
|
return SWIFT_EXISTENTIAL;
|
|
case RecordKind::ClassExistential:
|
|
return SWIFT_CLASS_EXISTENTIAL;
|
|
case RecordKind::ExistentialMetatype:
|
|
return SWIFT_EXISTENTIAL_METATYPE;
|
|
case RecordKind::ClassInstance:
|
|
return SWIFT_CLASS_INSTANCE;
|
|
}
|
|
}
|
|
case TypeInfoKind::Reference: {
|
|
auto &ReferenceTI = cast<ReferenceTypeInfo>(TI);
|
|
switch (ReferenceTI.getReferenceKind()) {
|
|
case ReferenceKind::Strong:
|
|
return SWIFT_STRONG_REFERENCE;
|
|
case ReferenceKind::Unowned:
|
|
return SWIFT_UNOWNED_REFERENCE;
|
|
case ReferenceKind::Weak:
|
|
return SWIFT_WEAK_REFERENCE;
|
|
case ReferenceKind::Unmanaged:
|
|
return SWIFT_UNMANAGED_REFERENCE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static swift_typeinfo_t convertTypeInfo(const TypeInfo *TI) {
|
|
if (TI == nullptr) {
|
|
return {
|
|
SWIFT_UNKNOWN,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
};
|
|
}
|
|
|
|
unsigned NumFields = 0;
|
|
if (auto *RecordTI = dyn_cast<RecordTypeInfo>(TI))
|
|
NumFields = RecordTI->getNumFields();
|
|
|
|
return {
|
|
getTypeInfoKind(*TI),
|
|
TI->getSize(),
|
|
TI->getAlignment(),
|
|
TI->getStride(),
|
|
NumFields
|
|
};
|
|
}
|
|
|
|
static swift_childinfo_t convertChild(const TypeInfo *TI, unsigned Index) {
|
|
auto *RecordTI = cast<RecordTypeInfo>(TI);
|
|
auto &FieldInfo = RecordTI->getFields()[Index];
|
|
|
|
return {
|
|
FieldInfo.Name.c_str(),
|
|
FieldInfo.Offset,
|
|
getTypeInfoKind(FieldInfo.TI),
|
|
reinterpret_cast<swift_typeref_t>(FieldInfo.TR),
|
|
};
|
|
}
|
|
|
|
swift_typeinfo_t
|
|
swift_reflection_infoForTypeRef(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
auto TI = Context->getTypeInfo(TR);
|
|
return convertTypeInfo(TI);
|
|
}
|
|
|
|
swift_childinfo_t
|
|
swift_reflection_childOfTypeRef(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef,
|
|
unsigned Index) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
auto *TI = Context->getTypeInfo(TR);
|
|
return convertChild(TI, Index);
|
|
}
|
|
|
|
swift_typeinfo_t
|
|
swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto *TI = Context->getMetadataTypeInfo(Metadata);
|
|
return convertTypeInfo(TI);
|
|
}
|
|
|
|
swift_childinfo_t
|
|
swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata,
|
|
unsigned Index) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto *TI = Context->getMetadataTypeInfo(Metadata);
|
|
return convertChild(TI, Index);
|
|
}
|
|
|
|
swift_typeinfo_t
|
|
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto *TI = Context->getInstanceTypeInfo(Object);
|
|
return convertTypeInfo(TI);
|
|
}
|
|
|
|
swift_childinfo_t
|
|
swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object,
|
|
unsigned Index) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto *TI = Context->getInstanceTypeInfo(Object);
|
|
return convertChild(TI, Index);
|
|
}
|
|
|
|
int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
|
|
addr_t InstanceAddress,
|
|
swift_typeref_t ExistentialTypeRef,
|
|
swift_typeref_t *InstanceTypeRef,
|
|
addr_t *StartOfInstanceData) {
|
|
// TODO
|
|
return false;
|
|
}
|
|
|
|
void swift_reflection_dumpTypeRef(swift_typeref_t OpaqueTypeRef) {
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
if (TR == nullptr) {
|
|
std::cerr << "<null type reference>\n";
|
|
} else {
|
|
TR->dump();
|
|
}
|
|
}
|
|
|
|
void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
|
|
swift_typeref_t OpaqueTypeRef) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
|
|
auto TI = Context->getTypeInfo(TR);
|
|
if (TI == nullptr) {
|
|
std::cerr << "<null type info>\n";
|
|
} else {
|
|
TI->dump();
|
|
}
|
|
}
|
|
|
|
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Metadata) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TI = Context->getMetadataTypeInfo(Metadata);
|
|
if (TI == nullptr) {
|
|
std::cerr << "<null type info>\n";
|
|
} else {
|
|
TI->dump();
|
|
}
|
|
}
|
|
|
|
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
|
|
uintptr_t Object) {
|
|
auto Context = reinterpret_cast<NativeReflectionContext *>(ContextRef);
|
|
auto TI = Context->getInstanceTypeInfo(Object);
|
|
if (TI == nullptr) {
|
|
std::cerr << "<null type info>\n";
|
|
} else {
|
|
TI->dump();
|
|
}
|
|
}
|