//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // This function should be opaque to the optimizer. // BLOCKED: This function will be unnecessary when // fix_lifetime is honored by the ARC optimizer. @asmname("swift_keepAlive") func swift_keepAlive(inout _: T) /// \brief An instance of this struct keeps the references registered with it /// at +1 reference count until the call to \c release(). /// /// It is absolutely necessary to call \c release(). Forgetting to call /// \c release() will not cause a memory leak. Instead, the managed objects will be /// released earlier than expected. /// /// This class can be used to extend lifetime of objects to pass UnsafePointers /// to them to C APIs. class LifetimeManager { var _managedRefs : Builtin.NativeObject[] var _releaseCalled : Bool init() { _managedRefs = Array() _releaseCalled = false } deinit { if !_releaseCalled { fatal("release() should have been called") } } func put(objPtr: Builtin.NativeObject) { _managedRefs.append(objPtr) } // FIXME: Need class constraints for this to work properly. // func put(obj: T) { // put(Builtin.castToNativeObject(obj)) // } /// \brief Call this function to end the forced lifetime extension. func release() { _fixLifetime(_managedRefs.owner) _releaseCalled = true } } /// \brief Evaluate f() and return its result, ensuring that x is not /// destroyed before f returns. func withExtendedLifetime( x: T, f: ()->Result ) -> Result { let result = f() _fixLifetime(x) return result } /// \brief Evaluate f(x) and return its result, ensuring that x is not /// destroyed before f returns. func withExtendedLifetime( x: T, f: (T)->Result ) -> Result { let result = f(x) _fixLifetime(x) return result } // FIXME: this function can die once (need // support for CF bridging) is solved. /// \brief Pass a given object as a COpaquePointer at +0 to the given /// function, returning its result. This function is useful for /// calling CoreFoundation functions on NS types that are toll-free /// bridged; you have to declare these functions as taking /// COpaquePointer, obviously. func withObjectAtPlusZero(x: AnyObject, f: (COpaquePointer)->Result) -> Result { return withExtendedLifetime(x) { return f( COpaquePointer(UnsafePointer(Builtin.bridgeToRawPointer(Builtin.castToNativeObject(x))))) } } extension String { /// \brief Invoke f on the contents of this string, represented as /// a nul-terminated array of char, ensuring that the array's /// lifetime extends through the execution of f func withCString( f: (CString)->Result ) -> Result { return self.nulTerminatedUTF8.withUnsafePointerToElements { f(CString($0)) } } /// \brief Invoke f on the contents of this string, represented as /// a nul-terminated array of char, ensuring that the array's /// lifetime extends through the execution of f func withCString( f: (UnsafePointer)->Result ) -> Result { return self.nulTerminatedUTF8.withUnsafePointerToElements { f(UnsafePointer($0)) } } } @transparent func _fixLifetime(var x: T) { swift_keepAlive(&x) }