Objective-C Interop Extensions

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Sun Nov 17 07:52:42 UTC 2024


Me and Luna have talked a bit on Discord about this, and I've done quite 
a bit of reading.

With ARC (adding of retain/release automatically) we do not need release 
pool support. However while we might not need it, there is a lot of code 
out there that is not compiled with ARC which we will want to use.

This does place an importance on us adding reference counting that would 
be objective-c/COM aware.

Regarding code-gen, it is equivalent to a ``scope(exit)`` to perform the 
pool leaving.

```d
void main() @autorelease {

}
```

Is equivalent to:

```d
void main() {
     void* __generatedIdentifier1 = objc_autoreleasePoolPush();
     bool __generatedIdentifier2 = true;

     try {
     } catch (NSException e) {
         __generatedIdentifier2 = false;
         throw e;
     } finally {
         if (__generatedIdentifier2)
             objc_autoreleasePoolPop(__generatedIdentifier);
     }
}
```

The reason for the guard variable is that NSException effectively 
inherits from ``Error`` not ``Exception``. It is not meant to be caught. 
The lifetime of the auto release memory must outlive the catch.

Due to this exception behavior, this would be a valuable addition to our 
Objective-c support.

For the grammar:

```diff
ScopeStatement:
+   @autorelease BlockStatement

AtAttribute:
+   @autorelease
```

```d
void func() @autorelease {
	@autorelease {

	}
}
```

Mangling is unaffected by the attribute on the function.

https://clang.llvm.org/docs/AutomaticReferenceCounting.html

As for:

```d
void* _d_pool_enter() { return null; }
void  _d_pool_leave(void*) { }
```

I would suggest not doing it, it doesn't add anything.

Either its linked in on non-Apple platforms and then turned on by 
compiler switch, or it is not emitted.


More information about the dip.ideas mailing list