A Stable Modular ABI for Rust

I'm doing interesting stuff with Trait vtables: https://github.com/rust-lang/rfcs/pull/2955. It describes how to layout the trait object pointers themselves, as well as the vtable, for traits that opt into it.

1 Like

https://people.gnome.org/~federico/blog/rust-stable-abi.html

4 Likes

We all just kind of... stopped talking. @isaac, have you gotten along further on this?

1 Like

Yeah, the issue is that eventually somebody's got to like do some of this stuff, and who has time for that. :upside_down_face:

This stuff is too far over my head, and I don't have time to work on it anyway. It seems like a really complicated and involved project too so I wouldn't blame anybody for being shy to invest the huge amount of work probably necessary for this.

If there's still discussion that can be done to forward the goal, then cool, but this one's gonna be tough I think. :slight_smile:

2 Likes

I'd be interested in working on this, however I'm not yet familiar enough with the specifics of the Rust compiler implementaion to do anything actionable on my own.

However, I am very interested in this proposal coming to fruition. To be honest, I'm probably not the best person to lead this project, but I'd be willing to dedicate a significant portion my time to work on this. If anyone would like to form a team, plan out a solid pre-RFC incorporating ideas raised in this discussion, and start working on a prototype together, reach out!

By the way, is there a specific channel in the Discord server (or on gitter/zulip/etc.) where further rapid-pace planning and discussion would be appropriate? Thanks :slight_smile:

3 Likes

I completely understand, I'm in the same boat as you are, except that I have no time, so the most I can do is periodically ask what's going on with this discussion!

That said, how about just starting a GitHub repository? It could just contain a bunch of wiki pages that people could contribute to. Even just summarizing the discussion so far would be fantastic, or building out a checklist of things people have said that they want. Once we all have a pretty good idea as to what our end goal is (and what it isn't'), then we can start designing and planning things out.

3 Likes

That's a great idea!

1 Like

That's a great idea! Here it is: https://github.com/slightknack/rust-abi-wiki.

Feel free to fork it! Later today, I'll add and summarize different points from our discussion.

Let's get this show on the road!

5 Likes

That's perfect! I forked it and quickly read through it, I like it so far. You might want to edit the first post here to point to the repo, so that as others come along they know where to go to find it.

OK, going back to making my first PR to it! :wink:

3 Likes

Thanks! That's a good idea, I'll change that now.

The wiki is now up on GitHub Pages. I've put the skeleton in place and fleshed out the introduction.

2 Likes

Dude, love it! Having a real MDBook for this makes the effort real real. :smiley:

2 Likes

Will this also take in account interacting with the (new stable) rust abi from other languages? IE to make talking to rust from c or custom languages possible. (The way apple did Swift's stable abi does not make that easier in any way)

1 Like

So this project is addressing two goals: stabilizing rust's ABI, i.e. making it consistent across versions of the compiler (this does not mean static, however), and making rust's FFI modularizable, meaning one could drop in a swift binary and call it from rust, or compile a rust binary with a swift ABI, and call it from swift.

2 Likes

My view is that the second answer snippet, with which I agree, implies that the answer to the first snippet is: No, that is not the purpose of "a stable, modular ABI for Rust", which is the subject of this thread.

ABI interoperability with another language inherently restricts the ABI to concepts that are expressible in both languages. repr(C) already accomplishes that purpose for concepts expressible in C. repr(Swift) would accomplish the same for concepts that are mutually expressible in Rust and Swift.

But Rust has concepts (and constraints) that are not expressible in other languages. IMO a repr(Rust) ABI should be an intra-language ABI (i.e., Rust to Rust) that provides interoperability among Rust compilation units, even when those units were generated by different compiler versions/point-releases. There is no way today to annotate Rust code so that such cross-version interoperation is guaranteed at designated interfaces (except by using repr(C), thus dropping to the reduced subset of concepts expressible in C).

Another goal of this effort, IMO, is development of the in-language descriptive mechanisms needed to specify repr(Rust), such as assignment of enum variants to niches in a unified enum representation (e.g., Option). The expectation is that such descriptive mechanisms will also be usable to specify inter-language ABIs (i.e, Rust to non-Rust) such as repr(Swift). It is that latter potential that makes Rust a potential run-time bridging languages between binaries that use incompatible ABIs.

13 Likes

Yes, I think primarily the goal of this effort is to produce a way to create ABI plugins for Rust that can be swapped out. The specification for this modular ABI mechanism should be able to at least supply a stable Rust-to-Rust ABI and provide Rust-to-OtherLanguage ABIs.

1 Like

It seems we need some abstract ABI first, which could then be described via traits in suitable for the compiler manner. Later, such framework could be used to add support for other ABIs.

So we have following basic items: functions, types, traits, DSTs, pointers - everything else is a combination of above. At the time of writing we have: pointers with metadata, mangling scheme, which allows to export functions and types with concrete type parameters from rust modules.

So the only two things left are:

  • to invent an DST ABI, this allows to work with DSTs in stable way; I think this must be concrete, due to little to no design space for such a thing.
  • find out abstract VTable format. Probably a VTable trait which would be used to perform an operations on a VTable by rust; might be a DST.

All of these is supposed to work in tandem and produce a MVP of Stable Modular ABI.

2 Likes

We also need a methodology to describe niche encodings, including both multiple parallel niches and niches within niches. My belief is that the best test case for such a methodology is IEEE 754 floating point: if we can describe the niches that allow signed infinities, NANs, zeros, and subnormal numbers to be embedded in the basic floating point format, we will be able to handle multiple niches of both types that I listed above.

VTable trait sketch:

/// Trait for vtbl-objects
/// Reason doing `Id` as trait parameter is that we want to allow a vtable-type to be indexed by multiple types
/// unresolved: Should it be `unsafe` or not?
unsafe trait VTable<Id: Eq> {
    /// Get fn_ptr by id
    #[inline]
    fn ptr_by_key(&self,key: Id) -> Option<*const ()>;
}

Also, to support languages with multiple-dispatch or duck-typing, we want some conventions around the trait.

  • Do we want the Id parameter to follow newtype pattern? Or something more complicated? This could add more meaning in types used as Id.
  • Do we want a separate copy of this trait dedicated to duck-typed languages? E.g. something like VTableDuck trait?
/// *
unsafe trait VTableDuck {

    /// A type passed to a language runtime
    type Id;
    
    /// Get fn_ptr by id from a runtime.
    /// This is expected to be expensive.
    #[inline]
    fn ptr_by_key(&self,key: Self::Id) -> Option<*const ()>;
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.