Skip to content

[ffigen] ObjC bindings auto-load their dylib - #3344

Merged
liamappelbe merged 23 commits into
mainfrom
ffigen_self_load
May 19, 2026
Merged

liamappelbe merged 23 commits into
mainfrom
ffigen_self_load

Conversation

@liamappelbe

@liamappelbe liamappelbe commented May 4, 2026 •

Copy link
Copy Markdown
Contributor

There's a bug in FFIgen where if a user only uses ObjC classes, protocols, and methods (no globals or static functions), and all of them are defined in a dylib (as opposed to built in classes which are baked into the exe), then the dylib probably won't be loaded. This is because classes and protocols are loaded using objc_getClass and objc_getProtocol, which are reflective.

To fix this, we can instead get the class pointer by loading the OBJC_CLASS_$_Foo global variable from the dylib. Protocols are supposed to have a similar global variable, but it seems to be stripped out in most cases. Luckily we already have a workaround for protocol tree shaking: we define a function in the generated .m file that returns a pointer to the protocol. So for protocols we can just invoke this function.

However, if the class/protocol is built in, then this approach will fail (those symbols won't exist in the dylib). So we still need to fallback to objc_getClass and objc_getProtocol if loading fails. Since failure to load the symbol throws an ArgumentError, we have to wrap the symbol loading in a lambda, and then in getClass we catch that error and then do the fallback. (maybe it would be better to have an untyped catch (e) {?)

Details:

  • The class and protocol global variables now get their own AST representation in FFIgen, ObjCClassGlobal and ObjCProtocolGlobal, rather than just using ObjCInternalGlobal.
  • Swift classes also have a OBJC_CLASS variable, but the class name gets prefixed with the module name, plus some minor name mangling.
  • Swift protocols don't need any special handling beyond ObjC protocols, but I added a test for swift protocols anyway. This slightly complicated the ffigen build hook because the swift test's .m file needs to be built in to the swift dylib.
  • A bunch of the native_objc_tests were using a work around where they call a dummy native function in the dylib to force it to load. That's no longer necessary.

Fixes #3338

@github-actions

github-actions Bot commented May 4, 2026 •

Copy link
Copy Markdown

PR Health

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
objective_c Breaking 9.3.0 9.4.0-wip 9.4.0-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

@github-actions github-actions Bot added the type-infra A repository infrastructure change or enhancement label May 6, 2026
@github-actions github-actions Bot removed the type-infra A repository infrastructure change or enhancement label May 13, 2026
@liamappelbe liamappelbe changed the title WIP [ffigen] Avoid objc_getClass and objc_getProtocol [ffigen] Bindings self-load dylib May 14, 2026
@liamappelbe liamappelbe changed the title [ffigen] Bindings self-load dylib [ffigen] ObjC bindings auto-load their dylib May 14, 2026
@liamappelbe
liamappelbe marked this pull request as ready for review May 14, 2026 05:50
@liamappelbe
liamappelbe requested a review from goderbauer May 14, 2026 05:50
@liamappelbe
liamappelbe merged commit fb727c6 into main May 19, 2026
46 checks passed
@liamappelbe
liamappelbe deleted the ffigen_self_load branch May 19, 2026 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ffigen] Auto-load native asset

2 participants