mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
If a struct has fixed layout but contains fields which are opaque,
or if the struct itself is opaque, use a metadata accessor function
instead of loading the metadata directly.
Let's say that A and B are two structs defined in the same module,
and B has a fixed size. This patch adds support for these two cases:
1) Fixed-layout struct A contains resilient struct B
2) Resilient struct A contains resilient struct B
In case 1),
a) Inside X: A is fixed-size and has constant metadata
i) Direct metadata access can be performed on A and B
ii) Direct field access can be performed on A and B
d) Outside X: B has an opaque layout
i) Metadata accessor must be called for A and B
ii) Fields of A do not have constant offsets, instead the offsets
must be loaded from type metadata
Case 2) is the same as above except ii) does not apply, since fields
of resilient structs are manipulated via accessors.
Eventually, we will use metadata accessor functions for all public
struct and enum types.
80 lines
1.5 KiB
Swift
80 lines
1.5 KiB
Swift
// Fixed-layout struct
|
|
@_fixed_layout public struct Point {
|
|
public var x: Int // read-write stored property
|
|
public let y: Int // read-only stored property
|
|
|
|
public init(x: Int, y: Int) {
|
|
self.x = x
|
|
self.y = y
|
|
}
|
|
|
|
public func method() {}
|
|
public mutating func mutantMethod() {}
|
|
}
|
|
|
|
// Resilient-layout struct
|
|
public struct Size {
|
|
public var w: Int // should have getter and setter
|
|
public let h: Int // getter only
|
|
|
|
public init(w: Int, h: Int) {
|
|
self.w = w
|
|
self.h = h
|
|
}
|
|
|
|
public func method() {}
|
|
public mutating func mutantMethod() {}
|
|
}
|
|
|
|
// Fixed-layout struct with resilient members
|
|
@_fixed_layout public struct Rectangle {
|
|
public let p: Point
|
|
public let s: Size
|
|
public let color: Int
|
|
|
|
public init(p: Point, s: Size, color: Int) {
|
|
self.p = p
|
|
self.s = s
|
|
self.color = color
|
|
}
|
|
}
|
|
|
|
// More complicated resilient structs for runtime tests
|
|
public struct ResilientBool {
|
|
public let b: Bool
|
|
|
|
public init(b: Bool) {
|
|
self.b = b
|
|
}
|
|
}
|
|
|
|
public struct ResilientInt {
|
|
public let i: Int
|
|
|
|
public init(i: Int) {
|
|
self.i = i
|
|
}
|
|
}
|
|
|
|
public struct ResilientDouble {
|
|
public let d: Double
|
|
|
|
public init(d: Double) {
|
|
self.d = d
|
|
}
|
|
}
|
|
|
|
@_fixed_layout public struct ResilientLayoutRuntimeTest {
|
|
public let b1: ResilientBool
|
|
public let i: ResilientInt
|
|
public let b2: ResilientBool
|
|
public let d: ResilientDouble
|
|
|
|
public init(b1: ResilientBool, i: ResilientInt, b2: ResilientBool, d: ResilientDouble) {
|
|
self.b1 = b1
|
|
self.i = i
|
|
self.b2 = b2
|
|
self.d = d
|
|
}
|
|
}
|