File: Unmanaged.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (96 lines) | stat: -rw-r--r-- 2,792 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// RUN: %target-run-simple-swift
// REQUIRES: executable_test

import StdlibUnittest


// Check that the generic parameter is called 'Instance'.
protocol TestProtocol1 {}

extension Unmanaged where Instance : TestProtocol1 {
  var _instanceIsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

var UnmanagedTests = TestSuite("Unmanaged")

class FooClass {}

UnmanagedTests.test("unsafeBitCast(Unmanaged, Int)") {
  let ref = FooClass()
  expectNotEqual(
    0,
    unsafeBitCast(
      Unmanaged.passUnretained(ref) as Unmanaged<AnyObject>,
      to: Int.self))
  _fixLifetime(ref)
}

class Foobar {
  func foo() -> Int { return 1 }
}

UnmanagedTests.test("_withUnsafeGuaranteedRef") {
  var ref = Foobar()
  var unmanaged = Unmanaged.passUnretained(ref)
  withExtendedLifetime(ref) {
    unmanaged._withUnsafeGuaranteedRef {
      expectTrue(ref === $0)
    }
    unmanaged._withUnsafeGuaranteedRef {
      expectEqual(1, $0.foo())
    }
  }
}

UnmanagedTests.test("_withUnsafeGuaranteedRef/return") {
  var ref = Foobar()
  var unmanaged = Unmanaged.passUnretained(ref)
  withExtendedLifetime(ref) {
    expectEqual(1, unmanaged._withUnsafeGuaranteedRef {
      return $0.foo()
    })
  }
}

UnmanagedTests.test("Opaque") {
  var ref = Foobar()
  let opaquePtr = Unmanaged.passUnretained(ref).toOpaque()
  
  let unknownPtr = Int(bitPattern: opaquePtr)
  let voidPtr = UnsafeRawPointer(bitPattern: unknownPtr)
  expectNotNil(voidPtr, "toOpaque must not return null pointer")
  
  let unmanaged = Unmanaged<Foobar>.fromOpaque(voidPtr!)
  expectEqual(
    ref === unmanaged.takeUnretainedValue(),
    true,
    "fromOpaque must return the same reference")
  
  _fixLifetime(ref)
}

UnmanagedTests.test("Opaque avoid retain/release") {
  // The purpose of this test is to ensure that the fromOpaque/toOpaque calls do
  // NOT attempt to retain/release the class instance at the passed pointer.
  // Here we're simulating a dangling pointer referencing a class who has
  // already been released (the allocated pointer points at nothing) and
  // attempting to create an Unmanaged instance from it and get back the
  // pointer. This test's expectEqual is kind of bogus, we're just checking that
  // it doesn't crash.

  // Create a dangling pointer, usually to unmapped memory.
  let ref = UnsafeRawPointer(bitPattern: 1)!
  // Turn it into a dangling unmanaged reference.
  // We expect this not to crash, as this operation isn't 
  // supposed to dereference the pointer in any way.
  let unmanaged = Unmanaged<Foobar>.fromOpaque(ref)
  // Similarly, converting the unmanaged reference back to a 
  // pointer should not ever try to dereference it either.
  let ref2 = unmanaged.toOpaque()
  // ...and we must get back the same pointer.
  expectEqual(ref, ref2)
}

runAllTests()