runtime/lib/ffi.cc
// Checks that a dart type correspond to a [NativeType].
// Because this is checked already in a kernel transformation, it does not throw
// an ArgumentException but a boolean which should be asserted.
//
// [Int8]                               -> [int]
// [Int16]                              -> [int]
// [Int32]                              -> [int]
// [Int64]                              -> [int]
// [Uint8]                              -> [int]
// [Uint16]                             -> [int]
// [Uint32]                             -> [int]
// [Uint64]                             -> [int]
// [IntPtr]                             -> [int]
// [Double]                             -> [double]
// [Float]                              -> [double]
// [Pointer]<T>                         -> [Pointer]<T>
// T extends [Struct]                   -> T
// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
//    where DartRepresentationOf(Tn) -> Sn
Checks that a dart type correspond to a [NativeType].
Because this is checked already in a kernel transformation, it does not throw
an ArgumentException but a boolean which should be asserted.


Checks that a dart type correspond to a [ NativeType ] . Because this is checked already in a kernel transformation it does not throw an ArgumentException but a boolean which should be asserted .
static bool DartAndCTypeCorrespond(const AbstractType& native_type,
                                   const AbstractType& dart_type,
                                   FfiVariance variance) {
  classid_t native_type_cid = native_type.type_class_id();
  if (RawObject::IsFfiTypeIntClassId(native_type_cid)) {
    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::IntType()),
                                 Heap::kNew);
  }
  if (RawObject::IsFfiTypeDoubleClassId(native_type_cid)) {
    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::Double()),
                                 Heap::kNew);
  }
  if (RawObject::IsFfiPointerClassId(native_type_cid)) {
    return (variance == FfiVariance::kCovariant &&
            dart_type.IsSubtypeOf(native_type, Heap::kNew)) ||
           (variance == FfiVariance::kContravariant &&
            native_type.IsSubtypeOf(dart_type, Heap::kNew)) ||
           dart_type.IsNullType();
  }
  if (RawObject::IsFfiTypeNativeFunctionClassId(native_type_cid)) {
    if (!dart_type.IsFunctionType()) {
      return false;
    }
    TypeArguments& nativefunction_type_args =
        TypeArguments::Handle(native_type.arguments());
    AbstractType& nativefunction_type_arg =
        AbstractType::Handle(nativefunction_type_args.TypeAt(0));
    if (!nativefunction_type_arg.IsFunctionType()) {
      return false;
    }
    Function& dart_function =
        Function::Handle((Type::Cast(dart_type)).signature());
    if (dart_function.NumTypeParameters() != 0 ||
        dart_function.HasOptionalPositionalParameters() ||
        dart_function.HasOptionalNamedParameters()) {
      return false;
    }
    Function& nativefunction_function =
        Function::Handle(((Type&)nativefunction_type_arg).signature());
    if (nativefunction_function.NumTypeParameters() != 0 ||
        nativefunction_function.HasOptionalPositionalParameters() ||
        nativefunction_function.HasOptionalNamedParameters()) {
      return false;
    }
    if (!(dart_function.NumParameters() ==
          nativefunction_function.NumParameters())) {
      return false;
    }
    if (!DartAndCTypeCorrespond(
            AbstractType::Handle(nativefunction_function.result_type()),
            AbstractType::Handle(dart_function.result_type()), variance)) {
      return false;
    }
    for (intptr_t i = 0; i < dart_function.NumParameters(); i++) {
      if (!DartAndCTypeCorrespond(
              AbstractType::Handle(nativefunction_function.ParameterTypeAt(i)),
              AbstractType::Handle(dart_function.ParameterTypeAt(i)),
              variance)) {
        return false;
      }
    }
  }
  return true;
}
static bool DartAndCTypeCorrespond ( const AbstractType & native_type , const AbstractType & dart_type , FfiVariance variance ) { classid_t native_type_cid = native_type . type_class_id ( ) ; if ( RawObject :: IsFfiTypeIntClassId ( native_type_cid ) ) { return dart_type . IsSubtypeOf ( AbstractType :: Handle ( Type :: IntType ( ) ) , Heap :: kNew ) ; } if ( RawObject :: IsFfiTypeDoubleClassId ( native_type_cid ) ) { return dart_type . IsSubtypeOf ( AbstractType :: Handle ( Type :: Double ( ) ) , Heap :: kNew ) ; } if ( RawObject :: IsFfiPointerClassId ( native_type_cid ) ) { return ( variance == FfiVariance :: kCovariant && dart_type . IsSubtypeOf ( native_type , Heap :: kNew ) ) || ( variance == FfiVariance :: kContravariant && native_type . IsSubtypeOf ( dart_type , Heap :: kNew ) ) || dart_type . IsNullType ( ) ; } if ( RawObject :: IsFfiTypeNativeFunctionClassId ( native_type_cid ) ) { if ( ! dart_type . IsFunctionType ( ) ) { return false ; } TypeArguments & nativefunction_type_args = TypeArguments :: Handle ( native_type . arguments ( ) ) ; AbstractType & nativefunction_type_arg = AbstractType :: Handle ( nativefunction_type_args . TypeAt ( 0 ) ) ; if ( ! nativefunction_type_arg . IsFunctionType ( ) ) { return false ; } Function & dart_function = Function :: Handle ( ( Type :: Cast ( dart_type ) ) . signature ( ) ) ; if ( dart_function . NumTypeParameters ( ) != 0 || dart_function . HasOptionalPositionalParameters ( ) || dart_function . HasOptionalNamedParameters ( ) ) { return false ; } Function & nativefunction_function = Function :: Handle ( ( ( Type & ) nativefunction_type_arg ) . signature ( ) ) ; if ( nativefunction_function . NumTypeParameters ( ) != 0 || nativefunction_function . HasOptionalPositionalParameters ( ) || nativefunction_function . HasOptionalNamedParameters ( ) ) { return false ; } if ( ! ( dart_function . NumParameters ( ) == nativefunction_function . NumParameters ( ) ) ) { return false ; } if ( ! DartAndCTypeCorrespond ( AbstractType :: Handle ( nativefunction_function . result_type ( ) ) , AbstractType :: Handle ( dart_function . result_type ( ) ) , variance ) ) { return false ; } for ( intptr_t i = 0 ; i < dart_function . NumParameters ( ) ; i ++ ) { if ( ! DartAndCTypeCorrespond ( AbstractType :: Handle ( nativefunction_function . ParameterTypeAt ( i ) ) , AbstractType :: Handle ( dart_function . ParameterTypeAt ( i ) ) , variance ) ) { return false ; } } } return true ; }
Checks that a dart type correspond to a [NativeType].
Checks that a dart type correspond to a [ NativeType ] .