blob: 7ecccf060a8b3bf7bdf0dbda1abf60e0d043519d [file] [log] [blame]
// 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());
}