// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This file contains logic which is shared between the ffi_definition and
// ffi_use_site transformers.

library vm.transformations.ffi;

import 'package:front_end/src/api_unstable/vm.dart'
    show
        messageFfiLeafCallMustNotReturnHandle,
        messageFfiLeafCallMustNotTakeHandle,
        templateFfiTypeInvalid,
        messageFfiCallbackMustNotUseTypedData,
        messageFfiCallMustNotReturnTypedData,
        messageFfiNonLeafCallMustNotTakeTypedData,
        templateFfiTypeMismatch;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart';
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/reference_from_index.dart';
import 'package:kernel/target/targets.dart' show DiagnosticReporter;
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:kernel/type_environment.dart'
    show TypeEnvironment, SubtypeCheckMode;
import 'package:kernel/util/graph.dart' as kernelGraph;

import 'abi.dart';
import 'native_type_cfe.dart';

/// Represents the (instantiated) ffi.NativeType.
enum NativeType {
  kNativeType,
  kNativeInteger,
  kNativeDouble,
  kPointer,
  kNativeFunction,
  kInt8,
  kInt16,
  kInt32,
  kInt64,
  kUint8,
  kUint16,
  kUint32,
  kUint64,
  kFloat,
  kDouble,
  kVoid,
  kOpaque,
  kStruct,
  kHandle,
  kBool,
}

const Set<NativeType> nativeIntTypesFixedSize = <NativeType>{
  NativeType.kInt8,
  NativeType.kInt16,
  NativeType.kInt32,
  NativeType.kInt64,
  NativeType.kUint8,
  NativeType.kUint16,
  NativeType.kUint32,
  NativeType.kUint64,
};

/// The [NativeType] class names.
const Map<NativeType, String> nativeTypeClassNames = <NativeType, String>{
  NativeType.kNativeType: 'NativeType',
  NativeType.kNativeInteger: '_NativeInteger',
  NativeType.kNativeDouble: '_NativeDouble',
  NativeType.kPointer: 'Pointer',
  NativeType.kNativeFunction: 'NativeFunction',
  NativeType.kInt8: 'Int8',
  NativeType.kInt16: 'Int16',
  NativeType.kInt32: 'Int32',
  NativeType.kInt64: 'Int64',
  NativeType.kUint8: 'Uint8',
  NativeType.kUint16: 'Uint16',
  NativeType.kUint32: 'Uint32',
  NativeType.kUint64: 'Uint64',
  NativeType.kFloat: 'Float',
  NativeType.kDouble: 'Double',
  NativeType.kVoid: 'Void',
  NativeType.kOpaque: 'Opaque',
  NativeType.kStruct: 'Struct',
  NativeType.kHandle: 'Handle',
  NativeType.kBool: 'Bool',
};

const int UNKNOWN = 0;
const int WORD_SIZE = -1;

/// The [NativeType] sizes in bytes.
const Map<NativeType, int> nativeTypeSizes = <NativeType, int>{
  NativeType.kNativeType: UNKNOWN,
  NativeType.kNativeInteger: UNKNOWN,
  NativeType.kNativeDouble: UNKNOWN,
  NativeType.kPointer: WORD_SIZE,
  NativeType.kNativeFunction: UNKNOWN,
  NativeType.kInt8: 1,
  NativeType.kInt16: 2,
  NativeType.kInt32: 4,
  NativeType.kInt64: 8,
  NativeType.kUint8: 1,
  NativeType.kUint16: 2,
  NativeType.kUint32: 4,
  NativeType.kUint64: 8,
  NativeType.kFloat: 4,
  NativeType.kDouble: 8,
  NativeType.kVoid: UNKNOWN,
  NativeType.kOpaque: UNKNOWN,
  NativeType.kStruct: UNKNOWN,
  NativeType.kHandle: WORD_SIZE,
  NativeType.kBool: 1,
};

/// Load and store are rewired to their static type for these types.
const List<NativeType> optimizedTypes = [
  NativeType.kBool,
  NativeType.kInt8,
  NativeType.kInt16,
  NativeType.kInt32,
  NativeType.kInt64,
  NativeType.kUint8,
  NativeType.kUint16,
  NativeType.kUint32,
  NativeType.kUint64,
  NativeType.kFloat,
  NativeType.kDouble,
  NativeType.kPointer,
];

const List<NativeType> unalignedLoadsStores = [
  NativeType.kFloat,
  NativeType.kDouble,
];

/// [FfiTransformer] contains logic which is shared between
/// _FfiUseSiteTransformer and _FfiDefinitionTransformer.
class FfiTransformer extends Transformer {
  final TypeEnvironment env;
  final CoreTypes coreTypes;
  final LibraryIndex index;
  final ClassHierarchy hierarchy;
  final DiagnosticReporter diagnosticReporter;
  final ReferenceFromIndex? referenceFromIndex;

  final Class objectClass;
  final Class intClass;
  final Class doubleClass;
  final Class boolClass;
  final Class listClass;
  final Class typeClass;
  final Procedure unsafeCastMethod;
  final Procedure nativeEffectMethod;
  final Class typedDataClass;
  final Procedure typedDataBufferGetter;
  final Procedure typedDataOffsetInBytesGetter;
  final Procedure byteBufferAsUint8List;
  final Procedure uint8ListFactory;
  final Class pragmaClass;
  final Field pragmaName;
  final Field pragmaOptions;
  final Procedure listElementAt;
  final Procedure numAddition;
  final Procedure numMultiplication;
  final Procedure objectEquals;
  final Procedure stateErrorThrowNewFunction;

