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.
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.
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.
// 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.