Mirror
public init(reflecting subject: Any) {
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(internalReflecting: subject)
}
}
Mirror(internalReflecting: subject)
的实现,里面有两个关键方法_getNormalizedType
和_getChildCount
,一个是获取类型,一个是获取属性

_getNormalizedType
的调用使用了关键字@_silgen_name
,相当于调用swift_reflectionMirror_normalizedType
函数
@_silgen_name("swift_reflectionMirror_normalizedType")
internal func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
@_silgen_name
@_silgen_name
的作用就是调用关键字下面的函数时候实际上调用的是关键字包装的函数,我们新建一个test.c
文件,实现一个方法并将它声明在.h文件中
int c_add(int a, int b) {
return a + b;
}
- 将头文件加入到桥接文件中,在
main.swift
文件中调用它
var value = c_add(1, 2)
- 使用
@_silgen_name
关键字,也是可以调用的,我们直接删掉桥接文件和test.h
文件都是可以调用成功的,使用了@_silgen_name
修饰之后,调用下面的方法会去全局搜索括号里面的方法,需要注意的是要保证方法的实现,参数对应
@_silgen_name("c_add")
func swift_add(_ a:Int32,_ b:Int32) -> Int32
var value = swift_add(2, 4)
print(value)
- 接着上文的分析找到
swift_reflectionMirror_normalizedType
的实现
/ func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
const Metadata *swift_reflectionMirror_normalizedType(OpaqueValue *value,
const Metadata *type,
const Metadata *T) {
return call(value, T, type, [](ReflectionMirrorImpl *impl) { return impl->type; });
}
call
的实现

unwrapExistential
的实现,可以看到最终获取数据都会找到MetadataKind
里面,所以我们接下来对MetaData
数据进行研究,因为类的的结构会比较复杂,我们来研究结构体
static std::tuple<const Metadata *, OpaqueValue *>
unwrapExistential(const Metadata *T, OpaqueValue *Value) {
while (T->getKind() == MetadataKind::Existential) {
auto *existential
= static_cast<const ExistentialTypeMetadata *>(T);
T = existential->getDynamicType(Value);
Value = existential->projectValue(Value);
}
return std::make_tuple(T, Value);
}
TargetStructMetadata
- 在
Swift
源码中搜索TargetStructMetadata
的结构

TargetStructMetadata
继承自TargetValueMetadata
template <typename Runtime>
struct TargetValueMetadata : public TargetMetadata<Runtime> {
using StoredPointer = typename Runtime::StoredPointer;
TargetValueMetadata(MetadataKind Kind,
const TargetTypeContextDescriptor<Runtime> *description)
: TargetMetadata<Runtime>(Kind), Description(description) {}
TargetSignedPointer<Runtime, const TargetValueTypeDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
static bool classof(const TargetMetadata<Runtime> *metadata) {
return metadata->getKind() == MetadataKind::Struct
|| metadata->getKind() == MetadataKind::Enum
|| metadata->getKind() == MetadataKind::Optional;
}
ConstTargetMetadataPointer<Runtime, TargetValueTypeDescriptor>
getDescription() const {
return Description;
}
typename Runtime::StoredSignedPointer
getDescriptionAsSignedPointer() const {
return Description;
}
};
TargetValueMetadata
继承自TargetMetadata

Description
- 通过上面对结构体元类的分析,它除了有
Kind
之外还有一个 TargetSignedPointer<Runtime, const TargetValueTypeDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
变量,来看下它的结构
TargetValueTypeDescriptor
是一个模板类,继承自TargetTypeContextDescriptor
template <typename Runtime>
class TargetValueTypeDescriptor
: public TargetTypeContextDescriptor<Runtime> {
public:
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
return cd->getKind() == ContextDescriptorKind::Struct ||
cd->getKind() == ContextDescriptorKind::Enum;
}
};
TargetTypeContextDescriptor
类的结构,里面有一个变量Name
,继承自TargetContextDescriptor

TargetContextDescriptor
的结构

