You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.5 KiB
97 lines
2.5 KiB
// |
|
// 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 |
|
}
|
|
|