-
-
Notifications
You must be signed in to change notification settings - Fork 9
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
Make selector!
macro zero-cost
#2
Comments
This uses the same approach as native selectors in Objective-C. Swift selectors are similar, and in this case would use `L_selector(class)` for the selector reference and `L_selector_data(class)` for the "class" string data. This is a step towards #2. However, this currently fails to compile when used externally. That is because a private symbols (required by linker for selector sections) cannot cross compilation units. This appears to be a bug in LLVM. See rust-lang/rust#53929 for current status.
A couple guesses as to why this fails (the first being the likely culprit, but I'd be curious to hear if you know otherwise):
|
For the same reason I would have expected difficulties using the |
In my fork of fn main() {
let s = || fruity::ns_string!("abc");
println!("{}", s());
} Linkers and dynamic linkers are very much opaque pieces of software to me, are there some resources you can recommend to get a better understanding of such details (I'm asking you because you seem very knowledgable in this area)? The writeup you provided is very cool, but sadly I feel I lack the necessary foundation to properly understand it. (Also, I've implemented a static selector macro that somewhat works (but is still very brittle), search for |
It's really neat to have the hunch confirmed, thank you for letting me know! Unfortunately I don't know of a good resource to point to for a '10,000 foot' view. For me, I look at and parse many binaries for work, so I've gotten familiar with the structure that way. I personally think that parsing binaries is probably the best way to gain familiarity, as you're 'forced' to understand all the pieces. I would just throw in: while they may be opaque to you now, there's absolutely no magic and it's all approachable. That said, everybody here is deep into Rust/Darwin land so that might go without saying =). If you're not already doing this, I would strongly recommend compiling a binary containing some simple structure (like the ObjC equivalent of the fruity example you gave above) with the first-party toolchain, then crack open the resulting binary with Hopper/IDA and click around to see how the internal Mach-O structures reference each other, and have a look at all the resulting Mach-O sections. Any time you're having a bug with your tooling, look at the diff in the resulting binaries. Learning the For work, I regularly make internal educational content describing various bits of esoterica. A couple months ago, I happened to make a ~10 minute video covering some conceptual introductions to dynamic linking, as well as the Lastly, I'm happy to answer other questions that you might have now or in the future! Feel free to ping in-thread or elsewhere. |
Currently, the
selector!
macro callsSel::register
, which in turn callssel_registerName
. This is inefficient compared to@selector
in Objective-C.On my machine, I measure:
This is relatively small compared to
objc_msgSend
. However, one of the goals of this crate is to be zero-cost compared to the same code written directly in Objective-C.Related issues:
I made an attempt in nvzqz/rust-selector-example, however it fails to build at link time. See that repo for details.
The culprit seems to be the
literal_pointers
link option. It builds fine with just__DATA,__objc_selrefs
, but I get "unrecognized selector" when trying to use the selector.The text was updated successfully, but these errors were encountered: