Giter Site home page Giter Site logo

swift-bindgen's Introduction

swift-bindgen

Bridging the gap between Swift and Rust, brought to you by Nikolai Vazquez!

This project is very much a work-in-progress. If you would like to contribute, please get involved by submitting issues, pull requests, or getting in contact to brainstorm.

If this project is useful to you, please support it by sponsoring on GitHub or donating directly!

Project Structure

This project is composed of the following crates:

  • swift-bindgen: Generates bindings for two-way bridging of Rust/Swift types.

  • swift: High-level idiomatic bindings to the Swift standard library.

  • swift-rt: High-level idiomatic bindings to the Swift runtime.

  • swift-sys: Low-level bindings to the Swift runtime.

Acknowledgements

  • Jordan Rose (@UINT_MIN) for insight into how the Swift runtime works internally.

  • Joe Groff (@jckarter) for being my Swift emotional support dog while I ask for feedback on my assumptions of Swift internals and ABI.

  • Contributors to Swift—past, present, and future—for creating a fascinating language that makes apps easier to develop and faster to run.

License

This project is licensed under the Apache License (Version 2.0).

swift-bindgen's People

Contributors

dante-broggi avatar nvzqz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-bindgen's Issues

Expectations

What does having two-way bindings between Rust and Swift even mean?

We can cross the bridge in many ways today. However, there's a point where each language's limitations stop us from expressing notions from the other.

Generate rust bindings from Swift.

It looks like this project might be a little stagnant but I thought I'd show some interest and write some words on generating rust bindings from swift.

The front end of this (or one of the crates in here) should be both a library and an executable similar to cbindgen or rust-bindgen.

Some notes:

  • cbindgen uses syn to parse the rust source to generate some of the C bindings.
  • rust-bindgen uses clang-sys to get the AST of the C, C++ or Objective-C and then uses syn as part of the rust generation phase.

To move forward with this, I think we should try to follow similar choices in design. To parse the swift and parse the AST, we should use the swift tooling.

swiftc has some functionality to spit out the AST for a given file as shown here. After a bit of messing around, it would seem that we'd want to parse the swiftinterface. At least, that's what seems to be the closes thing to a header file.

I managed to get:xcrun swiftc -frontend -emit-syntax -target x86_64-apple-ios13.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -Osize -module-name SwiftUI $(xcrun --show-sdk-path -sdk iphonesimulator)/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/x86_64.swiftinterface to produce a syntax tree. It doesn't like @objc syntax but I think there's a way to ignore that.

Anyway, the above spits out a lot of json. I'm not super into the idea of parsing that. We could look into getting some bindings to lib/Syntax using cmake-rs/bindgen or something.

Swift Runtime

All public functions that manipulate the Swift runtime are annotated with SWIFT_RUNTIME_EXPORT.

Are these considered stable and part of Swift's ABI?

Swift Function Call ABI

For the long-term success of this project, it should allow for exposing functions in Rust that can be called in Swift via the Swift function ABI as well as calling functions declared in Swift directly from Rust without an intermediate C or Objective-C layer. LLVM currently supports the Swift calling convention, also known as swiftcc. In order to expose Swift functions and call them directly in an FFI-safe manner, the Rust compiler needs to be taught Swift's function call ABI.

rust-lang/rust#64582 implements the basic function ABI in rustc via LLVM. This would allow for:

extern "Swift" {
    fn foo();
}

extern "Swift" fn bar() {
    // ...
}

type F = extern "Swift" fn();

Expressing Rust Move-Only Types in Swift

In Rust, types that don't implement Copy are considered to be move-only and can only be copied via Clone or other means.

In Swift, there's currently no notion of moving a value. Reassignments of a value result in an implicit copy. For class types or anything that contains a class member, this will increment the strong reference count.

There seems to be three approaches to this:

  1. Retrofit a Move protocol that gives automagical move semantics.

    Pros:

    • Doesn't require Swift users to rewrite any existing code.

    • Allows for deinit on non-class types.

    Cons:

    • Wouldn't work in the context of generics. Implicit copying would still be the default there unless a generic type is specified as Move. Rust's move-only types work in generics because all types are assumed to be move-only unless a generic type is specified as Copy.
  2. Introduce a Copy protocol and assume move-only otherwise. Essentially, just copy Rust.

    Pros:

    • Allows for easier FFI when Swift types cross over into Rust-land.

    • Fine-grained control over move semantics types.

    • Works in the context of generics out-of-the-box.

    Cons:

    • Results in significant added complexity, increasing the learning curve. Implicit copying helps keep Swift succinct and expressive.

    • Massive source compatibility break. Requires stdlib and Swift users to rewrite all implicit copies and opt into Copy where appropriate.

  3. Introduce a special Move<T> wrapper type that gives a type move semantics.

    Pros:

    • Allows for basic move-only types.

    Cons:

    • Doesn't gain much. Really only makes existing code more verbose.

Expressing the Swift struct and enum layouts to Rust

The Swift struct and enum layouts, distinguish between the size (store size) and stride (array size) of types.
In particular, the stable Swift 5 layout algorithm (mostly) documented here, which would be largely reasonable to define as a Rust #[repr(Swift_5)], implemented naively is unsound.

The notable example is in this playground

A possible way to fix this is to first add a (Sized-like) implicit auto trait Strided which would encode the necessary guarantee (that the size equals the stride) and which would not be implemented by #[repr(Swift_5)] types.

Another point of remark is that Swift requires all types to have nonzero stride, even if they have zero size.
This means that Swift assumes all ZSTs have unique addresses in memory, if they have an address, though I do not know if Swift acts upon this assumption.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.