Skip to content

Commit

Permalink
Merge pull request #43 from wickwirew/nested-struct-crash
Browse files Browse the repository at this point in the history
check the flags to check whether the type is generic or not
  • Loading branch information
wickwirew authored Apr 26, 2019
2 parents 49433c6 + 304fa5d commit c167476
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Sources/Runtime/Layouts/StructTypeDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct StructTypeDescriptor: TypeDescriptor {
var flags: ContextDescriptorFlags
var parent: Int32
var mangledName: RelativePointer<Int32, CChar>
var unknown3: Int32
var accessFunctionPtr: RelativePointer<Int32, UnsafeRawPointer>
var fieldDescriptor: RelativePointer<Int32, FieldDescriptor>
var numberOfFields: Int32
var offsetToTheFieldOffsetVector: RelativeVectorPointer<Int32, Int32>
Expand Down
1 change: 1 addition & 0 deletions Sources/Runtime/Layouts/TypeDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ protocol TypeDescriptor {
/// e.g. Struct are an Int32 and classes are an Int
associatedtype FieldOffsetVectorOffsetType: IntegerConvertible

var flags: ContextDescriptorFlags { get set }
var mangledName: RelativePointer<Int32, CChar> { get set }
var fieldDescriptor: RelativePointer<Int32, FieldDescriptor> { get set }
var numberOfFields: Int32 { get set }
Expand Down
17 changes: 14 additions & 3 deletions Sources/Runtime/Metadata/NominalMetadataType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ extension NominalMetadataType {
return 2
}

var isGeneric: Bool {
return (pointer.pointee.typeDescriptor.pointee.flags & 0x80) != 0
}

mutating func mangledName() -> String {
return String(cString: pointer.pointee.typeDescriptor.pointee.mangledName.advanced())
}
Expand Down Expand Up @@ -78,11 +82,18 @@ extension NominalMetadataType {
}

func genericArguments() -> [Any.Type] {
let n = pointer.pointee.typeDescriptor.pointee.genericContextHeader.base.numberOfParams
guard n > 0 else { return [] }
guard isGeneric else { return [] }

let genericHeader = pointer.pointee
.typeDescriptor
.pointee
.genericContextHeader

guard genericHeader.base.numberOfParams > 0 else { return [] }

let vector = genericArgumentVector()
return (0..<Int(pointer.pointee.typeDescriptor.pointee.genericContextHeader.base.numberOfParams)).map { i in

return (0..<Int(genericHeader.base.numberOfParams)).map { i in
return vector.pointee.element(at: i).pointee
}
}
Expand Down
27 changes: 27 additions & 0 deletions Tests/RuntimeTests/MetadataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class MetadataTests: XCTestCase {

var md = StructMetadata(type: A.self)
let info = md.toTypeInfo()
XCTAssert(info.genericTypes.count == 0)
XCTAssert(info.kind == .struct)
XCTAssert(info.type == A.self)
XCTAssert(info.properties.count == 5)
Expand All @@ -89,6 +90,32 @@ class MetadataTests: XCTestCase {
XCTAssert(info.properties[4].isVar)
}

// https://github.com/wickwirew/Runtime/issues/42
func testNestedStruct() {

let nest: () -> Void = {

struct NestedA {
let a, b, c, d: Int
var e: Int
}

var md = StructMetadata(type: NestedA.self)
let info = md.toTypeInfo()
XCTAssert(info.genericTypes.count == 0)
XCTAssert(info.kind == .struct)
XCTAssert(info.type == NestedA.self)
XCTAssert(info.properties.count == 5)
XCTAssert(info.size == MemoryLayout<NestedA>.size)
XCTAssert(info.alignment == MemoryLayout<NestedA>.alignment)
XCTAssert(info.stride == MemoryLayout<NestedA>.stride)
XCTAssert(!info.properties[0].isVar)
XCTAssert(info.properties[4].isVar)
}

nest()
}

func testProtocol() {
var md = ProtocolMetadata(type: MyProtocol.self)
let info = md.toTypeInfo()
Expand Down

0 comments on commit c167476

Please sign in to comment.