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