Skip to content

Commit

Permalink
fix swift_getFieldAt symbol missing in Swift 5
Browse files Browse the repository at this point in the history
  • Loading branch information
chantu committed Feb 2, 2019
1 parent 5aef695 commit da72f29
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 51 deletions.
20 changes: 20 additions & 0 deletions HandyJSON.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@
393E10011DA249DC00B3BC12 /* NestTypesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F252A91D58BE9100B214BB /* NestTypesTest.swift */; };
393E10021DA249DC00B3BC12 /* CustomTransformTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2144A50D1D9A7A770090F50E /* CustomTransformTest.swift */; };
393E10061DA249DC00B3BC12 /* InvalidStateHandlingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F252B31D599DE200B214BB /* InvalidStateHandlingTest.swift */; };
7D2813E722058D060044E052 /* MangledName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2813E622058D060044E052 /* MangledName.swift */; };
7D2813E822058D060044E052 /* MangledName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2813E622058D060044E052 /* MangledName.swift */; };
7D2813E922058D060044E052 /* MangledName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2813E622058D060044E052 /* MangledName.swift */; };
7D2813EA22058D060044E052 /* MangledName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2813E622058D060044E052 /* MangledName.swift */; };
7D460F662203511D0027428E /* FieldDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D460F652203511D0027428E /* FieldDescriptor.swift */; };
7D460F672203511D0027428E /* FieldDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D460F652203511D0027428E /* FieldDescriptor.swift */; };
7D460F682203511D0027428E /* FieldDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D460F652203511D0027428E /* FieldDescriptor.swift */; };
7D460F692203511D0027428E /* FieldDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D460F652203511D0027428E /* FieldDescriptor.swift */; };
7DCD448220FB593600370EF4 /* CBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DCD448120FB593600370EF4 /* CBridge.swift */; };
7DCD448320FB593600370EF4 /* CBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DCD448120FB593600370EF4 /* CBridge.swift */; };
7DCD448420FB593600370EF4 /* CBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DCD448120FB593600370EF4 /* CBridge.swift */; };
Expand Down Expand Up @@ -318,6 +326,8 @@
393E0FE91DA2494F00B3BC12 /* HandyJSON macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HandyJSON macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
393E10081DA249F100B3BC12 /* Info-macOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = "<group>"; };
393E100A1DA24A0600B3BC12 /* Info-macOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = "<group>"; };
7D2813E622058D060044E052 /* MangledName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MangledName.swift; sourceTree = "<group>"; };
7D460F652203511D0027428E /* FieldDescriptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FieldDescriptor.swift; sourceTree = "<group>"; };
7DCD448120FB593600370EF4 /* CBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBridge.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -387,6 +397,7 @@
210A76271E210F5B000C3DDD /* Reflection */ = {
isa = PBXGroup;
children = (
7D460F652203511D0027428E /* FieldDescriptor.swift */,
210A76291E210FBB000C3DDD /* AnyExtensions.swift */,
215F13281E2175C500B0FFEC /* OtherExtension.swift */,
210A762F1E210FBB000C3DDD /* Metadata.swift */,
Expand All @@ -396,6 +407,7 @@
210A76A51E211331000C3DDD /* ReflectionHelper.swift */,
215F132D1E2179E700B0FFEC /* LICENSE */,
7DCD448120FB593600370EF4 /* CBridge.swift */,
7D2813E622058D060044E052 /* MangledName.swift */,
);
name = Reflection;
sourceTree = "<group>";
Expand Down Expand Up @@ -860,6 +872,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7D2813E722058D060044E052 /* MangledName.swift in Sources */,
210A76441E210FBB000C3DDD /* AnyExtensions.swift in Sources */,
21DFCA6E1E18EBA600856775 /* TransformOf.swift in Sources */,
2145B0B31F1A7DE700707730 /* ExtendCustomModelType.swift in Sources */,
Expand Down Expand Up @@ -889,6 +902,7 @@
21DFCA5E1E18EB9C00856775 /* ISO8601DateTransform.swift in Sources */,
21A192021E22332000CD7609 /* Configuration.swift in Sources */,
21A191FD1E222E8C00CD7609 /* Logger.swift in Sources */,
7D460F662203511D0027428E /* FieldDescriptor.swift in Sources */,
210A76801E210FBB000C3DDD /* Properties.swift in Sources */,
2179B6B31D911DB4007B0320 /* HelpingMapper.swift in Sources */,
2145B0AB1F1A3AF600707730 /* Transformable.swift in Sources */,
Expand Down Expand Up @@ -931,6 +945,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7D2813E822058D060044E052 /* MangledName.swift in Sources */,
21D7AD3D1F610197008FC7A4 /* PropertyInfo.swift in Sources */,
21356CDA1F1A82220094A4F5 /* Measuable.swift in Sources */,
21356CDB1F1A82220094A4F5 /* Transformable.swift in Sources */,
Expand Down Expand Up @@ -960,6 +975,7 @@
21A192031E22332000CD7609 /* Configuration.swift in Sources */,
21A191FE1E222E8C00CD7609 /* Logger.swift in Sources */,
210A76811E210FBB000C3DDD /* Properties.swift in Sources */,
7D460F672203511D0027428E /* FieldDescriptor.swift in Sources */,
393E0FA91DA165E300B3BC12 /* Deserializer.swift in Sources */,
217801E91F5E60C900EDEB38 /* ExtendCustomBasicType.swift in Sources */,
393E0FAA1DA165E300B3BC12 /* Serializer.swift in Sources */,
Expand All @@ -971,6 +987,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7D2813E922058D060044E052 /* MangledName.swift in Sources */,
21D7AD3C1F610192008FC7A4 /* PropertyInfo.swift in Sources */,
21356CE21F1A82440094A4F5 /* Measuable.swift in Sources */,
21356CE31F1A82440094A4F5 /* Transformable.swift in Sources */,
Expand Down Expand Up @@ -1000,6 +1017,7 @@
21A192041E22332000CD7609 /* Configuration.swift in Sources */,
21A191FF1E222E8C00CD7609 /* Logger.swift in Sources */,
210A76821E210FBB000C3DDD /* Properties.swift in Sources */,
7D460F682203511D0027428E /* FieldDescriptor.swift in Sources */,
393E0FD01DA2484F00B3BC12 /* Deserializer.swift in Sources */,
217801EA1F5E60C900EDEB38 /* ExtendCustomBasicType.swift in Sources */,
393E0FD11DA2484F00B3BC12 /* Serializer.swift in Sources */,
Expand Down Expand Up @@ -1032,6 +1050,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7D2813EA22058D060044E052 /* MangledName.swift in Sources */,
21D7AD3B1F61018C008FC7A4 /* PropertyInfo.swift in Sources */,
21356CE81F1A824B0094A4F5 /* Measuable.swift in Sources */,
21356CE91F1A824B0094A4F5 /* Transformable.swift in Sources */,
Expand Down Expand Up @@ -1061,6 +1080,7 @@
21A192051E22332000CD7609 /* Configuration.swift in Sources */,
21A192001E222E8C00CD7609 /* Logger.swift in Sources */,
210A76831E210FBB000C3DDD /* Properties.swift in Sources */,
7D460F692203511D0027428E /* FieldDescriptor.swift in Sources */,
393E0FFC1DA2495900B3BC12 /* Deserializer.swift in Sources */,
217801EB1F5E60C900EDEB38 /* ExtendCustomBasicType.swift in Sources */,
393E0FFD1DA2495900B3BC12 /* Serializer.swift in Sources */,
Expand Down
14 changes: 7 additions & 7 deletions Source/CBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@

import Foundation

@_silgen_name("swift_getFieldAt")
func _getFieldAt(
_ type: Any.Type,
_ index: Int,
_ callback: @convention(c) (UnsafePointer<CChar>, UnsafeRawPointer, UnsafeMutableRawPointer) -> Void,
_ ctx: UnsafeMutableRawPointer
)
@_silgen_name("swift_getTypeByMangledNameInContext")
public func _getTypeByMangledNameInContext(
_ name: UnsafePointer<UInt8>,
_ nameLength: Int,
genericContext: UnsafeRawPointer?,
genericArguments: UnsafeRawPointer?)
-> Any.Type?
48 changes: 43 additions & 5 deletions Source/ContextDescriptorType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ extension ContextDescriptorType {
}
}

