Change-Id: I6e8bcfe8b8ad19726f5ccf9b64b3b45eec2d33ce Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120793 Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
2.9 KiB
FFI static checks
Translating FFI types
The FFI library defines a number of "native" types, which have corresponding
Dart types. This is a many-to-one mapping, defined by DartRepresentationOf in
native_type.dart.
Subtyping restrictions
No class may extend, implement or mixin any classes inside the FFI library, with
the following exception. Any class may extend (but not implement or mixin)
ffi.Struct. In this case, the subclass is considered a struct class. No
class may extend, implement or mixin a struct class.
Struct rules
The following restrictions apply to struct classes:
- A struct class must not be generic.
- A struct class
Xmust extendStruct<X>. That is, the type argument to the superclass must be exactly the subclass itself.
Some restrictions apply to fields of struct classes:
- A field of a struct class must not have an initializer.
- A field of a struct class must either have a type which is a subtype of
ffi.Pointeror else be annotated by one of the following types:ffi.UintNorffi.IntNfor any Nffi.Floatorffi.DoubleIf the field is annotated, the Dart version of the annotated type must be identical to the field's declared type. Note that struct classes currently must not be used as fields.
- A field of a struct class must not have more than one annotation corresponding to an FFI native type.
Finally, struct classes must not have constructors with field initializers.
fromFunction rules
The following restrictions apply to static invocations of the factory
constructor Pointer<T>.fromFunction(f, e). Dynamic invocations of this method,
e.g. through mirrors, are runtime errors. T must be a subtype of
NativeFunction<T'> for some T'. Let F be the Dart type which corresponds
to static type of T' and R be the return type of F.
Tmust be instantiated; i.e., it must not reference any class or function type parameters.- The static type of
fmust be a subtype ofF. - Struct classes are not allowed as the top-level class in a parameter or return
type of
F. - The static type of
emust be a subtype ofR. emust be an expression which is legal in a constant context.fmust be a direct reference to a top-level method.emust not be provided ifRisvoidorffi.Pointer.emust be provided otherwise.
asFunction and lookupFunction rules
The following restrictions apply to statically resolved invocations of the
instance method Pointer<T>.asFunction<F>() and
DynamicLibrary.lookupFunction<S, F>(). Dynamic invocations of these methods,
e.g. through mirrors or a receiver of static type dynamic, are runtime errors.
T must be a subtype of NativeFunction<T'> for some T'. Let F' be the
Dart type which corresponds to static type of T'/S.
T,SandFmust be constants; i.e., they must not reference any class or function type parameters.F'must be a subtype ofF.