[vm/ffi] Pointer.asExternalTypedData to extension method
Issue: https://github.com/dart-lang/sdk/issues/38610
Change-Id: Ib07f50b23e3be2bce2d7b973c0f0196884397952
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-dartkb-linux-debug-simarm64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-dartkb-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-reload-mac-release-simdbc64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-precomp-mac-release-simarm_x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121384
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/tools/ffi/sdk_lib_ffi_generator.dart b/runtime/tools/ffi/sdk_lib_ffi_generator.dart
index 565ccdd..657920d 100644
--- a/runtime/tools/ffi/sdk_lib_ffi_generator.dart
+++ b/runtime/tools/ffi/sdk_lib_ffi_generator.dart
@@ -15,19 +15,19 @@
// Configuration.
//
-const Map<String, String> nativeToDartType = {
- "Int8": "int",
- "Int16": "int",
- "Int32": "int",
- "Int64": "int",
- "Uint8": "int",
- "Uint16": "int",
- "Uint32": "int",
- "Uint64": "int",
- "IntPtr": "int",
- "Float": "double",
- "Double": "double",
-};
+const configuration = [
+ Config("Int8", "int", "Int8List", 1),
+ Config("Int16", "int", "Int16List", 2),
+ Config("Int32", "int", "Int32List", 4),
+ Config("Int64", "int", "Int64List", 8),
+ Config("Uint8", "int", "Uint8List", 1),
+ Config("Uint16", "int", "Uint16List", 2),
+ Config("Uint32", "int", "Uint32List", 4),
+ Config("Uint64", "int", "Uint64List", 8),
+ Config("IntPtr", "int", kDoNotEmit, kIntPtrElementSize),
+ Config("Float", "double", "Float32List", 4),
+ Config("Double", "double", "Float64List", 8),
+];
//
// Generator.
@@ -41,13 +41,11 @@
generate(path, "ffi_patch.g.dart", generatePatchExtension);
}
-void generate(Uri path, String fileName,
- Function(StringBuffer, String, String) generator) {
+void generate(
+ Uri path, String fileName, Function(StringBuffer, Config) generator) {
final buffer = StringBuffer();
generateHeader(buffer);
- nativeToDartType.forEach((String nativeType, String dartType) {
- generator(buffer, nativeType, dartType);
- });
+ configuration.forEach((Config c) => generator(buffer, c));
generateFooter(buffer);
final fullPath = path.resolve(fileName).path;
@@ -73,8 +71,12 @@
buffer.write(header);
}
-void generatePublicExtension(
- StringBuffer buffer, String nativeType, String dartType) {
+void generatePublicExtension(StringBuffer buffer, Config config) {
+ final nativeType = config.nativeType;
+ final dartType = config.dartType;
+ final typedListType = config.typedListType;
+ final elementSize = config.elementSize;
+
final storeTrunctateInt = """
/// Note that ints which do not fit in `$nativeType` are truncated.
""";
@@ -92,6 +94,19 @@
final loadSignExtend = _isInt(nativeType) ? loadSignExtendInt : "";
+ final asTypedList = typedListType == kDoNotEmit
+ ? ""
+ : """
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + ${elementSize > 1 ? '$elementSize * ' : ''}length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external $typedListType asTypedList(int length);
+""";
+
// TODO(dartdoc-bug): Use [] instead of ``, once issue
// https://github.com/dart-lang/dartdoc/issues/2039 is fixed.
buffer.write("""
@@ -124,13 +139,25 @@
$storeTruncate ///
/// Note that `address` needs to be aligned to the size of `$nativeType`.
external void operator []=(int index, $dartType value);
+
+$asTypedList
}
""");
}
-void generatePatchExtension(
- StringBuffer buffer, String nativeType, String dartType) {
+void generatePatchExtension(StringBuffer buffer, Config config) {
+ final nativeType = config.nativeType;
+ final dartType = config.dartType;
+ final typedListType = config.typedListType;
+
+ final asTypedList = typedListType == kDoNotEmit
+ ? ""
+ : """
+ @patch
+ $typedListType asTypedList(int elements) => _asExternalTypedData(this, elements);
+""";
+
buffer.write("""
extension ${nativeType}Pointer on Pointer<$nativeType> {
@patch
@@ -144,6 +171,8 @@
@patch
operator []=(int index, $dartType value) => _store$nativeType(this, index, value);
+
+$asTypedList
}
""");
@@ -185,3 +214,15 @@
// pinned fully supports extension methods.
return Uri.parse("dartfmt");
}
+
+class Config {
+ final String nativeType;
+ final String dartType;
+ final String typedListType;
+ final int elementSize;
+ const Config(
+ this.nativeType, this.dartType, this.typedListType, this.elementSize);
+}
+
+const String kDoNotEmit = "donotemit";
+const int kIntPtrElementSize = -1;
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index ea2df82..1407b6b 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -5,7 +5,7 @@
// All imports must be in all FFI patch files to not depend on the order
// the patches are applied.
import "dart:_internal" show patch;
-import 'dart:typed_data' show TypedData;
+import 'dart:typed_data';
const Map<Type, int> _knownSizes = {
Int8: 1,
@@ -268,6 +268,9 @@
@patch
operator []=(int index, int value) => _storeInt8(this, index, value);
+
+ @patch
+ Int8List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int16Pointer on Pointer<Int16> {
@@ -282,6 +285,9 @@
@patch
operator []=(int index, int value) => _storeInt16(this, index, value);
+
+ @patch
+ Int16List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int32Pointer on Pointer<Int32> {
@@ -296,6 +302,9 @@
@patch
operator []=(int index, int value) => _storeInt32(this, index, value);
+
+ @patch
+ Int32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int64Pointer on Pointer<Int64> {
@@ -310,6 +319,9 @@
@patch
operator []=(int index, int value) => _storeInt64(this, index, value);
+
+ @patch
+ Int64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint8Pointer on Pointer<Uint8> {
@@ -324,6 +336,9 @@
@patch
operator []=(int index, int value) => _storeUint8(this, index, value);
+
+ @patch
+ Uint8List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint16Pointer on Pointer<Uint16> {
@@ -338,6 +353,9 @@
@patch
operator []=(int index, int value) => _storeUint16(this, index, value);
+
+ @patch
+ Uint16List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint32Pointer on Pointer<Uint32> {
@@ -352,6 +370,9 @@
@patch
operator []=(int index, int value) => _storeUint32(this, index, value);
+
+ @patch
+ Uint32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint64Pointer on Pointer<Uint64> {
@@ -366,6 +387,9 @@
@patch
operator []=(int index, int value) => _storeUint64(this, index, value);
+
+ @patch
+ Uint64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension IntPtrPointer on Pointer<IntPtr> {
@@ -394,6 +418,9 @@
@patch
operator []=(int index, double value) => _storeFloat(this, index, value);
+
+ @patch
+ Float32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension DoublePointer on Pointer<Double> {
@@ -408,6 +435,9 @@
@patch
operator []=(int index, double value) => _storeDouble(this, index, value);
+
+ @patch
+ Float64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
//
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index a0d2820..1b15eb3 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -14,7 +14,7 @@
*/
library dart.ffi;
-import 'dart:typed_data' show TypedData;
+import 'dart:typed_data';
part "native_type.dart";
part "annotations.dart";
@@ -143,10 +143,9 @@
/// data from a [Pointer] to any other native type is not supported.
///
/// The pointer must be aligned to a multiple of the native type's size.
- //
- // TODO(37773): Use extension methods to articulate more precise return types.
- // We should still keep this member though as a generic way to access a
- // Pointer of unknown type.
+ ///
+ /// Deprecated, replace with `asTypedList()`.
+ @deprecated
external TypedData asExternalTypedData({int count: 1});
/// Equality for Pointers only depends on their address.
@@ -200,6 +199,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int8`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int16].
@@ -235,6 +243,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int16`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 2 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int32].
@@ -270,6 +287,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int32`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int64].
@@ -305,6 +331,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int64`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint8].
@@ -340,6 +375,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint8`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint16].
@@ -375,6 +419,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint16`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 2 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint32].
@@ -410,6 +463,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint32`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint64].
@@ -445,6 +507,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint64`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [IntPtr].
@@ -513,6 +584,15 @@
///
/// Note that `address` needs to be aligned to the size of `Float`.
external void operator []=(int index, double value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Float32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Double].
@@ -546,6 +626,15 @@
///
/// Note that `address` needs to be aligned to the size of `Double`.
external void operator []=(int index, double value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Float64List asTypedList(int length);
}
//
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
index 82946a4..43c2098 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
@@ -7,7 +7,7 @@
// All imports must be in all FFI patch files to not depend on the order
// the patches are applied.
import "dart:_internal" show patch;
-import 'dart:typed_data' show TypedData;
+import 'dart:typed_data';
const Map<Type, int> _knownSizes = {
Int8: 1,
@@ -270,6 +270,9 @@
@patch
operator []=(int index, int value) => _storeInt8(this, index, value);
+
+ @patch
+ Int8List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int16Pointer on Pointer<Int16> {
@@ -284,6 +287,9 @@
@patch
operator []=(int index, int value) => _storeInt16(this, index, value);
+
+ @patch
+ Int16List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int32Pointer on Pointer<Int32> {
@@ -298,6 +304,9 @@
@patch
operator []=(int index, int value) => _storeInt32(this, index, value);
+
+ @patch
+ Int32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Int64Pointer on Pointer<Int64> {
@@ -312,6 +321,9 @@
@patch
operator []=(int index, int value) => _storeInt64(this, index, value);
+
+ @patch
+ Int64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint8Pointer on Pointer<Uint8> {
@@ -326,6 +338,9 @@
@patch
operator []=(int index, int value) => _storeUint8(this, index, value);
+
+ @patch
+ Uint8List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint16Pointer on Pointer<Uint16> {
@@ -340,6 +355,9 @@
@patch
operator []=(int index, int value) => _storeUint16(this, index, value);
+
+ @patch
+ Uint16List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint32Pointer on Pointer<Uint32> {
@@ -354,6 +372,9 @@
@patch
operator []=(int index, int value) => _storeUint32(this, index, value);
+
+ @patch
+ Uint32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension Uint64Pointer on Pointer<Uint64> {
@@ -368,6 +389,9 @@
@patch
operator []=(int index, int value) => _storeUint64(this, index, value);
+
+ @patch
+ Uint64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension IntPtrPointer on Pointer<IntPtr> {
@@ -396,6 +420,9 @@
@patch
operator []=(int index, double value) => _storeFloat(this, index, value);
+
+ @patch
+ Float32List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
extension DoublePointer on Pointer<Double> {
@@ -410,6 +437,9 @@
@patch
operator []=(int index, double value) => _storeDouble(this, index, value);
+
+ @patch
+ Float64List asTypedList(int elements) => _asExternalTypedData(this, elements);
}
//
diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart
index 57274f5..2dbed06 100644
--- a/sdk_nnbd/lib/ffi/ffi.dart
+++ b/sdk_nnbd/lib/ffi/ffi.dart
@@ -16,7 +16,7 @@
*/
library dart.ffi;
-import 'dart:typed_data' show TypedData;
+import 'dart:typed_data';
part "native_type.dart";
part "annotations.dart";
@@ -43,7 +43,7 @@
/// On Windows, this memory may only be freed via [Pointer.free].
///
/// This method is deprecated. Please resolve allocation methods via
- /// [DynamicLibrary] instead.
+ /// [DynamicLibrary] instead, or use "package:ffi".
@deprecated
external factory Pointer.allocate({int count: 1});
@@ -78,7 +78,8 @@
///
/// Note that `this.address` needs to be aligned to the size of `T`.
///
- /// Deprecated, use `pointer[...] =` and `pointer.value =` instead.
+ /// Deprecated, use `pointer[...] =` and `pointer.value =` instead, or use
+ /// "package:ffi".
@deprecated
external void store(@DartRepresentationOf("T") Object value);
@@ -144,10 +145,9 @@
/// data from a [Pointer] to any other native type is not supported.
///
/// The pointer must be aligned to a multiple of the native type's size.
- //
- // TODO(37773): Use extension methods to articulate more precise return types.
- // We should still keep this member though as a generic way to access a
- // Pointer of unknown type.
+ ///
+ /// Deprecated, replace with `asTypedList()`.
+ @deprecated
external TypedData asExternalTypedData({int count: 1});
/// Equality for Pointers only depends on their address.
@@ -201,6 +201,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int8`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int16].
@@ -236,6 +245,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int16`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 2 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int32].
@@ -271,6 +289,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int32`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int64].
@@ -306,6 +333,15 @@
///
/// Note that `address` needs to be aligned to the size of `Int64`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Int64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint8].
@@ -341,6 +377,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint8`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint16].
@@ -376,6 +421,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint16`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 2 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint32].
@@ -411,6 +465,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint32`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint64].
@@ -446,6 +509,15 @@
///
/// Note that `address` needs to be aligned to the size of `Uint64`.
external void operator []=(int index, int value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Uint64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [IntPtr].
@@ -514,6 +586,15 @@
///
/// Note that `address` needs to be aligned to the size of `Float`.
external void operator []=(int index, double value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 4 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Float32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Double].
@@ -547,6 +628,15 @@
///
/// Note that `address` needs to be aligned to the size of `Double`.
external void operator []=(int index, double value);
+
+ /// Creates a typed list view backed by memory in the address space.
+ ///
+ /// The returned view will allow access to the memory range from `address`
+ /// to `address + 8 * length`.
+ ///
+ /// The user has to ensure the memory range is accessible while using the
+ /// returned list.
+ external Float64List asTypedList(int length);
}
//
diff --git a/tests/ffi/external_typed_data_test.dart b/tests/ffi/external_typed_data_test.dart
index ae0fbbb..8d19f79 100644
--- a/tests/ffi/external_typed_data_test.dart
+++ b/tests/ffi/external_typed_data_test.dart
@@ -26,7 +26,6 @@
testInt64Store();
testUint64Load();
testUint64Store();
- testIntPtr();
testFloatLoad();
testFloatStore();
testDoubleLoad();
@@ -44,7 +43,7 @@
// Load
Pointer<Int8> ptr = allocate();
ptr.value = 0xff;
- Int8List list = ptr.asExternalTypedData();
+ Int8List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
free(ptr);
@@ -53,7 +52,7 @@
void testInt8Store() {
// Store
Pointer<Int8> ptr = allocate();
- Int8List list = ptr.asExternalTypedData();
+ Int8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
@@ -64,7 +63,7 @@
// Load
Pointer<Uint8> ptr = allocate();
ptr.value = 0xff;
- Uint8List list = ptr.asExternalTypedData();
+ Uint8List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xff);
Expect.equals(list.length, 1);
free(ptr);
@@ -73,7 +72,7 @@
void testUint8Store() {
// Store
Pointer<Uint8> ptr = allocate();
- Uint8List list = ptr.asExternalTypedData();
+ Uint8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xff);
@@ -84,7 +83,7 @@
// Load
Pointer<Int16> ptr = allocate();
ptr.value = 0xffff;
- Int16List list = ptr.asExternalTypedData();
+ Int16List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
free(ptr);
@@ -93,7 +92,7 @@
void testInt16Store() {
// Store
Pointer<Int16> ptr = allocate();
- Int16List list = ptr.asExternalTypedData();
+ Int16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
@@ -104,7 +103,7 @@
// Load
Pointer<Uint16> ptr = allocate();
ptr.value = 0xffff;
- Uint16List list = ptr.asExternalTypedData();
+ Uint16List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffff);
Expect.equals(list.length, 1);
free(ptr);
@@ -113,7 +112,7 @@
void testUint16Store() {
// Store
Pointer<Uint16> ptr = allocate();
- Uint16List list = ptr.asExternalTypedData();
+ Uint16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffff);
@@ -124,7 +123,7 @@
// Load
Pointer<Int32> ptr = allocate();
ptr.value = 0xffffffff;
- Int32List list = ptr.asExternalTypedData();
+ Int32List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
free(ptr);
@@ -133,7 +132,7 @@
void testInt32Store() {
// Store
Pointer<Int32> ptr = allocate();
- Int32List list = ptr.asExternalTypedData();
+ Int32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
@@ -144,7 +143,7 @@
// Load
Pointer<Uint32> ptr = allocate();
ptr.value = 0xffffffff;
- Uint32List list = ptr.asExternalTypedData();
+ Uint32List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffff);
Expect.equals(list.length, 1);
free(ptr);
@@ -153,7 +152,7 @@
void testUint32Store() {
// Store
Pointer<Uint32> ptr = allocate();
- Uint32List list = ptr.asExternalTypedData();
+ Uint32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffff);
@@ -164,7 +163,7 @@
// Load
Pointer<Int64> ptr = allocate();
ptr.value = 0xffffffffffffffff;
- Int64List list = ptr.asExternalTypedData();
+ Int64List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
free(ptr);
@@ -173,7 +172,7 @@
void testInt64Store() {
// Store
Pointer<Int64> ptr = allocate();
- Int64List list = ptr.asExternalTypedData();
+ Int64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
@@ -184,7 +183,7 @@
// Load
Pointer<Uint64> ptr = allocate();
ptr.value = 0xffffffffffffffff;
- Uint64List list = ptr.asExternalTypedData();
+ Uint64List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffffffffffff);
Expect.equals(list.length, 1);
free(ptr);
@@ -193,25 +192,13 @@
void testUint64Store() {
// Store
Pointer<Uint64> ptr = allocate();
- Uint64List list = ptr.asExternalTypedData();
+ Uint64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffffffffffff);
free(ptr);
}
-void testIntPtr() {
- bool is32Bit = sizeOf<IntPtr>() == 4;
- Pointer<IntPtr> ptr = allocate();
- final array = ptr.asExternalTypedData();
- if (is32Bit) {
- Expect.type<Int32List>(array);
- } else {
- Expect.type<Int64List>(array);
- }
- free(ptr);
-}
-
double maxFloat = (2 - pow(2, -23)) * pow(2, 127);
double maxDouble = (2 - pow(2, -52)) * pow(2, pow(2, 10) - 1);
@@ -219,7 +206,7 @@
// Load
Pointer<Float> ptr = allocate();
ptr.value = maxFloat;
- Float32List list = ptr.asExternalTypedData();
+ Float32List list = ptr.asTypedList(1);
Expect.equals(list[0], maxFloat);
Expect.equals(list.length, 1);
free(ptr);
@@ -228,7 +215,7 @@
void testFloatStore() {
// Store
Pointer<Float> ptr = allocate();
- Float32List list = ptr.asExternalTypedData();
+ Float32List list = ptr.asTypedList(1);
list[0] = maxFloat;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxFloat);
@@ -239,7 +226,7 @@
// Load
Pointer<Double> ptr = allocate();
ptr.value = maxDouble;
- Float64List list = ptr.asExternalTypedData();
+ Float64List list = ptr.asTypedList(1);
Expect.equals(list[0], maxDouble);
Expect.equals(list.length, 1);
free(ptr);
@@ -248,7 +235,7 @@
void testDoubleStore() {
// Store
Pointer<Double> ptr = allocate();
- Float64List list = ptr.asExternalTypedData();
+ Float64List list = ptr.asTypedList(1);
list[0] = maxDouble;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxDouble);
@@ -261,7 +248,7 @@
for (int i = 0; i < count; ++i) {
ptr[i] = i;
}
- Int32List array = ptr.asExternalTypedData(count: count);
+ Int32List array = ptr.asTypedList(count);
for (int i = 0; i < count; ++i) {
Expect.equals(array[i], i);
}
@@ -271,7 +258,7 @@
void testArrayStore() {
const int count = 0x100;
Pointer<Int32> ptr = allocate(count: count);
- Int32List array = ptr.asExternalTypedData(count: count);
+ Int32List array = ptr.asTypedList(count);
for (int i = 0; i < count; ++i) {
array[i] = i;
}
@@ -283,26 +270,26 @@
void testNegativeArray() {
Pointer<Int32> ptr = nullptr;
- Expect.throws<ArgumentError>(() => ptr.asExternalTypedData(count: -1));
+ Expect.throws<ArgumentError>(() => ptr.asTypedList(-1));
}
// Tests that the address we're creating an ExternalTypedData from is aligned to
// the element size.
void testAlignment() {
Expect.throws<ArgumentError>(
- () => Pointer<Int16>.fromAddress(1).asExternalTypedData());
+ () => Pointer<Int16>.fromAddress(1).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Int32>.fromAddress(2).asExternalTypedData());
+ () => Pointer<Int32>.fromAddress(2).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Int64>.fromAddress(4).asExternalTypedData());
+ () => Pointer<Int64>.fromAddress(4).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Uint16>.fromAddress(1).asExternalTypedData());
+ () => Pointer<Uint16>.fromAddress(1).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Uint32>.fromAddress(2).asExternalTypedData());
+ () => Pointer<Uint32>.fromAddress(2).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Uint64>.fromAddress(4).asExternalTypedData());
+ () => Pointer<Uint64>.fromAddress(4).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Float>.fromAddress(2).asExternalTypedData());
+ () => Pointer<Float>.fromAddress(2).asTypedList(1));
Expect.throws<ArgumentError>(
- () => Pointer<Double>.fromAddress(4).asExternalTypedData());
+ () => Pointer<Double>.fromAddress(4).asTypedList(1));
}
diff --git a/tests/ffi/highmem_32bit_test.dart b/tests/ffi/highmem_32bit_test.dart
index 36e9c5f..eeee5fa 100644
--- a/tests/ffi/highmem_32bit_test.dart
+++ b/tests/ffi/highmem_32bit_test.dart
@@ -51,23 +51,23 @@
memory[indexOffset + i] = 10 + i;
}
Expect.listEquals(<int>[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
- memory.offsetBy(indexOffset).asExternalTypedData(count: 10) as Uint8List);
+ memory.offsetBy(indexOffset).asTypedList(10));
for (int i = 0; i < 9; ++i) {
swapBytes(memory, indexOffset + 0, i, i + 1);
}
Expect.listEquals(<int>[11, 12, 13, 14, 15, 16, 17, 18, 19, 10],
- memory.offsetBy(indexOffset).asExternalTypedData(count: 10) as Uint8List);
+ memory.offsetBy(indexOffset).asTypedList(10));
for (int i = 0; i < 9; ++i) {
swapBytes(memory, indexOffset + kIgnoreBytesPositive, i, i + 1);
}
Expect.listEquals(<int>[12, 13, 14, 15, 16, 17, 18, 19, 10, 11],
- memory.offsetBy(indexOffset).asExternalTypedData(count: 10) as Uint8List);
+ memory.offsetBy(indexOffset).asTypedList(10));
for (int i = 0; i < 9; ++i) {
swapBytes(memory, indexOffset + kIgnoreBytesNegative, i, i + 1);
}
Expect.listEquals(<int>[13, 14, 15, 16, 17, 18, 19, 10, 11, 12],
- memory.offsetBy(indexOffset).asExternalTypedData(count: 10) as Uint8List);
+ memory.offsetBy(indexOffset).asTypedList(10));
}
void testOnHighOrLowMemory(Pointer<Uint8> memory, int indexOffset) {
diff --git a/tests/ffi/regress_37511_test.dart b/tests/ffi/regress_37511_test.dart
index 03403e4..e2a2e70 100644
--- a/tests/ffi/regress_37511_test.dart
+++ b/tests/ffi/regress_37511_test.dart
@@ -36,7 +36,7 @@
() => highAddressPointer.address,
() => highAddressPointer.elementAt(1),
() => highAddressPointer.offsetBy(1),
- () => highAddressPointer.asExternalTypedData(),
+ () => highAddressPointer.asTypedList(1),
// DynamicLibrary operations.
doDlopen,