var mangledName: String {
let pointer = UnsafePointer<Int>(self.pointer)
let base = pointer.advanced(by: contextDescriptorOffsetLocation)
let mangledNameAddress = base.pointee + 2 * 4 // 2 properties in front
if let offset = contextDescriptor?.mangledName,
let cString = UnsafePointer<UInt8>(bitPattern: mangledNameAddress + offset) {
return String(cString: cString)
}
return ""
}

var numberOfFields: Int {
return contextDescriptor?.numberOfFields ?? 0
}
Expand All @@ -60,50 +71,77 @@ extension ContextDescriptorType {
}
}
}

var reflectionFieldDescriptor: FieldDescriptor? {
guard let contextDescriptor = self.contextDescriptor else {
return nil
}
let pointer = UnsafePointer<Int>(self.pointer)
let base = pointer.advanced(by: contextDescriptorOffsetLocation)
let offset = contextDescriptor.reflectionFieldDescriptor
let address = base.pointee + 4 * 4
guard let fieldDescriptorPtr = UnsafePointer<_FieldDescriptor>(bitPattern: address + offset) else {
return nil
}
return FieldDescriptor(pointer: fieldDescriptorPtr)
}
}

protocol ContextDescriptorProtocol {
var mangledName: Int { get }
var numberOfFields: Int { get }
var fieldOffsetVector: Int { get }
var reflectionFieldDescriptor: Int { get }
}