Name
Name
是TargetTypeContextDescriptor
类的变量TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;
,TargetRelativeDirectPointer
的定义如下
template <typename Runtime, typename Pointee, bool Nullable = true>
using TargetRelativeDirectPointer
= typename Runtime::template RelativeDirectPointer<Pointee, Nullable>;
RelativeDirectPointer
的结构,它是继承自RelativeDirectPointerImpl

RelativeDirectPointerImpl
的实现,有一个变量Offset RelativeOffset;
,这个类是通过地址偏移获取ValueTy
和PointerTy

- 可以看看它的
get()
的实现,可以看到它是通过地址偏移获取对应的数据的
get()
PointerTy get() const & {
if (Nullable && RelativeOffset == 0)
return nullptr;
uintptr_t absolute = detail::applyRelativeOffset(this, RelativeOffset);
return reinterpret_cast<PointerTy>(absolute);
}
👇
namespace detail {
template<typename BasePtrTy, typename Offset>
static inline uintptr_t applyRelativeOffset(BasePtrTy *basePtr, Offset offset) {
static_assert(std::is_integral<Offset>::value &&
std::is_signed<Offset>::value,
"offset type should be signed integer");
auto base = reinterpret_cast<uintptr_t>(basePtr);
auto extendOffset = (uintptr_t)(intptr_t)offset;
return base + extendOffset;
}
- 我们可以通过自定义结构体
MetaData
的方式来理解结构体的底层构成,通过上面的分析可以得到下面的结构体StructMetaData
的结构,并可以通过它获取到它的Name
struct StructMetaData {
var Kind : Int
var Description : UnsafeMutablePointer<StructDescriptor>
}
struct StructDescriptor {
var Flags : Int32
var Parent : Int32
var name : RelativeDirectPointer<CChar>
}
struct RelativeDirectPointer<T> {
var Offset : Int32
mutating func get() -> UnsafeMutablePointer<T> {
let offset = self.Offset
return withUnsafePointer(to: &self, { p in
return UnsafeMutablePointer(mutating: UnsafeRawPointer(p).advanced(by: numericCast(offset)).assumingMemoryBound(to: T.self))
})
}
}
struct XQTeacher {
var age = 18
var name = "xq"
}
var t = XQTeacher()
var t1 = XQTeacher.self
let ptr = unsafeBitCast(XQTeacher.self as Any.Type, to: UnsafeMutablePointer<StructMetaData>.self)
let namePtr = ptr.pointee.Description.pointee.name.get()
print(String(cString: namePtr))
_getChildCount
_getChildCount
的调用也是使用了关键字@_silgen_name
,最终调用的是swift_reflectionMirror_count
,可以看到它也是调用了call
函数
@_silgen_name("swift_reflectionMirror_count")
internal func _getChildCount<T>(_: T, type: Any.Type) -> Int
// func _getChildCount<T>(_: T, type: Any.Type) -> Int
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
intptr_t swift_reflectionMirror_count(OpaqueValue *value,
const Metadata *type,
const Metadata *T) {
return call(value, T, type, [](ReflectionMirrorImpl *impl) {
return impl->count();
});
}
- 在
call
函数里面看到对结构体的处理是一个StructImpl
格式的,也是从Metadata
获取数据
struct StructImpl : ReflectionMirrorImpl {
bool isReflectable() {
const auto *Struct = static_cast<const StructMetadata *>(type);
const auto &Description = Struct->getDescription();
return Description->isReflectable();
}
char displayStyle() {
return 's';
}
intptr_t count() {
if (!isReflectable()) {
return 0;
}
auto *Struct = static_cast<const StructMetadata *>(type);
return Struct->getDescription()->NumFields;
}
intptr_t childOffset(intptr_t i) {
auto *Struct = static_cast<const StructMetadata *>(type);
if (i < 0 || (size_t)i > Struct->getDescription()->NumFields)
swift::crash("Swift mirror subscript bounds check failure");
return Struct->getFieldOffsets()[i];
}
const FieldType childMetadata(intptr_t i, const char **outName,
void (**outFreeFunc)(const char *)) {
StringRef name;
FieldType fieldInfo;
std::tie(name, fieldInfo) = getFieldAt(type, i);
assert(!fieldInfo.isIndirect() && "indirect struct fields not implemented");
*outName = name.data();
*outFreeFunc = nullptr;
return fieldInfo;
}
AnyReturn subscript(intptr_t i, const char **outName,
void (**outFreeFunc)(const char *)) {
auto fieldInfo = childMetadata(i, outName, outFreeFunc);
auto *bytes = reinterpret_cast<char*>(value);
auto fieldOffset = childOffset(i);
auto *fieldData = reinterpret_cast<OpaqueValue *>(bytes + fieldOffset);
return copyFieldContents(fieldData, fieldInfo);
}
};
- 在上文对
TargetStructDescriptor
类的研究中,还有一些成员属性没有列举出来,我们将它补全如
uint32_t NumFields;
uint32_t FieldOffsetVectorOffset;
-----------------------------
class TargetTypeContextDescriptor
: public TargetContextDescriptor<Runtime> {
public:
TargetRelativeDirectPointer<Runtime, const char, false> Name;
TargetRelativeDirectPointer<Runtime, MetadataResponse(...),
true> AccessFunctionPtr;
TargetRelativeDirectPointer<Runtime, const reflection::FieldDescriptor,
true> Fields;
......
}
StructImpl
中有一个获取属性名及值的函数subscript
,通过函数``

class FieldRecord {
const FieldRecordFlags Flags;
public:
const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> FieldName;
FieldRecord() = delete;
bool hasMangledTypeName() const {
return MangledTypeName;
}
StringRef getMangledTypeName() const {
return Demangle::makeSymbolicMangledNameStringRef(MangledTypeName.get());
}
StringRef getFieldName() const {
return FieldName.get();
}
bool isIndirectCase() const {
return Flags.isIndirectCase();
}
};
struct StructMetaData {
var Kind : Int
var Description : UnsafeMutablePointer<StructDescriptor>
}
struct StructDescriptor {
var Flags : Int32
var Parent : Int32
var name : RelativeDirectPointer<CChar>
var AccessFunctionPtr : RelativeDirectPointer<UnsafeRawPointer>
var Fields : RelativeDirectPointer<FieldDescriptor>
var NumFields : Int32
var FieldOffsetVectorOffset : Int32
}
struct FieldDescriptor {
var MangledTypeName : RelativeDirectPointer<CChar>
var Superclass : RelativeDirectPointer<CChar>
var Kind : Int16
var FieldRecordSize : Int16
var NumFields : Int32
var fields: FieldRecord
}
struct FieldRecord {
var Flags: Int32
var MangledTypeName: RelativeDirectPointer<CChar>
var FieldName: RelativeDirectPointer<CChar>
}
struct RelativeDirectPointer<T> {
var Offset : Int32
mutating func get() -> UnsafeMutablePointer<T> {
let offset = self.Offset
return withUnsafePointer(to: &self, { p in
return UnsafeMutablePointer(mutating: UnsafeRawPointer(p).advanced(by: numericCast(offset)).assumingMemoryBound(to: T.self))
})
}
}
struct XQTeacher {
var age = 18
var name = "xq"
}
var t = XQTeacher()
var t1 = XQTeacher.self
let ptr = unsafeBitCast(XQTeacher.self as Any.Type, to: UnsafeMutablePointer<StructMetaData>.self)
let namePtr = ptr.pointee.Description.pointee.name.get()
print(String(cString: namePtr))
let fieldDescriptorPtr = ptr.pointee.Description.pointee.Fields.get()
let recordPtr = withUnsafePointer(to: &fieldDescriptorPtr.pointee.fields, {
return UnsafeMutablePointer(mutating: UnsafeRawPointer($0).assumingMemoryBound(to:FieldRecord.self).advanced(by: 0))
})
print(String(cString:recordPtr.pointee.FieldName.get()))