Swift 5 ABI 稳定了,Swift的class和struct实际是个HeapObjectSwift源码分析类的初始化(零)
struct InProcess;
template <typename Target> struct TargetHeapMetadata;
using HeapMetadata = TargetHeapMetadata<InProcess>;
struct HeapObject {
/// This is always a valid pointer to a metadata object.
HeapMetadata const *__ptrauth_objc_isa_pointer metadata;
SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;//uint64 refCount;
...
}
// 对应Swift的Int类型,如果32位为Int32,64位为Int64
StoredPointer = typename Runtime::StoredPointer
class RelativeDirectPointerImpl {
Offset RelativeOffset;
}
class RelativeDirectPointer<T, Nullable, Offset,typename std::enable_if<!std::is_function<T>::value>::type>
: private RelativeDirectPointerImpl<T, Nullable, Offset> { }
template <typename Runtime, typename Pointee, bool Nullable = true>
using TargetRelativeDirectPointer = typename Runtime::template RelativeDirectPointer<Pointee, Nullable>;
enum class FieldDescriptorKind : uint16_t { Struct, Class, Enum, MultiPayloadEnum, Protocol, ClassProtocol, ObjCProtocol, ObjCClass };
class FieldRecord {
const FieldRecordFlags Flags;
const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> FieldName;
}
// FieldDescriptor的getFields返回类型
class LLVM_GSL_POINTER LLVM_NODISCARD ArrayRef
{
const T *Data = nullptr;/// The start of the array, in an external buffer.
size_type Length = 0; /// The number of elements.
}
class FieldDescriptor {
const RelativeDirectPointer<const char> MangledTypeName;
const RelativeDirectPointer<const char> Superclass;
const FieldDescriptorKind Kind;
const uint16_t FieldRecordSize;
const uint32_t NumFields;
// 属性地址
llvm::ArrayRef<FieldRecord> getFields() const {
return {getFieldRecordBuffer(), NumFields};
}
}
struct TargetMetadata {
StoredPointer Kind;
}
struct TargetValueMetadata : public TargetMetadata<Runtime> {
TargetSignedPointer<Runtime, const TargetValueTypeDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description;
}
template <typename Target> struct TargetHeapMetadata;
using HeapMetadata = TargetHeapMetadata<InProcess>;
struct TargetHeapMetadata : TargetMetadata<Runtime> { }
struct TargetAnyClassMetadata : public TargetHeapMetadata<Runtime> {
constexpr TargetAnyClassMetadata(TargetAnyClassMetadataObjCInterop<Runtime> *isa,TargetClassMetadata *superclass) : TargetHeapMetadata<Runtime>(isa), Superclass(superclass) { }
TargetSignedPointer<Runtime, const TargetClassMetadata *__ptrauth_swift_objc_superclass> Superclass;
}
struct TargetAnyClassMetadataObjCInterop: public TargetAnyClassMetadata<Runtime> {
TargetPointer<Runtime, void> CacheData[2];
StoredSize Data;
}
If the Runtime supports Objective-C interoperability, this class inherits from TargetAnyClassMetadataObjCInterop, otherwise it inherits from TargetAnyClassMetadata.
struct TargetClassMetadata : public TargetAnyClassMetadataVariant {
ClassFlags Flags; //特有标志
uint32_t InstanceAddressPoint; //实例内存首地址
uint32_t InstanceSize; //实例内存大小
uint16_t InstanceAlignMask; //实例内存对齐方式
uint16_t Reserved; //保留字段
uint32_t ClassSize; //类内存大小
uint32_t ClassAddressPoint; //类内存首地址
TargetSignedPointer<Runtime, const TargetClassDescriptor<Runtime> * __ptrauth_swift_type_descriptor> Description; //类描述器
TargetSignedPointer<Runtime, ClassIVarDestroyer * __ptrauth_swift_heap_object_destructor> IVarDestroyer; //实例销毁器
}
struct TargetStructMetadata : public TargetValueMetadata<Runtime> { }
using TargetRelativeContextPointer = RelativeIndirectablePointer<const Context<Runtime>,/nullable/ true, int32_t,TargetSignedContextPointer<Runtime, Context>>;
using RelativeIndirectablePointer = RelativeIndirectablePointer<T, Nullable>;
class RelativeIndirectablePointer {
Offset RelativeOffsetPlusIndirect;
}
struct TargetContextDescriptor {
ContextDescriptorFlags Flags;
TargetRelativeContextPointer<Runtime> Parent;
}
class TargetTypeContextDescriptor: public TargetContextDescriptor<Runtime> {
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;
TargetCompactFunctionPointer<Runtime, MetadataResponse(...),true> AccessFunctionPtr;
TargetRelativeDirectPointer<Runtime, const reflection::FieldDescriptor,true> Fields;
}
class TargetValueTypeDescriptor: public TargetTypeContextDescriptor<Runtime> { }
class TargetStructDescriptor final: public TargetValueTypeDescriptor<Runtime>,
public TrailingGenericContextObjects<TargetStructDescriptor<Runtime>,
TargetTypeGenericContextDescriptorHeader,/*additional trailing objects*/
TargetForeignMetadataInitialization<Runtime>,
TargetSingletonMetadataInitialization<Runtime>,
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
uint32_t NumFields;
uint32_t FieldOffsetVectorOffset;
}
struct TargetVTableDescriptorHeader {
uint32_t VTableOffset;
uint32_t VTableSize;
}
class TargetClassDescriptor final: public TargetTypeContextDescriptor<Runtime>,
public TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
TargetTypeGenericContextDescriptorHeader,/*additional trailing objects:*/
TargetResilientSuperclass<Runtime>,
TargetForeignMetadataInitialization<Runtime>,
TargetSingletonMetadataInitialization<Runtime>,
TargetVTableDescriptorHeader<Runtime>,
TargetMethodDescriptor<Runtime>,
TargetOverrideTableHeader<Runtime>,
TargetMethodOverrideDescriptor<Runtime>,
TargetObjCResilientClassStubInfo<Runtime>,
TargetCanonicalSpecializedMetadatasListCount<Runtime>,
TargetCanonicalSpecializedMetadatasListEntry<Runtime>,
TargetCanonicalSpecializedMetadataAccessorsListEntry<Runtime>,
TargetCanonicalSpecializedMetadatasCachingOnceToken<Runtime>> {
TargetRelativeDirectPointer<Runtime, const char> SuperclassType;
uint32_t MetadataNegativeSizeInWords;
uint32_t MetadataPositiveSizeInWords;
uint32_t NumImmediateMembers;
uint32_t NumFields;
uint32_t FieldOffsetVectorOffset;
}
const TypeContextDescriptor *swift::swift_getTypeContextDescriptor(const Metadata *type) {
return type->getTypeContextDescriptor();
}
getTypeContextDescriptor() const {
switch (getKind()) {
case MetadataKind::Class: {
const auto cls = static_cast<const TargetClassMetadataType<Runtime> *>(this);
if (!cls->isTypeMetadata()) return nullptr;
if (cls->isArtificialSubclass()) return nullptr;
return cls->getDescription();
}
case MetadataKind::Struct:
case MetadataKind::Enum:
case MetadataKind::Optional:
return static_cast<const TargetValueMetadata<Runtime> *>(this)->Description;
case MetadataKind::ForeignClass:
return static_cast<const TargetForeignClassMetadata<Runtime> *>(this)->Description;
default return nullptr;
}
}
const StoredPointer *getFieldOffsets() const {
assert(isTypeMetadata());
auto offset = getDescription()->getFieldOffsetVectorOffset();
if (offset == 0) return nullptr;
auto asWords = reinterpret_cast<const void * const*>(this);
return reinterpret_cast<const StoredPointer *>(asWords + offset);
}
const uint32_t *getFieldOffsets() const {
auto offset = getDescription()->FieldOffsetVectorOffset;
if (offset == 0) return nullptr;
auto asWords = reinterpret_cast<const void * const*>(this);
return reinterpret_cast<const uint32_t *>(asWords + offset);
}
2、Swift映射
struct TargetMetadata {
var kind: Int
}
struct TargetValueMetadata {//:TargetMetadata
var kind: Int
var typeDescriptor: UnsafeMutablePointer<BaseContextDescriptor>
}
struct TargetHeapMetadata {//:TargetMetadata
var kind: Int
}
struct TargetAnyClassMetadata {//:TargetHeapMatadata
var superclass: Any.Type
}
struct TargetAnyClassMetadataObjCInterop {//:TargetAnyClassMetadata
var superclass: Any.Type
var reserveword1: Int
var reserveword2: Int
var data: UInt
}
enum FieldDescriptorKind : UInt16 {
case Struct,Class,Enum,MultiPayloadEnum,`Protocol`,ClassProtocol,ObjCProtocol,ObjCClass
}
struct BaseRelativePoiner<Pointee> {
var offset: Int32
mutating func relativeOffset() -> UnsafeMutablePointer<Pointee> {
let offset = self.offset
return withUnsafePointer(to: &self) { p in
UnsafeMutablePointer(mutating: UnsafeRawPointer(p)
.advanced(by: numericCast(offset))
.assumingMemoryBound(to: Pointee.self))
}
}
}
struct FieldRecord {
var flags: Int32
var mangledTypeName: BaseRelativePoiner<UInt8>
var fieldName: BaseRelativePoiner<CChar>
}
struct FieldRecordBuffer<T> {
var element: T
var lenght: UInt32
mutating func index(of i: Int) -> UnsafeMutablePointer<T> {
return withUnsafePointer(to: &self) {
UnsafeMutablePointer(mutating: UnsafeRawPointer($0)
.assumingMemoryBound(to: T.self)
.advanced(by: i))
}
}
}
struct FieldDescriptor {
var mangledTypeName: BaseRelativePoiner<CChar>
var superclass: BaseRelativePoiner<CChar>
var kind: FieldDescriptorKind
var fieldRecordSize: UInt16
var numFields: UInt32
var fields: FieldRecordBuffer<FieldRecord> // 属性列表提取的
}
struct BaseContextDescriptor {
var flags: Int32
var parent: Int32
var name: BaseRelativePoiner<CChar>
var accessFunctionPtr: Int32
var fieldDescriptor: BaseRelativePoiner<FieldDescriptor>
}
struct TargetStructMetadata {//:TargetValueMetadata
var kind: Int
var typeDescriptor: UnsafeMutablePointer<StructContextDescriptor>
}
struct TargetClassMetadata {//:TargetAnyClassMetadata
var kind: Int
var superclass: Any.Type
var reserveword1: Int
var reserveword2: Int
var data: UInt
var flags: UInt32
var instanceAddressPoint: UInt32
var instanceSize: UInt32
var instanceAlignMask: UInt16
var reserved: UInt16
var classSize: UInt32
var classAddressPoint: UInt32
var descriptor: Int
var ivarDestroyer: Int
}
struct StructContextDescriptor {
var flags: Int32
var parent: Int32
var mangledName: BaseRelativePoiner<CChar>
var accessFunctionPtr: BaseRelativePoiner<UnsafeRawPointer>
var fieldDescriptor: BaseRelativePoiner<FieldDescriptor>
var numberOfFields: UInt32
var fieldOffsetVector: UInt32
func fieldOffsets(_ metadata: UnsafeRawPointer) -> [Int] {
(0..<numberOfFields).map {
Int(metadata.assumingMemoryBound(to: Int32.self)[Int(fieldOffsetVector * 2 + $0)])
}
}
}
struct ClassContextDescriptor {
var flags: Int32
var parent: Int32
var mangledName: BaseRelativePoiner<CChar>
var accessFunctionPtr: BaseRelativePoiner<UnsafeRawPointer>
var fieldDescriptor: BaseRelativePoiner<FieldDescriptor>
var superclassType: BaseRelativePoiner<CChar>
var metadataNegativeSizeInWords: UInt32
var metadataPositiveSizeInWords: UInt32
var numImmediateMembers: UInt32
var numberOfFields: UInt32
var fieldOffsetVector: UInt32 // 每一个属性值距离当前实例对象地址的偏移量
var vTableOffset: UInt32
var vTableSize: UInt32
// ......... VTable部分
func fieldOffsets(_ metadata: UnsafeRawPointer) -> [Int] {
(0..<numberOfFields).map {
Int(metadata.assumingMemoryBound(to: Int.self)[Int(fieldOffsetVector + $0)])
}
}
}
// include/swift/ABI/MetadataValues.h
let MetadataKindIsNonHeap = 0x200
let MetadataKindIsRuntimePrivate = 0x100
let MetadataKindIsNonType = 0x400
// 根据include/swift/ABI/MetadataKind.def翻译成Swift,下面在源码中也有Swift结构
struct _MetadataKind {
static let kind: Kind? = nil
enum Kind {
case `struct`
case `enum`
case optional
case opaque
case foreignClass
case tuple
case function
case existential
case metatype
case objCClassWrapper
case existentialMetatype
case heapLocalVariable
case heapGenericLocalVariable
case errorObject
case `class` // The kind only valid for non-class metadata
init(flag: Int) {
switch flag {
case (0 | MetadataKindIsNonHeap): self = .struct
case (1 | MetadataKindIsNonHeap): self = .enum
case (2 | MetadataKindIsNonHeap): self = .optional
case (3 | MetadataKindIsNonHeap): self = .foreignClass
case (0 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .opaque
case (1 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .tuple
case (2 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .function
case (3 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .existential
case (4 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .metatype
case (5 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .objCClassWrapper
case (6 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .existentialMetatype
case (0 | MetadataKindIsNonType): self = .heapLocalVariable
case (0 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate): self = .heapGenericLocalVariable
case (1 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate): self = .errorObject
default: self = .class
}
}
}
}
// stdlib/public/core/ReflectionMirror.swift
@available(SwiftStdlib 5.2, *)
@_spi(Reflection)
public enum _MetadataKind: UInt {
// With "flags":
// runtimePrivate = 0x100
// nonHeap = 0x200
// nonType = 0x400
case `class` = 0
case `struct` = 0x200 // 0 | nonHeap
case `enum` = 0x201 // 1 | nonHeap
case optional = 0x202 // 2 | nonHeap
case foreignClass = 0x203 // 3 | nonHeap
case opaque = 0x300 // 0 | runtimePrivate | nonHeap
case tuple = 0x301 // 1 | runtimePrivate | nonHeap
case function = 0x302 // 2 | runtimePrivate | nonHeap
case existential = 0x303 // 3 | runtimePrivate | nonHeap
case metatype = 0x304 // 4 | runtimePrivate | nonHeap
case objcClassWrapper = 0x305 // 5 | runtimePrivate | nonHeap
case existentialMetatype = 0x306 // 6 | runtimePrivate | nonHeap
case heapLocalVariable = 0x400 // 0 | nonType
case heapGenericLocalVariable = 0x500 // 0 | nonType | runtimePrivate
case errorObject = 0x501 // 1 | nonType | runtimePrivate
case unknown = 0xffff
init(_ type: Any.Type) {
let v = _metadataKind(type)
if let result = _MetadataKind(rawValue: v) {
self = result
} else {
self = .unknown
}
}
}
- 桥接元数据
typealias AnyObject = protocol<class>
typealias Any = protocol<>
public typealias AnyClass = AnyObject.Type
Swift 中的元类型用 .Type 表示。比如 Int.Type 就是 Int 的元类型
.Type 是类型,类型的 .self 是值
protocol AnyExtensions {}
extension AnyExtensions {
public static func write(_ value: Any, to storage: UnsafeMutableRawPointer) {
guard let this = value as? Self else { return }
storage.assumingMemoryBound(to: self).pointee = this
}
public static func value(storage: UnsafeMutableRawPointer) -> Any {
storage.assumingMemoryBound(to: self).pointee
}
mutating func storage() -> UnsafeRawPointer {
if type(of: self) is AnyClass {
let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
return UnsafeRawPointer(opaquePointer)
} else {
return withUnsafePointer(to: &self) { pointer in
return UnsafeRawPointer(pointer)
}
}
}
}
func extensions(of type: Any.Type) -> AnyExtensions.Type {
struct Extensions : AnyExtensions {}
var extensions: AnyExtensions.Type = Extensions.self
/// Any.Type.self == Any.Type.Protocol
withUnsafePointer(to: &extensions) { pointer in
UnsafeMutableRawPointer(mutating: pointer).assumingMemoryBound(to: Any.Type.self).pointee = type
}
return extensions
}
func extensions(of value: Any) -> AnyExtensions {
struct Extensions : AnyExtensions {}
var extensions: AnyExtensions = Extensions()
withUnsafePointer(to: &extensions) { pointer in
UnsafeMutableRawPointer(mutating: pointer).assumingMemoryBound(to: Any.self).pointee = value
}
return extensions
}
- Swift映射对c++方法
// 根据swift混淆类型名、长度、属性描述、属性入参得到Swift类型元数据
@_silgen_name("swift_getTypeByMangledNameInContext")
public func _getTypeByMangledNameInContext(
_ name: UnsafePointer<CChar>,
_ nameLength: Int,
genericContext: UnsafeRawPointer?,
genericArguments: UnsafeRawPointer?)
-> Any.Type?
// 根据元数据提取类型描述
@_silgen_name("swift_getTypeContextDescriptor")
public func _swift_getTypeContextDescriptor(_ metadata: UnsafeRawPointer?) -> UnsafeRawPointer?
// 获取元数据类型
@_silgen_name("swift_getMetadataKind")
internal func _swift_getMetadataKind(_: Any.Type) -> UInt
// 获取元数据类型
@_silgen_name("getMetadataKindOf")
private func _metadataKind<T>(of value: T) -> UnsafePointer<CChar>
// 获取元数据
@_silgen_name("swift_reflectionMirror_normalizedType")
internal func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
// 获取当前元数据属性个数
@_silgen_name("swift_reflectionMirror_count")
internal func _getChildCount<T>(_: T, type: Any.Type) -> Int
// 递归元数据属性个数
@_silgen_name("swift_reflectionMirror_recursiveCount")
internal func _getRecursiveChildCount(_: Any.Type) -> Int
internal typealias NameFreeFunc = @convention(c) (UnsafePointer<CChar>?) -> Void
//typedef void (*NameFreeFunc)(const char*);
struct _FieldReflectionMetadata {
var name: UnsafePointer<CChar>?
var freeFunc: NameFreeFunc?
var isStrong: Bool?
var isVar: Bool?
}
// 递归属性
@_silgen_name("swift_reflectionMirror_recursiveChildMetadata")
internal func _getRecursiveChildMetadata(
_: Any.Type,
index: Int,
fieldMetadata: UnsafeMutablePointer<_FieldReflectionMetadata>
) -> Any.Type
// 递归元数据属性偏移量
@_silgen_name("swift_reflectionMirror_recursiveChildOffset")
internal func _getRecursiveChildOffset(
_: Any.Type,
index: Int
) -> Int
// 获取属性
@_silgen_name("swift_reflectionMirror_subscript")
internal func _getChild<T>(
of: T,
type: Any.Type,
index: Int,
outName: UnsafeMutablePointer<UnsafePointer<CChar>?>,
outFreeFunc: UnsafeMutablePointer<NameFreeFunc?>
) -> Any
// Returns 'c' (class), 'e' (enum), 's' (struct), 't' (tuple), or '\0' (none)
@_silgen_name("swift_reflectionMirror_displayStyle")
internal func _getDisplayStyle<T>(_: T) -> CChar
- 例子
protocol SwiftRuntime {
mutating func resolve(isUpdate:Bool);
}
extension SwiftRuntime {
mutating func resolve(isUpdate:Bool = true) {
let type = type(of: self)
// 对象首地址
let basePtr:UnsafeMutableRawPointer?
// class 和 strutc获取地址方式有区别
if type is AnyClass {
basePtr = UnsafeMutableRawPointer(mutating: Unmanaged.passUnretained(self as AnyObject).toOpaque())
} else {
basePtr = withUnsafePointer(to: &self, { UnsafeMutableRawPointer(mutating: $0) })
}
guard let basePtr = basePtr else { return }
let numFields = _getRecursiveChildCount(type)
for i in 0..<Int(numFields) {
// 属性地址偏移量
let offset = _getRecursiveChildOffset(type, index: i)
// 属性元数据
var field = _FieldReflectionMetadata()
// 属性类型
let fieldType = _getRecursiveChildMetadata(type, index: i, fieldMetadata: &field)
// 属性地址
let pptr = basePtr.advanced(by: offset)
// 桥接属性,因为不知道fieldType的实际类型
let anex = extensions(of: fieldType)
print(" \(String(cString: field.name!)): \(fieldType) = \(anex.value(storage: pptr))")
// 测试
if isUpdate {
if fieldType == Int.self {
anex.write(123, to: pptr)
} else {
anex.write("hello world!", to: pptr)
}
}
}
}
}
class MZBase {
var kind: String = "parent"
}
class MZPerson:MZBase, SwiftRuntime {
var age: Int = 18
var name: String = "LL"
var nameTwo: String = "LLLL"
}
输入结果:
================== 修改前 ==================
kind: String = parent
age: Int = 18
name: String = LL
nameTwo: String = LLLL
================== 修改后 ==================
kind: String = hello world!
age: Int = 123
name: String = hello world!
nameTwo: String = hello world!