  final Library ffiLibrary;
  final Class allocatorClass;
  final Class nativeFunctionClass;
  final Class handleClass;
  final Class opaqueClass;
  final Class arrayClass;
  final Class arraySizeClass;
  final Field arraySizeDimension1Field;
  final Field arraySizeDimension2Field;
  final Field arraySizeDimension3Field;
  final Field arraySizeDimension4Field;
  final Field arraySizeDimension5Field;
  final Field arraySizeDimensionsField;
  final Class pointerClass;
  final Class compoundClass;
  final Class structClass;
  final Class unionClass;
  final Class abiSpecificIntegerClass;
  final Class abiSpecificIntegerMappingClass;
  final Class varArgsClass;
  final Class nativeFieldWrapperClass1Class;
  final Class ffiStructLayoutClass;
  final Field ffiStructLayoutTypesField;
  final Field ffiStructLayoutPackingField;
  final Class ffiAbiSpecificMappingClass;
  final Field ffiAbiSpecificMappingNativeTypesField;
  final Class ffiInlineArrayClass;
  final Field ffiInlineArrayElementTypeField;
  final Field ffiInlineArrayLengthField;
  final Class packedClass;
  final Field packedMemberAlignmentField;
  final Procedure allocateMethod;
  final Procedure allocatorAllocateMethod;
  final Procedure castMethod;
  final Procedure offsetByMethod;
  final Procedure addressGetter;
  final Procedure structPointerGetRef;
  final Procedure structPointerSetRef;
  final Procedure structPointerGetElemAt;
  final Procedure structPointerSetElemAt;
  final Procedure structPointerElementAt;
  final Procedure structPointerPlusOperator;
  final Procedure structPointerMinusOperator;
  final Procedure structPointerElementAtTearoff;
  final Procedure unionPointerGetRef;
  final Procedure unionPointerSetRef;
  final Procedure unionPointerGetElemAt;
  final Procedure unionPointerSetElemAt;
  final Procedure unionPointerElementAt;
  final Procedure unionPointerPlusOperator;
  final Procedure unionPointerMinusOperator;
  final Procedure unionPointerElementAtTearoff;
  final Procedure structArrayElemAt;
  final Procedure unionArrayElemAt;
  final Procedure arrayArrayElemAt;
  final Procedure arrayArrayAssignAt;
  final Procedure abiSpecificIntegerPointerGetValue;
  final Procedure abiSpecificIntegerPointerSetValue;
  final Procedure abiSpecificIntegerPointerElemAt;
  final Procedure abiSpecificIntegerPointerSetElemAt;
  final Procedure abiSpecificIntegerPointerElementAt;
  final Procedure abiSpecificIntegerPointerPlusOperator;
  final Procedure abiSpecificIntegerPointerMinusOperator;
  final Procedure abiSpecificIntegerPointerElementAtTearoff;
  final Procedure abiSpecificIntegerArrayElemAt;
  final Procedure abiSpecificIntegerArraySetElemAt;
  final Procedure asFunctionMethod;
  final Procedure asFunctionInternal;
  final Procedure sizeOfMethod;
  final Procedure lookupFunctionMethod;
  final Procedure fromFunctionMethod;
  final Field compoundTypedDataBaseField;
  final Field arrayTypedDataBaseField;
  final Field arraySizeField;
  final Field arrayNestedDimensionsField;
  final Procedure arrayCheckIndex;
  final Procedure arrayNestedDimensionsFlattened;
  final Procedure arrayNestedDimensionsFirst;
  final Procedure arrayNestedDimensionsRest;
  final Constructor structFromTypedDataBase;
  final Constructor unionFromTypedDataBase;
  final Constructor arrayConstructor;
  final Procedure fromAddressInternal;
  final Procedure libraryLookupMethod;
  final Procedure abiMethod;
  final Procedure createNativeCallableListenerProcedure;
  final Procedure nativeCallbackFunctionProcedure;
  final Procedure nativeAsyncCallbackFunctionProcedure;
  final Procedure createNativeCallableIsolateLocalProcedure;
  final Procedure nativeIsolateLocalCallbackFunctionProcedure;
  final Map<NativeType, Procedure> loadMethods;
  final Map<NativeType, Procedure> loadUnalignedMethods;
  final Map<NativeType, Procedure> storeMethods;
  final Map<NativeType, Procedure> storeUnalignedMethods;
  final Procedure loadAbiSpecificIntMethod;
  final Procedure loadAbiSpecificIntAtIndexMethod;
  final Procedure storeAbiSpecificIntMethod;
  final Procedure storeAbiSpecificIntAtIndexMethod;
  final Procedure abiCurrentMethod;
  final Map<Constant, Abi> constantAbis;
  final Class intptrClass;
  late AbiSpecificNativeTypeCfe intptrNativeTypeCfe;
  final Procedure memCopy;
  final Procedure allocationTearoff;
  final Procedure asFunctionTearoff;
  final Procedure lookupFunctionTearoff;
  final Procedure getNativeFieldFunction;
  final Class finalizableClass;
  final Procedure reachabilityFenceFunction;
  final Procedure checkAbiSpecificIntegerMappingFunction;
  final Class rawRecvPortClass;
  final Class nativeCallableClass;
  final Procedure nativeCallableIsolateLocalConstructor;
  final Constructor nativeCallablePrivateIsolateLocalConstructor;
  final Procedure nativeCallableListenerConstructor;
  final Constructor nativeCallablePrivateListenerConstructor;
  final Field nativeCallablePortField;
  final Field nativeCallablePointerField;
  final Procedure nativeAddressOf;
  final Procedure nativePrivateAddressOf;

  late final InterfaceType nativeFieldWrapperClass1Type;
  late final InterfaceType voidType;
  late final InterfaceType pointerVoidType;
  // The instantiated to bounds type argument for the Pointer class.
  late final InterfaceType nativeTypeType;
  // The Pointer type when instantiated to bounds.
  late final InterfaceType pointerNativeTypeType;

  /// Classes corresponding to [NativeType], indexed by [NativeType].
  final Map<NativeType, Class> nativeTypesClasses;
  final Map<Class, NativeType> classNativeTypes;

  /// Typed data classes.
  final Map<NativeType, Class> nativeTypesTypedDataClasses;

  Library? _currentLibrary;
  Library get currentLibrary => _currentLibrary!;

  IndexedLibrary? currentLibraryIndex;

