Objective-C Interop Extensions
Luna
luna at foxgirls.gay
Sun Nov 17 00:19:25 UTC 2024
On Sunday, 17 November 2024 at 00:09:06 UTC, Luna wrote:
> On Saturday, 16 November 2024 at 22:47:09 UTC, Nicholas Wilson
> wrote:
>> On Saturday, 16 November 2024 at 22:29:36 UTC, Luna wrote:
>>> [...]
>>
>> This would be easy to do, synchronised works in pretty much
>> the exact same way, but why does this need to be a compiler
>> thing? i.e. what does it offer that
>>
>> ```d
>> struct AutoreleasePool
>> {
>> private void* __p;
>> static AutoreleasePool opCall()
>> {
>> AutoreleasePool ret;
>> ret.__p = objc_autoreleasePoolPush();
>> return ret;
>> }
>> ~this () { objc_autoreleasePoolPop(__p); }
>> }
>>
>> void main()
>> {
>> auto x = AutoreleasePool();
>> }
>> ```
>> does not?
>>
>> I think I saw some of your code that used a scope delegate as
>> `autorelease((){ ... });` why is that not sufficient?
>>
>> Given how niche this is, there had better be a very good
>> reason for adding it, e.g. generality with regular D code, not
>> just Obj-C.
>
> There's a few subtleties that would make this change in
> particular good to have on macOS at least. Given that, as said,
> threads and the runtime entry and exits needs to have implicit
> autoreleasepools to avoid potentially leaking both memory, but
> more importantly: kernel handles. A lot of functionality in
> macOS relies on getting shared memory handles that are wrapped
> in autorelease handlers; and without a pool to clean them up
> you can end up with a bunch of zombie handles exhausting the
> available handles in the system.
>
> Having this implicit and explicit control over autorelease
> behaviour would be a massive benefit and memory safety
> improvement when working on cross-platform software in D, as
> you can not avoid relying on Objective-C, eg. if you're making
> graphical applications.
I will add that the code I shared on the D Language Code Club
discord still leaks ~10 objects on exit (but no kernel handles)
due to a pool not being created before the objective-c runtime is
loaded. This however is serviceable, as the memory gets freed
anyway when the process exits.
However if you are opening file handles without an autorelease
pool you may end up leaking handles if you forget creating one.
Having that handled automatically would be of great benefit in
ensuring correct behaviour. However there's a single exception to
autorelease pools, and that's Objective-C exceptions. Those
implicitly free pool objects and don't need special handling,
from my understanding. As such pools should only be freed when
its scope exits *without any Objective-C exception being thrown*.
D exceptions don't trigger this behaviour though, so there might
need to be special handling for uncaught exceptions and errors.
More information about the dip.ideas
mailing list