Skip to content

Commit 87e1ab5

Browse files
committed
SwiftRemoteMirror: Add validation test for projecting existentials
1 parent 4da656c commit 87e1ab5

File tree

2 files changed

+281
-0
lines changed

2 files changed

+281
-0
lines changed

stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,52 @@ public func reflect(object: AnyObject) {
303303
///
304304
/// This function serves to exercise the projectExistential function of the
305305
/// SwiftRemoteMirror API.
306+
///
307+
/// It tests the three conditions of existential layout:
308+
///
309+
/// ## Class existentials
310+
///
311+
/// For example, a `MyClass as Any`:
312+
/// ```
313+
/// [Pointer to class instance]
314+
/// [Witness table 1]
315+
/// [Witness table 2]
316+
/// ...
317+
/// [Witness table n]
318+
/// ```
319+
///
320+
/// ## Existentials whose contained type fits in the 3-word buffer
321+
///
322+
/// For example, a `(1, 2) as Any`:
323+
/// ```
324+
/// [Tuple element 1: Int]
325+
/// [Tuple element 2: Int]
326+
/// [-Empty_]
327+
/// [Metadata Pointer]
328+
/// [Witness table 1]
329+
/// [Witness table 2]
330+
/// ...
331+
/// [Witness table n]
332+
/// ```
333+
///
334+
/// ## Existentials whose contained type has to be allocated into a
335+
/// heap buffer.
336+
///
337+
/// For example, a `LargeStruct<T> as Any`:
338+
/// ```
339+
/// [Pointer to unmanaged heap container] --> [Large struct]
340+
/// [-Empty-]
341+
/// [-Empty-]
342+
/// [Metadata Pointer]
343+
/// [Witness table 1]
344+
/// [Witness table 2]
345+
/// ...
346+
/// [Witness table n]
347+
/// ```
348+
///
349+
/// The test doesn't care about the witness tables - we only care
350+
/// about what's in the buffer, so we always put these values into
351+
/// an Any existential.
306352
public func reflect<T>(any: T) {
307353
let any: Any = any
308354
let anyPointer = UnsafeMutablePointer<Any>(allocatingCapacity: sizeof(Any.self))
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %target-build-swift -Xfrontend -enable-reflection-metadata -Xfrontend -enable-reflection-names -lswiftSwiftReflectionTest %s -o %T/example
3+
// RUN: %target-run %target-swift-reflection-test %T/example 2>&1 | FileCheck %s --check-prefix=CHECK-%target-ptrsize
4+
// REQUIRES: objc_interop
5+
6+
/*
7+
This file pokes at the swift_reflection_projectExistential API
8+
of the SwiftRemoteMirror library.
9+
10+
It tests the three conditions of existential layout:
11+
12+
- Class existentials
13+
- Existentials whose contained type fits in the 3-word buffer
14+
- Existentials whose contained type has to be allocated into a
15+
raw heap buffer.
16+
17+
- See also: SwiftReflectionTest.reflect(any:)
18+
*/
19+
20+
import SwiftReflectionTest
21+
22+
class MyClass<T, U> {
23+
let x: T
24+
let y: (T, U)
25+
init(x: T, y: (T, U)) {
26+
self.x = x
27+
self.y = y
28+
}
29+
}
30+
31+
struct MyStruct<T, U, V> {
32+
let x: T
33+
let y: U
34+
let z: V
35+
}
36+
37+
// This will be projected as a class existential, so its
38+
// size doesn't matter.
39+
var mc = MyClass(x: 1010, y: (2020, 3030))
40+
reflect(any: mc)
41+
42+
// CHECK-64: Reflecting an existential.
43+
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
44+
// CHECK-64: Type reference:
45+
// CHECK-64: (bound_generic_class example.MyClass
46+
// CHECK-64: (struct Swift.Int)
47+
// CHECK-64: (struct Swift.Int))
48+
// CHECK-64: Type info:
49+
// CHECK-64: (reference kind=strong refcounting=native)
50+
51+
// CHECK-32: Reflecting an existential.
52+
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
53+
// CHECK-32: Type reference:
54+
// CHECK-32: (bound_generic_class example.MyClass
55+
// CHECK-32: (struct Swift.Int)
56+
// CHECK-32: (struct Swift.Int))
57+
// CHECK-32: Type info:
58+
// CHECK-32: (reference kind=strong refcounting=native)
59+
60+
// This value fits in the 3-word buffer in the container.
61+
var smallStruct = MyStruct(x: 1, y: 2, z: 3)
62+
reflect(any: smallStruct)
63+
64+
// CHECK-64: Reflecting an existential.
65+
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
66+
// CHECK-64: Type reference:
67+
// CHECK-64: (bound_generic_struct example.MyStruct
68+
// CHECK-64: (struct Swift.Int)
69+
// CHECK-64: (struct Swift.Int)
70+
// CHECK-64: (struct Swift.Int))
71+
// CHECK-64: Type info:
72+
// CHECK-64: (struct size=24 alignment=8 stride=24 num_extra_inhabitants=0
73+
// CHECK-64: (field name=x offset=0
74+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
75+
// CHECK-64: (field offset=0
76+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
77+
// CHECK-64: (field name=y offset=8
78+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
79+
// CHECK-64: (field offset=0
80+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
81+
// CHECK-64: (field name=z offset=16
82+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
83+
// CHECK-64: (field offset=0
84+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
85+
86+
// CHECK-32: Reflecting an existential.
87+
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
88+
// CHECK-32: Type reference:
89+
// CHECK-32: (bound_generic_struct example.MyStruct
90+
// CHECK-32: (struct Swift.Int)
91+
// CHECK-32: (struct Swift.Int)
92+
// CHECK-32: (struct Swift.Int))
93+
// CHECK-32: Type info:
94+
// CHECK-32: (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
95+
// CHECK-32: (field name=x offset=0
96+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
97+
// CHECK-32: (field offset=0
98+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
99+
// CHECK-32: (field name=y offset=4
100+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
101+
// CHECK-32: (field offset=0
102+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
103+
// CHECK-32: (field name=z offset=8
104+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
105+
// CHECK-32: (field offset=0
106+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
107+
108+
// This value will be copied into a heap buffer, with a
109+
// pointer to it in the existential.
110+
var largeStruct = MyStruct(x: (1,1,1), y: (2,2,2), z: (3,3,3))
111+
reflect(any: largeStruct)
112+
113+
// CHECK-64: Reflecting an existential.
114+
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
115+
// CHECK-64: Type reference:
116+
// CHECK-64: (bound_generic_struct example.MyStruct
117+
// CHECK-64: (tuple
118+
// CHECK-64: (struct Swift.Int)
119+
// CHECK-64: (struct Swift.Int)
120+
// CHECK-64: (struct Swift.Int))
121+
// CHECK-64: (tuple
122+
// CHECK-64: (struct Swift.Int)
123+
// CHECK-64: (struct Swift.Int)
124+
// CHECK-64: (struct Swift.Int))
125+
// CHECK-64: (tuple
126+
// CHECK-64: (struct Swift.Int)
127+
// CHECK-64: (struct Swift.Int)
128+
// CHECK-64: (struct Swift.Int)))
129+
// CHECK-64: Type info:
130+
// CHECK-64: (struct size=72 alignment=8 stride=72 num_extra_inhabitants=0
131+
// CHECK-64: (field name=x offset=0
132+
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
133+
// CHECK-64: (field offset=0
134+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
135+
// CHECK-64: (field offset=0
136+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
137+
// CHECK-64: (field offset=8
138+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
139+
// CHECK-64: (field offset=0
140+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
141+
// CHECK-64: (field offset=16
142+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
143+
// CHECK-64: (field offset=0
144+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
145+
// CHECK-64: (field name=y offset=24
146+
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
147+
// CHECK-64: (field offset=0
148+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
149+
// CHECK-64: (field offset=0
150+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
151+
// CHECK-64: (field offset=8
152+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
153+
// CHECK-64: (field offset=0
154+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
155+
// CHECK-64: (field offset=16
156+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
157+
// CHECK-64: (field offset=0
158+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
159+
// CHECK-64: (field name=z offset=48
160+
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
161+
// CHECK-64: (field offset=0
162+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
163+
// CHECK-64: (field offset=0
164+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
165+
// CHECK-64: (field offset=8
166+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
167+
// CHECK-64: (field offset=0
168+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
169+
// CHECK-64: (field offset=16
170+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
171+
// CHECK-64: (field offset=0
172+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
173+
174+
// CHECK-32: Reflecting an existential.
175+
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
176+
// CHECK-32: Type reference:
177+
// CHECK-32: (bound_generic_struct example.MyStruct
178+
// CHECK-32: (tuple
179+
// CHECK-32: (struct Swift.Int)
180+
// CHECK-32: (struct Swift.Int)
181+
// CHECK-32: (struct Swift.Int))
182+
// CHECK-32: (tuple
183+
// CHECK-32: (struct Swift.Int)
184+
// CHECK-32: (struct Swift.Int)
185+
// CHECK-32: (struct Swift.Int))
186+
// CHECK-32: (tuple
187+
// CHECK-32: (struct Swift.Int)
188+
// CHECK-32: (struct Swift.Int)
189+
// CHECK-32: (struct Swift.Int)))
190+
// CHECK-32: Type info:
191+
// CHECK-32: (struct size=36 alignment=4 stride=36 num_extra_inhabitants=0
192+
// CHECK-32: (field name=x offset=0
193+
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
194+
// CHECK-32: (field offset=0
195+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
196+
// CHECK-32: (field offset=0
197+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
198+
// CHECK-32: (field offset=4
199+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
200+
// CHECK-32: (field offset=0
201+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
202+
// CHECK-32: (field offset=8
203+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
204+
// CHECK-32: (field offset=0
205+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
206+
// CHECK-32: (field name=y offset=12
207+
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
208+
// CHECK-32: (field offset=0
209+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
210+
// CHECK-32: (field offset=0
211+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
212+
// CHECK-32: (field offset=4
213+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
214+
// CHECK-32: (field offset=0
215+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
216+
// CHECK-32: (field offset=8
217+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
218+
// CHECK-32: (field offset=0
219+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
220+
// CHECK-32: (field name=z offset=24
221+
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
222+
// CHECK-32: (field offset=0
223+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
224+
// CHECK-32: (field offset=0
225+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
226+
// CHECK-32: (field offset=4
227+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
228+
// CHECK-32: (field offset=0
229+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
230+
// CHECK-32: (field offset=8
231+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
232+
// CHECK-32: (field offset=0
233+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))))
234+
235+
doneReflecting()

0 commit comments

Comments
 (0)