  FfiTransformer(this.index, this.coreTypes, this.hierarchy,
      this.diagnosticReporter, this.referenceFromIndex)
      : env = TypeEnvironment(coreTypes, hierarchy),
        objectClass = coreTypes.objectClass,
        intClass = coreTypes.intClass,
        doubleClass = coreTypes.doubleClass,
        boolClass = coreTypes.boolClass,
        listClass = coreTypes.listClass,
        typeClass = coreTypes.typeClass,
        unsafeCastMethod =
            index.getTopLevelProcedure('dart:_internal', 'unsafeCast'),
        nativeEffectMethod =
            index.getTopLevelProcedure('dart:_internal', '_nativeEffect'),
        typedDataClass = index.getClass('dart:typed_data', 'TypedData'),
        typedDataBufferGetter =
            index.getProcedure('dart:typed_data', 'TypedData', 'get:buffer'),
        typedDataOffsetInBytesGetter = index.getProcedure(
            'dart:typed_data', 'TypedData', 'get:offsetInBytes'),
        byteBufferAsUint8List =
            index.getProcedure('dart:typed_data', 'ByteBuffer', 'asUint8List'),
        uint8ListFactory =
            index.getProcedure('dart:typed_data', 'Uint8List', ''),
        pragmaClass = coreTypes.pragmaClass,
        pragmaName = coreTypes.pragmaName,
        pragmaOptions = coreTypes.pragmaOptions,
        listElementAt = coreTypes.index.getProcedure('dart:core', 'List', '[]'),
        numAddition = coreTypes.index.getProcedure('dart:core', 'num', '+'),
        numMultiplication =
            coreTypes.index.getProcedure('dart:core', 'num', '*'),
        objectEquals =
            coreTypes.index.getProcedure('dart:core', 'Object', '=='),
        stateErrorThrowNewFunction = coreTypes.index
            .getProcedure('dart:core', 'StateError', '_throwNew'),
        ffiLibrary = index.getLibrary('dart:ffi'),
        allocatorClass = index.getClass('dart:ffi', 'Allocator'),
        nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
        handleClass = index.getClass('dart:ffi', 'Handle'),
        opaqueClass = index.getClass('dart:ffi', 'Opaque'),
        arrayClass = index.getClass('dart:ffi', 'Array'),
        arraySizeClass = index.getClass('dart:ffi', '_ArraySize'),
        arraySizeDimension1Field =
            index.getField('dart:ffi', '_ArraySize', 'dimension1'),
        arraySizeDimension2Field =
            index.getField('dart:ffi', '_ArraySize', 'dimension2'),
        arraySizeDimension3Field =
            index.getField('dart:ffi', '_ArraySize', 'dimension3'),
        arraySizeDimension4Field =
            index.getField('dart:ffi', '_ArraySize', 'dimension4'),
        arraySizeDimension5Field =
            index.getField('dart:ffi', '_ArraySize', 'dimension5'),
        arraySizeDimensionsField =
            index.getField('dart:ffi', '_ArraySize', 'dimensions'),
        pointerClass = index.getClass('dart:ffi', 'Pointer'),
        compoundClass = index.getClass('dart:ffi', '_Compound'),
        structClass = index.getClass('dart:ffi', 'Struct'),
        unionClass = index.getClass('dart:ffi', 'Union'),
        abiSpecificIntegerClass =
            index.getClass('dart:ffi', 'AbiSpecificInteger'),
        abiSpecificIntegerMappingClass =
            index.getClass('dart:ffi', 'AbiSpecificIntegerMapping'),
        varArgsClass = index.getClass('dart:ffi', 'VarArgs'),
        nativeFieldWrapperClass1Class =
            index.getClass('dart:nativewrappers', 'NativeFieldWrapperClass1'),
        ffiStructLayoutClass = index.getClass('dart:ffi', '_FfiStructLayout'),
        ffiStructLayoutTypesField =
            index.getField('dart:ffi', '_FfiStructLayout', 'fieldTypes'),
        ffiStructLayoutPackingField =
            index.getField('dart:ffi', '_FfiStructLayout', 'packing'),
        ffiAbiSpecificMappingClass =
            index.getClass('dart:ffi', '_FfiAbiSpecificMapping'),
        ffiAbiSpecificMappingNativeTypesField =
            index.getField('dart:ffi', '_FfiAbiSpecificMapping', 'nativeTypes'),
        ffiInlineArrayClass = index.getClass('dart:ffi', '_FfiInlineArray'),
        ffiInlineArrayElementTypeField =
            index.getField('dart:ffi', '_FfiInlineArray', 'elementType'),
        ffiInlineArrayLengthField =
            index.getField('dart:ffi', '_FfiInlineArray', 'length'),
        packedClass = index.getClass('dart:ffi', 'Packed'),
        packedMemberAlignmentField =
            index.getField('dart:ffi', 'Packed', 'memberAlignment'),
        allocateMethod =
            index.getProcedure('dart:ffi', 'AllocatorAlloc', 'call'),
        allocatorAllocateMethod =
            index.getProcedure('dart:ffi', 'Allocator', 'allocate'),
        castMethod = index.getProcedure('dart:ffi', 'Pointer', 'cast'),
        offsetByMethod = index.getProcedure('dart:ffi', 'Pointer', '_offsetBy'),
        addressGetter =
            index.getProcedure('dart:ffi', 'Pointer', 'get:address'),
        compoundTypedDataBaseField =
            index.getField('dart:ffi', '_Compound', '_typedDataBase'),
        arrayTypedDataBaseField =
            index.getField('dart:ffi', 'Array', '_typedDataBase'),
        arraySizeField = index.getField('dart:ffi', 'Array', '_size'),
        arrayNestedDimensionsField =
            index.getField('dart:ffi', 'Array', '_nestedDimensions'),
        arrayCheckIndex =
            index.getProcedure('dart:ffi', 'Array', '_checkIndex'),
        arrayNestedDimensionsFlattened = index.getProcedure(
            'dart:ffi', 'Array', 'get:_nestedDimensionsFlattened'),
        arrayNestedDimensionsFirst = index.getProcedure(
            'dart:ffi', 'Array', 'get:_nestedDimensionsFirst'),
        arrayNestedDimensionsRest = index.getProcedure(
            'dart:ffi', 'Array', 'get:_nestedDimensionsRest'),
        structFromTypedDataBase =
            index.getConstructor('dart:ffi', 'Struct', '_fromTypedDataBase'),
        unionFromTypedDataBase =
            index.getConstructor('dart:ffi', 'Union', '_fromTypedDataBase'),
        arrayConstructor = index.getConstructor('dart:ffi', 'Array', '_'),
        fromAddressInternal =
            index.getTopLevelProcedure('dart:ffi', '_fromAddress'),
        structPointerGetRef =
            index.getProcedure('dart:ffi', 'StructPointer', 'get:ref'),
        structPointerSetRef =
            index.getProcedure('dart:ffi', 'StructPointer', 'set:ref'),
        structPointerGetElemAt =
            index.getProcedure('dart:ffi', 'StructPointer', '[]'),
        structPointerSetElemAt =
            index.getProcedure('dart:ffi', 'StructPointer', '[]='),
        structPointerElementAt =
            index.getProcedure('dart:ffi', 'StructPointer', 'elementAt'),
        structPointerPlusOperator =
            index.getProcedure('dart:ffi', 'StructPointer', '+'),
        structPointerMinusOperator =
            index.getProcedure('dart:ffi', 'StructPointer', '-'),
        structPointerElementAtTearoff = index.getProcedure('dart:ffi',
            'StructPointer', LibraryIndex.tearoffPrefix + 'elementAt'),
        unionPointerGetRef =
            index.getProcedure('dart:ffi', 'UnionPointer', 'get:ref'),
        unionPointerSetRef =
            index.getProcedure('dart:ffi', 'UnionPointer', 'set:ref'),
        unionPointerGetElemAt =
            index.getProcedure('dart:ffi', 'UnionPointer', '[]'),
        unionPointerSetElemAt =
            index.getProcedure('dart:ffi', 'UnionPointer', '[]='),
        unionPointerElementAt =
            index.getProcedure('dart:ffi', 'UnionPointer', 'elementAt'),
        unionPointerPlusOperator =
            index.getProcedure('dart:ffi', 'UnionPointer', '+'),
        unionPointerMinusOperator =
            index.getProcedure('dart:ffi', 'UnionPointer', '-'),
        unionPointerElementAtTearoff = index.getProcedure('dart:ffi',
            'UnionPointer', LibraryIndex.tearoffPrefix + 'elementAt'),
        structArrayElemAt = index.getProcedure('dart:ffi', 'StructArray', '[]'),
        unionArrayElemAt = index.getProcedure('dart:ffi', 'UnionArray', '[]'),
        arrayArrayElemAt = index.getProcedure('dart:ffi', 'ArrayArray', '[]'),
        arrayArrayAssignAt =
            index.getProcedure('dart:ffi', 'ArrayArray', '[]='),
        abiSpecificIntegerPointerGetValue = index.getProcedure(
            'dart:ffi', 'AbiSpecificIntegerPointer', 'get:value'),
        abiSpecificIntegerPointerSetValue = index.getProcedure(
            'dart:ffi', 'AbiSpecificIntegerPointer', 'set:value'),
        abiSpecificIntegerPointerElemAt =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '[]'),
        abiSpecificIntegerPointerSetElemAt =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '[]='),
        abiSpecificIntegerPointerElementAt = index.getProcedure(
            'dart:ffi', 'AbiSpecificIntegerPointer', 'elementAt'),
        abiSpecificIntegerPointerPlusOperator =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '+'),
        abiSpecificIntegerPointerMinusOperator =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '-'),
        abiSpecificIntegerPointerElementAtTearoff = index.getProcedure(
            'dart:ffi',
            'AbiSpecificIntegerPointer',
            LibraryIndex.tearoffPrefix + 'elementAt'),
        abiSpecificIntegerArrayElemAt =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerArray', '[]'),
        abiSpecificIntegerArraySetElemAt =
            index.getProcedure('dart:ffi', 'AbiSpecificIntegerArray', '[]='),
        asFunctionMethod = index.getProcedure(
            'dart:ffi', 'NativeFunctionPointer', 'asFunction'),
        asFunctionInternal =
            index.getTopLevelProcedure('dart:ffi', '_asFunctionInternal'),
        sizeOfMethod = index.getTopLevelProcedure('dart:ffi', 'sizeOf'),
        lookupFunctionMethod = index.getProcedure(
            'dart:ffi', 'DynamicLibraryExtension', 'lookupFunction'),
        fromFunctionMethod =
            index.getProcedure('dart:ffi', 'Pointer', 'fromFunction'),
        libraryLookupMethod =
            index.getProcedure('dart:ffi', 'DynamicLibrary', 'lookup'),
        abiMethod = index.getTopLevelProcedure('dart:ffi', '_abi'),
        createNativeCallableListenerProcedure = index.getTopLevelProcedure(
            'dart:ffi', '_createNativeCallableListener'),
        createNativeCallableIsolateLocalProcedure = index.getTopLevelProcedure(
            'dart:ffi', '_createNativeCallableIsolateLocal'),
        nativeCallbackFunctionProcedure =
            index.getTopLevelProcedure('dart:ffi', '_nativeCallbackFunction'),
        nativeAsyncCallbackFunctionProcedure = index.getTopLevelProcedure(
            'dart:ffi', '_nativeAsyncCallbackFunction'),
        nativeIsolateLocalCallbackFunctionProcedure =
            index.getTopLevelProcedure(
                'dart:ffi', '_nativeIsolateLocalCallbackFunction'),
        nativeTypesClasses = nativeTypeClassNames.map((nativeType, name) =>
            MapEntry(nativeType, index.getClass('dart:ffi', name))),
        classNativeTypes = nativeTypeClassNames.map((nativeType, name) =>
            MapEntry(index.getClass('dart:ffi', name), nativeType)),
        nativeTypesTypedDataClasses = {
          for (final nativeType in nativeIntTypesFixedSize)
            nativeType: index.getClass(
              'dart:typed_data',
              '${nativeTypeClassNames[nativeType]}List',
            ),
          NativeType.kFloat: index.getClass(
            'dart:typed_data',
            'Float32List',
          ),
          NativeType.kDouble: index.getClass(
            'dart:typed_data',
            'Float64List',
          ),
        },
        loadMethods = Map.fromIterable(optimizedTypes, value: (t) {
          final name = nativeTypeClassNames[t];
          return index.getTopLevelProcedure('dart:ffi', "_load$name");
        }),
        loadUnalignedMethods =
            Map.fromIterable(unalignedLoadsStores, value: (t) {
          final name = nativeTypeClassNames[t];
          return index.getTopLevelProcedure(
              'dart:ffi', "_load${name}Unaligned");
        }),
        storeMethods = Map.fromIterable(optimizedTypes, value: (t) {
          final name = nativeTypeClassNames[t];
          return index.getTopLevelProcedure('dart:ffi', "_store$name");
        }),
        storeUnalignedMethods =
            Map.fromIterable(unalignedLoadsStores, value: (t) {
          final name = nativeTypeClassNames[t];
          return index.getTopLevelProcedure(
              'dart:ffi', "_store${name}Unaligned");
        }),
        loadAbiSpecificIntMethod =
            index.getTopLevelProcedure('dart:ffi', "_loadAbiSpecificInt"),
        loadAbiSpecificIntAtIndexMethod = index.getTopLevelProcedure(
            'dart:ffi', "_loadAbiSpecificIntAtIndex"),
        storeAbiSpecificIntMethod =
            index.getTopLevelProcedure('dart:ffi', "_storeAbiSpecificInt"),
        storeAbiSpecificIntAtIndexMethod = index.getTopLevelProcedure(
            'dart:ffi', "_storeAbiSpecificIntAtIndex"),
        abiCurrentMethod = index.getProcedure('dart:ffi', 'Abi', 'current'),
        constantAbis = abiNames.map((abi, name) => MapEntry(
            (index.getField('dart:ffi', 'Abi', name).initializer
                    as ConstantExpression)
                .constant,
            abi)),
        intptrClass = index.getClass('dart:ffi', 'IntPtr'),
        memCopy = index.getTopLevelProcedure('dart:ffi', '_memCopy'),
        allocationTearoff = index.getProcedure(
            'dart:ffi', 'AllocatorAlloc', LibraryIndex.tearoffPrefix + 'call'),
        asFunctionTearoff = index.getProcedure('dart:ffi',
            'NativeFunctionPointer', LibraryIndex.tearoffPrefix + 'asFunction'),
        lookupFunctionTearoff = index.getProcedure(
            'dart:ffi',
            'DynamicLibraryExtension',
            LibraryIndex.tearoffPrefix + 'lookupFunction'),
        getNativeFieldFunction = index.getTopLevelProcedure(
            'dart:nativewrappers', '_getNativeField'),
        finalizableClass = index.getClass('dart:ffi', 'Finalizable'),
        reachabilityFenceFunction =
            index.getTopLevelProcedure('dart:_internal', 'reachabilityFence'),
        checkAbiSpecificIntegerMappingFunction = index.getTopLevelProcedure(
            'dart:ffi', "_checkAbiSpecificIntegerMapping"),
        rawRecvPortClass = index.getClass('dart:isolate', 'RawReceivePort'),
        nativeCallableClass = index.getClass('dart:ffi', 'NativeCallable'),
        nativeCallableIsolateLocalConstructor =
            index.getProcedure('dart:ffi', 'NativeCallable', 'isolateLocal'),
        nativeCallablePrivateIsolateLocalConstructor =
            index.getConstructor('dart:ffi', '_NativeCallableIsolateLocal', ''),
        nativeCallableListenerConstructor =
            index.getProcedure('dart:ffi', 'NativeCallable', 'listener'),
        nativeCallablePrivateListenerConstructor =
            index.getConstructor('dart:ffi', '_NativeCallableListener', ''),
        nativeCallablePortField =
            index.getField('dart:ffi', '_NativeCallableListener', '_port'),
        nativeCallablePointerField =
            index.getField('dart:ffi', '_NativeCallableBase', '_pointer'),
        nativeAddressOf =
            index.getMember('dart:ffi', 'Native', 'addressOf') as Procedure,
        nativePrivateAddressOf =
            index.getMember('dart:ffi', 'Native', '_addressOf') as Procedure {
    nativeFieldWrapperClass1Type = nativeFieldWrapperClass1Class.getThisType(
        coreTypes, Nullability.nonNullable);
    voidType = nativeTypesClasses[NativeType.kVoid]!
        .getThisType(coreTypes, Nullability.nonNullable);
    pointerVoidType =
        InterfaceType(pointerClass, Nullability.nonNullable, [voidType]);
    nativeTypeType = nativeTypesClasses[NativeType.kNativeType]!
        .getThisType(coreTypes, Nullability.nonNullable);
    pointerNativeTypeType =
        InterfaceType(pointerClass, Nullability.nonNullable, [nativeTypeType]);
    intptrNativeTypeCfe =
        NativeTypeCfe(this, InterfaceType(intptrClass, Nullability.nonNullable))
            as AbiSpecificNativeTypeCfe;
  }

  @override
  TreeNode visitLibrary(Library node) {
    assert(_currentLibrary == null);
    _currentLibrary = node;
    currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
    final result = super.visitLibrary(node);
    _currentLibrary = null;
    return result;
  }

  /// Computes the Dart type corresponding to a ffi.[NativeType], returns null
  /// if it is not a valid NativeType.
  ///
  /// [Int8]                               -> [int]
  /// [Int16]                              -> [int]
  /// [Int32]                              -> [int]
  /// [Int64]                              -> [int]
  /// [Uint8]                              -> [int]
  /// [Uint16]                             -> [int]
  /// [Uint32]                             -> [int]
  /// [Uint64]                             -> [int]
  /// [IntPtr]                             -> [int]
  /// T extends [AbiSpecificInteger]       -> [int]
  /// [Double]                             -> [double]
  /// [Float]                              -> [double]
  /// [Bool]                               -> [bool]
  /// [Void]                               -> [void]
  /// [Pointer]<T>                         -> [Pointer]<T>
  ///                                      -> `${T}List` (from dart:typed_data)
  /// T extends [Compound]                 -> T
  /// [Handle]                             -> [Object]
  /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
  ///    where DartRepresentationOf(Tn) -> Sn
  ///
  /// If [dartType] is provided, it can be used to guide what Dart type is
  /// expected. Currently, this is only used if [allowTypedData] is provided,
  /// because `Pointer` is a one to many mapping in this case.
  ///
  /// Some Dart types only have one possible native type (and vice-versa). For
  /// those types, [convertNativeTypeToDartType] is the inverse of
  /// [convertDartTypeToNativeType].
  DartType? convertNativeTypeToDartType(
    DartType nativeType, {
    DartType? dartType,
    bool allowCompounds = false,
    bool allowHandle = false,
    bool allowInlineArray = false,
    bool allowVoid = false,
    bool allowTypedData = false,
  }) {
    if (nativeType is! InterfaceType) {
      return null;
    }
    final InterfaceType native = nativeType;
    final Class nativeClass = native.classNode;
    final NativeType? nativeType_ = getType(nativeClass);

    if (nativeClass == arrayClass) {
      if (!allowInlineArray) {
        return null;
      }
      final nested = convertNativeTypeToDartType(
        nativeType.typeArguments.single,
        allowInlineArray: true,
        allowCompounds: true,
      );
      if (nested == null) {
        return null;
      }
      return nativeType;
    }
    if (hierarchy.isSubclassOf(nativeClass, abiSpecificIntegerClass)) {
      return InterfaceType(intClass, Nullability.legacy);
    }
    if (hierarchy.isSubclassOf(nativeClass, compoundClass)) {
      if (nativeClass == structClass || nativeClass == unionClass) {
        return null;
      }
      return allowCompounds ? nativeType : null;
    }
    if (nativeType_ == null) {
      return null;
    }
    if (nativeType_ == NativeType.kPointer) {
      if (allowTypedData && dartType != null) {
        final elementType = nativeType.typeArguments.single;
        if (elementType is InterfaceType) {
          final elementType_ = getType(elementType.classNode);
          final typedDataClass = nativeTypesTypedDataClasses[elementType_];
          if (typedDataClass != null) {
            final typedDataType =
                InterfaceType(typedDataClass, Nullability.nonNullable);
            if (typedDataType == dartType) {
              return dartType;
            }
          }
        }
      }
      return nativeType;
    }
    if (nativeIntTypesFixedSize.contains(nativeType_)) {
      return InterfaceType(intClass, Nullability.legacy);
    }
    if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
      return InterfaceType(doubleClass, Nullability.legacy);
    }
    if (nativeType_ == NativeType.kBool) {
      return InterfaceType(boolClass, Nullability.legacy);
    }
    if (nativeType_ == NativeType.kVoid) {
      if (!allowVoid) {
        return null;
      }
      return VoidType();
    }
    if (nativeType_ == NativeType.kHandle && allowHandle) {
      return InterfaceType(objectClass, Nullability.legacy);
    }
    if (nativeType_ != NativeType.kNativeFunction ||
        native.typeArguments[0] is! FunctionType) {
      return null;
    }

    final FunctionType fun = native.typeArguments[0] as FunctionType;
    if (fun.namedParameters.isNotEmpty) return null;
    if (fun.positionalParameters.length != fun.requiredParameterCount) {
      return null;
    }
    if (fun.typeParameters.isNotEmpty) return null;

    final DartType? returnType = convertNativeTypeToDartType(
      fun.returnType,
      dartType: dartType is! FunctionType ? null : dartType.returnType,
      allowCompounds: true,
      allowHandle: true,
      allowVoid: true,
      allowTypedData: allowTypedData,
    );
    if (returnType == null) return null;
    final argumentTypes = <DartType>[];
    int i = 0;
    for (final paramDartType in flattenVarargs(fun).positionalParameters) {
      argumentTypes.add(
        convertNativeTypeToDartType(
              paramDartType,
              dartType: dartType is! FunctionType
                  ? null
                  : dartType.positionalParameters.elementAtOrNull(i),
              allowCompounds: true,
              allowHandle: true,
              allowTypedData: allowTypedData,
            ) ??
            dummyDartType,
      );
      i++;
    }
    if (argumentTypes.contains(dummyDartType)) return null;
    return FunctionType(argumentTypes, returnType, Nullability.legacy);
  }

  /// Finds a native type for the given [dartType] if there is only one possible
  /// native type.
  ///
  /// This is impossible for some types (like [int] which needs a specific ffi
  /// type to denote the width in C). This method returns `null` for those
  /// types.
  ///
  /// For types where this returns a non-null value, this is the inverse of
  /// [convertNativeTypeToDartType].
  DartType? convertDartTypeToNativeType(DartType dartType) {
    if (isPointerType(dartType) ||
        isCompoundSubtype(dartType) ||
        isArrayType(dartType)) {
      return dartType;
    } else {
      return null;
    }
  }

  /// Removes the VarArgs from a DartType list.
  ///
  /// ```
  /// [Int8, Int8] -> [Int8, Int8]
  /// [Int8, VarArgs<(Int8,)>] -> [Int8, Int8]
  /// [Int8, VarArgs<(Int8, Int8)>] -> [Int8, Int8, Int8]
  /// ```
  FunctionType flattenVarargs(FunctionType functionTypeWithPossibleVarArgs) {
    final positionalParameters =
        functionTypeWithPossibleVarArgs.positionalParameters;
    if (positionalParameters.isEmpty) {
      return functionTypeWithPossibleVarArgs;
    }
    final lastPositionalParameter = positionalParameters.last;
    if (lastPositionalParameter is InterfaceType &&
        lastPositionalParameter.classNode == varArgsClass) {
      final typeArgument = lastPositionalParameter.typeArguments.single;
      if (typeArgument is! RecordType) {
        return functionTypeWithPossibleVarArgs;
      }

      if (typeArgument.named.isNotEmpty) {
        // Named record fields are not supported.
        return functionTypeWithPossibleVarArgs;
      }

      final positionalParameters = [
        ...functionTypeWithPossibleVarArgs.positionalParameters.sublist(
            0, functionTypeWithPossibleVarArgs.positionalParameters.length - 1),
        for (final paramDartType in typeArgument.positional) paramDartType,
      ];
      return FunctionType(
        positionalParameters,
        functionTypeWithPossibleVarArgs.returnType,
        functionTypeWithPossibleVarArgs.declaredNullability,
        namedParameters: functionTypeWithPossibleVarArgs.namedParameters,
        typeParameters: functionTypeWithPossibleVarArgs.typeParameters,
        requiredParameterCount: positionalParameters.length,
      );
    }
    return functionTypeWithPossibleVarArgs;
  }

  /// The [NativeType] corresponding to [c]. Returns `null` for user-defined
  /// structs.
  NativeType? getType(Class c) {
    return classNativeTypes[c];
  }

  InterfaceType _listOfIntType() => InterfaceType(
      listClass, Nullability.legacy, [coreTypes.intLegacyRawType]);

  ConstantExpression intListConstantExpression(List<int?> values) =>
      ConstantExpression(
          ListConstant(coreTypes.intLegacyRawType, [
            for (var v in values)
              if (v != null) IntConstant(v) else NullConstant()
          ]),
          _listOfIntType());

  /// Expression that queries VM internals at runtime to figure out on which ABI
  /// we are.
  Expression runtimeBranchOnLayout(Map<Abi, int?> values) {
    final result = InstanceInvocation(
        InstanceAccessKind.Instance,
        intListConstantExpression([
          for (final abi in Abi.values) values[abi],
        ]),
        listElementAt.name,
        Arguments([StaticInvocation(abiMethod, Arguments([]))]),
        interfaceTarget: listElementAt,
        functionType: Substitution.fromInterfaceType(_listOfIntType())
            .substituteType(listElementAt.getterType) as FunctionType);
    if (values.isPartial) {
      return checkAbiSpecificIntegerMapping(result);
    }
    return result;
  }

  Expression checkAbiSpecificIntegerMapping(Expression nullableExpression) =>
      StaticInvocation(
        checkAbiSpecificIntegerMappingFunction,
        Arguments(
          [nullableExpression],
          types: [InterfaceType(intClass, Nullability.nonNullable)],
        ),
      );

  /// Generates an expression that returns a new `Pointer<dartType>` offset
  /// by [offset] from [pointer].
  ///
  /// Sample output:
  ///
  /// ```
  /// _fromAddress<dartType>(pointer.address + #offset)
  /// ```
  Expression _pointerOffset(Expression pointer, Expression offset,
          DartType dartType, int fileOffset) =>
      StaticInvocation(
          fromAddressInternal,
          Arguments([
            add(
                InstanceGet(
                    InstanceAccessKind.Instance, pointer, addressGetter.name,
                    interfaceTarget: addressGetter,
                    resultType: addressGetter.getterType)
                  ..fileOffset = fileOffset,
                offset)
          ], types: [
            dartType
          ]))
        ..fileOffset = fileOffset;

  /// Generates an expression that returns a new `TypedData` offset
  /// by [offset] from [typedData].
  ///
  /// Sample output:
  ///
  /// ```
  /// TypedData #typedData = typedData;
  /// #typedData.buffer.asInt8List(#typedData.offsetInBytes + offset, length)
  /// ```
  Expression _typedDataOffset(Expression typedData, Expression offset,
      Expression length, int fileOffset) {
    final typedDataVar = VariableDeclaration("#typedData",
        initializer: typedData,
        type: InterfaceType(typedDataClass, Nullability.nonNullable),
        isSynthesized: true)
      ..fileOffset = fileOffset;
    return Let(
        typedDataVar,
        InstanceInvocation(
            InstanceAccessKind.Instance,
            InstanceGet(InstanceAccessKind.Instance, VariableGet(typedDataVar),
                typedDataBufferGetter.name,
                interfaceTarget: typedDataBufferGetter,
                resultType: typedDataBufferGetter.getterType)
              ..fileOffset = fileOffset,
            byteBufferAsUint8List.name,
            Arguments([
              add(
                  InstanceGet(
                      InstanceAccessKind.Instance,
                      VariableGet(typedDataVar),
                      typedDataOffsetInBytesGetter.name,
                      interfaceTarget: typedDataOffsetInBytesGetter,
                      resultType: typedDataOffsetInBytesGetter.getterType)
                    ..fileOffset = fileOffset,
                  offset),
              length
            ]),
            interfaceTarget: byteBufferAsUint8List,
            functionType: byteBufferAsUint8List.getterType as FunctionType));
  }

  /// Generates an expression that returns a new `TypedDataBase` offset
  /// by [offset] from [typedDataBase].
  ///
  /// If [typedDataBase] is a `Pointer`, returns a `Pointer<dartType>`.
  /// If [typedDataBase] is a `TypedData` returns a `TypedData`.
  ///
  /// Sample output:
  ///
  /// ```
  /// Object #typedDataBase = typedDataBase;
  /// int #offset = offset;
  /// #typedDataBase is Pointer ?
  ///   _pointerOffset<dartType>(#typedDataBase, #offset) :
  ///   _typedDataOffset((#typedDataBase as TypedData), #offset, length)
  /// ```
  Expression typedDataBaseOffset(Expression typedDataBase, Expression offset,
      Expression length, DartType dartType, int fileOffset) {
    // Avoid generating the branch on the kind of typed data and the offset
    // calculation if the end result is a no-op. This offset-generating method
    // is used to load compound subtypes, which in many cases are not using any
    // offset from their base.
    if (offset case ConstantExpression(constant: IntConstant(value: 0))) {
      return typedDataBase;
    }

    final typedDataBaseVar = VariableDeclaration("#typedDataBase",
        initializer: typedDataBase,
        type: coreTypes.objectNonNullableRawType,
        isSynthesized: true)
      ..fileOffset = fileOffset;
    final offsetVar = VariableDeclaration("#offset",
        initializer: offset,
        type: coreTypes.intNonNullableRawType,
        isSynthesized: true)
      ..fileOffset = fileOffset;
    return BlockExpression(
        Block([typedDataBaseVar, offsetVar]),
        ConditionalExpression(
            IsExpression(VariableGet(typedDataBaseVar), pointerNativeTypeType),
            _pointerOffset(VariableGet(typedDataBaseVar),
                VariableGet(offsetVar), dartType, fileOffset),
            _typedDataOffset(
                StaticInvocation(
                    unsafeCastMethod,
                    Arguments([
                      VariableGet(typedDataBaseVar)
                    ], types: [
                      InterfaceType(typedDataClass, Nullability.nonNullable)
                    ])),
                VariableGet(offsetVar),
                length,
                fileOffset),
            coreTypes.objectNonNullableRawType));
  }

  bool isPrimitiveType(DartType type) {
    if (type is InvalidType) {
      return false;
    }
    if (type is NullType) {
      return false;
    }
    if (!env.isSubtypeOf(
        type, nativeTypeType, SubtypeCheckMode.ignoringNullabilities)) {
      return false;
    }
    if (isPointerType(type)) {
      return false;
    }
    if (type is InterfaceType) {
      final nativeType = getType(type.classNode);
      return nativeType != null;
    }
    return false;
  }

  bool isPointerType(DartType type) {
    if (type is InvalidType) {
      return false;
    }
    if (type is NullType) {
      return false;
    }
    return env.isSubtypeOf(
        type, pointerNativeTypeType, SubtypeCheckMode.ignoringNullabilities);
  }

  bool isArrayType(DartType type) {
    if (type is InvalidType) {
      return false;
    }
    if (type is NullType) {
      return false;
    }
    return env.isSubtypeOf(
        type,
        InterfaceType(arrayClass, Nullability.legacy, [nativeTypeType]),
        SubtypeCheckMode.ignoringNullabilities);
  }

  /// Returns the single element type nested type argument of `Array`.
  ///
  /// `Array<Array<Array<Int8>>>` -> `Int8`.
  ///
  /// `Array<Array<Array<Unknown>>>` -> [InvalidType].
  DartType arraySingleElementType(DartType dartType) {
    if (dartType is! InterfaceType) {
      return InvalidType();
    }
    InterfaceType elementType = dartType;
    while (elementType.classNode == arrayClass) {
      final elementTypeAny = elementType.typeArguments[0];
      if (elementTypeAny is! InterfaceType) {
        return InvalidType();
      }
      elementType = elementTypeAny;
    }
    return elementType;
  }

  /// Returns the number of dimensions of `Array`.
  ///
  /// `Array<Array<Array<Int8>>>` -> 3.
  ///
  /// `Array<Array<Array<Unknown>>>` -> 3.
  int arrayDimensions(DartType dartType) {
    DartType elementType = dartType;
    int dimensions = 0;
    while (
        elementType is InterfaceType && elementType.classNode == arrayClass) {
      elementType = elementType.typeArguments[0];
      dimensions++;
    }
    return dimensions;
  }

  bool isAbiSpecificIntegerSubtype(DartType type) {
    if (type is InvalidType) {
      return false;
    }
    if (type is NullType) {
      return false;
    }
    if (type is InterfaceType) {
      if (type.classNode == abiSpecificIntegerClass) {
        return false;
      }
    }
    return env.isSubtypeOf(
        type,
        InterfaceType(abiSpecificIntegerClass, Nullability.legacy),
        SubtypeCheckMode.ignoringNullabilities);
  }

  bool isCompoundSubtype(DartType type) {
    if (type is InvalidType) {
      return false;
    }
    if (type is NullType) {
      return false;
    }
    if (type is InterfaceType) {
      if (type.classNode == structClass || type.classNode == unionClass) {
        return false;
      }
    }
    return env.isSubtypeOf(
        type,
        InterfaceType(compoundClass, Nullability.legacy),
        SubtypeCheckMode.ignoringNullabilities);
  }

  Expression getCompoundTypedDataBaseField(
      Expression receiver, int fileOffset) {
    return InstanceGet(
        InstanceAccessKind.Instance, receiver, compoundTypedDataBaseField.name,
        interfaceTarget: compoundTypedDataBaseField,
        resultType: compoundTypedDataBaseField.type)
      ..fileOffset = fileOffset;
  }

  Expression getArrayTypedDataBaseField(Expression receiver,
      [int fileOffset = TreeNode.noOffset]) {
    return InstanceGet(
        InstanceAccessKind.Instance, receiver, arrayTypedDataBaseField.name,
        interfaceTarget: arrayTypedDataBaseField,
        resultType: arrayTypedDataBaseField.type)
      ..fileOffset = fileOffset;
  }

  Expression add(Expression a, Expression b) {
    return InstanceInvocation(
        InstanceAccessKind.Instance, a, numAddition.name, Arguments([b]),
        interfaceTarget: numAddition,
        functionType: numAddition.getterType as FunctionType);
  }

  Expression multiply(Expression a, Expression b) {
    return InstanceInvocation(
        InstanceAccessKind.Instance, a, numMultiplication.name, Arguments([b]),
        interfaceTarget: numMultiplication,
        functionType: numMultiplication.getterType as FunctionType);
  }

  MapConstant? getAbiSpecificIntegerMappingAnnotation(Class node) {
    final annotations = node.annotations
        .whereType<ConstantExpression>()
        .map((e) => e.constant)
        .whereType<InstanceConstant>()
        .where((e) => e.classNode == abiSpecificIntegerMappingClass)
        .map((instanceConstant) =>
            instanceConstant.fieldValues.values.single as MapConstant)
        .toList();

    // There can be at most one annotation (checked by `_FfiDefinitionTransformer`)
    if (annotations.length == 1) {
      return annotations[0];
    }
    return null;
  }

  Expression? inlineSizeOf(InterfaceType nativeType) {
    final Class nativeClass = nativeType.classNode;
    final NativeType? nt = getType(nativeClass);
    if (nt == null) {
      // User-defined compounds.
      final Procedure sizeOfGetter = nativeClass.procedures
          .firstWhere((function) => function.name == Name('#sizeOf'));
      return StaticGet(sizeOfGetter);
    }
    final int size = nativeTypeSizes[nt]!;
    if (size == WORD_SIZE) {
      return runtimeBranchOnLayout(wordSize);
    }
    if (size != UNKNOWN) {
      return ConstantExpression(IntConstant(size),
          InterfaceType(intClass, currentLibrary.nonNullable));
    }
    // Size unknown.
    return null;
  }

  /// Generates an expression performing an Abi specific integer load or store.
  ///
  /// If [value] is provided, it is a store, otherwise a load.
  ///
  /// Provide either [index], or [offsetInBytes], or none for an offset of 0.
  ///
  /// Generates an expression:
  ///
  /// ```dart
  /// _storeAbiSpecificInt(
  ///   [8, 8, 4][_abi()],
  ///   typedDataBase,
  ///   index * [8, 8, 4][_abi()],
  ///   value,
  /// )
  /// ```
  Expression abiSpecificLoadOrStoreExpression(
    AbiSpecificNativeTypeCfe nativeTypeCfe, {
    required Expression typedDataBase,
    Expression? offsetInBytes,
    Expression? index,
    Expression? value,
    required fileOffset,
  }) {
    assert(index == null || offsetInBytes == null);
    final method = () {
      if (value != null) {
        if (index != null) {
          return storeAbiSpecificIntAtIndexMethod;
        }
        return storeAbiSpecificIntMethod;
      }
      if (index != null) {
        return loadAbiSpecificIntAtIndexMethod;
      }
      return loadAbiSpecificIntMethod;
    }();

    final Expression offsetOrIndex = () {
      if (offsetInBytes != null) {
        return offsetInBytes;
      }
      if (index != null) {
        return index;
      }
      return ConstantExpression(IntConstant(0));
    }();

    return StaticInvocation(
      method,
      Arguments([
        typedDataBase,
        offsetOrIndex,
        if (value != null) value,
      ], types: [
        InterfaceType(nativeTypeCfe.clazz, Nullability.nonNullable)
      ]),
    )..fileOffset = fileOffset;
  }

  /// Prevents the struct from being tree-shaken in TFA by invoking its
  /// constructor in a `_nativeEffect` expression.
  Expression invokeCompoundConstructor(
      Expression nestedExpression, Class compoundClass) {
    final constructor = compoundClass.constructors
        .firstWhere((c) => c.name == Name("#fromTypedDataBase"));
    return BlockExpression(
        Block([
          ExpressionStatement(StaticInvocation(
              nativeEffectMethod,
              Arguments([
                ConstructorInvocation(
                    constructor,
                    Arguments([
                      StaticInvocation(
                          uint8ListFactory,
                          Arguments([
                            ConstantExpression(IntConstant(1)),
                          ]))
                        ..fileOffset = nestedExpression.fileOffset,
                    ]))
                  ..fileOffset = nestedExpression.fileOffset
              ])))
        ]),
        nestedExpression)
      ..fileOffset = nestedExpression.fileOffset;
  }

  /// Creates an invocation to asFunctionInternal.
  ///
  /// Adds a native effect invoking a compound constructors if this is used
  /// as return type.
  Expression buildAsFunctionInternal({
    required Expression functionPointer,
    required DartType nativeSignature,
    required DartType dartSignature,
    required bool isLeaf,
    required int fileOffset,
  }) {
    final asFunctionInternalInvocation = StaticInvocation(
        asFunctionInternal,
        Arguments([
          functionPointer,
          BoolLiteral(isLeaf),
        ], types: [
          dartSignature,
          nativeSignature,
        ]))
      ..fileOffset = fileOffset;

    final possibleCompoundReturn = findCompoundReturnType(dartSignature);
    if (possibleCompoundReturn != null) {
      return invokeCompoundConstructor(
          asFunctionInternalInvocation, possibleCompoundReturn);
    }

    return asFunctionInternalInvocation;
  }

  /// Returns the compound [Class] if a compound is returned, otherwise `null`.
  Class? findCompoundReturnType(DartType dartSignature) {
    if (dartSignature is! FunctionType) {
      return null;
    }
    final returnType = dartSignature.returnType;
    if (returnType is! InterfaceType) {
      return null;
    }
    final clazz = returnType.classNode;
    if (clazz.superclass == structClass || clazz.superclass == unionClass) {
      return clazz;
    }
    return null;
  }

  /// Returns
  /// - `true` if leaf
  /// - `false` if not leaf
  /// - `null` if the expression is not valid (e.g. non-const bool, null)
  bool? getIsLeafBoolean(StaticInvocation node) {
    for (final named in node.arguments.named) {
      if (named.name == 'isLeaf') {
        final expr = named.value;
        if (expr is BoolLiteral) {
          return expr.value;
        } else if (expr is ConstantExpression) {
          final constant = expr.constant;
          if (constant is BoolConstant) {
            return constant.value;
          }
        }
        // isLeaf is passed some invalid value.
        return null;
      }
    }
    // isLeaf defaults to false.
    return false;
  }

  void ensureLeafCallDoesNotUseHandles(
    InterfaceType nativeType,
    bool isLeaf, {
    required TreeNode reportErrorOn,
  }) {
    // Handles are only disallowed for leaf calls.
    if (isLeaf == false) {
      return;
    }

    bool error = false;

    // Check if return type is Handle.
    final functionType = nativeType.typeArguments[0];
    if (functionType is FunctionType) {
      final returnType = functionType.returnType;
      if (returnType is InterfaceType) {
        if (returnType.classNode == handleClass) {
          diagnosticReporter.report(messageFfiLeafCallMustNotReturnHandle,
              reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          error = true;
        }
      }
      // Check if any of the argument types are Handle.
      for (DartType param in functionType.positionalParameters) {
        if ((param as InterfaceType).classNode == handleClass) {
          diagnosticReporter.report(messageFfiLeafCallMustNotTakeHandle,
              reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          error = true;
        }
      }
    }

    if (error) {
      throw FfiStaticTypeError();
    }
  }

  void ensureOnlyLeafCallsUseTypedData(
    DartType nativeType,
    DartType dartType, {
    required bool isLeaf,
    required bool isCall,
    required TreeNode reportErrorOn,
  }) {
    if (dartType is! FunctionType || nativeType is! FunctionType) {
      return;
    }

    bool error = false;

    final dartReturnType = dartType.returnType;
    final nativeReturnType = nativeType.returnType;
    if (dartReturnType is InterfaceType && nativeReturnType is InterfaceType) {
      if (nativeTypesTypedDataClasses.values
          .contains(dartReturnType.classNode)) {
        final nativeIsPointer =
            getType(nativeReturnType.classNode) == NativeType.kPointer;
        if (nativeIsPointer) {
          if (!isCall) {
            // error callbacks
            diagnosticReporter.report(messageFfiCallbackMustNotUseTypedData,
                reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          } else {
            // error return of call
            diagnosticReporter.report(messageFfiCallMustNotReturnTypedData,
                reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          }
          error = true;
        }
      }
    }
    int i = 0;
    nativeType = flattenVarargs(nativeType);
    for (DartType dartParam in dartType.positionalParameters) {
      final nativeParam = nativeType.positionalParameters[i];
      i++;
      if (dartParam is! InterfaceType || nativeParam is! InterfaceType) {
        continue;
      }
      final nativeIsPointer =
          getType(nativeParam.classNode) == NativeType.kPointer;
      if (!nativeIsPointer) {
        continue;
      }
      if (nativeTypesTypedDataClasses.values.contains(dartParam.classNode)) {
        if (!isCall) {
          // error callback
          diagnosticReporter.report(messageFfiCallbackMustNotUseTypedData,
              reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          error = true;
        } else if (!isLeaf) {
          // error not leaf
          diagnosticReporter.report(messageFfiNonLeafCallMustNotTakeTypedData,
              reportErrorOn.fileOffset, 1, reportErrorOn.location?.file);
          error = true;
        }
      }
    }

    if (error) {
      throw FfiStaticTypeError();
    }
  }

  void ensureNativeTypeToDartType(
    DartType nativeType,
    DartType dartType,
    TreeNode reportErrorOn, {
    bool allowHandle = false,
    bool allowVoid = false,
    bool allowTypedData = false,
    bool allowArray = false,
  }) {
    final DartType correspondingDartType = convertNativeTypeToDartType(
      nativeType,
      dartType: dartType,
      allowCompounds: true,
      allowHandle: allowHandle,
      allowInlineArray: allowArray,
      allowVoid: allowVoid,
      allowTypedData: allowTypedData,
    )!;
    if (dartType == correspondingDartType) return;
    if (env.isSubtypeOf(correspondingDartType, dartType,
        SubtypeCheckMode.ignoringNullabilities)) {
      // If subtype, manually check the return type is not void.
      if (correspondingDartType is FunctionType) {
        if (dartType is FunctionType) {
          if ((dartType.returnType is VoidType) ==
              (correspondingDartType.returnType is VoidType)) {
            return;
          }
          // One of the return types is void, the other isn't, report error.
        } else {
          // One is a function type, the other isn't, report error.
        }
      } else {
        return;
      }
    }
    diagnosticReporter.report(
        templateFfiTypeMismatch.withArguments(dartType, correspondingDartType,
            nativeType, currentLibrary.isNonNullableByDefault),
        reportErrorOn.fileOffset,
        1,
        reportErrorOn.location?.file);
    throw FfiStaticTypeError();
  }

  void ensureNativeTypeValid(
    DartType nativeType,
    TreeNode reportErrorOn, {
    bool allowHandle = false,
    bool allowCompounds = false,
    bool allowInlineArray = false,
    bool allowVoid = false,
  }) {
    if (!_nativeTypeValid(nativeType,
        allowCompounds: allowCompounds,
        allowHandle: allowHandle,
        allowInlineArray: allowInlineArray,
        allowVoid: allowVoid)) {
      diagnosticReporter.report(
          templateFfiTypeInvalid.withArguments(
              nativeType, currentLibrary.isNonNullableByDefault),
          reportErrorOn.fileOffset,
          1,
          reportErrorOn.location?.file);
      throw FfiStaticTypeError();
    }
  }

  /// The Dart type system does not enforce that NativeFunction return and
  /// parameter types are only NativeTypes, so we need to check this.
  bool _nativeTypeValid(
    DartType nativeType, {
    bool allowCompounds = false,
    bool allowHandle = false,
    bool allowInlineArray = false,
    bool allowVoid = false,
  }) {
    return convertNativeTypeToDartType(nativeType,
            allowCompounds: allowCompounds,
            allowHandle: allowHandle,
            allowInlineArray: allowInlineArray,
            allowVoid: allowVoid) !=
        null;
  }
}

/// Returns all libraries including the ones from component except for platform
/// libraries that are only in component.
Set<Library> _getAllRelevantLibraries(
    Component component, List<Library> libraries) {
  Set<Library> allLibs = {};
  allLibs.addAll(libraries);
  for (Library lib in component.libraries) {
    // Skip real dart: libraries. dart:core imports dart:ffi, but that doesn't
    // mean we have to transform anything.
    if (lib.importUri.isScheme("dart") && !lib.isSynthetic) continue;
    allLibs.add(lib);
  }
  return allLibs;
}

/// Checks if any library depends on dart:ffi.
Library? importsFfi(Component component, List<Library> libraries) {
  final Uri dartFfiUri = Uri.parse("dart:ffi");
  Set<Library> allLibs = _getAllRelevantLibraries(component, libraries);
  for (Library lib in allLibs) {
    for (LibraryDependency dependency in lib.dependencies) {
      Library targetLibrary = dependency.targetLibrary;
      if (targetLibrary.importUri == dartFfiUri) {
        return targetLibrary;
      }
    }
  }
  return null;
}

/// Calculates the libraries in [libraries] that transitively imports dart:ffi.
///
/// Returns null if dart:ffi is not imported.
List<Library>? calculateTransitiveImportsOfDartFfiIfUsed(
    Component component, List<Library> libraries) {
  Set<Library> allLibs = _getAllRelevantLibraries(component, libraries);

  final Uri dartFfiUri = Uri.parse("dart:ffi");
  Library? dartFfi;
  canFind:
  for (Library lib in allLibs) {
    for (LibraryDependency dependency in lib.dependencies) {
      Library targetLibrary = dependency.targetLibrary;
      if (targetLibrary.importUri == dartFfiUri) {
        dartFfi = targetLibrary;
        break canFind;
      }
    }
  }
  if (dartFfi == null) return null;

  kernelGraph.LibraryGraph graph = new kernelGraph.LibraryGraph(allLibs);
  Set<Library> result =
      kernelGraph.calculateTransitiveDependenciesOf(graph, {dartFfi});
  return (result..retainAll(libraries)).toList();
}

extension on Map<Abi, Object?> {
  bool get isPartial =>
      [for (final abi in Abi.values) this[abi]].contains(null);
}

/// Used internally for abnormal control flow to prevent cascading error
/// messages.
class FfiStaticTypeError implements Exception {}
