Follow up to #3209
Anywhere we're passing object.ref.pointer, we need to instead capture object.ref in a local variable, then pass objRef.pointer. Same goes for blocks. This is to work around a behaviour (a bug??) where the implicit local generated by that expression can be garbage collected while whatever native call we pass the pointer to is being executed.
For context, our ObjC Objects look like this (simplified for clarity):
class ObjCObject {
final ObjCObjectRef ref;
}
@pragma('vm:deeply-immutable')
final class ObjCObjectRef implements Finalizable {
final _FinalizablePointer _finalizable;
Pointer get pointer => _finalizable.ptr;
}
@pragma('vm:deeply-immutable')
final class _FinalizablePointer implements Finalizable {
final Pointer ptr;
}
Fix looks like this, in generated code:
+ final objcRef = object$.ref;
final $ret = _objc_msgSend_1sotr3r(
- object$.ref.retainAndReturnPointer(),
+ objRef.retainAndReturnPointer(),
_sel_initWithURL_,
url.ref.pointer,
);
#3307 cleans up the case that was causing the crash reported in the original bug, but this could theoretically happen in any FFIgen generated code.
Follow up to #3209
Anywhere we're passing
object.ref.pointer, we need to instead captureobject.refin a local variable, then passobjRef.pointer. Same goes for blocks. This is to work around a behaviour (a bug??) where the implicit local generated by that expression can be garbage collected while whatever native call we pass the pointer to is being executed.For context, our ObjC Objects look like this (simplified for clarity):
Fix looks like this, in generated code:
#3307 cleans up the case that was causing the crash reported in the original bug, but this could theoretically happen in any FFIgen generated code.