// 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.

// All imports must be in all FFI patch files to not depend on the order
// the patches are applied.
import "dart:_internal" show patch, has63BitSmis;
import 'dart:typed_data';
import 'dart:isolate';

const Map<Type, int> _knownSizes = {
  Int8: 1,
  Uint8: 1,
  Int16: 2,
  Uint16: 2,
  Int32: 4,
  Uint32: 4,
  Int64: 8,
  Uint64: 8,
  Float: 4,
  Double: 8,
};

// Keep consistent with pkg/vm/lib/transformations/ffi/abi.dart.
@pragma("vm:prefer-inline")
int get _intPtrSize => (const [
      4, // androidArm,
      8, // androidArm64,
      4, // androidIA32,
      8, // androidX64,
      8, // fuchsiaArm64,
      8, // fuchsiaX64,
      4, // iosArm,
      8, // iosArm64,
      8, // iosX64,
      4, // linuxArm,
      8, // linuxArm64,
      4, // linuxIA32,
      8, // linuxX64,
      8, // macosArm64,
      8, // macosX64,
      8, // windowsArm64,
      4, // windowsIA32,
      8, // windowsX64,
    ])[_abi()];

@pragma("vm:prefer-inline")
int get _smiMax {
  // See runtime/vm/globals.h for how smiMax is calculated.
  final smiBits = has63BitSmis ? 62 : 30;
  return (1 << smiBits) - 1;
}

@pragma("vm:prefer-inline")
void _checkExternalTypedDataLength(int length, int elementSize) {
  final maxElements = _smiMax ~/ elementSize;
  if (length < 0 || length > maxElements) {
    throw ArgumentError("length must be in the range [0, $maxElements].");
  }
}

@pragma("vm:prefer-inline")
void _checkPointerAlignment(int address, int elementSize) {
  if (address & (elementSize - 1) != 0) {
    throw ArgumentError("Pointer address must be aligned to a multiple of "
        "the element size ($elementSize).");
  }
}

@patch
int sizeOf<T extends NativeType>() {
  // This case should have been rewritten in pre-processing.
  throw UnimplementedError("$T");
}

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_fromAddress")
external Pointer<T> _fromAddress<T extends NativeType>(int ptr);

// The real implementation of this function (for interface calls) lives in
// BuildFfiAsFunctionCall in the Kernel frontend. No calls can actually reach
// this function.
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asFunctionInternal")
external DS _asFunctionInternal<DS extends Function, NS extends Function>(
    Pointer<NativeFunction<NS>> ptr, bool isLeaf);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataInt8")
