Metadata.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /*
  2. * Copyright 1999-2101 Alibaba Group.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //
  17. // Created by zhouzhuo on 07/01/2017.
  18. //
  19. struct _class_rw_t {
  20. var flags: Int32
  21. var version: Int32
  22. var ro: UInt
  23. // other fields we don't care
  24. func class_ro_t() -> UnsafePointer<_class_ro_t>? {
  25. return UnsafePointer<_class_ro_t>(bitPattern: self.ro)
  26. }
  27. }
  28. struct _class_ro_t {
  29. var flags: Int32
  30. var instanceStart: Int32
  31. var instanceSize: Int32
  32. // other fields we don't care
  33. }
  34. // MARK: MetadataType
  35. protocol MetadataType : PointerType {
  36. static var kind: Metadata.Kind? { get }
  37. }
  38. extension MetadataType {
  39. var kind: Metadata.Kind {
  40. return Metadata.Kind(flag: UnsafePointer<Int>(pointer).pointee)
  41. }
  42. init?(anyType: Any.Type) {
  43. self.init(pointer: unsafeBitCast(anyType, to: UnsafePointer<Int>.self))
  44. if let kind = type(of: self).kind, kind != self.kind {
  45. return nil
  46. }
  47. }
  48. }
  49. // MARK: Metadata
  50. struct Metadata : MetadataType {
  51. var pointer: UnsafePointer<Int>
  52. init(type: Any.Type) {
  53. self.init(pointer: unsafeBitCast(type, to: UnsafePointer<Int>.self))
  54. }
  55. }
  56. struct _Metadata {}
  57. var is64BitPlatform: Bool {
  58. return MemoryLayout<Int>.size == MemoryLayout<Int64>.size
  59. }
  60. // MARK: Metadata + Kind
  61. // include/swift/ABI/MetadataKind.def
  62. let MetadataKindIsNonHeap = 0x200
  63. let MetadataKindIsRuntimePrivate = 0x100
  64. let MetadataKindIsNonType = 0x400
  65. extension Metadata {
  66. static let kind: Kind? = nil
  67. enum Kind {
  68. case `struct`
  69. case `enum`
  70. case optional
  71. case opaque
  72. case foreignClass
  73. case tuple
  74. case function
  75. case existential
  76. case metatype
  77. case objCClassWrapper
  78. case existentialMetatype
  79. case heapLocalVariable
  80. case heapGenericLocalVariable
  81. case errorObject
  82. case `class` // The kind only valid for non-class metadata
  83. init(flag: Int) {
  84. switch flag {
  85. case (0 | MetadataKindIsNonHeap): self = .struct
  86. case (1 | MetadataKindIsNonHeap): self = .enum
  87. case (2 | MetadataKindIsNonHeap): self = .optional
  88. case (3 | MetadataKindIsNonHeap): self = .foreignClass
  89. case (0 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .opaque
  90. case (1 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .tuple
  91. case (2 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .function
  92. case (3 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .existential
  93. case (4 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .metatype
  94. case (5 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .objCClassWrapper
  95. case (6 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap): self = .existentialMetatype
  96. case (0 | MetadataKindIsNonType): self = .heapLocalVariable
  97. case (0 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate): self = .heapGenericLocalVariable
  98. case (1 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate): self = .errorObject
  99. default: self = .class
  100. }
  101. }
  102. }
  103. }
  104. // MARK: Metadata + Class
  105. extension Metadata {
  106. struct Class : ContextDescriptorType {
  107. static let kind: Kind? = .class
  108. var pointer: UnsafePointer<_Metadata._Class>
  109. var isSwiftClass: Bool {
  110. get {
  111. // see include/swift/Runtime/Config.h macro SWIFT_CLASS_IS_SWIFT_MASK
  112. // it can be 1 or 2 depending on environment
  113. let lowbit = self.pointer.pointee.rodataPointer & 3
  114. return lowbit != 0
  115. }
  116. }
  117. var contextDescriptorOffsetLocation: Int {
  118. return is64BitPlatform ? 8 : 11
  119. }
  120. var superclass: Class? {
  121. guard let superclass = pointer.pointee.superclass else {
  122. return nil
  123. }
  124. // If the superclass doesn't conform to handyjson/handyjsonenum protocol,
  125. // we should ignore the properties inside
  126. if !(superclass is HandyJSON.Type) && !(superclass is HandyJSONEnum.Type) {
  127. return nil
  128. }
  129. // ignore objc-runtime layer
  130. guard let metaclass = Metadata.Class(anyType: superclass) else {
  131. return nil
  132. }
  133. return metaclass
  134. }
  135. var vTableSize: Int {
  136. // memory size after ivar destroyer
  137. return Int(pointer.pointee.classObjectSize - pointer.pointee.classObjectAddressPoint) - (contextDescriptorOffsetLocation + 2) * MemoryLayout<Int>.size
  138. }
  139. // reference: https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst#generic-argument-vector
  140. var genericArgumentVector: UnsafeRawPointer? {
  141. let pointer = UnsafePointer<Int>(self.pointer)
  142. var superVTableSize = 0
  143. if let _superclass = self.superclass {
  144. superVTableSize = _superclass.vTableSize / MemoryLayout<Int>.size
  145. }
  146. let base = pointer.advanced(by: contextDescriptorOffsetLocation + 2 + superVTableSize)
  147. if base.pointee == 0 {
  148. return nil
  149. }
  150. return UnsafeRawPointer(base)
  151. }
  152. func _propertyDescriptionsAndStartPoint() -> ([Property.Description], Int32?)? {
  153. let instanceStart = pointer.pointee.class_rw_t()?.pointee.class_ro_t()?.pointee.instanceStart
  154. var result: [Property.Description] = []
  155. if let fieldOffsets = self.fieldOffsets {
  156. class NameAndType {
  157. var name: String?
  158. var type: Any.Type?
  159. }
  160. for i in 0..<self.numberOfFields {
  161. if let name = self.reflectionFieldDescriptor?.fieldRecords[i].fieldName,
  162. let cMangledTypeName = self.reflectionFieldDescriptor?.fieldRecords[i].mangledTypeName,
  163. let fieldType = _getTypeByMangledNameInContext(cMangledTypeName, getMangledTypeNameSize(cMangledTypeName), genericContext: self.contextDescriptorPointer, genericArguments: self.genericArgumentVector) {
  164. result.append(Property.Description(key: name, type: fieldType, offset: fieldOffsets[i]))
  165. }
  166. }
  167. }
  168. if let superclass = superclass,
  169. String(describing: unsafeBitCast(superclass.pointer, to: Any.Type.self)) != "SwiftObject", // ignore the root swift object
  170. let superclassProperties = superclass._propertyDescriptionsAndStartPoint(),
  171. superclassProperties.0.count > 0 {
  172. return (superclassProperties.0 + result, superclassProperties.1)
  173. }
  174. return (result, instanceStart)
  175. }
  176. func propertyDescriptions() -> [Property.Description]? {
  177. let propsAndStp = _propertyDescriptionsAndStartPoint()
  178. if let firstInstanceStart = propsAndStp?.1,
  179. let firstProperty = propsAndStp?.0.first?.offset {
  180. return propsAndStp?.0.map({ (propertyDesc) -> Property.Description in
  181. let offset = propertyDesc.offset - firstProperty + Int(firstInstanceStart)
  182. return Property.Description(key: propertyDesc.key, type: propertyDesc.type, offset: offset)
  183. })
  184. } else {
  185. return propsAndStp?.0
  186. }
  187. }
  188. }
  189. }
  190. extension _Metadata {
  191. struct _Class {
  192. var kind: Int
  193. var superclass: Any.Type?
  194. var reserveword1: Int
  195. var reserveword2: Int
  196. var rodataPointer: UInt
  197. var classFlags: UInt32
  198. var instanceAddressPoint: UInt32
  199. var instanceSize: UInt32
  200. var instanceAlignmentMask: UInt16
  201. var runtimeReservedField: UInt16
  202. var classObjectSize: UInt32
  203. var classObjectAddressPoint: UInt32
  204. var nominalTypeDescriptor: Int
  205. var ivarDestroyer: Int
  206. // other fields we don't care
  207. func class_rw_t() -> UnsafePointer<_class_rw_t>? {
  208. if MemoryLayout<Int>.size == MemoryLayout<Int64>.size {
  209. let fast_data_mask: UInt64 = 0x00007ffffffffff8
  210. let databits_t: UInt64 = UInt64(self.rodataPointer)
  211. return UnsafePointer<_class_rw_t>(bitPattern: UInt(databits_t & fast_data_mask))
  212. } else {
  213. return UnsafePointer<_class_rw_t>(bitPattern: self.rodataPointer & 0xfffffffc)
  214. }
  215. }
  216. }
  217. }
  218. // MARK: Metadata + Struct
  219. extension Metadata {
  220. struct Struct : ContextDescriptorType {
  221. static let kind: Kind? = .struct
  222. var pointer: UnsafePointer<_Metadata._Struct>
  223. var contextDescriptorOffsetLocation: Int {
  224. return 1
  225. }
  226. var genericArgumentOffsetLocation: Int {
  227. return 2
  228. }
  229. var genericArgumentVector: UnsafeRawPointer? {
  230. let pointer = UnsafePointer<Int>(self.pointer)
  231. let base = pointer.advanced(by: genericArgumentOffsetLocation)
  232. if base.pointee == 0 {
  233. return nil
  234. }
  235. return UnsafeRawPointer(base)
  236. }
  237. func propertyDescriptions() -> [Property.Description]? {
  238. guard let fieldOffsets = self.fieldOffsets else {
  239. return []
  240. }
  241. var result: [Property.Description] = []
  242. class NameAndType {
  243. var name: String?
  244. var type: Any.Type?
  245. }
  246. for i in 0..<self.numberOfFields {
  247. if let name = self.reflectionFieldDescriptor?.fieldRecords[i].fieldName,
  248. let cMangledTypeName = self.reflectionFieldDescriptor?.fieldRecords[i].mangledTypeName,
  249. let fieldType = _getTypeByMangledNameInContext(cMangledTypeName, getMangledTypeNameSize(cMangledTypeName), genericContext: self.contextDescriptorPointer, genericArguments: self.genericArgumentVector) {
  250. result.append(Property.Description(key: name, type: fieldType, offset: fieldOffsets[i]))
  251. }
  252. }
  253. return result
  254. }
  255. }
  256. }
  257. extension _Metadata {
  258. struct _Struct {
  259. var kind: Int
  260. var contextDescriptorOffset: Int
  261. var parent: Metadata?
  262. }
  263. }
  264. // MARK: Metadata + ObjcClassWrapper
  265. extension Metadata {
  266. struct ObjcClassWrapper: ContextDescriptorType {
  267. static let kind: Kind? = .objCClassWrapper
  268. var pointer: UnsafePointer<_Metadata._ObjcClassWrapper>
  269. var contextDescriptorOffsetLocation: Int {
  270. return is64BitPlatform ? 8 : 11
  271. }
  272. var targetType: Any.Type? {
  273. get {
  274. return pointer.pointee.targetType
  275. }
  276. }
  277. }
  278. }
  279. extension _Metadata {
  280. struct _ObjcClassWrapper {
  281. var kind: Int
  282. var targetType: Any.Type?
  283. }
  284. }