Description
Summary
Disallow invoking Dart_NewWeakPersistentHandle
and Dart_NewFinalizableHandle
in dart_api.h
with object
without identity.
This is already already true for integers, true
, and false
, but we'd like to extend it to dart:ffi
's Pointer
, and subtypes of dart:ffi
's Struct
.
We also disallow using Pointer
, and subtypes of dart:ffi
's Struct
in Expando
s, similar to how numbers, booleans, and null
are disallowed.
sdk/runtime/include/dart_api.h
Lines 460 to 494 in 8f0d5ef
sdk/runtime/include/dart_api.h
Lines 512 to 550 in 8f0d5ef
Motivation
- We want to be able to optimize
Pointer
and subtypes ofStruct
away completely at runtime. - We want to prevent use after free issues with the GC running finalizers on these objects when derived pointers or the pointer's addresses are still in use. (Example in [vm/ffi] Disallow adding finalizers to Pointer #45071.)
Impact
We're not aware of any uses of finalizers on Pointer
s or structs. (If there are any, they might already suffer from use-after-free bugs due to premature finalization.)
Migration
void myCode() {
Pointer<Database> pointer = // ...
// Pass `pointer` to native code with `dart:ffi` and call `Dart_NewFInalizableHandle` to attach finalizer.
use(pointer);
}
becomes
class DatabaseResource implements NativeResource {
final Pointer<Database> _database;
DatabaseResource(this._database) {
// Pass `this` and `_database` to native code with `dart:ffi` and call `Dart_NewFInalizableHandle`
// with `this` as parameter to `object` and `_database` as `peer`.
}
void use();
}
void myCode() {
DatabaseResource database;
database.use();
}
https://dart-review.googlesource.com/c/sdk/+/143804
Future work
Ensuring that classes implementing this this NativeResource
/WeakHandleable
interface are kept alive on all method calls is future work (design discussion).