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