SwiftRemoteMirror: Add validation test for projecting existentials

This commit is contained in:
David Farler
2016-05-04 13:58:10 -07:00
parent 4da656c438
commit 87e1ab5dcf
2 changed files with 281 additions and 0 deletions

View File

@@ -303,6 +303,52 @@ public func reflect(object: AnyObject) {
///
/// This function serves to exercise the projectExistential function of the
/// SwiftRemoteMirror API.
///
/// It tests the three conditions of existential layout:
///
/// ## Class existentials
///
/// For example, a `MyClass as Any`:
/// ```
/// [Pointer to class instance]
/// [Witness table 1]
/// [Witness table 2]
/// ...
/// [Witness table n]
/// ```
///
/// ## Existentials whose contained type fits in the 3-word buffer
///
/// For example, a `(1, 2) as Any`:
/// ```
/// [Tuple element 1: Int]
/// [Tuple element 2: Int]
/// [-Empty_]
/// [Metadata Pointer]
/// [Witness table 1]
/// [Witness table 2]
/// ...
/// [Witness table n]
/// ```
///
/// ## Existentials whose contained type has to be allocated into a
/// heap buffer.
///
/// For example, a `LargeStruct<T> as Any`:
/// ```
/// [Pointer to unmanaged heap container] --> [Large struct]
/// [-Empty-]
/// [-Empty-]
/// [Metadata Pointer]
/// [Witness table 1]
/// [Witness table 2]
/// ...
/// [Witness table n]
/// ```
///
/// The test doesn't care about the witness tables - we only care
/// about what's in the buffer, so we always put these values into
/// an Any existential.
public func reflect<T>(any: T) {
let any: Any = any
let anyPointer = UnsafeMutablePointer<Any>(allocatingCapacity: sizeof(Any.self))

View File

@@ -0,0 +1,235 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %target-build-swift -Xfrontend -enable-reflection-metadata -Xfrontend -enable-reflection-names -lswiftSwiftReflectionTest %s -o %T/example
// RUN: %target-run %target-swift-reflection-test %T/example 2>&1 | FileCheck %s --check-prefix=CHECK-%target-ptrsize
// REQUIRES: objc_interop
/*
This file pokes at the swift_reflection_projectExistential API
of the SwiftRemoteMirror library.
It tests the three conditions of existential layout:
- Class existentials
- Existentials whose contained type fits in the 3-word buffer
- Existentials whose contained type has to be allocated into a
raw heap buffer.
- See also: SwiftReflectionTest.reflect(any:)
*/
import SwiftReflectionTest
class MyClass<T, U> {
let x: T
let y: (T, U)
init(x: T, y: (T, U)) {
self.x = x
self.y = y
}
}
struct MyStruct<T, U, V> {
let x: T
let y: U
let z: V
}
// This will be projected as a class existential, so its
// size doesn't matter.
var mc = MyClass(x: 1010, y: (2020, 3030))
reflect(any: mc)
// CHECK-64: Reflecting an existential.
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-64: Type reference:
// CHECK-64: (bound_generic_class example.MyClass
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int))
// CHECK-64: Type info:
// CHECK-64: (reference kind=strong refcounting=native)
// CHECK-32: Reflecting an existential.
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-32: Type reference:
// CHECK-32: (bound_generic_class example.MyClass
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int))
// CHECK-32: Type info:
// CHECK-32: (reference kind=strong refcounting=native)
// This value fits in the 3-word buffer in the container.
var smallStruct = MyStruct(x: 1, y: 2, z: 3)
reflect(any: smallStruct)
// CHECK-64: Reflecting an existential.
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-64: Type reference:
// CHECK-64: (bound_generic_struct example.MyStruct
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int))
// CHECK-64: Type info:
// CHECK-64: (struct size=24 alignment=8 stride=24 num_extra_inhabitants=0
// CHECK-64: (field name=x offset=0
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field name=y offset=8
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field name=z offset=16
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
// CHECK-32: Reflecting an existential.
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-32: Type reference:
// CHECK-32: (bound_generic_struct example.MyStruct
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int))
// CHECK-32: Type info:
// CHECK-32: (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
// CHECK-32: (field name=x offset=0
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field name=y offset=4
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field name=z offset=8
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
// This value will be copied into a heap buffer, with a
// pointer to it in the existential.
var largeStruct = MyStruct(x: (1,1,1), y: (2,2,2), z: (3,3,3))
reflect(any: largeStruct)
// CHECK-64: Reflecting an existential.
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-64: Type reference:
// CHECK-64: (bound_generic_struct example.MyStruct
// CHECK-64: (tuple
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int))
// CHECK-64: (tuple
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int))
// CHECK-64: (tuple
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int)
// CHECK-64: (struct Swift.Int)))
// CHECK-64: Type info:
// CHECK-64: (struct size=72 alignment=8 stride=72 num_extra_inhabitants=0
// CHECK-64: (field name=x offset=0
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=8
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=16
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
// CHECK-64: (field name=y offset=24
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=8
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=16
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
// CHECK-64: (field name=z offset=48
// CHECK-64: (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=8
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
// CHECK-64: (field offset=16
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
// CHECK-64: (field offset=0
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
// CHECK-32: Reflecting an existential.
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
// CHECK-32: Type reference:
// CHECK-32: (bound_generic_struct example.MyStruct
// CHECK-32: (tuple
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int))
// CHECK-32: (tuple
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int))
// CHECK-32: (tuple
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int)
// CHECK-32: (struct Swift.Int)))
// CHECK-32: Type info:
// CHECK-32: (struct size=36 alignment=4 stride=36 num_extra_inhabitants=0
// CHECK-32: (field name=x offset=0
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=4
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=8
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
// CHECK-32: (field name=y offset=12
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=4
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=8
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
// CHECK-32: (field name=z offset=24
// CHECK-32: (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=4
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
// CHECK-32: (field offset=8
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
// CHECK-32: (field offset=0
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))))
doneReflecting()