external Int8List _asExternalTypedDataInt8(Pointer<Int8> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataInt16")
external Int16List _asExternalTypedDataInt16(Pointer<Int16> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataInt32")
external Int32List _asExternalTypedDataInt32(Pointer<Int32> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataInt64")
external Int64List _asExternalTypedDataInt64(Pointer<Int64> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataUint8")
external Uint8List _asExternalTypedDataUint8(Pointer<Uint8> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataUint16")
external Uint16List _asExternalTypedDataUint16(Pointer<Uint16> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataUint32")
external Uint32List _asExternalTypedDataUint32(Pointer<Uint32> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataUint64")
external Uint64List _asExternalTypedDataUint64(Pointer<Uint64> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataFloat")
external Float32List _asExternalTypedDataFloat(Pointer<Float> ptr, int length);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_asExternalTypedDataDouble")
external Float64List _asExternalTypedDataDouble(
    Pointer<Double> ptr, int length);

// Returns a Function object for a native callback.
//
// Calls to [Pointer.fromFunction] are re-written by the FE into calls to this
// method + _pointerFromFunction. All three arguments must be constants.
//
// In AOT we evaluate calls to this function during precompilation and replace
// them with Constant instruction referencing the callback trampoline, to ensure
// that it will be precompiled.
//
// In all JIT modes we call a native runtime entry. We *cannot* use the IL
// implementation, since that would pull the callback trampoline into JIT
// snapshots. The callback trampolines can only be serialized into AOT snapshots
// because they embed the addresses of runtime routines in JIT mode.
//
// Function objects returned by this native method are not Dart instances,
// so we need to use top type as a return type to avoid type check.
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_nativeCallbackFunction")
external dynamic _nativeCallbackFunction<NS extends Function>(
    Function target, Object? exceptionalReturn);

@pragma("vm:external-name", "Ffi_pointerFromFunction")
external Pointer<NS> _pointerFromFunction<NS extends NativeFunction>(
    dynamic function);

@patch
@pragma("vm:entry-point")
class Pointer<T extends NativeType> {
  @patch
  factory Pointer.fromAddress(int ptr) => _fromAddress(ptr);

  // All static calls to this method are replaced by the FE into
  // _nativeCallbackFunction + _pointerFromFunction.
  //
  // We still need to throw an error on a dynamic invocations, invocations
  // through tearoffs or reflective calls.
  @patch
  static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
      @DartRepresentationOf("T") Function f,
      [Object? exceptionalReturn]) {
    throw UnsupportedError(
        "Pointer.fromFunction cannot be called dynamically.");
  }

  @patch
  @pragma("vm:recognized", "other")
  @pragma("vm:external-name", "Ffi_address")
  external int get address;

  // For statically known types, this is rewritten.
  @patch
  Pointer<T> elementAt(int index) {
    // This case should have been rewritten in pre-processing.
    // Only dynamic invocations are not rewritten in pre-processing.
    throw UnsupportedError("Pointer.elementAt cannot be called dynamically.");
  }

  @patch
  Pointer<T> _offsetBy(int offsetInBytes) =>
      Pointer.fromAddress(address + offsetInBytes);

  @patch
  Pointer<U> cast<U extends NativeType>() => Pointer.fromAddress(address);
}

@patch
@pragma("vm:entry-point")
class Array<T extends NativeType> {
  @pragma("vm:entry-point")
  final Object _typedDataBase;

  @pragma("vm:entry-point")
  final int _size;

  @pragma("vm:entry-point")
  final List<int> _nestedDimensions;

  @pragma("vm:entry-point")
  Array._(this._typedDataBase, this._size, this._nestedDimensions);

  late final int _nestedDimensionsFlattened = _nestedDimensions.fold(
      1, (accumulator, element) => accumulator * element);

  late final int _nestedDimensionsFirst = _nestedDimensions.first;

  late final List<int> _nestedDimensionsRest = _nestedDimensions.sublist(1);

  _checkIndex(int index) {
    if (index < 0 || index >= _size) {
      throw RangeError.range(index, 0, _size - 1);
    }
  }
}

/// Returns an integer encoding the ABI used for size and alignment
/// calculations. See pkg/vm/lib/transformations/ffi.dart.
@pragma("vm:recognized", "other")
@pragma('vm:prefer-inline')
@pragma("vm:external-name",
    "Recognized method: IR graph is built in the flow graph builder.")
external int _abi();

@patch
@pragma("vm:entry-point")
class Abi {
  @patch
  @pragma("vm:prefer-inline")
  factory Abi.current() => values[_abi()];
}

@pragma("vm:entry-point")
class _FfiAbiSpecificMapping {
  /// Indexed by [_abi].
  @pragma("vm:entry-point")
  final List<Object> nativeTypes;

  const _FfiAbiSpecificMapping(this.nativeTypes);
}

/// Copies data byte-wise from [source] to [target].
///
/// [source] and [target] should either be [Pointer] or [TypedData].
///
/// TODO(dartbug.com/37271): Make recognized method and use MemoryCopyInstr.
void _memCopy(Object target, int targetOffsetInBytes, Object source,
    int sourceOffsetInBytes, int lengthInBytes) {
  assert(source is Pointer || source is TypedData);
  assert(target is Pointer || target is TypedData);
  if (source is Pointer) {
    final sourcePointer = source.cast<Uint8>();
    if (target is Pointer) {
      final targetPointer = target.cast<Uint8>();
      for (int i = 0; i < lengthInBytes; i++) {
        targetPointer[i + targetOffsetInBytes] =
            sourcePointer[i + sourceOffsetInBytes];
      }
    } else if (target is TypedData) {
      final targetTypedData = target.buffer.asUint8List(target.offsetInBytes);
      for (int i = 0; i < lengthInBytes; i++) {
        targetTypedData[i + targetOffsetInBytes] =
            sourcePointer[i + sourceOffsetInBytes];
      }
    }
  } else if (source is TypedData) {
    final sourceTypedData = source.buffer.asUint8List(source.offsetInBytes);
    if (target is Pointer) {
      final targetPointer = target.cast<Uint8>();
      for (int i = 0; i < lengthInBytes; i++) {
        targetPointer[i + targetOffsetInBytes] =
            sourceTypedData[i + sourceOffsetInBytes];
      }
    } else if (target is TypedData) {
      final targetTypedData = target.buffer.asUint8List(target.offsetInBytes);
      targetTypedData.setRange(
          targetOffsetInBytes,
          targetOffsetInBytes + lengthInBytes,
          sourceTypedData.sublist(sourceOffsetInBytes));
    }
  }
}

// The following functions are implemented in the method recognizer.
//
// TODO(38172): Since these are not inlined (force optimize), they force
// allocating a Pointer with in elementAt/offsetBy. Allocating these pointers
// and GCing new spaces takes a lot of the benchmark time. The next speedup is
// getting rid of these allocations by inlining these functions.
@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadInt8")
external int _loadInt8(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadInt16")
external int _loadInt16(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadInt32")
external int _loadInt32(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadInt64")
external int _loadInt64(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadUint8")
external int _loadUint8(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadUint16")
external int _loadUint16(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadUint32")
external int _loadUint32(Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadUint64")
external int _loadUint64(Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
external int _loadAbiSpecificInt<T extends AbiSpecificInteger>(
    Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
external int _loadAbiSpecificIntAtIndex<T extends AbiSpecificInteger>(
    Object typedDataBase, int index);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadFloat")
external double _loadFloat(Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadDouble")
external double _loadDouble(Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadFloatUnaligned")
external double _loadFloatUnaligned(Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadDoubleUnaligned")
external double _loadDoubleUnaligned(Object typedDataBase, int offsetInBytes);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_loadPointer")
external Pointer<S> _loadPointer<S extends NativeType>(
    Object typedDataBase, int offsetInBytes);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeInt8")
external void _storeInt8(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeInt16")
external void _storeInt16(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeInt32")
external void _storeInt32(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeInt64")
external void _storeInt64(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeUint8")
external void _storeUint8(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeUint16")
external void _storeUint16(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeUint32")
external void _storeUint32(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:entry-point")
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeUint64")
external void _storeUint64(Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:recognized", "other")
external int _storeAbiSpecificInt<T extends AbiSpecificInteger>(
    Object typedDataBase, int offsetInBytes, int value);

@pragma("vm:recognized", "other")
external int _storeAbiSpecificIntAtIndex<T extends AbiSpecificInteger>(
    Object typedDataBase, int index, int value);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeFloat")
external void _storeFloat(
    Object typedDataBase, int offsetInBytes, double value);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeDouble")
external void _storeDouble(
    Object typedDataBase, int offsetInBytes, double value);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeFloatUnaligned")
external void _storeFloatUnaligned(
    Object typedDataBase, int offsetInBytes, double value);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storeDoubleUnaligned")
external void _storeDoubleUnaligned(
    Object typedDataBase, int offsetInBytes, double value);

@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Ffi_storePointer")
external void _storePointer<S extends NativeType>(
    Object typedDataBase, int offsetInBytes, Pointer<S> value);

bool _loadBool(Object typedDataBase, int offsetInBytes) =>
    _loadUint8(typedDataBase, offsetInBytes) != 0;

void _storeBool(Object typedDataBase, int offsetInBytes, bool value) =>
    _storeUint8(typedDataBase, offsetInBytes, value ? 1 : 0);

Pointer<Bool> _elementAtBool(Pointer<Bool> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 1 * index);

Pointer<Int8> _elementAtInt8(Pointer<Int8> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 1 * index);

Pointer<Int16> _elementAtInt16(Pointer<Int16> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 2 * index);

Pointer<Int32> _elementAtInt32(Pointer<Int32> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 4 * index);

Pointer<Int64> _elementAtInt64(Pointer<Int64> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 8 * index);

Pointer<Uint8> _elementAtUint8(Pointer<Uint8> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 1 * index);

Pointer<Uint16> _elementAtUint16(Pointer<Uint16> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 2 * index);

Pointer<Uint32> _elementAtUint32(Pointer<Uint32> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 4 * index);

Pointer<Uint64> _elementAtUint64(Pointer<Uint64> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 8 * index);

Pointer<Float> _elementAtFloat(Pointer<Float> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 4 * index);

Pointer<Double> _elementAtDouble(Pointer<Double> pointer, int index) =>
    Pointer.fromAddress(pointer.address + 8 * index);

Pointer<Pointer<S>> _elementAtPointer<S extends NativeType>(
        Pointer<Pointer<S>> pointer, int index) =>
    Pointer.fromAddress(pointer.address + _intPtrSize * index);

@pragma("vm:prefer-inline")
@pragma("vm:entry-point")
T _checkAbiSpecificIntegerMapping<T>(T? object) {
  if (object == null) {
    throw ArgumentError(
        'AbiSpecificInteger is missing mapping for "${Abi.current()}".');
  }
  return object;
}

extension NativeFunctionPointer<NF extends Function>
    on Pointer<NativeFunction<NF>> {
  @patch
  DF asFunction<DF extends Function>({bool isLeaf: false}) =>
      throw UnsupportedError("The body is inlined in the frontend.");
}

//
// The following code is generated, do not edit by hand.
//
// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`.
//

extension Int8Pointer on Pointer<Int8> {
  @patch
  int get value => _loadInt8(this, 0);

  @patch
  set value(int value) => _storeInt8(this, 0, value);

  @patch
  int operator [](int index) => _loadInt8(this, index);

  @patch
  operator []=(int index, int value) => _storeInt8(this, index, value);

  @patch
  Int8List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Int8>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 1);
    _checkPointerAlignment(address, 1);
    return _asExternalTypedDataInt8(this, length);
  }
}

extension Int16Pointer on Pointer<Int16> {
  @patch
  int get value => _loadInt16(this, 0);

  @patch
  set value(int value) => _storeInt16(this, 0, value);

  @patch
  int operator [](int index) => _loadInt16(this, 2 * index);

  @patch
  operator []=(int index, int value) => _storeInt16(this, 2 * index, value);

  @patch
  Int16List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Int16>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 2);
    _checkPointerAlignment(address, 2);
    return _asExternalTypedDataInt16(this, length);
  }
}

extension Int32Pointer on Pointer<Int32> {
  @patch
  int get value => _loadInt32(this, 0);

  @patch
  set value(int value) => _storeInt32(this, 0, value);

  @patch
  int operator [](int index) => _loadInt32(this, 4 * index);

  @patch
  operator []=(int index, int value) => _storeInt32(this, 4 * index, value);

  @patch
  Int32List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Int32>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 4);
    _checkPointerAlignment(address, 4);
    return _asExternalTypedDataInt32(this, length);
  }
}

extension Int64Pointer on Pointer<Int64> {
  @patch
  int get value => _loadInt64(this, 0);

  @patch
  set value(int value) => _storeInt64(this, 0, value);

  @patch
  int operator [](int index) => _loadInt64(this, 8 * index);

  @patch
  operator []=(int index, int value) => _storeInt64(this, 8 * index, value);

  @patch
  Int64List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Int64>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 8);
    _checkPointerAlignment(address, 8);
    return _asExternalTypedDataInt64(this, length);
  }
}

extension Uint8Pointer on Pointer<Uint8> {
  @patch
  int get value => _loadUint8(this, 0);

  @patch
  set value(int value) => _storeUint8(this, 0, value);

  @patch
  int operator [](int index) => _loadUint8(this, index);

  @patch
  operator []=(int index, int value) => _storeUint8(this, index, value);

  @patch
  Uint8List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Uint8>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 1);
    _checkPointerAlignment(address, 1);
    return _asExternalTypedDataUint8(this, length);
  }
}

extension Uint16Pointer on Pointer<Uint16> {
  @patch
  int get value => _loadUint16(this, 0);

  @patch
  set value(int value) => _storeUint16(this, 0, value);

  @patch
  int operator [](int index) => _loadUint16(this, 2 * index);

  @patch
  operator []=(int index, int value) => _storeUint16(this, 2 * index, value);

  @patch
  Uint16List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Uint16>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 2);
    _checkPointerAlignment(address, 2);
    return _asExternalTypedDataUint16(this, length);
  }
}

extension Uint32Pointer on Pointer<Uint32> {
  @patch
  int get value => _loadUint32(this, 0);

  @patch
  set value(int value) => _storeUint32(this, 0, value);

  @patch
  int operator [](int index) => _loadUint32(this, 4 * index);

  @patch
  operator []=(int index, int value) => _storeUint32(this, 4 * index, value);

  @patch
  Uint32List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Uint32>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 4);
    _checkPointerAlignment(address, 4);
    return _asExternalTypedDataUint32(this, length);
  }
}

extension Uint64Pointer on Pointer<Uint64> {
  @patch
  int get value => _loadUint64(this, 0);

  @patch
  set value(int value) => _storeUint64(this, 0, value);

  @patch
  int operator [](int index) => _loadUint64(this, 8 * index);

  @patch
  operator []=(int index, int value) => _storeUint64(this, 8 * index, value);

  @patch
  Uint64List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Uint64>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 8);
    _checkPointerAlignment(address, 8);
    return _asExternalTypedDataUint64(this, length);
  }
}

extension FloatPointer on Pointer<Float> {
  @patch
  double get value => _loadFloat(this, 0);

  @patch
  set value(double value) => _storeFloat(this, 0, value);

  @patch
  double operator [](int index) => _loadFloat(this, 4 * index);

  @patch
  operator []=(int index, double value) => _storeFloat(this, 4 * index, value);

  @patch
  Float32List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Float>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 4);
    _checkPointerAlignment(address, 4);
    return _asExternalTypedDataFloat(this, length);
  }
}

extension DoublePointer on Pointer<Double> {
  @patch
  double get value => _loadDouble(this, 0);

  @patch
  set value(double value) => _storeDouble(this, 0, value);

  @patch
  double operator [](int index) => _loadDouble(this, 8 * index);

  @patch
  operator []=(int index, double value) => _storeDouble(this, 8 * index, value);

  @patch
  Float64List asTypedList(int length) {
    ArgumentError.checkNotNull(this, "Pointer<Double>");
    ArgumentError.checkNotNull(length, "length");
    _checkExternalTypedDataLength(length, 8);
    _checkPointerAlignment(address, 8);
    return _asExternalTypedDataDouble(this, length);
  }
}

extension BoolPointer on Pointer<Bool> {
  @patch
  bool get value => _loadBool(this, 0);

  @patch
  set value(bool value) => _storeBool(this, 0, value);

  @patch
  bool operator [](int index) => _loadBool(this, index);

  @patch
  operator []=(int index, bool value) => _storeBool(this, index, value);
}

extension Int8Array on Array<Int8> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadInt8(_typedDataBase, index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeInt8(_typedDataBase, index, value);
  }
}

extension Int16Array on Array<Int16> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadInt16(_typedDataBase, 2 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeInt16(_typedDataBase, 2 * index, value);
  }
}

extension Int32Array on Array<Int32> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadInt32(_typedDataBase, 4 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeInt32(_typedDataBase, 4 * index, value);
  }
}

extension Int64Array on Array<Int64> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadInt64(_typedDataBase, 8 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeInt64(_typedDataBase, 8 * index, value);
  }
}

extension Uint8Array on Array<Uint8> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadUint8(_typedDataBase, index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeUint8(_typedDataBase, index, value);
  }
}

extension Uint16Array on Array<Uint16> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadUint16(_typedDataBase, 2 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeUint16(_typedDataBase, 2 * index, value);
  }
}

extension Uint32Array on Array<Uint32> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadUint32(_typedDataBase, 4 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeUint32(_typedDataBase, 4 * index, value);
  }
}

extension Uint64Array on Array<Uint64> {
  @patch
  int operator [](int index) {
    _checkIndex(index);
    return _loadUint64(_typedDataBase, 8 * index);
  }

  @patch
  operator []=(int index, int value) {
    _checkIndex(index);
    return _storeUint64(_typedDataBase, 8 * index, value);
  }
}

extension FloatArray on Array<Float> {
  @patch
  double operator [](int index) {
    _checkIndex(index);
    return _loadFloat(_typedDataBase, 4 * index);
  }

  @patch
  operator []=(int index, double value) {
    _checkIndex(index);
    return _storeFloat(_typedDataBase, 4 * index, value);
  }
}

extension DoubleArray on Array<Double> {
  @patch
  double operator [](int index) {
    _checkIndex(index);
    return _loadDouble(_typedDataBase, 8 * index);
  }

  @patch
  operator []=(int index, double value) {
    _checkIndex(index);
    return _storeDouble(_typedDataBase, 8 * index, value);
  }
}

extension BoolArray on Array<Bool> {
  @patch
  bool operator [](int index) {
    _checkIndex(index);
    return _loadBool(_typedDataBase, index);
  }

  @patch
  operator []=(int index, bool value) {
    _checkIndex(index);
    return _storeBool(_typedDataBase, index, value);
  }
}

//
// End of generated code.
//

extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
  @patch
  Pointer<T> get value => _loadPointer(this, 0);

  @patch
  set value(Pointer<T> value) => _storePointer(this, 0, value);

  @patch
  Pointer<T> operator [](int index) => _loadPointer(this, _intPtrSize * index);

  @patch
  operator []=(int index, Pointer<T> value) =>
      _storePointer(this, _intPtrSize * index, value);
}

extension StructPointer<T extends Struct> on Pointer<T> {
  @patch
  T get ref =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  set ref(T value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE";

  @patch
  T operator [](int index) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  void operator []=(int index, T value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
}

extension UnionPointer<T extends Union> on Pointer<T> {
  @patch
  T get ref =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  set ref(T value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE";

  @patch
  T operator [](int index) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  void operator []=(int index, T value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
}

extension AbiSpecificIntegerPointer<T extends AbiSpecificInteger>
    on Pointer<T> {
  @patch
  int get value =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  void set value(int value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  int operator [](int index) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  void operator []=(int index, int value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
}

extension PointerArray<T extends NativeType> on Array<Pointer<T>> {
  @patch
  Pointer<T> operator [](int index) =>
      _loadPointer(_typedDataBase, _intPtrSize * index);

  @patch
  void operator []=(int index, Pointer<T> value) =>
      _storePointer(_typedDataBase, _intPtrSize * index, value);
}

extension ArrayArray<T extends NativeType> on Array<Array<T>> {
  @patch
  Array<T> operator [](int index) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";

  @patch
  void operator []=(int index, Array<T> value) =>
      throw "UNREACHABLE: This case should have been rewritten in the CFE.";
}

extension StructArray<T extends Struct> on Array<T> {
  @patch
  T operator [](int index) {
    throw ArgumentError(
        "T ($T) should be a subtype of Struct at compile-time.");
  }
}

extension UnionArray<T extends Union> on Array<T> {
  @patch
  T operator [](int index) {
    throw ArgumentError("T ($T) should be a subtype of Union at compile-time.");
  }
}

extension AbiSpecificIntegerArray on Array<AbiSpecificInteger> {
  @patch
  int operator [](int index) {
    throw ArgumentError(
        "Receiver should be a subtype of AbiSpecificInteger at compile-time.");
  }

  @patch
  void operator []=(int index, int value) {
    throw ArgumentError(
        "Receiver should be a subtype of AbiSpecificInteger at compile-time.");
  }
}

extension NativePort on SendPort {
  @patch
  @pragma("vm:external-name", "SendPortImpl_get_id")
  external int get nativePort;
}

@pragma("vm:external-name", "DartNativeApiFunctionPointer")
external int _nativeApiFunctionPointer(String symbol);

@pragma("vm:external-name", "DartApiDLInitializeData")
external int _initializeApiDLData();

@pragma("vm:external-name", "DartApiDLMajorVersion")
external int _dartApiMajorVersion();

@pragma("vm:external-name", "DartApiDLMinorVersion")
external int _dartApiMinorVersion();

@patch
abstract class NativeApi {
  @patch
  static Pointer<NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
      get postCObject =>
          Pointer.fromAddress(_nativeApiFunctionPointer("Dart_PostCObject"));

  @patch
  static Pointer<
      NativeFunction<
          Int64 Function(
              Pointer<Uint8>,
              Pointer<NativeFunction<Dart_NativeMessageHandler>>,
              Int8)>> get newNativePort =>
      Pointer.fromAddress(_nativeApiFunctionPointer("Dart_NewNativePort"));

  @patch
  static Pointer<NativeFunction<Int8 Function(Int64)>> get closeNativePort =>
      Pointer.fromAddress(_nativeApiFunctionPointer("Dart_CloseNativePort"));

  @patch
  static int get majorVersion => _dartApiMajorVersion();

  @patch
  static int get minorVersion => _dartApiMinorVersion();

  @patch
  static Pointer<Void> get initializeApiDLData =>
      Pointer.fromAddress(_initializeApiDLData());
}
