-
Notifications
You must be signed in to change notification settings - Fork 120
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
objc_constructInstance and objc_destructInstance are unimplemented #121
Comments
These look like terrible APIs. Presumably it's the responsibility of the caller to ensure that there's enough space, but how does it know how much space the runtime will use? The GNUstep runtime will use the object size plus one word for the refcount. Is this used only for immutable non-releaseable classes? If so, we can implement that without a refcount (there's sufficient logic for that already). If they're embedded in other objects, presumably they don't get separate refcounts? |
Yes, this appears to be the case.
According to the documentation here (https://developer.apple.com/documentation/objectivec/1441663-objc_constructinstance?language=objc):
Swift only uses it with the SwiftValue class (the above source file), which is immutable and non-releaseable. I don't know of anywhere else where it may be used. |
Oh I missed one additional use, which is headlined with the comment
This seems to be part of the implementation of -dealloc. |
That last use appears to be very dangerous. A weak reference can be turned into a strong reference at any point. If one thread tries to dealloc the object and another tries to turn the weak ref into a strong ref, then there needs to be some synchronisation. Since |
Indeed, it looks like Swift does not have a concurrency model and encourages programmers to rely on OS abstractions for concurrency (see https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782). It looks like the last use was added to deal with associated objects set using objc_setAssociatedObject — see swiftlang/swift@0885c56 for the full commit where it was added and the associated test. Perhaps this is not the best way to clean it up and it would make more sense that this be improved Swift-side? |
e.g. using objc_removeAssociatedObjects instead. |
Possibly. There's still the question of what to do if you have a Swift object that wraps an Objective-C object and something takes a weak reference to it. Calling
I think that the way we could support this is probably:
I'm happy to take a PR that does this. I suspect that there's some more subtle interaction with Swift here though. How are Swift objects allocated? Do they use |
Additionally, should the retain / release mechanism for these objects actually manipulate the enclosing object? We could have a much simpler API along the lines of this: id objc_createEmbeddedInstance(id enclosingObject, Class cls, ptrdiff_t offset);
void objc_destroyEmbeddedInstance(id enclosingObject, ptrdiff_t offset); The first of these would create an Objective-C object that is physically embedded within |
The Apple runtime has the following methods for instantiating and destroying an instance of a class at an already-allocated memory location.
id objc_constructInstance(Class cls, void *bytes);
(This mirrorsclass_createinstance
)void * objc_destructInstance(id obj);
These are unimplemented in the GNUstep runtime and are used in Swift at the following locations:
https://github.com/apple/swift/blob/01823ca52138a9844e84ee7e8efba13970e1e25d/stdlib/public/runtime/SwiftValue.mm#L191
https://github.com/apple/swift/blob/01823ca52138a9844e84ee7e8efba13970e1e25d/stdlib/public/runtime/SwiftValue.mm#L285
The text was updated successfully, but these errors were encountered: