- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 267
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
Improve Objective-C support #4777
Conversation
Question: in this implementation I wish to add another UDA to Idea there is to implement support for binding Swift interop class stubs as well, which have unique behaviour that would require this new attribute. Essentially Swift may declare Objective-C classes in the This would allow interop with Swift code using bridging headers and wouldn't be too much extra work. Is it okay if I add that to this PR? |
Yes. |
this already works in opend so if you copy the impl it should work here too; that's how the final iphone demo from my blog worked, as well as simpledisplay's cocoa implementation, and to triple check i just did one more test:
and then the D
and all worked. of course, possible i missed some details that won't emerge until you get into more features, but still a lot already works in the opend world. |
BTW something i think would be kinda cool is a kind of import objective-c dstep can do a good amount of that already, and the objective c parts look easier to parse and interface with than regular import c so im p sure it doable with a week or two of work |
Yeah, I'm thinking of making an Objective-C code generator once I get the compiler support up and running. |
(once this is good to go) Could you please open a PR to DMD with all of the frontend/druntime changes? (Just stub out anything needs anything extra to work) |
Sure, will do. However I think I'll reduce the scope of this PR slightly to just be the core objective-c and Swift stub class support. Given that some existing Apple platforms don't align neatly with the code I was referencing I'm doing a pretty big refactor of the objective-c data struct generation to be compatible with all of the Apple sub architectures supported. |
cc @adamdruppe once I finish this PR you may want to back integrate it into OpenD's LDC fork. Your current implementation is broken on quite a few platforms and in some cases may crash the Xcode linker |
plz write up some notes as you go, as it might also apply back to dmd's separate implementation (and the abi spec on the website) as well. depends on if it was just me bugging it up or if the original was wrong too. much of it came from reverse engineering the output on a x86 Mac so no surprise they'd be some differences (one we all found early is the arm objc_msgSend is slightly different on arm), then i just sucked at ldc code so prolly a lot of impl bugs too lol. |
Yeah my recommendation there is to look at the actual objective-c runtime source. The data structures relevant are listed there https://github.com/apple-oss-distributions/objc4 as well as the Swift interop documentation. I'm adding the finishing touches to this PR tonight, and will mark it as ready to merge then. |
I'll reread the whole thing when I get another chunk of time free, idk if it'll be today or tomorrow, but I'll let you know when I do. My biggest concern is just if it works and that last test I did with it passing was a good sign! |
@kinke anything left to solve? All the tests succeed (minus the ones that are either broken for unrelated reasons and the ones where you've run out of compute credits) |
Also it seems my refactor somehow fixed all the random asserts that was happening. |
I think that's everything? |
Yeah that's it from my side at least, thanks. :) |
This is super valuable work! Thanks |
Is it possible that this could be merged for the next release or is there further things I need to sort out? I'm slightly burnt out after staring at aarch64 disassembly for 50+ hours the past few days @thewilsonator @kinke @jacob-carlborg |
I think we can have this in v1.40 final, which I wanna release in December, regardless whether DMD v2.110 is finalized or not by then. In that regard, feel free to add a changelog entry in |
Okay, done! |
} | ||
|
||
/// Returns: the number of times `cd` has been declared as optional. | ||
private int declaredAsSwiftStubCount(ClassDeclaration cd, Scope* sc) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this exactly the same as declaredAsOptionalCount
, it just takes a different kind of declaration? Can't that be reused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly but I don't know my way around this codebase very well. Takes a long time to figure out how anything works. Also the Swift stub UDA only applies to classes, as it affects how the isa pointer/classref is dereferenced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, isn't declaredAsOptionalCount
what you copy-pasted? Seems very likely, especially since the documentation is now wrong, it says: as optional
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I copied it and modified it as needed since I didn't see an obvious way of checking for UDAs otherwise.
I'll look into making it a reusable function after I get some rest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you can replace ClassDeclaration
with Dsymbol
for the cd
parameter, given it a more generic name, like "countUdas" and pass in the UDA identifier as an additional argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, something like that
if (linkNoObjc) | ||
return; | ||
|
||
args.push_back("-lobjc"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different behavior compared to DMD.
// Dynamic casting in Objective-C works differently from D. | ||
// We call objc_opt_isKindOfClass to get a bool defining | ||
// whether the cast is valid, if it is then we go ahead. | ||
if (DtoIsObjcLinkage(_to)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a test for this. This is not implemented in upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm avoiding writing my own tests, would prefer is someone else picks that up. I simply don't know this testing system very well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's pretty straightforward. Just add a new file here https://github.com/ldc-developers/ldc/tree/master/tests/dmd/runnable and it will be picked up automatically. You can take a look at one of the existing Objective-C tests, like this one: https://github.com/ldc-developers/ldc/blob/master/tests/dmd/runnable/objc_call.d.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll let someone else decide if the tests are necessary or not.
Landing this eagerly for upcoming beta5. Thx all! |
Very nice, thanks @LunaTheFoxgirl! That will lower the bar for macOS/iOS development considerably. It's a shame that the money from the bounty has been lost by now. |
It is what it is. I've already begun working on dub packages to cover API bindings to Apple APIs, which should lower the barrier further. That being said, I'm doing it by hand to make sure all of the API has appropriate ddoc documentation as well. |
This pull-request aims to improve the Objective-C support of LDC. This PR additionally changes the Objective-C generation system to only support the Objective-C 2.0 ABI, as very little documentation of older ABIs have survived.
A good chunk of this code is more or less taken from the OpenD implementation, but I'm already working on cleaning parts up as I go. I am looking into how feasible it'll be to make extern(Objective-C) classes export neccesary ABI for Objective-C code to be able to call it as well, which mainly involves metadata generation.
TODO List:
@swift
keyword)