feedback on alternatives for importing libdispatch types into Swift on Liunx


(Dave Grove) #1

Currently on Linux, the various libdispatch types (dispatch_object_t,
dispatch_queue_t, etc.) are imported into Swift as COpaquePointer on Linux.
This causes a number of problems including:
  (a) The intended subtyping relationships are lost, resulting in some
of the dispatch APIs not being usable (https://bugs.swift.org/browse/SR-737
)
  (b) The libdispatch types can't be used in Swift where AnyObject is
expected (https://bugs.swift.org/browse/SR-740)
  (c) In Swift code that manipulates values coming from libdispatch,
the expected retain/release operations are not generated by the compiler on
Linux.

I can see two obvious ways to tackle these issues (and perhaps other
problems with the same root cause I haven't encountered yet).
  (1) Stay with the current C-level code of libdispatch where
dispatch_object_t et al. simulate enough of the Objective-C object model
that they can masquerade as Objective-C objects. Convince the Swift
compiler to import them as Objective-C types on Linux even though there is
not an Objective-C runtime (just the stubbed out bits of it that are in
libdispatch).
  (2) Change the current C-level code of libdispatch so that on Linux
dispatch_object_t et al. simulate/implement enough of the Swift object
model that they can masquerade as Swift objects. Convince the Swift
compiler to import them as Swift types.

My gut is that (2) is the more desirable path to pursue. The main downside
I see is that it will likely make libdispatch.so dependent on
libswiftCore.so (to avoid replicating object model implementation
functions).

Before seriously starting down either path, I'd like to get some guidance
on what experts think the desired outcome should be and if I've overlooked
a better option.

thanks,

--dave


(Joe Groff) #2

I agree that (2) is preferable; it'd be great if the entire corelibs platform could avoid needing to support multiple object models. You'll probably also have problems with blocks, which also aren't Swift-refcountable. We might be able to also customize the blocks runtime to use Swift refcounting as well. There's some trickiness there since global and stack blocks are ABI emitted by Clang, so swift-clang would need changes to match.

-Joe

···

On Feb 25, 2016, at 3:34 PM, David P Grove via swift-dev <swift-dev@swift.org> wrote:

Currently on Linux, the various libdispatch types (dispatch_object_t, dispatch_queue_t, etc.) are imported into Swift as COpaquePointer on Linux. This causes a number of problems including:
(a) The intended subtyping relationships are lost, resulting in some of the dispatch APIs not being usable (https://bugs.swift.org/browse/SR-737)
(b) The libdispatch types can't be used in Swift where AnyObject is expected (https://bugs.swift.org/browse/SR-740)
(c) In Swift code that manipulates values coming from libdispatch, the expected retain/release operations are not generated by the compiler on Linux.

I can see two obvious ways to tackle these issues (and perhaps other problems with the same root cause I haven't encountered yet).
(1) Stay with the current C-level code of libdispatch where dispatch_object_t et al. simulate enough of the Objective-C object model that they can masquerade as Objective-C objects. Convince the Swift compiler to import them as Objective-C types on Linux even though there is not an Objective-C runtime (just the stubbed out bits of it that are in libdispatch).
(2) Change the current C-level code of libdispatch so that on Linux dispatch_object_t et al. simulate/implement enough of the Swift object model that they can masquerade as Swift objects. Convince the Swift compiler to import them as Swift types.

My gut is that (2) is the more desirable path to pursue. The main downside I see is that it will likely make libdispatch.so dependent on libswiftCore.so (to avoid replicating object model implementation functions).

Before seriously starting down either path, I'd like to get some guidance on what experts think the desired outcome should be and if I've overlooked a better option.


(Dave Grove) #3

I've made some progress on getting libdispatch types like dispatch_queue_t
to implement the Swift object model and be imported as Swift classes. As
Joe suggested last week, I am attempting to implement the Swift object
model in libdispatch (and get the importer to realize that).

To simplify things, I created a tiny simulation of libdispatch [1] and used
it to explore options. I think I've ended up in a reasonable point, but
before actually making the changes for real in libdispatch and submitting
pull requests I want to get a sanity check on the approach.

Summary of the changes:
  1. In the ClangImporter, I added more Dispatch types to
MappedTypes.def and a new value, MappedCTypeKind::SwiftClass.

  2. In the simulated libdispatch, I define DISPATCH_RETURNS_RETAINED
to be __attribute__((cf_returns_retained)) instead of
__attribute__((__ns_returns_retained__))

  3. In the simulated libdispatch, I wired
dispatch_retain/dispatch_release to swift_retain/release. I used
swift_allocObject to create instances of dispatch_queue_t, etc.

  4. In Dispatch.swift I define stub classes DispatchObject,
DispatchQueue, etc. in a class hierarchy. I use the compiler-generated
metadata for these classes when calling swift_allocObject for the isa
pointer.

The changes to ClangImporter can be browsed at [2].

thanks for any feedback,

--dave

[1] https://github.com/dgrove-oss/swift-object-model-experiments
[2] https://github.com/dgrove-oss/swift/tree/dispatch-import-exploration