struct ContextDescriptor<T: _ContextDescriptorProtocol>: ContextDescriptorProtocol, PointerType {

var pointer: UnsafePointer<T>

var mangledName: Int {
return Int(pointer.pointee.mangledNameOffset)
}

var numberOfFields: Int {
return Int(pointer.pointee.numberOfFields)
}

var fieldOffsetVector: Int {
return Int(pointer.pointee.fieldOffsetVector)
}

var reflectionFieldDescriptor: Int {
return Int(pointer.pointee.reflectionFieldDescriptor)
}
}

protocol _ContextDescriptorProtocol {
var mangledName: Int32 { get }
var mangledNameOffset: Int32 { get }
var numberOfFields: Int32 { get }
var fieldOffsetVector: Int32 { get }
var fieldTypesAccessor: Int32 { get }
var reflectionFieldDescriptor: Int32 { get }
}

struct _StructContextDescriptor: _ContextDescriptorProtocol {
var flags: Int32
var parent: Int32
var mangledName: Int32
var mangledNameOffset: Int32
var fieldTypesAccessor: Int32
var reflectionFieldDescriptor: Int32
var numberOfFields: Int32
var fieldOffsetVector: Int32
}

struct _ClassContextDescriptor: _ContextDescriptorProtocol {
var flags: Int32
var parent: Int32
var mangledName: Int32
var mangledNameOffset: Int32
var fieldTypesAccessor: Int32
var reflectionFieldDescriptor: Int32
var superClsRef: Int32
var reservedWord1: Int32
var reservedWord2: Int32
var metadataNegativeSizeInWords: Int32
var metadataPositiveSizeInWords: Int32
var numImmediateMembers: Int32
var numberOfFields: Int32
var fieldOffsetVector: Int32
Expand Down
97 changes: 97 additions & 0 deletions Source/FieldDescriptor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// FieldDescriptor.swift
// HandyJSON
//
// Created by chantu on 2019/1/31.
// Copyright © 2019 aliyun. All rights reserved.
//

import Foundation

enum FieldDescriptorKind : UInt16 {
// Swift nominal types.
case Struct = 0
case Class
case Enum

// Fixed-size multi-payload enums have a special descriptor format that
// encodes spare bits.
//
// FIXME: Actually implement this. For now, a descriptor with this kind
// just means we also have a builtin descriptor from which we get the
// size and alignment.
case MultiPayloadEnum

// A Swift opaque protocol. There are no fields, just a record for the
// type itself.
case `Protocol`

// A Swift class-bound protocol.
case ClassProtocol

// An Objective-C protocol, which may be imported or defined in Swift.
case ObjCProtocol

// An Objective-C class, which may be imported or defined in Swift.
// In the former case, field type metadata is not emitted, and
// must be obtained from the Objective-C runtime.
case ObjCClass
}

struct FieldDescriptor: PointerType {

var pointer: UnsafePointer<_FieldDescriptor>

var fieldRecordSize: Int {
return Int(pointer.pointee.fieldRecordSize)
}

var numFields: Int {
return Int(pointer.pointee.numFields)
}

var fieldRecords: [FieldRecord] {
return (0..<numFields).map({ (i) -> FieldRecord in
return FieldRecord(pointer: UnsafePointer<_FieldRecord>(pointer + 1) + i)
})
}
}

struct _FieldDescriptor {
var mangledTypeNameOffset: Int32
var superClassOffset: Int32
var fieldDescriptorKind: FieldDescriptorKind
var fieldRecordSize: Int16
var numFields: Int32
}

struct FieldRecord: PointerType {

var pointer: UnsafePointer<_FieldRecord>

var fieldRecordFlags: Int {
return Int(pointer.pointee.fieldRecordFlags)
}

var mangledTypeName: UnsafePointer<UInt8>? {
let address = Int(bitPattern: pointer) + 1 * 4
let offset = Int(pointer.pointee.mangledTypeNameOffset)
let cString = UnsafePointer<UInt8>(bitPattern: address + offset)
return cString
}

var fieldName: String {
let address = Int(bitPattern: pointer) + 2 * 4
let offset = Int(pointer.pointee.fieldNameOffset)
if let cString = UnsafePointer<UInt8>(bitPattern: address + offset) {
return String(cString: cString)
}
return ""
}
}

struct _FieldRecord {
var fieldRecordFlags: Int32
var mangledTypeNameOffset: Int32
var fieldNameOffset: Int32
}
15 changes: 15 additions & 0 deletions Source/MangledName.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// MangledName.swift
// HandyJSON
//
// Created by chantu on 2019/2/2.
// Copyright © 2019 aliyun. All rights reserved.
//

import Foundation

// mangled name might contain 0 but it is not the end, do not just use strlen
func getMangledTypeNameSize(_ mangledName: UnsafePointer<UInt8>) -> Int {
// TODO: should find the actually size
return 256
}
Loading

2 comments on commit da72f29

@holy38321
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swift5.0 报错

@bearier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Xcode 10.2 Undefined symbol: _swift_getFieldAt

Please sign in to comment.