Objective-C Interop Extensions
    Luna 
    luna at foxgirls.gay
       
    Sat Nov 16 22:29:36 UTC 2024
    
    
  
## Proposal
Currently DLang has, in some compilers, support for ObjectiveC 
types being declared. However, modern Objective-C code is 
strongly dependent on autorelease and auto release pools.
Without them Objective-C code leaks memory (see: 
https://developer.apple.com/documentation/quartzcore/cametallayer?language=objc).
To alleviate this, clang implements the concept of an 
`@autoreleasepool` block, this block frees all Objective-C 
classes which have called `autorelease`. In the case of Metal, 
for example, a lot of internal data uses autorelease calls.
The `@autoreleasepool` blocks in clang are implemented via 2 
helper functions declared in the objective-c runtime 
`libobjc.dylib` or the like in alternate runtime implementations.
```d
extern(C) extern void* objc_autoreleasePoolPush();
extern(C) extern void  objc_autoreleasePoolPop(void*);
```
My proposal is to add 2 new hooks to the D runtime emitted by the 
compiler as well as a new keyword, `autoreleasepool`. This 
keyword should be followed by a block.
The runtime hooks should have a default implementation which do 
nothing.
```d
void* _d_pool_enter() { return null; }
void  _d_pool_leave(void*) { }
```
Whenever an `autoreleasepool` block is encountered by the 
compiler, the following code should be emitted.
```d
// Note: __ctx_ptr is just a placeholder, the name of the 
variable should be unique.
void* __ctx_ptr = _d_pool_enter();
// Code goes here
_d_pool_leave(__ctx_ptr);
```
autorelease pools should additionally, on macOS, automatically be 
generated in the runtime entry point and wrap the user D main 
function, and threads created in D should also include pool enter 
and leave calls.
If the D compiler links to a library defining 
`objc_autoreleasePoolPush` and `objc_autoreleasePoolPop`, the D 
runtime hooks should link against those, instead.
## Why not use NSAutoreleasePool?
The `Foundation` library includes a class called 
NSAutoreleasePool, however i've found that if Objective-C's 
runtime is compiled with ARC (Automatic Reference Counting) 
support, then NSAutoreleasePool becomes no-op in some instances, 
which in turn causes memory leaks.
    
    
More information about the dip.ideas
mailing list