Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial implementation of a stable API #229

Merged
merged 64 commits into from
Jul 18, 2023
Merged

Add initial implementation of a stable API #229

merged 64 commits into from
Jul 18, 2023

Conversation

ianks
Copy link
Collaborator

@ianks ianks commented Jun 17, 2023

As part of #227, this PR implements a the basis for a stable ABI for Ruby on Rust. For companies that run ruby-head in production, ABI instability is a serious priority, since without having stability it's hard (if not impossible) to test out certain changes to Ruby.

This can be incredibly disruptive to both Ruby core, as well as Rust gem authors. The goal here is to always Just Work™️ with ruby-head, but without sacrificing performance on stable Ruby.

The core idea consists of two main parts.

1) C Macro + Inline Function Support

In Rust, we don't get access to the suite of Ruby C macros or inline functions in libruby. So we have to either:

  • a) implement them by hand (most performant, benefits from rustc inlining, etc)
  • b) compile some C glue code to call into (compatible with unstable Ruby ABI like ruby-head)
  • c) both

This PR makes it so rb-sys does both, so we get the best of both worlds. On known stable versions of Ruby, we use the hand-written Rust implementations of the Ruby macros. On ruby-head, we use the compiled C glue code.

2) Make internal Ruby data structures opaque

This PR also adds a new stable-abi feature for rb-sys, which will make the internal layout of various Ruby structs opaque (i.e. RString and RArray). With this feature enabled, it will become impossible for upstream crates to have ABI instability when using the opaque struct.

For now, this feature is off by default (with some deprecation warnings) to allow for adoption (with. In v1.0, it will be enabled by default.

@ianks ianks changed the title Introduce stable-abi feature Add initial implementation of a stable ABI Jun 18, 2023
@ianks ianks marked this pull request as ready for review June 20, 2023 01:07
@ianks ianks requested a review from matsadler June 20, 2023 01:08
@ianks
Copy link
Collaborator Author

ianks commented Jul 12, 2023

Alright, so after thinking on what @matsadler said, I've decided to make the compiled C fallback optional (behind a stable-abi-compiled-fallback feature flag or --cfg=rb_sys_use_stable_api_compiled_fallback). This makes it easy to toggle on when required without risking unintended slowdowns, etc.

With that all said and done, I think this is close to being good to go. Just testing out a few more things on some gems in prod.

@ianks ianks changed the title Add initial implementation of a stable ABI Add initial implementation of a stable API Jul 13, 2023
@ianks
Copy link
Collaborator Author

ianks commented Jul 18, 2023

The windows failures are unrelated, and will be fixed in #221. Going to go ahead and merge this.

To be clear, this PR adds an opt-in stable-api with the ability to support ruby-head. It adds zero dependencie - in fact, it removes one! Typically, users should interact with the macros that are backed by this stable API (i.e. RSTRING_PTR, etc).

❤️

@ianks ianks merged commit b689d75 into main Jul 18, 2023
56 of 61 checks passed
@ianks ianks deleted the stable-abi branch July 18, 2023 13:23
@ianks ianks restored the stable-abi branch July 18, 2023 13:23
ianks added a commit that referenced this pull request Aug 2, 2023
* main:
  Only rerun on RBCONFIG_ prefixed env vars
  Detect and set RUBY_HAVE_IO_BUFFER_H
  Add initial implementation of a stable API (#229)
  Update syn to 2.0 (#231)
  Add slack noti for build failure (#226)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants