Version 2.12.0-224.0.dev
Merge commit 'd37e833e23641ae65d1cc0aca24ef0852fc79f65' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 3e6b7cb..9257edd 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -296,7 +296,7 @@
"name": "html",
"rootUri": "../third_party/pkg/html",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.8"
},
{
"name": "http",
diff --git a/DEPS b/DEPS
index eb1da40..2c9ef02 100644
--- a/DEPS
+++ b/DEPS
@@ -73,7 +73,7 @@
"bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
"benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
"boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
- "boringssl_gen_rev": "429ccb1877f7987a6f3988228bc2440e61293499",
+ "boringssl_gen_rev": "aaac86738c4f2d1bdf00f54d197f50f247ffee04",
"boringssl_rev" : "4dfd5af70191b068aebe567b8e29ce108cee85ce",
"browser-compat-data_tag": "v1.0.22",
"charcode_rev": "bcd8a12c315b7a83390e4865ad847ecd9344cba2",
@@ -98,7 +98,7 @@
# and land the review.
#
# For more details, see https://github.com/dart-lang/sdk/issues/30164
-"dart_style_tag": "1.3.10", # Please see the note above before updating.
+ "dart_style_tag": "1.3.11", # Please see the note above before updating.
"chromedriver_tag": "83.0.4103.39",
"dartdoc_rev" : "a1d86f2c992f4660ddcc09b27733396e92765d2a",
@@ -106,7 +106,7 @@
"fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
"file_rev": "0e09370f581ab6388d46fda4cdab66638c0171a1",
"glob_rev": "7c0ef8d4fa086f6b185c4dd724b700e7d7ad8f79",
- "html_rev": "22f17e97fedeacaa1e945cf84d8016284eed33a6",
+ "html_rev": "137be8db5d5b7f00530fca1591292849ce6779c9",
"http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
"http_multi_server_rev" : "e8c8be7f15b4fb50757ff5bf29766721fbe24fe4",
"http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
diff --git a/benchmarks/FfiBoringssl/dart/FfiBoringssl.dart b/benchmarks/FfiBoringssl/dart/FfiBoringssl.dart
index 7025194..b4ba0c3 100644
--- a/benchmarks/FfiBoringssl/dart/FfiBoringssl.dart
+++ b/benchmarks/FfiBoringssl/dart/FfiBoringssl.dart
@@ -11,6 +11,7 @@
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'digest.dart';
import 'types.dart';
@@ -48,11 +49,11 @@
EVP_DigestInit(context, hashAlgorithm);
EVP_DigestUpdate(context, data, length);
final int resultSize = EVP_MD_CTX_size(context);
- final Pointer<Bytes> result = allocate<Uint8>(count: resultSize).cast();
+ final Pointer<Bytes> result = calloc<Uint8>(resultSize).cast();
EVP_DigestFinal(context, result, nullptr);
EVP_MD_CTX_free(context);
final String hash = base64Encode(toUint8List(result.ref, resultSize));
- free(result);
+ calloc.free(result);
return hash;
}
@@ -83,14 +84,14 @@
@override
void setup() {
- data = allocate<Uint8>(count: L).cast();
+ data = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(inventData(L), data.ref);
hash(data, L, hashAlgorithm);
}
@override
void teardown() {
- free(data);
+ calloc.free(data);
}
@override
@@ -113,10 +114,10 @@
@override
void setup() {
data = inventData(L);
- final Pointer<Data> dataInC = allocate<Uint8>(count: L).cast();
+ final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(data, dataInC.ref);
hash(dataInC, L, hashAlgorithm);
- free(dataInC);
+ calloc.free(dataInC);
}
@override
@@ -124,10 +125,10 @@
@override
void run() {
- final Pointer<Data> dataInC = allocate<Uint8>(count: L).cast();
+ final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(data, dataInC.ref);
final String result = hash(dataInC, L, hashAlgorithm);
- free(dataInC);
+ calloc.free(dataInC);
if (result != expectedHash) {
throw Exception('$name: Unexpected result: $result');
}
diff --git a/benchmarks/FfiBoringssl/dart/calloc.dart b/benchmarks/FfiBoringssl/dart/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/benchmarks/FfiBoringssl/dart/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiBoringssl/dart2/FfiBoringssl.dart b/benchmarks/FfiBoringssl/dart2/FfiBoringssl.dart
index 7db1f91..6bd064a 100644
--- a/benchmarks/FfiBoringssl/dart2/FfiBoringssl.dart
+++ b/benchmarks/FfiBoringssl/dart2/FfiBoringssl.dart
@@ -13,6 +13,7 @@
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'digest.dart';
import 'types.dart';
@@ -50,11 +51,11 @@
EVP_DigestInit(context, hashAlgorithm);
EVP_DigestUpdate(context, data, length);
final int resultSize = EVP_MD_CTX_size(context);
- final Pointer<Bytes> result = allocate<Uint8>(count: resultSize).cast();
+ final Pointer<Bytes> result = calloc<Uint8>(resultSize).cast();
EVP_DigestFinal(context, result, nullptr);
EVP_MD_CTX_free(context);
final String hash = base64Encode(toUint8List(result.ref, resultSize));
- free(result);
+ calloc.free(result);
return hash;
}
@@ -85,14 +86,14 @@
@override
void setup() {
- data = allocate<Uint8>(count: L).cast();
+ data = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(inventData(L), data.ref);
hash(data, L, hashAlgorithm);
}
@override
void teardown() {
- free(data);
+ calloc.free(data);
}
@override
@@ -115,10 +116,10 @@
@override
void setup() {
data = inventData(L);
- final Pointer<Data> dataInC = allocate<Uint8>(count: L).cast();
+ final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(data, dataInC.ref);
hash(dataInC, L, hashAlgorithm);
- free(dataInC);
+ calloc.free(dataInC);
}
@override
@@ -126,10 +127,10 @@
@override
void run() {
- final Pointer<Data> dataInC = allocate<Uint8>(count: L).cast();
+ final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
copyFromUint8ListToTarget(data, dataInC.ref);
final String result = hash(dataInC, L, hashAlgorithm);
- free(dataInC);
+ calloc.free(dataInC);
if (result != expectedHash) {
throw Exception('$name: Unexpected result: $result');
}
diff --git a/benchmarks/FfiBoringssl/dart2/calloc.dart b/benchmarks/FfiBoringssl/dart2/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/benchmarks/FfiBoringssl/dart2/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiCall/dart/FfiCall.dart b/benchmarks/FfiCall/dart/FfiCall.dart
index c2392a1..d33e120 100644
--- a/benchmarks/FfiCall/dart/FfiCall.dart
+++ b/benchmarks/FfiCall/dart/FfiCall.dart
@@ -13,6 +13,7 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
import 'dlopen_helper.dart';
//
@@ -1070,9 +1071,9 @@
Pointer<Uint8> pointer = nullptr;
@override
- void setup() => pointer = allocate(count: N + 1);
+ void setup() => pointer = calloc(N + 1);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -1091,13 +1092,13 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
}
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1119,7 +1120,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1127,7 +1128,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1156,7 +1157,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1170,7 +1171,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1219,7 +1220,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1243,7 +1244,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
diff --git a/benchmarks/FfiCall/dart/calloc.dart b/benchmarks/FfiCall/dart/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/benchmarks/FfiCall/dart/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiCall/dart2/FfiCall.dart b/benchmarks/FfiCall/dart2/FfiCall.dart
index fa67dce..3da29b4 100644
--- a/benchmarks/FfiCall/dart2/FfiCall.dart
+++ b/benchmarks/FfiCall/dart2/FfiCall.dart
@@ -15,6 +15,7 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
import 'dlopen_helper.dart';
//
@@ -1072,9 +1073,9 @@
Pointer<Uint8> pointer;
@override
- void setup() => pointer = allocate(count: N + 1);
+ void setup() => pointer = calloc(N + 1);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -1092,13 +1093,13 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
}
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1117,7 +1118,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1125,7 +1126,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1154,7 +1155,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1168,7 +1169,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
@@ -1217,7 +1218,7 @@
@override
void setup() {
- pointer = allocate(count: N + 1);
+ pointer = calloc(N + 1);
pointer2 = pointer.elementAt(1);
pointer3 = pointer.elementAt(2);
pointer4 = pointer.elementAt(3);
@@ -1241,7 +1242,7 @@
@override
void teardown() {
- free(pointer);
+ calloc.free(pointer);
}
@override
diff --git a/benchmarks/FfiCall/dart2/calloc.dart b/benchmarks/FfiCall/dart2/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/benchmarks/FfiCall/dart2/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiMemory/dart/FfiMemory.dart b/benchmarks/FfiMemory/dart/FfiMemory.dart
index d9ee487..423fa74 100644
--- a/benchmarks/FfiMemory/dart/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart/FfiMemory.dart
@@ -14,6 +14,8 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
+
//
// Pointer store.
//
@@ -210,9 +212,9 @@
PointerInt8() : super('FfiMemory.PointerInt8');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -229,9 +231,9 @@
PointerUint8() : super('FfiMemory.PointerUint8');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -248,9 +250,9 @@
PointerInt16() : super('FfiMemory.PointerInt16');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -267,9 +269,9 @@
PointerUint16() : super('FfiMemory.PointerUint16');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -286,9 +288,9 @@
PointerInt32() : super('FfiMemory.PointerInt32');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -305,9 +307,9 @@
PointerUint32() : super('FfiMemory.PointerUint32');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -324,9 +326,9 @@
PointerInt64() : super('FfiMemory.PointerInt64');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -343,9 +345,9 @@
PointerUint64() : super('FfiMemory.PointerUint64');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -362,9 +364,9 @@
PointerFloat() : super('FfiMemory.PointerFloat');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -381,9 +383,9 @@
PointerDouble() : super('FfiMemory.PointerDouble');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -402,14 +404,14 @@
@override
void setup() {
- pointer = allocate(count: N);
- data = allocate();
+ pointer = calloc(N);
+ data = calloc();
}
@override
void teardown() {
- free(pointer);
- free(data);
+ calloc.free(pointer);
+ calloc.free(data);
}
@override
@@ -427,9 +429,9 @@
PointerInt64Mint() : super('FfiMemory.PointerInt64Mint');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
diff --git a/benchmarks/FfiMemory/dart/calloc.dart b/benchmarks/FfiMemory/dart/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/benchmarks/FfiMemory/dart/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiMemory/dart2/FfiMemory.dart b/benchmarks/FfiMemory/dart2/FfiMemory.dart
index 11fbea2..d8d41e2 100644
--- a/benchmarks/FfiMemory/dart2/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart2/FfiMemory.dart
@@ -16,6 +16,8 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
+
//
// Pointer store.
//
@@ -212,9 +214,9 @@
PointerInt8() : super('FfiMemory.PointerInt8');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -231,9 +233,9 @@
PointerUint8() : super('FfiMemory.PointerUint8');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -250,9 +252,9 @@
PointerInt16() : super('FfiMemory.PointerInt16');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -269,9 +271,9 @@
PointerUint16() : super('FfiMemory.PointerUint16');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -288,9 +290,9 @@
PointerInt32() : super('FfiMemory.PointerInt32');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -307,9 +309,9 @@
PointerUint32() : super('FfiMemory.PointerUint32');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -326,9 +328,9 @@
PointerInt64() : super('FfiMemory.PointerInt64');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -345,9 +347,9 @@
PointerUint64() : super('FfiMemory.PointerUint64');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -364,9 +366,9 @@
PointerFloat() : super('FfiMemory.PointerFloat');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -383,9 +385,9 @@
PointerDouble() : super('FfiMemory.PointerDouble');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
@@ -404,14 +406,14 @@
@override
void setup() {
- pointer = allocate(count: N);
- data = allocate();
+ pointer = calloc(N);
+ data = calloc();
}
@override
void teardown() {
- free(pointer);
- free(data);
+ calloc.free(pointer);
+ calloc.free(data);
}
@override
@@ -429,9 +431,9 @@
PointerInt64Mint() : super('FfiMemory.PointerInt64Mint');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
diff --git a/benchmarks/FfiMemory/dart2/calloc.dart b/benchmarks/FfiMemory/dart2/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/benchmarks/FfiMemory/dart2/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiStruct/dart/FfiStruct.dart b/benchmarks/FfiStruct/dart/FfiStruct.dart
index 26768c5..a4a8f14 100644
--- a/benchmarks/FfiStruct/dart/FfiStruct.dart
+++ b/benchmarks/FfiStruct/dart/FfiStruct.dart
@@ -12,6 +12,8 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
+
//
// Struct field store (plus Pointer elementAt and load).
//
@@ -50,9 +52,9 @@
FieldLoadStore() : super('FfiStruct.FieldLoadStore');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
diff --git a/benchmarks/FfiStruct/dart/calloc.dart b/benchmarks/FfiStruct/dart/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/benchmarks/FfiStruct/dart/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/benchmarks/FfiStruct/dart2/FfiStruct.dart b/benchmarks/FfiStruct/dart2/FfiStruct.dart
index a11e8ab..6f4e17c 100644
--- a/benchmarks/FfiStruct/dart2/FfiStruct.dart
+++ b/benchmarks/FfiStruct/dart2/FfiStruct.dart
@@ -14,6 +14,8 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
+import 'calloc.dart';
+
//
// Struct field store (plus Pointer elementAt and load).
//
@@ -52,9 +54,9 @@
FieldLoadStore() : super('FfiStruct.FieldLoadStore');
@override
- void setup() => pointer = allocate(count: N);
+ void setup() => pointer = calloc(N);
@override
- void teardown() => free(pointer);
+ void teardown() => calloc.free(pointer);
@override
void run() {
diff --git a/benchmarks/FfiStruct/dart2/calloc.dart b/benchmarks/FfiStruct/dart2/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/benchmarks/FfiStruct/dart2/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/docs/process/breaking-changes.md b/docs/process/breaking-changes.md
index b277e44..b7023bd 100644
--- a/docs/process/breaking-changes.md
+++ b/docs/process/breaking-changes.md
@@ -35,7 +35,8 @@
* Must access libraries via the public API (for example, must not reach into
the internals of a package located in the `/src/` directory).
-* Must not rely on an [experiment flag](flags.md).
+* Must not rely on an [experiment flag](experimental-flags.md), or depend on
+ libraries or APIs that are documented as being experimental.
* Must not circumvent clear restrictions documented in the public API
documentation (for example, must not mixin a class clearly documented as
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/this.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/this.dart
new file mode 100644
index 0000000..4ea657e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/this.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test verifies that `this` cannot be promoted, even if it appears in an
+// extension method.
+
+class C {
+ void insideClass() {
+ if (this is D) {
+ this;
+ }
+ }
+}
+
+class D extends C {}
+
+extension on C {
+ void insideExtension() {
+ if (this is D) {
+ this;
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 4599f0a..95b2236 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -757,6 +757,11 @@
}
@override
+ void afterContextRefresh() {
+ analysisServer.addContextsToDeclarationsTracker();
+ }
+
+ @override
void afterWatchEvent(WatchEvent event) {
analysisServer._onAnalysisSetChangedController.add(null);
}
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 6fdd12d..d552d08 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -305,6 +305,10 @@
/// Create and return a new analysis driver rooted at the given [folder].
AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot);
+ /// Called after contexts are rebuilt, such as after recovering from a watcher
+ /// failure.
+ void afterContextRefresh();
+
/// An [event] was processed, so analysis state might be different now.
void afterWatchEvent(WatchEvent event);
@@ -563,6 +567,8 @@
// Rebuild contexts based on the data last sent to setRoots().
setRoots(includedPaths, excludedPaths);
+
+ callbacks.afterContextRefresh();
}
/// Sets the [ignorePatterns] for the context having info [info].
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
index 4a302a2..6ac4547 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
@@ -52,9 +52,9 @@
final result = await requireResolvedUnit(path);
return result.mapResult((result) async {
- return _getRefactoring(
- RefactoringKind(kind), result, offset, length, options)
- .mapResult((refactoring) async {
+ final refactoring = await _getRefactoring(
+ RefactoringKind(kind), result, offset, length, options);
+ return refactoring.mapResult((refactoring) async {
// If the token we were given is not cancellable, replace it with one that
// is for the rest of this request, as a future refactor may need to cancel
// this request.
@@ -99,24 +99,46 @@
});
}
- ErrorOr<Refactoring> _getRefactoring(
+ Future<ErrorOr<Refactoring>> _getRefactoring(
RefactoringKind kind,
ResolvedUnitResult result,
int offset,
int length,
Map<String, dynamic> options,
- ) {
+ ) async {
switch (kind) {
case RefactoringKind.EXTRACT_METHOD:
final refactor = ExtractMethodRefactoring(
server.searchEngine, result, offset, length);
- // TODO(dantup): For now we don't have a good way to prompt the user
- // for a method name so we just use a placeholder and expect them to
- // rename (this is what C#/Omnisharp does), but there's an open request
- // to handle this better.
- // https://github.com/microsoft/language-server-protocol/issues/764
- refactor.name =
- (options != null ? options['name'] : null) ?? 'newMethod';
+
+ var preferredName = options != null ? options['name'] : null;
+ // checkInitialConditions will populate names with suggestions.
+ if (preferredName == null) {
+ await refactor.checkInitialConditions();
+ if (refactor.names.isNotEmpty) {
+ preferredName = refactor.names.first;
+ }
+ }
+ refactor.name = preferredName ?? 'newMethod';
+
+ // Defaults to true, but may be surprising if users didn't have an option
+ // to opt in.
+ refactor.extractAll = false;
+ return success(refactor);
+
+ case RefactoringKind.EXTRACT_LOCAL_VARIABLE:
+ final refactor = ExtractLocalRefactoring(result, offset, length);
+
+ var preferredName = options != null ? options['name'] : null;
+ // checkInitialConditions will populate names with suggestions.
+ if (preferredName == null) {
+ await refactor.checkInitialConditions();
+ if (refactor.names.isNotEmpty) {
+ preferredName = refactor.names.first;
+ }
+ }
+ refactor.name = preferredName ?? 'newVariable';
+
// Defaults to true, but may be surprising if users didn't have an option
// to opt in.
refactor.extractAll = false;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 355cbde..f2bec91 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -439,6 +439,12 @@
'Extract Method', RefactoringKind.EXTRACT_METHOD));
}
+ // Extract Local Variable
+ if (ExtractLocalRefactoring(unit, offset, length).isAvailable()) {
+ refactorActions.add(createRefactor(CodeActionKind.RefactorExtract,
+ 'Extract Local Variable', RefactoringKind.EXTRACT_LOCAL_VARIABLE));
+ }
+
// Extract Widget
if (ExtractWidgetRefactoring(server.searchEngine, unit, offset, length)
.isAvailable()) {
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 7ec69da..106cd91 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -814,6 +814,11 @@
}
@override
+ void afterContextRefresh() {
+ analysisServer.addContextsToDeclarationsTracker();
+ }
+
+ @override
void afterWatchEvent(WatchEvent event) {
// TODO: implement afterWatchEvent
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 01b7721..ecaa1a8 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -153,8 +153,11 @@
var containingNode = request.target.containingNode;
var entity = request.target.entity;
- var token =
- entity is AstNode ? entity.endToken : entity is Token ? entity : null;
+ var token = entity is AstNode
+ ? entity.endToken
+ : entity is Token
+ ? entity
+ : null;
return (token != containingNode?.endToken) &&
token?.next?.type == TokenType.COMMA &&
!token.next.isSynthetic;
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 45318c1b..1bc803f 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -32,6 +32,7 @@
import 'package:analysis_server/src/services/correction/dart/create_method.dart';
import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
import 'package:analysis_server/src/services/correction/dart/make_final.dart';
import 'package:analysis_server/src/services/correction/dart/remove_argument.dart';
import 'package:analysis_server/src/services/correction/dart/remove_await.dart';
@@ -107,6 +108,9 @@
LintNames.avoid_init_to_null: [
RemoveInitializer.newInstance,
],
+ LintNames.avoid_private_typedef_functions: [
+ InlineTypedef.newInstance,
+ ],
LintNames.avoid_redundant_argument_values: [
RemoveArgument.newInstance,
],
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
index b4a176f..c62d89e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
@@ -188,20 +188,19 @@
} else if (node.parent is PropertyAccess) {
target = (node.parent as PropertyAccess).target;
}
- // find getter
- if (node.inGetterContext()) {
- await _proposeClassOrMixinMember(builder, target, (Element element) {
- return element is PropertyAccessorElement && element.isGetter ||
- element is FieldElement && element.getter != null;
- });
- }
- // find setter
- if (node.inSetterContext()) {
- await _proposeClassOrMixinMember(builder, target, (Element element) {
- return element is PropertyAccessorElement && element.isSetter ||
- element is FieldElement && element.setter != null;
- });
- }
+ // find getter or setter
+ var wantGetter = node.inGetterContext();
+ var wantSetter = node.inSetterContext();
+ await _proposeClassOrMixinMember(builder, target, (Element element) {
+ if (element is PropertyAccessorElement) {
+ return wantGetter && element.isGetter ||
+ wantSetter && element.isSetter;
+ } else if (element is FieldElement) {
+ return wantGetter && element.getter != null ||
+ wantSetter && element.setter != null;
+ }
+ return false;
+ });
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
new file mode 100644
index 0000000..765178a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, 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.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToNullAwareSpread extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE_SPREAD;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var parent = coveredNode.parent;
+ if (parent is SpreadElement && !parent.isNullAware) {
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleInsertion(parent.spreadOperator.end, '?');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertToNullAwareSpread newInstance() => ConvertToNullAwareSpread();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 23e7182..bce5281 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -247,6 +247,8 @@
'dart.fix.convert.toNamedArguments', 50, 'Convert to named arguments');
static const CONVERT_TO_NULL_AWARE =
FixKind('dart.fix.convert.toNullAware', 50, "Convert to use '?.'");
+ static const CONVERT_TO_NULL_AWARE_SPREAD = FixKind(
+ 'dart.fix.convert.toNullAwareSpread', 50, "Convert to use '...?'");
static const CONVERT_TO_ON_TYPE =
FixKind('dart.fix.convert.toOnType', 50, "Convert to 'on {0}'");
static const CONVERT_TO_PACKAGE_IMPORT = FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b84c1e6..97be45b 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -49,6 +49,7 @@
import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_named_arguments.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_spread.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
@@ -846,6 +847,7 @@
],
CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_IN_SPREAD: [
AddNullCheck.newInstance,
+ ConvertToNullAwareSpread.newInstance,
],
CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH: [
AddNullCheck.newInstance,
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 8b50d8f..61e3ffa 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -2325,6 +2325,9 @@
}
@override
+ void afterContextRefresh() {}
+
+ @override
void afterWatchEvent(WatchEvent event) {}
@override
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index 0db9f8d..bd236eb 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -17,6 +17,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(ExtractMethodRefactorCodeActionsTest);
defineReflectiveTests(ExtractWidgetRefactorCodeActionsTest);
+ defineReflectiveTests(ExtractVariableRefactorCodeActionsTest);
});
}
@@ -158,6 +159,38 @@
req1, throwsA(isResponseError(ErrorCodes.ContentModified)));
}
+ Future<void> test_generatesNames() async {
+ const content = '''
+Object main() {
+ return Container([[Text('Test!')]]);
+}
+
+Object Container(Object text) => null;
+Object Text(Object text) => null;
+ ''';
+ const expectedContent = '''
+Object main() {
+ return Container(text());
+}
+
+Object text() => Text('Test!');
+
+Object Container(Object text) => null;
+Object Text(Object text) => null;
+ ''';
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ range: rangeFromMarkers(content));
+ final codeAction =
+ findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
+ expect(codeAction, isNotNull);
+
+ await verifyCodeActionEdits(
+ codeAction, withoutMarkers(content), expectedContent);
+ }
+
Future<void> test_invalidLocation() async {
const content = '''
import 'dart:convert';
@@ -297,6 +330,71 @@
}
@reflectiveTest
+class ExtractVariableRefactorCodeActionsTest extends AbstractCodeActionsTest {
+ final extractVariableTitle = 'Extract Local Variable';
+
+ Future<void> test_appliesCorrectEdits() async {
+ const content = '''
+main() {
+ foo([[1 + 2]]);
+}
+
+void foo(int arg) {}
+ ''';
+ const expectedContent = '''
+main() {
+ var arg = 1 + 2;
+ foo(arg);
+}
+
+void foo(int arg) {}
+ ''';
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ range: rangeFromMarkers(content));
+ final codeAction = findCommand(
+ codeActions, Commands.performRefactor, extractVariableTitle);
+ expect(codeAction, isNotNull);
+
+ await verifyCodeActionEdits(
+ codeAction, withoutMarkers(content), expectedContent);
+ }
+
+ Future<void> test_doesNotCreateNameConflicts() async {
+ const content = '''
+main() {
+ var arg = "test";
+ foo([[1 + 2]]);
+}
+
+void foo(int arg) {}
+ ''';
+ const expectedContent = '''
+main() {
+ var arg = "test";
+ var arg2 = 1 + 2;
+ foo(arg2);
+}
+
+void foo(int arg) {}
+ ''';
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ range: rangeFromMarkers(content));
+ final codeAction = findCommand(
+ codeActions, Commands.performRefactor, extractVariableTitle);
+ expect(codeAction, isNotNull);
+
+ await verifyCodeActionEdits(
+ codeAction, withoutMarkers(content), expectedContent);
+ }
+}
+
+@reflectiveTest
class ExtractWidgetRefactorCodeActionsTest extends AbstractCodeActionsTest {
final extractWidgetTitle = 'Extract Widget';
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
index 623b668..6d9e3fc 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
@@ -67,6 +67,25 @@
expect(includedIdSet, contains(asyncSet.id));
}
+ Future<void> test_dart_afterRecovery() async {
+ addTestFile('');
+ // Wait for a known set to be available.
+ await waitForSetWithUri('dart:math');
+
+ // Ensure the set is returned in the results.
+ var results = await _getSuggestions(testFile, 0);
+ expect(results.includedSuggestionSets, isNotEmpty);
+
+ // Force the server to rebuild all contexts, as happens when the file watcher
+ // fails on Windows.
+ // https://github.com/dart-lang/sdk/issues/44650
+ server.contextManager.refresh(null);
+
+ // Ensure the set is still returned after the rebuild.
+ results = await _getSuggestions(testFile, 0);
+ expect(results.includedSuggestionSets, isNotEmpty);
+ }
+
Future<void> test_dart_instanceCreationExpression() async {
addTestFile(r'''
main() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
index e3a1c37..676a700 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
@@ -37,6 +37,52 @@
@override
FixKind get kind => DartFixKind.ADD_LATE;
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44534')
+ Future<void> test_changeInImportedLib() async {
+ addSource('/home/test/lib/a.dart', '''
+class C {
+ final String s;
+}
+''');
+ await resolveTestCode('''
+import 'a.dart';
+
+void f(C c) {
+ c.s = '';
+}
+''');
+ await assertHasFix('''
+class C {
+ late final String s;
+}
+''', target: '/home/test/lib/a.dart');
+ }
+
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44534')
+ Future<void> test_changeInPart() async {
+ addSource('/home/test/lib/a.dart', '''
+part 'test.dart';
+
+class C {
+ final String s;
+}
+''');
+ await resolveTestCode('''
+part of 'a.dart';
+
+void f(C c) {
+ c.s = '';
+}
+''');
+ await assertHasFix('''
+part 'test.dart';
+
+class C {
+ late final String s;
+}
+''', target: '/home/test/lib/a.dart');
+ }
+
Future<void> test_withFinal() async {
await resolveTestCode('''
class C {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart
new file mode 100644
index 0000000..c2612f9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/inline_typedef_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, 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.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InlineTypedefTest);
+ });
+}
+
+@reflectiveTest
+class InlineTypedefTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.avoid_private_typedef_functions;
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+typedef _F1 = void Function(int);
+typedef _F2<T> = void Function(T);
+void g(_F2<_F1> f) {}
+''');
+ // Eventually both fixes will be applied but for now we're satisfied that
+ // the results are clean.
+ await assertHasFix('''
+typedef _F2<T> = void Function(T);
+void g(_F2<void Function(int)> f) {}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 4ed3e33..76e9f01 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -34,6 +34,7 @@
import 'create_method_test.dart' as create_method;
import 'data_driven_test.dart' as data_driven;
import 'inline_invocation_test.dart' as inline_invocation;
+import 'inline_typedef_test.dart' as inline_typedef;
import 'make_final_test.dart' as make_final;
import 'remove_argument_test.dart' as remove_argument;
import 'remove_await_test.dart' as remove_await;
@@ -97,6 +98,7 @@
create_method.main();
data_driven.main();
inline_invocation.main();
+ inline_typedef.main();
make_final.main();
remove_argument.main();
remove_await.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
index e3e581b..da9231f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -311,6 +312,75 @@
''');
}
+ Future<void> test_getterSetter_qualified() async {
+ await resolveTestCode('''
+class A {
+ int get foo => 0;
+ set foo(int _) {}
+}
+
+void f(A a) {
+ a.foo2 += 2;
+}
+''');
+ await assertHasFix('''
+class A {
+ int get foo => 0;
+ set foo(int _) {}
+}
+
+void f(A a) {
+ a.foo += 2;
+}
+''', errorFilter: (e) => e.errorCode == CompileTimeErrorCode.UNDEFINED_GETTER);
+ }
+
+ Future<void> test_getterSetter_qualified_static() async {
+ await resolveTestCode('''
+class A {
+ static int get foo => 0;
+ static set foo(int _) {}
+}
+
+void f() {
+ A.foo2 += 2;
+}
+''');
+ await assertHasFix('''
+class A {
+ static int get foo => 0;
+ static set foo(int _) {}
+}
+
+void f() {
+ A.foo += 2;
+}
+''', errorFilter: (e) => e.errorCode == CompileTimeErrorCode.UNDEFINED_GETTER);
+ }
+
+ Future<void> test_getterSetter_unqualified() async {
+ await resolveTestCode('''
+class A {
+ int get foo => 0;
+ set foo(int _) {}
+
+ void f() {
+ foo2 += 2;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int get foo => 0;
+ set foo(int _) {}
+
+ void f() {
+ foo += 2;
+ }
+}
+''');
+ }
+
Future<void> test_method_ignoreOperators() async {
await resolveTestCode('''
main(Object object) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart
new file mode 100644
index 0000000..8cdcb25
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_spread_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2021, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../abstract_context.dart';
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToNullAwareSpreadTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToNullAwareSpreadTest extends FixProcessorTest
+ with WithNullSafetyMixin {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_TO_NULL_AWARE_SPREAD;
+
+ Future<void> test_spreadList() async {
+ await resolveTestCode('''
+void f (List<String>? args) {
+ [...args];
+}
+''');
+ await assertHasFix('''
+void f (List<String>? args) {
+ [...?args];
+}
+''');
+ }
+
+ Future<void> test_spreadMap() async {
+ await resolveTestCode('''
+void f (Map<int, String>? args) {
+ print({...args});
+}
+''');
+ await assertHasFix('''
+void f (Map<int, String>? args) {
+ print({...?args});
+}
+''');
+ }
+
+ Future<void> test_spreadSet() async {
+ await resolveTestCode('''
+void f (List<String>? args) {
+ print({...args});
+}
+''');
+ await assertHasFix('''
+void f (List<String>? args) {
+ print({...?args});
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index f4b05e6..62832b7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -54,6 +54,7 @@
import 'convert_to_list_literal_test.dart' as convert_to_list_literal;
import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
+import 'convert_to_null_aware_spread_test.dart' as convert_to_null_aware_spread;
import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
import 'convert_to_on_type_test.dart' as convert_to_on_type;
import 'convert_to_package_import_test.dart' as convert_to_package_import;
@@ -219,6 +220,7 @@
convert_to_map_literal.main();
convert_to_named_arguments.main();
convert_to_null_aware.main();
+ convert_to_null_aware_spread.main();
convert_to_on_type.main();
convert_to_package_import.main();
convert_to_relative_import.main();
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index c2ae7ca..ee72b09 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -63,13 +63,13 @@
}
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (value == null) {
return UNKNOWN_VALUE;
}
@@ -94,11 +94,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
BoolState lazyOr(InstanceState Function() rightOperandComputer) {
if (value == true) {
return TRUE_STATE;
@@ -415,7 +410,7 @@
return DartObjectImpl(
typeSystem,
typeSystem.typeProvider.boolType,
- _state.equalEqual(rightOperand._state),
+ _state.equalEqual(typeSystem, rightOperand._state),
);
}
throw EvaluationException(
@@ -544,7 +539,7 @@
return DartObjectImpl(
typeSystem,
typeSystem.typeProvider.boolType,
- _state.isIdentical(rightOperand._state),
+ _state.isIdentical(typeSystem, rightOperand._state),
);
}
@@ -582,7 +577,7 @@
return DartObjectImpl(
typeSystem,
typeSystem.typeProvider.boolType,
- _state.lazyEqualEqual(rightOperand._state),
+ _state.lazyEqualEqual(typeSystem, rightOperand._state),
);
}
throw EvaluationException(
@@ -1065,7 +1060,7 @@
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (value == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -1086,11 +1081,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
BoolState lessThan(InstanceState rightOperand) {
assertNumOrNull(rightOperand);
if (value == null) {
@@ -1249,12 +1239,12 @@
}
@override
- BoolState equalEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (_element == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -1269,11 +1259,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() => _element == null ? "-unknown-" : _element.name;
}
@@ -1340,22 +1325,17 @@
StringState convertToString() => StringState.UNKNOWN_VALUE;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
return BoolState.from(this == rightOperand);
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() {
StringBuffer buffer = StringBuffer();
List<String> fieldNames = _fieldMap.keys.toList();
@@ -1536,7 +1516,7 @@
///
/// Throws an [EvaluationException] if the operator is not appropriate for an
/// object of this kind.
- BoolState equalEqual(InstanceState rightOperand);
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand);
/// Return the result of invoking the '>' operator on this object with the
/// [rightOperand].
@@ -1573,7 +1553,7 @@
/// Return the result of invoking the identical function on this object with
/// the [rightOperand].
- BoolState isIdentical(InstanceState rightOperand);
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand);
/// Return the result of invoking the '&&' operator on this object with the
/// [rightOperand].
@@ -1595,7 +1575,12 @@
///
/// Throws an [EvaluationException] if the operator is not appropriate for an
/// object of this kind.
- BoolState lazyEqualEqual(InstanceState rightOperand);
+ BoolState lazyEqualEqual(
+ TypeSystemImpl typeSystem,
+ InstanceState rightOperand,
+ ) {
+ return isIdentical(typeSystem, rightOperand);
+ }
/// Return the result of invoking the '||' operator on this object with the
/// [rightOperand].
@@ -1988,7 +1973,7 @@
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (value == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -2009,11 +1994,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
BoolState lessThan(InstanceState rightOperand) {
assertNumOrNull(rightOperand);
if (value == null) {
@@ -2262,22 +2242,17 @@
StringState convertToString() => StringState.UNKNOWN_VALUE;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
return BoolState.from(this == rightOperand);
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() {
StringBuffer buffer = StringBuffer();
buffer.write('[');
@@ -2342,22 +2317,17 @@
StringState convertToString() => StringState.UNKNOWN_VALUE;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
return BoolState.from(this == rightOperand);
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() {
StringBuffer buffer = StringBuffer();
buffer.write('{');
@@ -2406,22 +2376,17 @@
StringState convertToString() => StringState("null");
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
return BoolState.from(rightOperand is NullState);
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
BoolState logicalNot() {
throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
@@ -2436,9 +2401,9 @@
bool get isBoolNumStringOrNull => true;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
}
@@ -2488,22 +2453,17 @@
StringState convertToString() => StringState.UNKNOWN_VALUE;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
return BoolState.from(this == rightOperand);
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() {
StringBuffer buffer = StringBuffer();
buffer.write('{');
@@ -2567,13 +2527,13 @@
StringState convertToString() => this;
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (value == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -2588,11 +2548,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
IntState stringLength() {
if (value == null) {
return IntState.UNKNOWN_VALUE;
@@ -2631,13 +2586,13 @@
}
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (value == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -2652,11 +2607,6 @@
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() => value == null ? "-unknown-" : "#$value";
}
@@ -2687,13 +2637,13 @@
}
@override
- BoolState equalEqual(InstanceState rightOperand) {
+ BoolState equalEqual(TypeSystemImpl typeSystem, InstanceState rightOperand) {
assertBoolNumStringOrNull(rightOperand);
- return isIdentical(rightOperand);
+ return isIdentical(typeSystem, rightOperand);
}
@override
- BoolState isIdentical(InstanceState rightOperand) {
+ BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) {
if (_type == null) {
return BoolState.UNKNOWN_VALUE;
}
@@ -2702,17 +2652,15 @@
if (rightType == null) {
return BoolState.UNKNOWN_VALUE;
}
- return BoolState.from(_type == rightType);
+
+ return BoolState.from(
+ typeSystem.runtimeTypesEqual(_type, rightType),
+ );
}
return BoolState.FALSE_STATE;
}
@override
- BoolState lazyEqualEqual(InstanceState rightOperand) {
- return isIdentical(rightOperand);
- }
-
- @override
String toString() {
return _type?.getDisplayString(withNullability: true) ?? '-unknown-';
}
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index d3d43e6..b46391b 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -285,7 +285,8 @@
errorNode: node,
);
- if (superMember is MethodElement &&
+ if (!_isNonNullableByDefault &&
+ superMember is MethodElement &&
member is MethodElement &&
methodParameterNodes != null) {
_checkForOptionalParametersDifferentDefaultValues(
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 160ed2f..aa2140b 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -14,6 +14,12 @@
/// used. See 'pkg/vm/lib/transformations/ffi_checks.md' for the specification
/// of the desired hints.
class FfiVerifier extends RecursiveAstVisitor<void> {
+ static const _allocatorClassName = 'Allocator';
+ static const _allocateExtensionMethodName = 'call';
+ static const _allocatorExtensionName = 'AllocatorAlloc';
+ static const _dartFfiLibraryName = 'dart.ffi';
+ static const _opaqueClassName = 'Opaque';
+
static const List<String> _primitiveIntegerNativeTypes = [
'Int8',
'Int16',
@@ -31,6 +37,8 @@
'Double',
];
+ static const _structClassName = 'Struct';
+
/// The type system used to check types.
final TypeSystemImpl typeSystem;
@@ -47,14 +55,16 @@
@override
void visitClassDeclaration(ClassDeclaration node) {
inStruct = false;
- // Only the Struct class may be extended.
+ // Only the Allocator, Opaque and Struct class may be extended.
ExtendsClause extendsClause = node.extendsClause;
if (extendsClause != null) {
final TypeName superclass = extendsClause.superclass;
if (_isDartFfiClass(superclass)) {
- if (superclass.name.staticElement.name == 'Struct') {
+ final className = superclass.name.staticElement.name;
+ if (className == _structClassName) {
inStruct = true;
- } else {
+ } else if (className != _allocatorClassName &&
+ className != _opaqueClassName) {
_errorReporter.reportErrorForNode(
FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS,
superclass.name,
@@ -71,6 +81,10 @@
// No classes from the FFI may be explicitly implemented.
void checkSupertype(TypeName typename, FfiCode subtypeOfFfiCode,
FfiCode subtypeOfStructCode) {
+ final superName = typename.name.staticElement?.name;
+ if (superName == _allocatorClassName) {
+ return;
+ }
if (_isDartFfiClass(typename)) {
_errorReporter.reportErrorForNode(
subtypeOfFfiCode, typename, [node.name, typename.name]);
@@ -120,6 +134,21 @@
}
@override
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ Element element = node.staticElement;
+ if (element is MethodElement) {
+ Element enclosingElement = element.enclosingElement;
+ if (enclosingElement is ExtensionElement) {
+ if (_isAllocatorExtension(enclosingElement) &&
+ element.name == _allocateExtensionMethodName) {
+ _validateAllocate(node);
+ }
+ }
+ }
+ super.visitFunctionExpressionInvocation(node);
+ }
+
+ @override
void visitMethodInvocation(MethodInvocation node) {
Element element = node.methodName.staticElement;
if (element is MethodElement) {
@@ -145,6 +174,12 @@
super.visitMethodInvocation(node);
}
+ /// Return `true` if the given [element] represents the extension
+ /// `AllocatorAlloc`.
+ bool _isAllocatorExtension(Element element) =>
+ element.name == _allocatorExtensionName &&
+ element.library.name == _dartFfiLibraryName;
+
/// Return `true` if the [typeName] is the name of a type from `dart:ffi`.
bool _isDartFfiClass(TypeName typeName) =>
_isDartFfiElement(typeName.name.staticElement);
@@ -154,14 +189,15 @@
if (element is ConstructorElement) {
element = element.enclosingElement;
}
- return element is ClassElement && element.library.name == 'dart.ffi';
+ return element is ClassElement &&
+ element.library.name == _dartFfiLibraryName;
}
/// Return `true` if the given [element] represents the extension
/// `DynamicLibraryExtension`.
bool _isDynamicLibraryExtension(Element element) =>
element.name == 'DynamicLibraryExtension' &&
- element.library.name == 'dart.ffi';
+ element.library.name == _dartFfiLibraryName;
bool _isEmptyStruct(ClassElement classElement) {
final fields = classElement.fields;
@@ -182,13 +218,13 @@
}
bool _isHandle(Element element) =>
- element.name == 'Handle' && element.library.name == 'dart.ffi';
+ element.name == 'Handle' && element.library.name == _dartFfiLibraryName;
/// Returns `true` iff [nativeType] is a `ffi.NativeFunction<???>` type.
bool _isNativeFunctionInterfaceType(DartType nativeType) {
if (nativeType is InterfaceType) {
final element = nativeType.element;
- if (element.library.name == 'dart.ffi') {
+ if (element.library.name == _dartFfiLibraryName) {
return element.name == 'NativeFunction' &&
nativeType.typeArguments?.length == 1;
}
@@ -198,28 +234,43 @@
bool _isNativeFunctionPointerExtension(Element element) =>
element.name == 'NativeFunctionPointer' &&
- element.library.name == 'dart.ffi';
+ element.library.name == _dartFfiLibraryName;
/// Returns `true` iff [nativeType] is a `ffi.NativeType` type.
bool _isNativeTypeInterfaceType(DartType nativeType) {
if (nativeType is InterfaceType) {
final element = nativeType.element;
- if (element.library.name == 'dart.ffi') {
+ if (element.library.name == _dartFfiLibraryName) {
return element.name == 'NativeType';
}
}
return false;
}
+ /// Returns `true` iff [nativeType] is a opaque type, i.e. a subtype of `Opaque`.
+ bool _isOpaqueClass(DartType nativeType) {
+ if (nativeType is InterfaceType) {
+ final superType = nativeType.element.supertype;
+ if (superType == null) {
+ return false;
+ }
+ final superClassElement = superType.element;
+ if (superClassElement.library.name == _dartFfiLibraryName) {
+ return superClassElement.name == _opaqueClassName;
+ }
+ }
+ return false;
+ }
+
/// Return `true` if the given [element] represents the class `Pointer`.
bool _isPointer(Element element) =>
- element.name == 'Pointer' && element.library.name == 'dart.ffi';
+ element.name == 'Pointer' && element.library.name == _dartFfiLibraryName;
/// Returns `true` iff [nativeType] is a `ffi.Pointer<???>` type.
bool _isPointerInterfaceType(DartType nativeType) {
if (nativeType is InterfaceType) {
final element = nativeType.element;
- if (element.library.name == 'dart.ffi') {
+ if (element.library.name == _dartFfiLibraryName) {
return element.name == 'Pointer' &&
nativeType.typeArguments?.length == 1;
}
@@ -235,8 +286,8 @@
return false;
}
final superClassElement = superType.element;
- if (superClassElement.library.name == 'dart.ffi') {
- return superClassElement.name == 'Struct' &&
+ if (superClassElement.library.name == _dartFfiLibraryName) {
+ return superClassElement.name == _structClassName &&
nativeType.typeArguments?.isEmpty == true;
}
}
@@ -249,8 +300,8 @@
if (superType is ClassElement) {
bool isStruct(InterfaceType type) {
return type != null &&
- type.element.name == 'Struct' &&
- type.element.library.name == 'dart.ffi';
+ type.element.name == _structClassName &&
+ type.element.library.name == _dartFfiLibraryName;
}
return isStruct(superType.supertype) ||
@@ -311,6 +362,9 @@
}
return true;
}
+ if (_isOpaqueClass(nativeType)) {
+ return true;
+ }
} else if (nativeType is FunctionType) {
return _isValidFfiNativeFunctionType(nativeType);
}
@@ -320,7 +374,7 @@
_PrimitiveDartType _primitiveNativeType(DartType nativeType) {
if (nativeType is InterfaceType) {
final element = nativeType.element;
- if (element.library.name == 'dart.ffi') {
+ if (element.library.name == _dartFfiLibraryName) {
final String name = element.name;
if (_primitiveIntegerNativeTypes.contains(name)) {
return _PrimitiveDartType.int;
@@ -353,6 +407,17 @@
return _PrimitiveDartType.none;
}
+ void _validateAllocate(FunctionExpressionInvocation node) {
+ final DartType dartType = node.typeArgumentTypes[0];
+ if (!_isValidFfiNativeType(dartType, true, true)) {
+ final AstNode errorNode = node;
+ _errorReporter.reportErrorForNode(
+ FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
+ errorNode,
+ ['$_allocatorExtensionName.$_allocateExtensionMethodName']);
+ }
+ }
+
/// Validate that the [annotations] include exactly one annotation that
/// satisfies the [requiredTypes]. If an error is produced that cannot be
/// associated with an annotation, associate it with the [errorNode].
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index f9aa5a8..0a47069 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -834,6 +834,34 @@
_assertIdentical(_boolValue(null), _stringValue(null), _stringValue("def"));
}
+ void test_identical_Type_interfaceType() {
+ _assertIdentical(
+ _boolValue(true),
+ _typeValue(_typeProvider.intType),
+ _typeValue(_typeProvider.intType),
+ );
+
+ _assertIdentical(
+ _boolValue(false),
+ _typeValue(_typeProvider.intType),
+ _typeValue(_typeProvider.numType),
+ );
+
+ _assertIdentical(
+ _boolValue(true),
+ _typeValue(_typeProvider.futureOrType2(_typeProvider.objectType)),
+ _typeValue(_typeProvider.objectType),
+ );
+ }
+
+ void test_identical_Type_notType() {
+ _assertIdentical(
+ _boolValue(false),
+ _typeValue(_typeProvider.intType),
+ _intValue(0),
+ );
+ }
+
void test_integerDivide_infinity_knownDouble() {
_assertIntegerDivide(
null,
@@ -2142,4 +2170,12 @@
SymbolState(value),
);
}
+
+ DartObjectImpl _typeValue(DartType value) {
+ return DartObjectImpl(
+ _typeSystem,
+ _typeProvider.typeType,
+ TypeState(value),
+ );
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
index 110480c..2c6d4f1 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
@@ -20,7 +20,8 @@
class InvalidOverrideDifferentDefaultValuesNamedTest
extends PubPackageResolutionTest {
test_abstract_different_base_value() async {
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
abstract class A {
void foo({x = 0}) {}
}
@@ -28,10 +29,12 @@
abstract class B extends A {
void foo({x = 1});
}
-''', [
- error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
- 86, 5),
- ]);
+''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+ 86, 5),
+ ]),
+ );
}
test_abstract_noDefault_base_noDefault() async {
@@ -132,16 +135,19 @@
}
test_concrete_different() async {
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
class A {
void foo({x = 0}) {}
}
class B extends A {
void foo({x = 1}) {}
-}''', [
- error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
- 67, 5),
- ]);
+}''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+ 67, 5),
+ ]),
+ );
}
test_concrete_equal() async {
@@ -282,17 +288,20 @@
// If the base class provided an explicit value for a default parameter,
// then it is a static warning for the derived class to provide a different
// value, even if implicitly.
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
class A {
void foo({x: 1}) {}
}
class B extends A {
void foo({x}) {}
}
-''', [
- error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
- 66, 1),
- ]);
+''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+ 66, 1),
+ ]),
+ );
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
index 50128c9..c25b8e0 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
@@ -20,7 +20,8 @@
class InvalidOverrideDifferentDefaultValuesPositionalTest
extends PubPackageResolutionTest {
test_abstract_different_base_value() async {
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
abstract class A {
void foo([x = 0]) {}
}
@@ -28,13 +29,15 @@
abstract class B extends A {
void foo([x = 1]);
}
-''', [
- error(
- StaticWarningCode
- .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
- 86,
- 5),
- ]);
+''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(
+ StaticWarningCode
+ .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+ 86,
+ 5),
+ ]),
+ );
}
test_abstract_noDefault_base_noDefault() async {
@@ -140,20 +143,23 @@
}
test_concrete_different() async {
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
class A {
void foo([x = 0]) {}
}
class B extends A {
void foo([x = 1]) {}
}
-''', [
- error(
- StaticWarningCode
- .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
- 67,
- 5),
- ]);
+''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(
+ StaticWarningCode
+ .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+ 67,
+ 5),
+ ]),
+ );
}
test_concrete_equal() async {
@@ -294,20 +300,23 @@
// If the base class provided an explicit value for a default parameter,
// then it is a static warning for the derived class to provide a different
// value, even if implicitly.
- await assertErrorsInCode(r'''
+ await assertErrorsInCode(
+ r'''
class A {
void foo([x = 1]) {}
}
class B extends A {
void foo([x]) {}
}
-''', [
- error(
- StaticWarningCode
- .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
- 67,
- 1),
- ]);
+''',
+ expectedErrorsByNullability(nullable: [], legacy: [
+ error(
+ StaticWarningCode
+ .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+ 67,
+ 1),
+ ]),
+ );
}
}
diff --git a/pkg/dds/test/sse_smoke_test.dart b/pkg/dds/test/sse_smoke_test.dart
index 823f816..9d4a9a6 100644
--- a/pkg/dds/test/sse_smoke_test.dart
+++ b/pkg/dds/test/sse_smoke_test.dart
@@ -106,7 +106,7 @@
createTest(true);
createTest(false);
- });
+ }, timeout: Timeout.none);
}
FutureOr<shelf.Response> _faviconHandler(shelf.Request request) {
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index 28122d7..391be7e 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -31,6 +31,34 @@
!node.name.text.endsWith(lateIsSetSuffix);
}
+/// Returns the name of the original field for a lowered late field where
+/// [node] is the field holding the value of a lowered late field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where '_#field' is the field holding that value and 'field' is the name of
+/// the original field.
+///
+/// This assumes that `isLateLoweredField(node)` is true.
+Name extractFieldNameFromLateLoweredField(Field node) {
+ assert(isLateLoweredField(node));
+ String prefix = lateFieldPrefix;
+ if (node.isInstanceMember) {
+ prefix = '$prefix${node.enclosingClass.name}#';
+ }
+ return new Name(node.name.text.substring(prefix.length), node.name.library);
+}
+
/// Returns `true` if [node] is the field holding the marker for whether a
/// lowered late field has been set or not.
///
@@ -58,6 +86,40 @@
node.name.text.endsWith(lateIsSetSuffix);
}
+/// Returns the name of the original field for a lowered late field where [node]
+/// is the field holding the marker for whether the lowered late field has been
+/// set or not.
+///
+/// For instance
+///
+/// late int? field;
+///
+/// is lowered to (simplified):
+///
+/// bool _#field#isSet = false;
+/// int? _#field = null;
+/// int get field => _#field#isSet ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// _#field#isSet = true;
+/// }
+///
+/// where '_#field#isSet' is the field holding the marker and 'field' is the
+/// name of the original field.
+///
+/// This assumes that `isLateLoweredIsSetField(node)` is true.
+Name extractFieldNameFromLateLoweredIsSetField(Field node) {
+ assert(isLateLoweredIsSetField(node));
+ String prefix = lateFieldPrefix;
+ if (node.isInstanceMember) {
+ prefix = '$prefix${node.enclosingClass.name}#';
+ }
+ return new Name(
+ node.name.text.substring(
+ prefix.length, node.name.text.length - lateIsSetSuffix.length),
+ node.name.library);
+}
+
/// Returns `true` if [node] is the getter for reading the value of a lowered
/// late field.
///
@@ -93,6 +155,30 @@
return false;
}
+/// Returns the name of the original field for a lowered late field where [node]
+/// is the getter for reading the value of a lowered late field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where 'int get field' is the getter for reading the field and 'field' is the
+/// name of the original field.
+///
+/// This assumes that `isLateLoweredFieldGetter(node)` is true.
+Name extractFieldNameFromLateLoweredFieldGetter(Procedure node) {
+ assert(isLateLoweredFieldGetter(node));
+ return node.name;
+}
+
/// Returns `true` if [node] is the setter for setting the value of a lowered
/// late field.
///
@@ -128,6 +214,265 @@
return false;
}
+/// Returns the name of the original field for a lowered late field where [node]
+/// is the setter for setting the value of a lowered late field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where 'void set field' is the setter for setting the value of the field and
+/// 'field' is the name of the original field.
+///
+/// This assumes that `isLateLoweredFieldSetter(node)` is true.
+Name extractFieldNameFromLateLoweredFieldSetter(Procedure node) {
+ assert(isLateLoweredFieldSetter(node));
+ return node.name;
+}
+
+/// Returns the original initializer of a lowered late field where [node] is
+/// either the field holding the value, the field holding the marker for whether
+/// it has been set or not, getter for reading the value, or the setter for
+/// setting the value of the field.
+///
+/// For instance
+///
+/// late int field = 42;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field == null ? throw 'Uninitialized' : _#field = 42;
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where this original initializer is `42`, '_#field' is the field holding that
+/// value, '_#field#isSet' is the field holding the marker, 'int get field' is
+/// the getter for reading the field, and 'void set field' is the setter for
+/// setting the value of the field.
+///
+/// If the original late field had no initializer, `null` is returned.
+///
+/// If [node] is not part of a late field lowering, `null` is returned.
+Expression getLateFieldInitializer(Member node) {
+ Procedure lateFieldGetter = _getLateFieldTarget(node);
+ if (lateFieldGetter != null) {
+ Statement body = lateFieldGetter.function.body;
+ if (body is Block &&
+ body.statements.length == 2 &&
+ body.statements.first is IfStatement) {
+ IfStatement ifStatement = body.statements.first;
+ if (ifStatement.then is Block) {
+ Block block = ifStatement.then;
+ if (block.statements.isNotEmpty &&
+ block.statements.first is ExpressionStatement) {
+ ExpressionStatement firstStatement = block.statements.first;
+ if (firstStatement.expression is PropertySet) {
+ // We have
+ //
+ // get field {
+ // if (!_#isSet#field) {
+ // this._#field = <init>;
+ // ...
+ // }
+ // return _#field;
+ // }
+ //
+ // in case `<init>` is the initializer.
+ PropertySet propertySet = firstStatement.expression;
+ assert(propertySet.interfaceTarget == getLateFieldTarget(node));
+ return propertySet.value;
+ } else if (firstStatement.expression is StaticSet) {
+ // We have
+ //
+ // get field {
+ // if (!_#isSet#field) {
+ // _#field = <init>;
+ // ...
+ // }
+ // return _#field;
+ // }
+ //
+ // in case `<init>` is the initializer.
+ StaticSet staticSet = firstStatement.expression;
+ assert(staticSet.target == getLateFieldTarget(node));
+ return staticSet.value;
+ }
+ } else if (block.statements.isNotEmpty &&
+ block.statements.first is VariableDeclaration) {
+ // We have
+ //
+ // get field {
+ // if (!_#isSet#field) {
+ // var temp = <init>;
+ // if (_#isSet#field) throw '...'
+ // _#field = temp;
+ // _#isSet#field = true
+ // }
+ // return _#field;
+ // }
+ //
+ // in case `<init>` is the initializer.
+ VariableDeclaration variableDeclaration = block.statements.first;
+ return variableDeclaration.initializer;
+ }
+ }
+ return null;
+ } else if (body is ReturnStatement) {
+ Expression expression = body.expression;
+ if (expression is ConditionalExpression &&
+ expression.otherwise is Throw) {
+ // We have
+ //
+ // get field => _#field#isSet ? #field : throw ...;
+ //
+ // in which case there is no initializer.
+ return null;
+ } else if (expression is Let) {
+ Expression letBody = expression.body;
+ if (letBody is ConditionalExpression) {
+ Expression then = letBody.then;
+ if (then is Throw) {
+ // We have
+ //
+ // get field => let # = _#field in <is-unset> ? throw ... : #;
+ //
+ // in which case there is no initializer.
+ return null;
+ } else if (then is PropertySet) {
+ // We have
+ //
+ // get field => let # = this._#field in <is-unset>
+ // ? this._#field = <init> : #;
+ //
+ // in which case `<init>` is the initializer.
+ assert(then.interfaceTarget == getLateFieldTarget(node));
+ return then.value;
+ } else if (then is StaticSet) {
+ // We have
+ //
+ // get field => let # = this._#field in <is-unset>
+ // ? this._#field = <init> : #;
+ //
+ // in which case `<init>` is the initializer.
+ assert(then.target == getLateFieldTarget(node));
+ return then.value;
+ } else if (then is Let && then.body is ConditionalExpression) {
+ // We have
+ //
+ // get field => let #1 = _#field in <is-unset>
+ // ? let #2 = <init> in ...
+ // : #1;
+ //
+ // in which case `<init>` is the initializer.
+ return then.variable.initializer;
+ }
+ }
+ }
+ }
+ throw new UnsupportedError(
+ 'Unrecognized late getter encoding for $lateFieldGetter: ${body}');
+ }
+
+ return null;
+}
+
+/// Returns getter for reading the value of a lowered late field where [node] is
+/// either the field holding the value, the field holding the marker for whether
+/// it has been set or not, getter for reading the value, or the setter for
+/// setting the value of the field.
+Procedure _getLateFieldTarget(Member node) {
+ Name lateFieldName;
+ if (node is Procedure) {
+ if (isLateLoweredFieldGetter(node)) {
+ return node;
+ } else if (isLateLoweredFieldSetter(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredFieldSetter(node);
+ }
+ } else if (node is Field) {
+ if (isLateLoweredField(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredField(node);
+ } else if (isLateLoweredIsSetField(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredIsSetField(node);
+ }
+ }
+ if (lateFieldName != null) {
+ TreeNode parent = node.parent;
+ List<Procedure> procedures;
+ if (parent is Class) {
+ procedures = parent.procedures;
+ } else if (parent is Library) {
+ procedures = parent.procedures;
+ }
+ return procedures.singleWhere((Procedure procedure) =>
+ isLateLoweredFieldGetter(procedure) &&
+ extractFieldNameFromLateLoweredFieldGetter(procedure) == lateFieldName);
+ }
+ return null;
+}
+
+/// Returns the field holding the value for a lowered late field where [node] is
+/// either the field holding the value, the field holding the marker for whether
+/// it has been set or not, getter for reading the value, or the setter for
+/// setting the value of the field.
+///
+/// For instance
+///
+/// late int field = 42;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field == null ? throw 'Uninitialized' : _#field = 42;
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where '_#field' is the field holding that value, '_#field#isSet' is the
+/// field holding the marker, 'int get field' is the getter for reading the
+/// field, and 'void set field' is the setter for setting the value of the
+/// field.
+///
+/// If [node] is not part of a late field lowering, `null` is returned.
+Field getLateFieldTarget(Member node) {
+ Name lateFieldName;
+ if (node is Procedure) {
+ if (isLateLoweredFieldGetter(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredFieldGetter(node);
+ } else if (isLateLoweredFieldSetter(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredFieldSetter(node);
+ }
+ } else if (node is Field) {
+ if (isLateLoweredField(node)) {
+ return node;
+ } else if (isLateLoweredIsSetField(node)) {
+ lateFieldName = extractFieldNameFromLateLoweredIsSetField(node);
+ }
+ }
+ if (lateFieldName != null) {
+ TreeNode parent = node.parent;
+ List<Field> fields;
+ if (parent is Class) {
+ fields = parent.fields;
+ } else if (parent is Library) {
+ fields = parent.fields;
+ }
+ return fields.singleWhere((Field field) =>
+ isLateLoweredField(field) &&
+ extractFieldNameFromLateLoweredField(field) == lateFieldName);
+ }
+ return null;
+}
+
/// Returns `true` if [node] is the local variable holding the value of a
/// lowered late variable.
///
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index a56f41c..2d5ad31 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -902,6 +902,7 @@
if (isSetEncoding == late_lowering.IsSetEncoding.useSentinel) {
_field.initializer = new StaticInvocation(coreTypes.createSentinelMethod,
new Arguments([], types: [_type])..fileOffset = fileOffset)
+ ..fileOffset = fileOffset
..parent = _field;
} else {
_field.initializer = new NullLiteral()
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 2173fcb..ebb0cce 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5,6 +5,7 @@
import 'dart:core' hide MapEntry;
import 'package:_fe_analyzer_shared/src/util/link.dart';
+import 'package:front_end/src/api_prototype/lowering_predicates.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/src/legacy_erasure.dart';
import 'package:kernel/type_algebra.dart' show Substitution;
@@ -6541,6 +6542,7 @@
node.initializer = new StaticInvocation(
inferrer.coreTypes.createSentinelMethod,
new Arguments([], types: [node.type])..fileOffset = fileOffset)
+ ..fileOffset = fileOffset
..parent = node;
} else {
node.initializer = null;
@@ -6567,8 +6569,12 @@
if (nonNullableType != variable.type) {
promotedType = nonNullableType;
}
- } else if (!variable.isLocalFunction) {
+ } else if (variable.isLocalFunction) {
// Don't promote local functions.
+ } else if (isExtensionThis(variable)) {
+ // Don't promote the synthetic variable `#this` that we use to represent
+ // `this` inside extension methods.
+ } else {
promotedType = inferrer.flowAnalysis.variableRead(node, variable);
}
} else {
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index 52c8586..8d98cff 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -168,8 +168,12 @@
offset = cls.fileOffset;
}
} else {
- member = lookupLibraryMember(library, id.memberName);
- offset = member.fileOffset;
+ member = lookupLibraryMember(library, id.memberName, required: false);
+ if (member != null) {
+ offset = member.fileOffset;
+ } else {
+ offset = 0;
+ }
}
if (offset == -1) {
offset = 0;
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 1b71339..74b4740 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -24,6 +24,14 @@
return member.name.text;
}
+/// Returns a canonical qualified name for [member].
+String getQualifiedMemberName(Member member) {
+ if (member.enclosingClass != null) {
+ return '${member.enclosingClass.name}.${getMemberName(member)}';
+ }
+ return getMemberName(member);
+}
+
/// Returns the enclosing [Member] for [node].
Member getEnclosingMember(TreeNode node) {
while (node is! Member) {
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 7e4bc88..0dd5247 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -295,6 +295,9 @@
String get updateExpectationsOption => '${UPDATE_EXPECTATIONS}=true';
@override
+ bool get canBeFixWithUpdateExpectations => true;
+
+ @override
final ExpectationSet expectationSet =
new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
@@ -1117,7 +1120,8 @@
description, p, userLibraries, options, sourceTarget),
context.expectationSet["InstrumentationMismatch"],
instrumentation.problemsAsString,
- autoFixCommand: '${UPDATE_COMMENTS}=true');
+ autoFixCommand: '${UPDATE_COMMENTS}=true',
+ canBeFixWithUpdateExpectations: true);
}
}
}
diff --git a/pkg/front_end/test/fasta/textual_outline_suite.dart b/pkg/front_end/test/fasta/textual_outline_suite.dart
index f0dbb30..8e38277 100644
--- a/pkg/front_end/test/fasta/textual_outline_suite.dart
+++ b/pkg/front_end/test/fasta/textual_outline_suite.dart
@@ -59,6 +59,9 @@
@override
String get updateExpectationsOption => '${UPDATE_EXPECTATIONS}=true';
+ @override
+ bool get canBeFixWithUpdateExpectations => true;
+
Context(this.updateExpectations);
final List<Step> steps = const <Step>[
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index dba9923..70a5360 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -1120,7 +1120,8 @@
"${extra}Unexpected serialized representation. "
"Fix or update $uri to contain the below:\n\n"
"$actualSerialized",
- autoFixCommand: "updateExpectations=true");
+ autoFixCommand: "updateExpectations=true",
+ canBeFixWithUpdateExpectations: true);
}
}
return null;
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index 70bbcad..3bc79a2 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -101,6 +101,9 @@
@override
String get updateExpectationsOption => '${UPDATE_EXPECTATIONS}=true';
+ @override
+ bool get canBeFixWithUpdateExpectations => true;
+
final bool addTrace;
final bool annotateLines;
final String suiteName;
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
index 55cfbb6..ebf4162 100644
--- a/pkg/front_end/test/predicates/data/late.dart
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -2,184 +2,842 @@
// 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.
-/*member: _#topLevelNonNullableWithoutInitializer:lateField*/
-/*member: topLevelNonNullableWithoutInitializer:lateFieldGetter*/
-/*member: topLevelNonNullableWithoutInitializer=:lateFieldSetter*/
-/*member: _#topLevelNonNullableWithoutInitializer#isSet:lateIsSetField*/
+/*member: _#topLevelNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=topLevelNonNullableWithoutInitializer,
+ lateFieldTarget=_#topLevelNonNullableWithoutInitializer
+*/
+/*member: topLevelNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=topLevelNonNullableWithoutInitializer,
+ lateFieldTarget=_#topLevelNonNullableWithoutInitializer
+*/
+/*member: topLevelNonNullableWithoutInitializer=:
+ lateFieldName=topLevelNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#topLevelNonNullableWithoutInitializer
+*/
late int topLevelNonNullableWithoutInitializer;
-/*member: _#finalTopLevelNonNullableWithoutInitializer:lateField*/
-/*member: finalTopLevelNonNullableWithoutInitializer:lateFieldGetter*/
-/*member: finalTopLevelNonNullableWithoutInitializer=:lateFieldSetter*/
-/*member: _#finalTopLevelNonNullableWithoutInitializer#isSet:lateIsSetField*/
+/*member: _#finalTopLevelNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalTopLevelNonNullableWithoutInitializer,
+ lateFieldTarget=_#finalTopLevelNonNullableWithoutInitializer
+*/
+/*member: finalTopLevelNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalTopLevelNonNullableWithoutInitializer,
+ lateFieldTarget=_#finalTopLevelNonNullableWithoutInitializer
+*/
+/*member: finalTopLevelNonNullableWithoutInitializer=:
+ lateFieldName=finalTopLevelNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#finalTopLevelNonNullableWithoutInitializer
+*/
late final int finalTopLevelNonNullableWithoutInitializer;
-/*member: _#topLevelNullableWithoutInitializer:lateField*/
-/*member: _#topLevelNullableWithoutInitializer#isSet:lateIsSetField*/
-/*member: topLevelNullableWithoutInitializer:lateFieldGetter*/
-/*member: topLevelNullableWithoutInitializer=:lateFieldSetter*/
+/*member: _#topLevelNullableWithoutInitializer:
+ lateField,
+ lateFieldName=topLevelNullableWithoutInitializer,
+ lateFieldTarget=_#topLevelNullableWithoutInitializer
+*/
+/*is-null.member: _#topLevelNullableWithoutInitializer#isSet:
+ lateFieldName=topLevelNullableWithoutInitializer,
+ lateFieldTarget=_#topLevelNullableWithoutInitializer,
+ lateIsSetField
+*/
+/*member: topLevelNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=topLevelNullableWithoutInitializer,
+ lateFieldTarget=_#topLevelNullableWithoutInitializer
+*/
+/*member: topLevelNullableWithoutInitializer=:
+ lateFieldName=topLevelNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#topLevelNullableWithoutInitializer
+*/
late int? topLevelNullableWithoutInitializer;
-/*member: _#finalTopLevelNullableWithoutInitializer:lateField*/
-/*member: _#finalTopLevelNullableWithoutInitializer#isSet:lateIsSetField*/
-/*member: finalTopLevelNullableWithoutInitializer:lateFieldGetter*/
-/*member: finalTopLevelNullableWithoutInitializer=:lateFieldSetter*/
+/*member: _#finalTopLevelNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalTopLevelNullableWithoutInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithoutInitializer
+*/
+/*is-null.member: _#finalTopLevelNullableWithoutInitializer#isSet:
+ lateFieldName=finalTopLevelNullableWithoutInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithoutInitializer,
+ lateIsSetField
+*/
+/*member: finalTopLevelNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalTopLevelNullableWithoutInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithoutInitializer
+*/
+/*member: finalTopLevelNullableWithoutInitializer=:
+ lateFieldName=finalTopLevelNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#finalTopLevelNullableWithoutInitializer
+*/
late final int? finalTopLevelNullableWithoutInitializer;
-/*member: _#topLevelNonNullableWithInitializer:lateField*/
-/*member: topLevelNonNullableWithInitializer:lateFieldGetter*/
-/*member: topLevelNonNullableWithInitializer=:lateFieldSetter*/
-/*member: _#topLevelNonNullableWithInitializer#isSet:lateIsSetField*/
-late int topLevelNonNullableWithInitializer = 0;
-/*member: _#finalTopLevelNonNullableWithInitializer:lateField*/
-/*member: finalTopLevelNonNullableWithInitializer:lateFieldGetter*/
-/*member: _#finalTopLevelNonNullableWithInitializer#isSet:lateIsSetField*/
-late final int finalTopLevelNonNullableWithInitializer = 0;
-/*member: _#topLevelNullableWithInitializer:lateField*/
-/*member: _#topLevelNullableWithInitializer#isSet:lateIsSetField*/
-/*member: topLevelNullableWithInitializer:lateFieldGetter*/
-/*member: topLevelNullableWithInitializer=:lateFieldSetter*/
-late int? topLevelNullableWithInitializer = 0;
-/*member: _#finalTopLevelNullableWithInitializer:lateField*/
-/*member: _#finalTopLevelNullableWithInitializer#isSet:lateIsSetField*/
-/*member: finalTopLevelNullableWithInitializer:lateFieldGetter*/
-late final int? finalTopLevelNullableWithInitializer = 0;
+/*member: _#topLevelNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=1,
+ lateFieldName=topLevelNonNullableWithInitializer,
+ lateFieldTarget=_#topLevelNonNullableWithInitializer
+*/
+/*member: topLevelNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=1,
+ lateFieldName=topLevelNonNullableWithInitializer,
+ lateFieldTarget=_#topLevelNonNullableWithInitializer
+*/
+/*member: topLevelNonNullableWithInitializer=:
+ lateFieldInitializer=1,
+ lateFieldName=topLevelNonNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#topLevelNonNullableWithInitializer
+*/
+late int topLevelNonNullableWithInitializer = 1;
+/*member: _#finalTopLevelNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=2,
+ lateFieldName=finalTopLevelNonNullableWithInitializer,
+ lateFieldTarget=_#finalTopLevelNonNullableWithInitializer
+*/
+/*member: finalTopLevelNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=2,
+ lateFieldName=finalTopLevelNonNullableWithInitializer,
+ lateFieldTarget=_#finalTopLevelNonNullableWithInitializer
+*/
+late final int finalTopLevelNonNullableWithInitializer = 2;
+/*member: _#topLevelNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=3,
+ lateFieldName=topLevelNullableWithInitializer,
+ lateFieldTarget=_#topLevelNullableWithInitializer
+*/
+/*is-null.member: _#topLevelNullableWithInitializer#isSet:
+ lateFieldInitializer=3,
+ lateFieldName=topLevelNullableWithInitializer,
+ lateFieldTarget=_#topLevelNullableWithInitializer,
+ lateIsSetField
+*/
+/*member: topLevelNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=3,
+ lateFieldName=topLevelNullableWithInitializer,
+ lateFieldTarget=_#topLevelNullableWithInitializer
+*/
+/*member: topLevelNullableWithInitializer=:
+ lateFieldInitializer=3,
+ lateFieldName=topLevelNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#topLevelNullableWithInitializer
+*/
+late int? topLevelNullableWithInitializer = 3;
+/*member: _#finalTopLevelNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=4,
+ lateFieldName=finalTopLevelNullableWithInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithInitializer
+*/
+/*is-null.member: _#finalTopLevelNullableWithInitializer#isSet:
+ lateFieldInitializer=4,
+ lateFieldName=finalTopLevelNullableWithInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithInitializer,
+ lateIsSetField
+*/
+/*member: finalTopLevelNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=4,
+ lateFieldName=finalTopLevelNullableWithInitializer,
+ lateFieldTarget=_#finalTopLevelNullableWithInitializer
+*/
+late final int? finalTopLevelNullableWithInitializer = 4;
class Class {
- /*member: Class._#Class#instanceNonNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class._#Class#instanceNonNullableWithoutInitializer:lateField*/
- /*member: Class.instanceNonNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.instanceNonNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#Class#instanceNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=instanceNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithoutInitializer
+ */
+ /*member: Class.instanceNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=instanceNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithoutInitializer
+ */
+ /*member: Class.instanceNonNullableWithoutInitializer=:
+ lateFieldName=instanceNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithoutInitializer
+ */
late int instanceNonNullableWithoutInitializer;
- /*member: Class._#Class#finalInstanceNonNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class._#Class#finalInstanceNonNullableWithoutInitializer:lateField*/
- /*member: Class.finalInstanceNonNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.finalInstanceNonNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#Class#finalInstanceNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalInstanceNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNonNullableWithoutInitializer
+ */
+ /*member: Class.finalInstanceNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalInstanceNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNonNullableWithoutInitializer
+ */
+ /*member: Class.finalInstanceNonNullableWithoutInitializer=:
+ lateFieldName=finalInstanceNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#finalInstanceNonNullableWithoutInitializer
+ */
late final int finalInstanceNonNullableWithoutInitializer;
- /*member: Class._#Class#instanceNullableWithoutInitializer:lateField*/
- /*member: Class._#Class#instanceNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class.instanceNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.instanceNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#Class#instanceNullableWithoutInitializer:
+ lateField,
+ lateFieldName=instanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithoutInitializer
+ */
+ /*is-null.member: Class._#Class#instanceNullableWithoutInitializer#isSet:
+ lateFieldName=instanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Class.instanceNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=instanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithoutInitializer
+ */
+ /*member: Class.instanceNullableWithoutInitializer=:
+ lateFieldName=instanceNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#instanceNullableWithoutInitializer
+ */
late int? instanceNullableWithoutInitializer;
- /*member: Class._#Class#finalInstanceNullableWithoutInitializer:lateField*/
- /*member: Class._#Class#finalInstanceNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class.finalInstanceNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.finalInstanceNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#Class#finalInstanceNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalInstanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithoutInitializer
+ */
+ /*is-null.member: Class._#Class#finalInstanceNullableWithoutInitializer#isSet:
+ lateFieldName=finalInstanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Class.finalInstanceNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalInstanceNullableWithoutInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithoutInitializer
+ */
+ /*member: Class.finalInstanceNullableWithoutInitializer=:
+ lateFieldName=finalInstanceNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithoutInitializer
+ */
late final int? finalInstanceNullableWithoutInitializer;
- /*member: Class._#Class#instanceNonNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class._#Class#instanceNonNullableWithInitializer:lateField*/
- /*member: Class.instanceNonNullableWithInitializer:lateFieldGetter*/
- /*member: Class.instanceNonNullableWithInitializer=:lateFieldSetter*/
- late int instanceNonNullableWithInitializer = 0;
- /*member: Class._#Class#finalInstanceNonNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class._#Class#finalInstanceNonNullableWithInitializer:lateField*/
- /*member: Class.finalInstanceNonNullableWithInitializer:lateFieldGetter*/
- late final int finalInstanceNonNullableWithInitializer = 0;
- /*member: Class._#Class#instanceNullableWithInitializer:lateField*/
- /*member: Class._#Class#instanceNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class.instanceNullableWithInitializer:lateFieldGetter*/
- /*member: Class.instanceNullableWithInitializer=:lateFieldSetter*/
- late int? instanceNullableWithInitializer = 0;
- /*member: Class._#Class#finalInstanceNullableWithInitializer:lateField*/
- /*member: Class._#Class#finalInstanceNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class.finalInstanceNullableWithInitializer:lateFieldGetter*/
- late final int? finalInstanceNullableWithInitializer = 0;
+ /*member: Class._#Class#instanceNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=5,
+ lateFieldName=instanceNonNullableWithInitializer,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithInitializer
+ */
+ /*member: Class.instanceNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=5,
+ lateFieldName=instanceNonNullableWithInitializer,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithInitializer
+ */
+ /*member: Class.instanceNonNullableWithInitializer=:
+ lateFieldInitializer=5,
+ lateFieldName=instanceNonNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#instanceNonNullableWithInitializer
+ */
+ late int instanceNonNullableWithInitializer = 5;
+ /*member: Class._#Class#finalInstanceNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=6,
+ lateFieldName=finalInstanceNonNullableWithInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNonNullableWithInitializer
+ */
+ /*member: Class.finalInstanceNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=6,
+ lateFieldName=finalInstanceNonNullableWithInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNonNullableWithInitializer
+ */
+ late final int finalInstanceNonNullableWithInitializer = 6;
+ /*member: Class._#Class#instanceNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=7,
+ lateFieldName=instanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithInitializer
+ */
+ /*is-null.member: Class._#Class#instanceNullableWithInitializer#isSet:
+ lateFieldInitializer=7,
+ lateFieldName=instanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Class.instanceNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=7,
+ lateFieldName=instanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#instanceNullableWithInitializer
+ */
+ /*member: Class.instanceNullableWithInitializer=:
+ lateFieldInitializer=7,
+ lateFieldName=instanceNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#instanceNullableWithInitializer
+ */
+ late int? instanceNullableWithInitializer = 7;
+ /*member: Class._#Class#finalInstanceNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=8,
+ lateFieldName=finalInstanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithInitializer
+ */
+ /*is-null.member: Class._#Class#finalInstanceNullableWithInitializer#isSet:
+ lateFieldInitializer=8,
+ lateFieldName=finalInstanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Class.finalInstanceNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=8,
+ lateFieldName=finalInstanceNullableWithInitializer,
+ lateFieldTarget=Class._#Class#finalInstanceNullableWithInitializer
+ */
+ late final int? finalInstanceNullableWithInitializer = 8;
- /*member: Class._#staticNonNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class._#staticNonNullableWithoutInitializer:lateField*/
- /*member: Class.staticNonNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.staticNonNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#staticNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=staticNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#staticNonNullableWithoutInitializer
+ */
+ /*member: Class.staticNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=staticNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#staticNonNullableWithoutInitializer
+ */
+ /*member: Class.staticNonNullableWithoutInitializer=:
+ lateFieldName=staticNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#staticNonNullableWithoutInitializer
+ */
static late int staticNonNullableWithoutInitializer;
- /*member: Class._#finalStaticNonNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class._#finalStaticNonNullableWithoutInitializer:lateField*/
- /*member: Class.finalStaticNonNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.finalStaticNonNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#finalStaticNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalStaticNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#finalStaticNonNullableWithoutInitializer
+ */
+ /*member: Class.finalStaticNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalStaticNonNullableWithoutInitializer,
+ lateFieldTarget=Class._#finalStaticNonNullableWithoutInitializer
+ */
+ /*member: Class.finalStaticNonNullableWithoutInitializer=:
+ lateFieldName=finalStaticNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#finalStaticNonNullableWithoutInitializer
+ */
static late final int finalStaticNonNullableWithoutInitializer;
- /*member: Class._#staticNullableWithoutInitializer:lateField*/
- /*member: Class._#staticNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class.staticNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.staticNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#staticNullableWithoutInitializer:
+ lateField,
+ lateFieldName=staticNullableWithoutInitializer,
+ lateFieldTarget=Class._#staticNullableWithoutInitializer
+ */
+ /*is-null.member: Class._#staticNullableWithoutInitializer#isSet:
+ lateFieldName=staticNullableWithoutInitializer,
+ lateFieldTarget=Class._#staticNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Class.staticNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=staticNullableWithoutInitializer,
+ lateFieldTarget=Class._#staticNullableWithoutInitializer
+ */
+ /*member: Class.staticNullableWithoutInitializer=:
+ lateFieldName=staticNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#staticNullableWithoutInitializer
+ */
static late int? staticNullableWithoutInitializer;
- /*member: Class._#finalStaticNullableWithoutInitializer:lateField*/
- /*member: Class._#finalStaticNullableWithoutInitializer#isSet:lateIsSetField*/
- /*member: Class.finalStaticNullableWithoutInitializer:lateFieldGetter*/
- /*member: Class.finalStaticNullableWithoutInitializer=:lateFieldSetter*/
+ /*member: Class._#finalStaticNullableWithoutInitializer:
+ lateField,
+ lateFieldName=finalStaticNullableWithoutInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithoutInitializer
+ */
+ /*is-null.member: Class._#finalStaticNullableWithoutInitializer#isSet:
+ lateFieldName=finalStaticNullableWithoutInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Class.finalStaticNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=finalStaticNullableWithoutInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithoutInitializer
+ */
+ /*member: Class.finalStaticNullableWithoutInitializer=:
+ lateFieldName=finalStaticNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#finalStaticNullableWithoutInitializer
+ */
static late final int? finalStaticNullableWithoutInitializer;
- /*member: Class._#staticNonNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class._#staticNonNullableWithInitializer:lateField*/
- /*member: Class.staticNonNullableWithInitializer:lateFieldGetter*/
- /*member: Class.staticNonNullableWithInitializer=:lateFieldSetter*/
- static late int staticNonNullableWithInitializer = 0;
- /*member: Class._#finalStaticNonNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class._#finalStaticNonNullableWithInitializer:lateField*/
- /*member: Class.finalStaticNonNullableWithInitializer:lateFieldGetter*/
- static late final int finalStaticNonNullableWithInitializer = 0;
- /*member: Class._#staticNullableWithInitializer:lateField*/
- /*member: Class._#staticNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class.staticNullableWithInitializer:lateFieldGetter*/
- /*member: Class.staticNullableWithInitializer=:lateFieldSetter*/
- static late int? staticNullableWithInitializer = 0;
- /*member: Class._#finalStaticNullableWithInitializer:lateField*/
- /*member: Class._#finalStaticNullableWithInitializer#isSet:lateIsSetField*/
- /*member: Class.finalStaticNullableWithInitializer:lateFieldGetter*/
- static late final int? finalStaticNullableWithInitializer = 0;
+ /*member: Class._#staticNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=9,
+ lateFieldName=staticNonNullableWithInitializer,
+ lateFieldTarget=Class._#staticNonNullableWithInitializer
+ */
+ /*member: Class.staticNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=9,
+ lateFieldName=staticNonNullableWithInitializer,
+ lateFieldTarget=Class._#staticNonNullableWithInitializer
+ */
+ /*member: Class.staticNonNullableWithInitializer=:
+ lateFieldInitializer=9,
+ lateFieldName=staticNonNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#staticNonNullableWithInitializer
+ */
+ static late int staticNonNullableWithInitializer = 9;
+ /*member: Class._#finalStaticNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=10,
+ lateFieldName=finalStaticNonNullableWithInitializer,
+ lateFieldTarget=Class._#finalStaticNonNullableWithInitializer
+ */
+ /*member: Class.finalStaticNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=10,
+ lateFieldName=finalStaticNonNullableWithInitializer,
+ lateFieldTarget=Class._#finalStaticNonNullableWithInitializer
+ */
+ static late final int finalStaticNonNullableWithInitializer = 10;
+ /*member: Class._#staticNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=11,
+ lateFieldName=staticNullableWithInitializer,
+ lateFieldTarget=Class._#staticNullableWithInitializer
+ */
+ /*is-null.member: Class._#staticNullableWithInitializer#isSet:
+ lateFieldInitializer=11,
+ lateFieldName=staticNullableWithInitializer,
+ lateFieldTarget=Class._#staticNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Class.staticNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=11,
+ lateFieldName=staticNullableWithInitializer,
+ lateFieldTarget=Class._#staticNullableWithInitializer
+ */
+ /*member: Class.staticNullableWithInitializer=:
+ lateFieldInitializer=11,
+ lateFieldName=staticNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=Class._#staticNullableWithInitializer
+ */
+ static late int? staticNullableWithInitializer = 11;
+ /*member: Class._#finalStaticNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=12,
+ lateFieldName=finalStaticNullableWithInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithInitializer
+ */
+ /*is-null.member: Class._#finalStaticNullableWithInitializer#isSet:
+ lateFieldInitializer=12,
+ lateFieldName=finalStaticNullableWithInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Class.finalStaticNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=12,
+ lateFieldName=finalStaticNullableWithInitializer,
+ lateFieldTarget=Class._#finalStaticNullableWithInitializer
+ */
+ static late final int? finalStaticNullableWithInitializer = 12;
+}
+
+extension on int? {
+ /*member: _#_extension#0|unnamedExtensionNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNonNullableWithoutInitializer=:
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithoutInitializer
+ */
+ static late int unnamedExtensionNonNullableWithoutInitializer;
+ /*member: _#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: _extension#0|finalUnnamedExtensionNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: _extension#0|finalUnnamedExtensionNonNullableWithoutInitializer=:
+ lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithoutInitializer
+ */
+ static late final int finalUnnamedExtensionNonNullableWithoutInitializer;
+ /*member: _#_extension#0|unnamedExtensionNullableWithoutInitializer:
+ lateField,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
+ */
+ /*is-null.member: _#_extension#0|unnamedExtensionNullableWithoutInitializer#isSet:
+ lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: _extension#0|unnamedExtensionNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNullableWithoutInitializer=:
+ lateFieldName=_extension#0|unnamedExtensionNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithoutInitializer
+ */
+ static late int? unnamedExtensionNullableWithoutInitializer;
+ /*member: _#_extension#0|finalUnnamedExtensionNullableWithoutInitializer:
+ lateField,
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+ */
+ /*is-null.member: _#_extension#0|finalUnnamedExtensionNullableWithoutInitializer#isSet:
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: _extension#0|finalUnnamedExtensionNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+ */
+ /*member: _extension#0|finalUnnamedExtensionNullableWithoutInitializer=:
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithoutInitializer
+ */
+ static late final int? finalUnnamedExtensionNullableWithoutInitializer;
+ /*member: _#_extension#0|unnamedExtensionNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=13,
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=13,
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNonNullableWithInitializer=:
+ lateFieldInitializer=13,
+ lateFieldName=_extension#0|unnamedExtensionNonNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNonNullableWithInitializer
+ */
+ static late int unnamedExtensionNonNullableWithInitializer = 13;
+ /*member: _#_extension#0|finalUnnamedExtensionNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=14,
+ lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithInitializer
+ */
+ /*member: _extension#0|finalUnnamedExtensionNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=14,
+ lateFieldName=_extension#0|finalUnnamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNonNullableWithInitializer
+ */
+ static late final int finalUnnamedExtensionNonNullableWithInitializer = 14;
+ /*member: _#_extension#0|unnamedExtensionNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=15,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
+ */
+ /*is-null.member: _#_extension#0|unnamedExtensionNullableWithInitializer#isSet:
+ lateFieldInitializer=15,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: _extension#0|unnamedExtensionNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=15,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
+ */
+ /*member: _extension#0|unnamedExtensionNullableWithInitializer=:
+ lateFieldInitializer=15,
+ lateFieldName=_extension#0|unnamedExtensionNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|unnamedExtensionNullableWithInitializer
+ */
+ static late int? unnamedExtensionNullableWithInitializer = 15;
+ /*member: _#_extension#0|finalUnnamedExtensionNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=16,
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer
+ */
+ /*is-null.member: _#_extension#0|finalUnnamedExtensionNullableWithInitializer#isSet:
+ lateFieldInitializer=16,
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: _extension#0|finalUnnamedExtensionNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=16,
+ lateFieldName=_extension#0|finalUnnamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#_extension#0|finalUnnamedExtensionNullableWithInitializer
+ */
+ static late final int? finalUnnamedExtensionNullableWithInitializer = 16;
+}
+
+extension Extension on int? {
+ /*member: _#Extension|namedExtensionNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=Extension|namedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithoutInitializer
+ */
+ /*member: Extension|namedExtensionNonNullableWithoutInitializer=:
+ lateFieldName=Extension|namedExtensionNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithoutInitializer
+ */
+ /*member: Extension|namedExtensionNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=Extension|namedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithoutInitializer
+ */
+ static late int namedExtensionNonNullableWithoutInitializer;
+ /*member: _#Extension|finalNamedExtensionNonNullableWithoutInitializer:
+ lateField,
+ lateFieldName=Extension|finalNamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: Extension|finalNamedExtensionNonNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=Extension|finalNamedExtensionNonNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNonNullableWithoutInitializer
+ */
+ /*member: Extension|finalNamedExtensionNonNullableWithoutInitializer=:
+ lateFieldName=Extension|finalNamedExtensionNonNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|finalNamedExtensionNonNullableWithoutInitializer
+ */
+ static late final int finalNamedExtensionNonNullableWithoutInitializer;
+ /*member: _#Extension|namedExtensionNullableWithoutInitializer:
+ lateField,
+ lateFieldName=Extension|namedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithoutInitializer
+ */
+ /*is-null.member: _#Extension|namedExtensionNullableWithoutInitializer#isSet:
+ lateFieldName=Extension|namedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Extension|namedExtensionNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=Extension|namedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithoutInitializer
+ */
+ /*member: Extension|namedExtensionNullableWithoutInitializer=:
+ lateFieldName=Extension|namedExtensionNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithoutInitializer
+ */
+ static late int? namedExtensionNullableWithoutInitializer;
+ /*member: _#Extension|finalNamedExtensionNullableWithoutInitializer:
+ lateField,
+ lateFieldName=Extension|finalNamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithoutInitializer
+ */
+ /*is-null.member: _#Extension|finalNamedExtensionNullableWithoutInitializer#isSet:
+ lateFieldName=Extension|finalNamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithoutInitializer,
+ lateIsSetField
+ */
+ /*member: Extension|finalNamedExtensionNullableWithoutInitializer:
+ lateFieldGetter,
+ lateFieldName=Extension|finalNamedExtensionNullableWithoutInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithoutInitializer
+ */
+ /*member: Extension|finalNamedExtensionNullableWithoutInitializer=:
+ lateFieldName=Extension|finalNamedExtensionNullableWithoutInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithoutInitializer
+ */
+ static late final int? finalNamedExtensionNullableWithoutInitializer;
+ /*member: _#Extension|namedExtensionNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=17,
+ lateFieldName=Extension|namedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithInitializer
+ */
+ /*member: Extension|namedExtensionNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=17,
+ lateFieldName=Extension|namedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithInitializer
+ */
+ /*member: Extension|namedExtensionNonNullableWithInitializer=:
+ lateFieldInitializer=17,
+ lateFieldName=Extension|namedExtensionNonNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|namedExtensionNonNullableWithInitializer
+ */
+ static late int namedExtensionNonNullableWithInitializer = 17;
+ /*member: _#Extension|finalNamedExtensionNonNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=18,
+ lateFieldName=Extension|finalNamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNonNullableWithInitializer
+ */
+ /*member: Extension|finalNamedExtensionNonNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=18,
+ lateFieldName=Extension|finalNamedExtensionNonNullableWithInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNonNullableWithInitializer
+ */
+ static late final int finalNamedExtensionNonNullableWithInitializer = 18;
+ /*member: _#Extension|namedExtensionNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=19,
+ lateFieldName=Extension|namedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithInitializer
+ */
+ /*is-null.member: _#Extension|namedExtensionNullableWithInitializer#isSet:
+ lateFieldInitializer=19,
+ lateFieldName=Extension|namedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Extension|namedExtensionNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=19,
+ lateFieldName=Extension|namedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithInitializer
+ */
+ /*member: Extension|namedExtensionNullableWithInitializer=:
+ lateFieldInitializer=19,
+ lateFieldName=Extension|namedExtensionNullableWithInitializer,
+ lateFieldSetter,
+ lateFieldTarget=_#Extension|namedExtensionNullableWithInitializer
+ */
+ static late int? namedExtensionNullableWithInitializer = 19;
+ /*member: _#Extension|finalNamedExtensionNullableWithInitializer:
+ lateField,
+ lateFieldInitializer=20,
+ lateFieldName=Extension|finalNamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithInitializer
+ */
+ /*is-null.member: _#Extension|finalNamedExtensionNullableWithInitializer#isSet:
+ lateFieldInitializer=20,
+ lateFieldName=Extension|finalNamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithInitializer,
+ lateIsSetField
+ */
+ /*member: Extension|finalNamedExtensionNullableWithInitializer:
+ lateFieldGetter,
+ lateFieldInitializer=20,
+ lateFieldName=Extension|finalNamedExtensionNullableWithInitializer,
+ lateFieldTarget=_#Extension|finalNamedExtensionNullableWithInitializer
+ */
+ static late final int? finalNamedExtensionNullableWithInitializer = 20;
}
method() {
late int
/*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter,
- lateLocalSetter
- */
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
localNonNullableWithoutInitializer;
late final int
/*
- lateIsSetLocal,
lateLocal,
lateLocalGetter,
lateLocalSetter
*/
finalLocalNonNullableWithoutInitializer;
late int?
- /*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter,
- lateLocalSetter
- */
+ /*is-null.
+ lateIsSetLocal,
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ /*sentinel.
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
localNullableWithoutInitializer;
late final int?
- /*
+ /*is-null.
lateIsSetLocal,
lateLocal,
lateLocalGetter,
lateLocalSetter
*/
+ /*sentinel.
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
finalLocalNullableWithoutInitializer;
late int
/*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter,
- lateLocalSetter
- */
- localNonNullableWithInitializer = 0;
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNonNullableWithInitializer = 21;
late final int /*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter
- */
- finalLocalNonNullableWithInitializer = 0;
+ lateLocal,
+ lateLocalGetter
+ */
+ finalLocalNonNullableWithInitializer = 22;
late int?
- /*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter,
- lateLocalSetter
- */
- localNullableWithInitializer = 0;
- late final int? /*
- lateIsSetLocal,
- lateLocal,
- lateLocalGetter
- */
- finalLocalNullableWithInitializer = 0;
+ /*is-null.
+ lateIsSetLocal,
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ /*sentinel.
+ lateLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNullableWithInitializer = 23;
+ late final int?
+ /*is-null.
+ lateIsSetLocal,
+ lateLocal,
+ lateLocalGetter
+ */
+ /*sentinel.
+ lateLocal,
+ lateLocalGetter
+ */
+ finalLocalNullableWithInitializer = 24;
}
diff --git a/pkg/front_end/test/predicates/data/late_names.dart b/pkg/front_end/test/predicates/data/late_names.dart
new file mode 100644
index 0000000..a67c9e9
--- /dev/null
+++ b/pkg/front_end/test/predicates/data/late_names.dart
@@ -0,0 +1,461 @@
+// Copyright (c) 2021, 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.
+
+/*member: _#a:
+ lateField,
+ lateFieldName=a,
+ lateFieldTarget=_#a
+*/
+/*is-null.member: _#a#isSet:
+ lateFieldName=a,
+ lateFieldTarget=_#a,
+ lateIsSetField
+*/
+/*member: a:
+ lateFieldGetter,
+ lateFieldName=a,
+ lateFieldTarget=_#a
+*/
+/*member: a=:
+ lateFieldName=a,
+ lateFieldSetter,
+ lateFieldTarget=_#a
+*/
+late int? a;
+
+/*member: _#aa:
+ lateField,
+ lateFieldName=aa,
+ lateFieldTarget=_#aa
+*/
+/*is-null.member: _#aa#isSet:
+ lateFieldName=aa,
+ lateFieldTarget=_#aa,
+ lateIsSetField
+*/
+/*member: aa:
+ lateFieldGetter,
+ lateFieldName=aa,
+ lateFieldTarget=_#aa
+*/
+/*member: aa=:
+ lateFieldName=aa,
+ lateFieldSetter,
+ lateFieldTarget=_#aa
+*/
+late int? aa;
+
+/*member: _#_a:
+ lateField,
+ lateFieldName=_a,
+ lateFieldTarget=_#_a
+*/
+/*is-null.member: _#_a#isSet:
+ lateFieldName=_a,
+ lateFieldTarget=_#_a,
+ lateIsSetField
+*/
+/*member: _a:
+ lateFieldGetter,
+ lateFieldName=_a,
+ lateFieldTarget=_#_a
+*/
+/*member: _a=:
+ lateFieldName=_a,
+ lateFieldSetter,
+ lateFieldTarget=_#_a
+*/
+late int? _a;
+
+class Class {
+ /*member: Class._#Class#a:
+ lateField,
+ lateFieldName=a,
+ lateFieldTarget=Class._#Class#a
+ */
+ /*is-null.member: Class._#Class#a#isSet:
+ lateFieldName=a,
+ lateFieldTarget=Class._#Class#a,
+ lateIsSetField
+ */
+ /*member: Class.a:
+ lateFieldGetter,
+ lateFieldName=a,
+ lateFieldTarget=Class._#Class#a
+ */
+ /*member: Class.a=:
+ lateFieldName=a,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#a
+ */
+ late int? a;
+ /*member: Class._#Class#aa:
+ lateField,
+ lateFieldName=aa,
+ lateFieldTarget=Class._#Class#aa
+ */
+ /*is-null.member: Class._#Class#aa#isSet:
+ lateFieldName=aa,
+ lateFieldTarget=Class._#Class#aa,
+ lateIsSetField
+ */
+ /*member: Class.aa:
+ lateFieldGetter,
+ lateFieldName=aa,
+ lateFieldTarget=Class._#Class#aa
+ */
+ /*member: Class.aa=:
+ lateFieldName=aa,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#aa
+ */
+ late int? aa;
+ /*member: Class._#Class#_a:
+ lateField,
+ lateFieldName=_a,
+ lateFieldTarget=Class._#Class#_a
+ */
+ /*is-null.member: Class._#Class#_a#isSet:
+ lateFieldName=_a,
+ lateFieldTarget=Class._#Class#_a,
+ lateIsSetField
+ */
+ /*member: Class._a:
+ lateFieldGetter,
+ lateFieldName=_a,
+ lateFieldTarget=Class._#Class#_a
+ */
+ /*member: Class._a=:
+ lateFieldName=_a,
+ lateFieldSetter,
+ lateFieldTarget=Class._#Class#_a
+ */
+ late int? _a;
+
+ /*member: Class._#b:
+ lateField,
+ lateFieldName=b,
+ lateFieldTarget=Class._#b
+ */
+ /*is-null.member: Class._#b#isSet:
+ lateFieldName=b,
+ lateFieldTarget=Class._#b,
+ lateIsSetField
+ */
+ /*member: Class.b:
+ lateFieldGetter,
+ lateFieldName=b,
+ lateFieldTarget=Class._#b
+ */
+ /*member: Class.b=:
+ lateFieldName=b,
+ lateFieldSetter,
+ lateFieldTarget=Class._#b
+ */
+ static late int? b;
+ /*member: Class._#bb:
+ lateField,
+ lateFieldName=bb,
+ lateFieldTarget=Class._#bb
+ */
+ /*is-null.member: Class._#bb#isSet:
+ lateFieldName=bb,
+ lateFieldTarget=Class._#bb,
+ lateIsSetField
+ */
+ /*member: Class.bb:
+ lateFieldGetter,
+ lateFieldName=bb,
+ lateFieldTarget=Class._#bb
+ */
+ /*member: Class.bb=:
+ lateFieldName=bb,
+ lateFieldSetter,
+ lateFieldTarget=Class._#bb
+ */
+ static late int? bb;
+ /*member: Class._#_b:
+ lateField,
+ lateFieldName=_b,
+ lateFieldTarget=Class._#_b
+ */
+ /*is-null.member: Class._#_b#isSet:
+ lateFieldName=_b,
+ lateFieldTarget=Class._#_b,
+ lateIsSetField
+ */
+ /*member: Class._b:
+ lateFieldGetter,
+ lateFieldName=_b,
+ lateFieldTarget=Class._#_b
+ */
+ /*member: Class._b=:
+ lateFieldName=_b,
+ lateFieldSetter,
+ lateFieldTarget=Class._#_b
+ */
+ static late int? _b;
+}
+
+class _Class {
+ /*member: _Class._#_Class#a:
+ lateField,
+ lateFieldName=a,
+ lateFieldTarget=_Class._#_Class#a
+ */
+ /*is-null.member: _Class._#_Class#a#isSet:
+ lateFieldName=a,
+ lateFieldTarget=_Class._#_Class#a,
+ lateIsSetField
+ */
+ /*member: _Class.a:
+ lateFieldGetter,
+ lateFieldName=a,
+ lateFieldTarget=_Class._#_Class#a
+ */
+ /*member: _Class.a=:
+ lateFieldName=a,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#_Class#a
+ */
+ late int? a;
+ /*member: _Class._#_Class#aa:
+ lateField,
+ lateFieldName=aa,
+ lateFieldTarget=_Class._#_Class#aa
+ */
+ /*is-null.member: _Class._#_Class#aa#isSet:
+ lateFieldName=aa,
+ lateFieldTarget=_Class._#_Class#aa,
+ lateIsSetField
+ */
+ /*member: _Class.aa:
+ lateFieldGetter,
+ lateFieldName=aa,
+ lateFieldTarget=_Class._#_Class#aa
+ */
+ /*member: _Class.aa=:
+ lateFieldName=aa,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#_Class#aa
+ */
+ late int? aa;
+ /*member: _Class._#_Class#_a:
+ lateField,
+ lateFieldName=_a,
+ lateFieldTarget=_Class._#_Class#_a
+ */
+ /*is-null.member: _Class._#_Class#_a#isSet:
+ lateFieldName=_a,
+ lateFieldTarget=_Class._#_Class#_a,
+ lateIsSetField
+ */
+ /*member: _Class._a:
+ lateFieldGetter,
+ lateFieldName=_a,
+ lateFieldTarget=_Class._#_Class#_a
+ */
+ /*member: _Class._a=:
+ lateFieldName=_a,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#_Class#_a
+ */
+ late int? _a;
+
+ /*member: _Class._#b:
+ lateField,
+ lateFieldName=b,
+ lateFieldTarget=_Class._#b
+ */
+ /*is-null.member: _Class._#b#isSet:
+ lateFieldName=b,
+ lateFieldTarget=_Class._#b,
+ lateIsSetField
+ */
+ /*member: _Class.b:
+ lateFieldGetter,
+ lateFieldName=b,
+ lateFieldTarget=_Class._#b
+ */
+ /*member: _Class.b=:
+ lateFieldName=b,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#b
+ */
+ static late int? b;
+ /*member: _Class._#bb:
+ lateField,
+ lateFieldName=bb,
+ lateFieldTarget=_Class._#bb
+ */
+ /*is-null.member: _Class._#bb#isSet:
+ lateFieldName=bb,
+ lateFieldTarget=_Class._#bb,
+ lateIsSetField
+ */
+ /*member: _Class.bb:
+ lateFieldGetter,
+ lateFieldName=bb,
+ lateFieldTarget=_Class._#bb
+ */
+ /*member: _Class.bb=:
+ lateFieldName=bb,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#bb
+ */
+ static late int? bb;
+ /*member: _Class._#_b:
+ lateField,
+ lateFieldName=_b,
+ lateFieldTarget=_Class._#_b
+ */
+ /*is-null.member: _Class._#_b#isSet:
+ lateFieldName=_b,
+ lateFieldTarget=_Class._#_b,
+ lateIsSetField
+ */
+ /*member: _Class._b:
+ lateFieldGetter,
+ lateFieldName=_b,
+ lateFieldTarget=_Class._#_b
+ */
+ /*member: _Class._b=:
+ lateFieldName=_b,
+ lateFieldSetter,
+ lateFieldTarget=_Class._#_b
+ */
+ static late int? _b;
+}
+
+extension on int? {
+ /*member: _#_extension#0|a:
+ lateField,
+ lateFieldName=_extension#0|a,
+ lateFieldTarget=_#_extension#0|a
+ */
+ /*is-null.member: _#_extension#0|a#isSet:
+ lateFieldName=_extension#0|a,
+ lateFieldTarget=_#_extension#0|a,
+ lateIsSetField
+ */
+ /*member: _extension#0|a:
+ lateFieldGetter,
+ lateFieldName=_extension#0|a,
+ lateFieldTarget=_#_extension#0|a
+ */
+ /*member: _extension#0|a=:
+ lateFieldName=_extension#0|a,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|a
+ */
+ static late int? a;
+ /*member: _#_extension#0|aa:
+ lateField,
+ lateFieldName=_extension#0|aa,
+ lateFieldTarget=_#_extension#0|aa
+ */
+ /*is-null.member: _#_extension#0|aa#isSet:
+ lateFieldName=_extension#0|aa,
+ lateFieldTarget=_#_extension#0|aa,
+ lateIsSetField
+ */
+ /*member: _extension#0|aa:
+ lateFieldGetter,
+ lateFieldName=_extension#0|aa,
+ lateFieldTarget=_#_extension#0|aa
+ */
+ /*member: _extension#0|aa=:
+ lateFieldName=_extension#0|aa,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|aa
+ */
+ static late int? aa;
+ /*member: _#_extension#0|_b:
+ lateField,
+ lateFieldName=_extension#0|_b,
+ lateFieldTarget=_#_extension#0|_b
+ */
+ /*is-null.member: _#_extension#0|_b#isSet:
+ lateFieldName=_extension#0|_b,
+ lateFieldTarget=_#_extension#0|_b,
+ lateIsSetField
+ */
+ /*member: _extension#0|_b:
+ lateFieldGetter,
+ lateFieldName=_extension#0|_b,
+ lateFieldTarget=_#_extension#0|_b
+ */
+ /*member: _extension#0|_b=:
+ lateFieldName=_extension#0|_b,
+ lateFieldSetter,
+ lateFieldTarget=_#_extension#0|_b
+ */
+ static late int? _b;
+}
+
+extension _Extension on int? {
+ /*member: _#_Extension|a:
+ lateField,
+ lateFieldName=_Extension|a,
+ lateFieldTarget=_#_Extension|a
+ */
+ /*is-null.member: _#_Extension|a#isSet:
+ lateFieldName=_Extension|a,
+ lateFieldTarget=_#_Extension|a,
+ lateIsSetField
+ */
+ /*member: _Extension|a:
+ lateFieldGetter,
+ lateFieldName=_Extension|a,
+ lateFieldTarget=_#_Extension|a
+ */
+ /*member: _Extension|a=:
+ lateFieldName=_Extension|a,
+ lateFieldSetter,
+ lateFieldTarget=_#_Extension|a
+ */
+ static late int? a;
+ /*member: _#_Extension|aa:
+ lateField,
+ lateFieldName=_Extension|aa,
+ lateFieldTarget=_#_Extension|aa
+ */
+ /*is-null.member: _#_Extension|aa#isSet:
+ lateFieldName=_Extension|aa,
+ lateFieldTarget=_#_Extension|aa,
+ lateIsSetField
+ */
+ /*member: _Extension|aa:
+ lateFieldGetter,
+ lateFieldName=_Extension|aa,
+ lateFieldTarget=_#_Extension|aa
+ */
+ /*member: _Extension|aa=:
+ lateFieldName=_Extension|aa,
+ lateFieldSetter,
+ lateFieldTarget=_#_Extension|aa
+ */
+ static late int? aa;
+ /*member: _#_Extension|_b:
+ lateField,
+ lateFieldName=_Extension|_b,
+ lateFieldTarget=_#_Extension|_b
+ */
+ /*is-null.member: _#_Extension|_b#isSet:
+ lateFieldName=_Extension|_b,
+ lateFieldTarget=_#_Extension|_b,
+ lateIsSetField
+ */
+ /*member: _Extension|_b:
+ lateFieldGetter,
+ lateFieldName=_Extension|_b,
+ lateFieldTarget=_#_Extension|_b
+ */
+ /*member: _Extension|_b=:
+ lateFieldName=_Extension|_b,
+ lateFieldSetter,
+ lateFieldTarget=_#_Extension|_b
+ */
+ static late int? _b;
+}
diff --git a/pkg/front_end/test/predicates/data/marker.options b/pkg/front_end/test/predicates/data/marker.options
index afd83e5..1053541 100644
--- a/pkg/front_end/test/predicates/data/marker.options
+++ b/pkg/front_end/test/predicates/data/marker.options
@@ -1 +1,2 @@
-cfe=pkg/front_end/test/predicates/predicate_test.dart
+is-null=pkg/front_end/test/predicates/predicate_test.dart
+sentinel=pkg/front_end/test/predicates/predicate_test.dart
diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart
index f62f803..ffe5ec2 100644
--- a/pkg/front_end/test/predicates/predicate_test.dart
+++ b/pkg/front_end/test/predicates/predicate_test.dart
@@ -9,12 +9,18 @@
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/base/nnbd_mode.dart';
import 'package:front_end/src/testing/id_extractor.dart';
import 'package:front_end/src/testing/id_testing_helper.dart';
+import 'package:front_end/src/testing/id_testing_utils.dart';
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
import 'package:kernel/ast.dart';
+import 'package:kernel/src/printer.dart';
import 'package:kernel/target/targets.dart';
+const String isNullMarker = 'is-null';
+const String sentinelMarker = 'sentinel';
+
main(List<String> args) async {
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await runTests<Features>(dataDir,
@@ -22,20 +28,33 @@
createUriForFileName: createUriForFileName,
onFailure: onFailure,
runTest: runTestFor(const PredicateDataComputer(), [
- const TestConfig(cfeMarker, 'cfe',
+ const TestConfig(isNullMarker, 'use is-null',
explicitExperimentalFlags: const {
ExperimentalFlag.nonNullable: true
},
targetFlags: const TargetFlags(
- forceLateLoweringsForTesting: LateLowering.all))
+ forceLateLoweringsForTesting: LateLowering.all,
+ forceLateLoweringSentinelForTesting: false),
+ nnbdMode: NnbdMode.Strong),
+ const TestConfig(sentinelMarker, 'use sentinel',
+ explicitExperimentalFlags: const {
+ ExperimentalFlag.nonNullable: true
+ },
+ targetFlags: const TargetFlags(
+ forceLateLoweringsForTesting: LateLowering.all,
+ forceLateLoweringSentinelForTesting: true),
+ nnbdMode: NnbdMode.Strong)
]));
}
class Tags {
static const String lateField = 'lateField';
+ static const String lateFieldName = 'lateFieldName';
static const String lateIsSetField = 'lateIsSetField';
static const String lateFieldGetter = 'lateFieldGetter';
static const String lateFieldSetter = 'lateFieldSetter';
+ static const String lateFieldTarget = 'lateFieldTarget';
+ static const String lateFieldInitializer = 'lateFieldInitializer';
static const String lateLocal = 'lateLocal';
static const String lateIsSetLocal = 'lateIsSetLocal';
@@ -95,19 +114,44 @@
Features features = new Features();
if (isLateLoweredField(node)) {
features.add(Tags.lateField);
+ features[Tags.lateFieldName] =
+ extractFieldNameFromLateLoweredField(node).text;
}
if (isLateLoweredIsSetField(node)) {
features.add(Tags.lateIsSetField);
+ features[Tags.lateFieldName] =
+ extractFieldNameFromLateLoweredIsSetField(node).text;
+ }
+ Field target = getLateFieldTarget(node);
+ if (target != null) {
+ features[Tags.lateFieldTarget] = getQualifiedMemberName(target);
+ }
+ Expression initializer = getLateFieldInitializer(node);
+ if (initializer != null) {
+ features[Tags.lateFieldInitializer] =
+ initializer.toText(astTextStrategyForTesting);
}
return features;
} else if (node is Procedure) {
Features features = new Features();
if (isLateLoweredFieldGetter(node)) {
features.add(Tags.lateFieldGetter);
+ features[Tags.lateFieldName] =
+ extractFieldNameFromLateLoweredFieldGetter(node).text;
}
-
if (isLateLoweredFieldSetter(node)) {
features.add(Tags.lateFieldSetter);
+ features[Tags.lateFieldName] =
+ extractFieldNameFromLateLoweredFieldSetter(node).text;
+ }
+ Field target = getLateFieldTarget(node);
+ if (target != null) {
+ features[Tags.lateFieldTarget] = getQualifiedMemberName(target);
+ }
+ Expression initializer = getLateFieldInitializer(node);
+ if (initializer != null) {
+ features[Tags.lateFieldInitializer] =
+ initializer.toText(astTextStrategyForTesting);
}
return features;
}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 12f059f..cfb9146 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -34,6 +34,7 @@
aligned
alive
allocate
+allocator
altered
analogous
analogy
@@ -441,6 +442,7 @@
foo
foobar
footer
+forcing
foreign
formed
former
@@ -836,6 +838,7 @@
pi
picking
pkg
+play
player
plugin
pm
@@ -1264,6 +1267,7 @@
unpleasant
unreachable
unseen
+unset
unshadowed
unsortable
unsound
diff --git a/pkg/front_end/test/unit_test_suites.dart b/pkg/front_end/test/unit_test_suites.dart
index 0bd8b66..8e256f6 100644
--- a/pkg/front_end/test/unit_test_suites.dart
+++ b/pkg/front_end/test/unit_test_suites.dart
@@ -138,24 +138,30 @@
"matches": matchedExpectations,
}));
if (!matchedExpectations) {
- String failureLog = result.log;
+ StringBuffer sb = new StringBuffer();
+ sb.write(result.log);
if (result.error != null) {
- failureLog = "$failureLog\n\n${result.error}";
+ sb.write("\n\n${result.error}");
}
if (result.trace != null) {
- failureLog = "$failureLog\n\n${result.trace}";
+ sb.write("\n\n${result.trace}");
}
+ sb.write("\n\nTo re-run this test, run:");
+ sb.write("\n\n dart pkg/front_end/test/unit_test_suites.dart -p "
+ "$testName");
if (result.autoFixCommand != null) {
- failureLog = "$failureLog\n\n"
- "To re-run this test, run:\n\n"
- " dart pkg/front_end/test/unit_test_suites.dart -p $testName\n\n"
- "To automatically update the test expectations, run:\n\n"
- " dart pkg/front_end/test/unit_test_suites.dart -p $testName "
- "-D${result.autoFixCommand}\n";
- } else {
- failureLog = "$failureLog\n\nRe-run this test: dart "
- "pkg/front_end/test/unit_test_suites.dart -p $testName";
+ sb.write("\n\nTo automatically update the test expectations, run:");
+ sb.write("\n\n dart pkg/front_end/test/unit_test_suites.dart -p "
+ "$testName -D${result.autoFixCommand}");
+ if (result.canBeFixWithUpdateExpectations) {
+ sb.write('\n\nTo update test expectations for all tests at once, '
+ 'run:');
+ sb.write('\n\n dart pkg/front_end/tool/update_expectations.dart');
+ sb.write('\n\nNote that this takes a long time and should only be '
+ 'used when many tests need updating.\n');
+ }
}
+ String failureLog = sb.toString();
String outcome = "${result.outcome}";
logsPort.send(jsonEncode({
"name": testName,
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 397879a..b76a823 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -66,6 +66,8 @@
String get updateExpectationsOption;
+ bool get canBeFixWithUpdateExpectations;
+
ExpectationSet get expectationSet;
Expectation get expectationFileMismatch =>
@@ -96,7 +98,10 @@
output, onMismatch, "$uri doesn't match ${expectedFile.uri}\n$diff",
autoFixCommand: onMismatch == expectationFileMismatch
? updateExpectationsOption
- : null);
+ : null,
+ canBeFixWithUpdateExpectations:
+ onMismatch == expectationFileMismatch &&
+ canBeFixWithUpdateExpectations);
} else {
return new Result<O>.pass(output);
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart
index 97b91dd..a424674 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart
@@ -20,8 +20,9 @@
Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
index e4af729..299f784 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
@@ -8,7 +8,8 @@
@Double()
double y;
Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {}
}
main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
index a7af7c2..2f99722 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
@@ -8,7 +8,8 @@
double x;
@Double()
double y;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {}
}
main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
index 7121f54..3d65f9e 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:ffi" as ffi;
import "dart:core" as core;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -13,8 +12,8 @@
@#C1
field core::double* y = null;
field ffi::Pointer<self::Coordinate*>* next = null;
- static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ static factory allocate(ffi::Allocator* allocator, core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(ffi::AllocatorAlloc|call<self::Coordinate*>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -41,4 +40,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
index 906fb3f..ce1ae9d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -16,8 +15,8 @@
constructor #fromTypedDataBase(dynamic #pointer) → dynamic
: super ffi::Struct::_fromPointer(#pointer)
;
- static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ static factory allocate(ffi::Allocator* allocator, core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(ffi::AllocatorAlloc|call<self::Coordinate*>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -72,4 +71,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart b/pkg/front_end/testcases/nnbd/ffi_sample.dart
index 0c7f870..c45b492 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart
@@ -18,8 +18,9 @@
external Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.outline.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.outline.expect
index 915c142..ad4664a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.outline.expect
@@ -17,7 +17,7 @@
external set y(core::double #externalFieldValue) → void;
external get next() → ffi::Pointer<self::Coordinate>;
external set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void;
- static factory allocate(core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate
+ static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
index 0b6b078..ff96753 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:ffi" as ffi;
import "dart:core" as core;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -18,8 +17,8 @@
external set y(core::double #externalFieldValue) → void;
external get next() → ffi::Pointer<self::Coordinate>;
external set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void;
- static factory allocate(core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
- return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(all::allocate<self::Coordinate>()) in block {
+ static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
+ return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(ffi::AllocatorAlloc|call<self::Coordinate>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -35,4 +34,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
index 92815a2..601d9fb 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -32,8 +31,8 @@
return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::Struct::_addressOf}, (#C18).{core::List::[]}(ffi::_abi())));
set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void
return ffi::_storeIntPtr(this.{ffi::Struct::_addressOf}, (#C18).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
- static factory allocate(core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
- return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(all::allocate<self::Coordinate>()) in block {
+ static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
+ return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(ffi::AllocatorAlloc|call<self::Coordinate>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -66,4 +65,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline.expect
index f21ecbe..326d793 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline.expect
@@ -7,7 +7,8 @@
@Double()
external double y;
external Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {}
}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline_modelled.expect
index 263267c..88e9317 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.textual_outline_modelled.expect
@@ -7,7 +7,8 @@
external double x;
@Double()
external double y;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {}
}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
index 0b6b078..ff96753 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:ffi" as ffi;
import "dart:core" as core;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -18,8 +17,8 @@
external set y(core::double #externalFieldValue) → void;
external get next() → ffi::Pointer<self::Coordinate>;
external set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void;
- static factory allocate(core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
- return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(all::allocate<self::Coordinate>()) in block {
+ static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
+ return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(ffi::AllocatorAlloc|call<self::Coordinate>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -35,4 +34,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
index 92815a2..601d9fb 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
-import "package:ffi/src/allocation.dart" as all;
import "dart:ffi";
import "package:ffi/ffi.dart";
@@ -32,8 +31,8 @@
return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::Struct::_addressOf}, (#C18).{core::List::[]}(ffi::_abi())));
set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void
return ffi::_storeIntPtr(this.{ffi::Struct::_addressOf}, (#C18).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
- static factory allocate(core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
- return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(all::allocate<self::Coordinate>()) in block {
+ static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
+ return let final self::Coordinate #t1 = ffi::StructPointer|get#ref<self::Coordinate>(ffi::AllocatorAlloc|call<self::Coordinate>(allocator)) in block {
#t1.{self::Coordinate::x} = x;
#t1.{self::Coordinate::y} = y;
#t1.{self::Coordinate::next} = next;
@@ -66,4 +65,4 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:116:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:122:9)
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b78e407..0d81ce0 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -141,8 +141,15 @@
bool disableLazyClassReading = false,
bool alwaysCreateNewNamedNodes})
: _disableLazyReading = disableLazyReading,
- _disableLazyClassReading =
- disableLazyReading || disableLazyClassReading,
+ _disableLazyClassReading = disableLazyReading ||
+ disableLazyClassReading ||
+ // Disable lazy class reading when forcing the creation of new named
+ // nodes as it is a logical "relink" to the new version (overwriting
+ // the old one) - which doesn't play well with lazy loading class
+ // content as old loaded references will then potentially still
+ // point to the old content until the new class has been lazy
+ // loaded.
+ (alwaysCreateNewNamedNodes == true),
this.alwaysCreateNewNamedNodes = alwaysCreateNewNamedNodes ?? false;
fail(String message) {
diff --git a/pkg/kernel/lib/src/tool/find_referenced_libraries.dart b/pkg/kernel/lib/src/tool/find_referenced_libraries.dart
new file mode 100644
index 0000000..e95c7df
--- /dev/null
+++ b/pkg/kernel/lib/src/tool/find_referenced_libraries.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2021, 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.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/visitor.dart';
+
+Set<Library> findAllReferencedLibraries(List<Library> from) {
+ _LibraryCollector collector = new _LibraryCollector();
+ for (Library library in from) {
+ collector.visitLibrary(library);
+ }
+ return collector.allSeenLibraries;
+}
+
+bool duplicateLibrariesReachable(List<Library> from) {
+ Set<Uri> seenUris = {};
+ for (Library lib in findAllReferencedLibraries(from)) {
+ if (!seenUris.add(lib.importUri)) return true;
+ }
+ return false;
+}
+
+class _LibraryCollector extends RecursiveVisitor<Null> {
+ Set<Library> allSeenLibraries = {};
+
+ Null defaultNode(Node node) {
+ if (node is NamedNode) {
+ // Named nodes can be linked to.
+ seen(node);
+ } else if (node is Name) {
+ if (node.library != null) {
+ seen(node.library);
+ }
+ }
+ super.defaultNode(node);
+ }
+
+ Null defaultMemberReference(Member node) {
+ seen(node);
+ super.defaultMemberReference(node);
+ }
+
+ void seen(TreeNode node) {
+ TreeNode parent = node;
+ while (parent != null && parent is! Library) {
+ parent = parent.parent;
+ }
+ allSeenLibraries.add(parent);
+ }
+}
diff --git a/pkg/kernel/test/binary/lazy_reading_test.dart b/pkg/kernel/test/binary/lazy_reading_test.dart
new file mode 100644
index 0000000..601cb4e
--- /dev/null
+++ b/pkg/kernel/test/binary/lazy_reading_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2021, 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.
+
+import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:kernel/src/tool/find_referenced_libraries.dart';
+import 'utils.dart';
+
+main() {
+ Library lib;
+ {
+ /// Create a library with two classes (A and B) where class A - in its
+ /// constructor - invokes the constructor for B.
+ lib = new Library(Uri.parse('org-dartlang:///lib.dart'));
+ final Class classA = new Class(name: "A");
+ lib.addClass(classA);
+ final Class classB = new Class(name: "B");
+ lib.addClass(classB);
+
+ final Constructor classBConstructor = new Constructor(
+ new FunctionNode(new EmptyStatement()),
+ name: new Name(""));
+ classB.addConstructor(classBConstructor);
+
+ final Constructor classAConstructor = new Constructor(
+ new FunctionNode(new ExpressionStatement(new ConstructorInvocation(
+ classBConstructor, new Arguments.empty()))),
+ name: new Name(""));
+ classA.addConstructor(classAConstructor);
+ }
+ Component c = new Component(libraries: [lib]);
+ c.setMainMethodAndMode(null, false, NonNullableByDefaultCompiledMode.Weak);
+ List<int> loadMe = serializeComponent(c);
+
+ // Load and make sure we can get at class B from class A (i.e. that it's
+ // loaded correctly!).
+ Component loadedComponent = new Component();
+ new BinaryBuilder(loadMe,
+ disableLazyReading: false, disableLazyClassReading: false)
+ .readSingleFileComponent(loadedComponent);
+ {
+ final Library loadedLib = loadedComponent.libraries.single;
+ final Class loadedClassA = loadedLib.classes.first;
+ final ExpressionStatement loadedConstructorA =
+ loadedClassA.constructors.single.function.body;
+ final ConstructorInvocation loadedConstructorInvocation =
+ loadedConstructorA.expression;
+ final Class pointedToClass =
+ loadedConstructorInvocation.target.enclosingClass;
+ final Library pointedToLib =
+ loadedConstructorInvocation.target.enclosingLibrary;
+
+ Set<Library> reachable = findAllReferencedLibraries([loadedLib]);
+ if (reachable.length != 1 || reachable.single != loadedLib) {
+ throw "Expected only the single library to be reachable, "
+ "but found $reachable";
+ }
+
+ final Class loadedClassB = loadedLib.classes[1];
+ if (loadedClassB != pointedToClass) {
+ throw "Doesn't point to the right class";
+ }
+ if (pointedToLib != loadedLib) {
+ throw "Doesn't point to the right library";
+ }
+ }
+ // Attempt to load again, overwriting the old stuff. This should logically
+ // "relink" to the newly loaded version.
+ Component loadedComponent2 = new Component(nameRoot: loadedComponent.root);
+ new BinaryBuilder(loadMe,
+ disableLazyReading: false,
+ disableLazyClassReading: false,
+ alwaysCreateNewNamedNodes: true)
+ .readSingleFileComponent(loadedComponent2);
+ {
+ final Library loadedLib = loadedComponent2.libraries.single;
+ final Class loadedClassA = loadedLib.classes.first;
+ final ExpressionStatement loadedConstructorA =
+ loadedClassA.constructors.single.function.body;
+ final ConstructorInvocation loadedConstructorInvocation =
+ loadedConstructorA.expression;
+ final Class pointedToClass =
+ loadedConstructorInvocation.target.enclosingClass;
+ final Library pointedToLib =
+ loadedConstructorInvocation.target.enclosingLibrary;
+
+ Set<Library> reachable = findAllReferencedLibraries([loadedLib]);
+ if (reachable.length != 1 || reachable.single != loadedLib) {
+ throw "Expected only the single library to be reachable, "
+ "but found $reachable";
+ }
+
+ final Class loadedClassB = loadedLib.classes[1];
+ if (loadedClassB != pointedToClass) {
+ throw "Doesn't point to the right class";
+ }
+ if (pointedToLib != loadedLib) {
+ throw "Doesn't point to the right library";
+ }
+ }
+}
diff --git a/pkg/kernel/test/convert_field_to_setter_getter.dart b/pkg/kernel/test/convert_field_to_setter_getter.dart
index 6e0b797..d449735 100644
--- a/pkg/kernel/test/convert_field_to_setter_getter.dart
+++ b/pkg/kernel/test/convert_field_to_setter_getter.dart
@@ -2,11 +2,9 @@
// 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.
-import 'dart:io';
-
-import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_from_binary.dart';
import 'package:kernel/binary/ast_to_binary.dart';
+import 'binary/utils.dart';
main() {
final Library lib1 = new Library(Uri.parse('org-dartlang:///lib.dart'));
@@ -180,14 +178,3 @@
StaticGet staticGet = setterStatement.expression;
return staticGet.target;
}
-
-/// A [Sink] that directly writes data into a byte builder.
-class ByteSink implements Sink<List<int>> {
- final BytesBuilder builder = new BytesBuilder();
-
- void add(List<int> data) {
- builder.add(data);
- }
-
- void close() {}
-}
diff --git a/pkg/kernel/test/relink_test.dart b/pkg/kernel/test/relink_test.dart
index ed51ee6..37b0f7d 100644
--- a/pkg/kernel/test/relink_test.dart
+++ b/pkg/kernel/test/relink_test.dart
@@ -2,16 +2,26 @@
// 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.
-import 'dart:io';
-
-import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_from_binary.dart';
import 'package:kernel/binary/ast_to_binary.dart';
+import 'package:kernel/src/tool/find_referenced_libraries.dart';
+import 'binary/utils.dart';
main() {
Component component1 = createComponent(42);
Component component2 = createComponent(43);
+ expectReachable(
+ findAllReferencedLibraries(component1.libraries), component1.libraries);
+ if (duplicateLibrariesReachable(component1.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
+ expectReachable(
+ findAllReferencedLibraries(component2.libraries), component2.libraries);
+ if (duplicateLibrariesReachable(component2.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
+
ByteSink sink = new ByteSink();
new BinaryPrinter(sink).writeComponentFile(component1);
List<int> writtenBytes1 = sink.builder.takeBytes();
@@ -25,6 +35,11 @@
Procedure target1 = getMainTarget(component1Prime);
Procedure procedureLib1 = getLibProcedure(component1Prime);
if (target1 != procedureLib1) throw "Unexpected target.";
+ expectReachable(findAllReferencedLibraries(component1Prime.libraries),
+ component1Prime.libraries);
+ if (duplicateLibrariesReachable(component1Prime.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
// Loading another one saying it should overwrite works as one would expect
// for this component: It gives a component that is linked to itself that is
@@ -36,6 +51,11 @@
Procedure procedureLib2 = getLibProcedure(component2Prime);
if (procedureLib2 == procedureLib1) throw "Unexpected procedure.";
if (target2 != procedureLib2) throw "Unexpected target.";
+ expectReachable(findAllReferencedLibraries(component2Prime.libraries),
+ component2Prime.libraries);
+ if (duplicateLibrariesReachable(component2Prime.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
// The old one that was loaded on top of was re-linked so it also points to
// procedureLib2.
@@ -44,17 +64,48 @@
// Relink back and forth a number of times: It keeps working as expected.
for (int i = 0; i < 6; i++) {
+ // Before the relink the lib from component2Prime is also reachable!
+ expectReachable(
+ findAllReferencedLibraries(component1Prime.libraries),
+ []
+ ..addAll(component1Prime.libraries)
+ ..add(procedureLib2.enclosingLibrary));
+ if (!duplicateLibrariesReachable(component1Prime.libraries)) {
+ throw "Expected duplicates libraries!";
+ }
+
// Relinking component1Prime works as one would expected: Both components
// main now points to procedureLib1.
component1Prime.relink();
+ // After the relink only the libs from component1Prime are reachable!
+ expectReachable(findAllReferencedLibraries(component1Prime.libraries),
+ component1Prime.libraries);
+ if (duplicateLibrariesReachable(component1Prime.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
target1 = getMainTarget(component1Prime);
if (target1 != procedureLib1) throw "Unexpected target.";
target2 = getMainTarget(component2Prime);
if (target2 != procedureLib1) throw "Unexpected target.";
+ // Before the relink the lib from component1Prime is also reachable!
+ expectReachable(
+ findAllReferencedLibraries(component2Prime.libraries),
+ []
+ ..addAll(component2Prime.libraries)
+ ..add(procedureLib1.enclosingLibrary));
+ if (!duplicateLibrariesReachable(component2Prime.libraries)) {
+ throw "Expected duplicates libraries!";
+ }
// Relinking component2Prime works as one would expected: Both components
// main now points to procedureLib2.
component2Prime.relink();
+ // After the relink only the libs from component1Prime are reachable!
+ expectReachable(findAllReferencedLibraries(component2Prime.libraries),
+ component2Prime.libraries);
+ if (duplicateLibrariesReachable(component2Prime.libraries)) {
+ throw "Didn't expect duplicates libraries!";
+ }
target1 = getMainTarget(component1Prime);
if (target1 != procedureLib2) throw "Unexpected target.";
target2 = getMainTarget(component2Prime);
@@ -62,6 +113,18 @@
}
}
+void expectReachable(
+ Set<Library> findAllReferencedLibraries, List<Library> libraries) {
+ Set<Library> onlyInReferenced = findAllReferencedLibraries.toSet()
+ ..removeAll(libraries);
+ Set<Library> onlyInLibraries = libraries.toSet()
+ ..removeAll(findAllReferencedLibraries);
+ if (onlyInReferenced.isNotEmpty || onlyInLibraries.isNotEmpty) {
+ throw "Expected to be the same, but ${onlyInReferenced} was only in "
+ "reachable and ${onlyInLibraries} was only in libraries";
+ }
+}
+
Procedure getLibProcedure(Component component1Prime) {
if (component1Prime.libraries[1].importUri !=
Uri.parse('org-dartlang:///lib.dart')) {
@@ -106,14 +169,3 @@
return new Component(libraries: [main, lib])
..setMainMethodAndMode(null, false, NonNullableByDefaultCompiledMode.Weak);
}
-
-/// A [Sink] that directly writes data into a byte builder.
-class ByteSink implements Sink<List<int>> {
- final BytesBuilder builder = new BytesBuilder();
-
- void add(List<int> data) {
- builder.add(data);
- }
-
- void close() {}
-}
diff --git a/pkg/kernel/test/round_trip.dart b/pkg/kernel/test/round_trip.dart
index b94ae42..271293a 100644
--- a/pkg/kernel/test/round_trip.dart
+++ b/pkg/kernel/test/round_trip.dart
@@ -6,7 +6,7 @@
import 'dart:io';
import 'package:kernel/binary/ast_from_binary.dart';
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/kernel.dart';
+import 'binary/utils.dart';
const String usage = '''
Usage: round_trip.dart FILE.dill [sdk.dill]
@@ -52,14 +52,3 @@
String show(int byte) {
return '$byte (0x${byte.toRadixString(16).padLeft(2, "0")})';
}
-
-/// A [Sink] that directly writes data into a byte builder.
-class ByteSink implements Sink<List<int>> {
- final BytesBuilder builder = new BytesBuilder();
-
- void add(List<int> data) {
- builder.add(data);
- }
-
- void close() {}
-}
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 6d682de..7c51016 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -828,6 +828,7 @@
}
// Expand runtimes.
+ var configurationNumber = 1;
for (var runtime in runtimes) {
// Expand architectures.
var architectures = data["arch"] as String;
@@ -852,8 +853,13 @@
}
for (var sanitizerName in sanitizers.split(",")) {
var sanitizer = Sanitizer.find(sanitizerName);
- var configuration = Configuration("custom configuration",
- architecture, compiler, mode, runtime, system,
+ var configuration = Configuration(
+ "custom configuration_${configurationNumber++}",
+ architecture,
+ compiler,
+ mode,
+ runtime,
+ system,
nnbdMode: nnbdMode,
sanitizer: sanitizer,
timeout: data["timeout"] as int,
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 9c1baf2..96f273a 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -221,26 +221,13 @@
/// Create a directories for generated assets (tests, html files,
/// pubspec checkouts ...).
String createOutputDirectory(Path testPath) {
- var checked = configuration.isChecked ? '-checked' : '';
- var minified = configuration.isMinified ? '-minified' : '';
- var sdk = configuration.useSdk ? '-sdk' : '';
- var dirName = "${configuration.compiler.name}-${configuration.runtime.name}"
- "$checked$minified$sdk";
- return createGeneratedTestDirectoryHelper("tests", dirName, testPath);
+ return createGeneratedTestDirectoryHelper(
+ "tests", configuration.configuration.name, testPath);
}
String createCompilationOutputDirectory(Path testPath) {
- var checked = configuration.isChecked ? '-checked' : '';
- var minified = configuration.isMinified ? '-minified' : '';
- var csp = configuration.isCsp ? '-csp' : '';
- var sdk = configuration.useSdk ? '-sdk' : '';
- var isLegacyModule = configuration.compiler == Compiler.dartdevk &&
- configuration.runtime == Runtime.d8;
- var module = isLegacyModule ? '-legacy' : '';
- var dirName = "${configuration.compiler.name}"
- "$checked$minified$csp$sdk$module";
return createGeneratedTestDirectoryHelper(
- "compilations", dirName, testPath);
+ "compilations", configuration.configuration.name, testPath);
}
String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) {
diff --git a/pkg/test_runner/lib/src/utils.dart b/pkg/test_runner/lib/src/utils.dart
index b1c41171..fc27e18 100644
--- a/pkg/test_runner/lib/src/utils.dart
+++ b/pkg/test_runner/lib/src/utils.dart
@@ -414,13 +414,11 @@
static void deleteTempSnapshotDirectory(TestConfiguration configuration) {
if (configuration.compiler == Compiler.dartk ||
configuration.compiler == Compiler.dartkp) {
- var checked = configuration.isChecked ? '-checked' : '';
- var minified = configuration.isMinified ? '-minified' : '';
- var csp = configuration.isCsp ? '-csp' : '';
- var sdk = configuration.useSdk ? '-sdk' : '';
- var dirName = "${configuration.compiler.name}$checked$minified$csp$sdk";
- var generatedPath =
- configuration.buildDirectory + "/generated_compilations/$dirName";
+ var generatedPath = [
+ configuration.buildDirectory,
+ "generated_compilations",
+ configuration.configuration.name
+ ].join('/');
if (FileSystemEntity.isDirectorySync(generatedPath)) {
TestUtils.deleteDirectory(generatedPath);
}
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index c6f6c16..1f7fc84 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -358,8 +358,16 @@
/// update the test to match new expectations.
final String autoFixCommand;
+ /// If set, the test can be fixed by running
+ ///
+ /// dart pkg/front_end/tool/update_expectations.dart
+ ///
+ final bool canBeFixWithUpdateExpectations;
+
Result(this.output, this.outcome, this.error,
- {this.trace, this.autoFixCommand});
+ {this.trace,
+ this.autoFixCommand,
+ this.canBeFixWithUpdateExpectations: false});
Result.pass(O output) : this(output, Expectation.Pass, null);
@@ -384,7 +392,9 @@
Result<O2> copyWithOutput<O2>(O2 output) {
return new Result<O2>(output, outcome, error,
- trace: trace, autoFixCommand: autoFixCommand)
+ trace: trace,
+ autoFixCommand: autoFixCommand,
+ canBeFixWithUpdateExpectations: canBeFixWithUpdateExpectations)
..logs.addAll(logs);
}
}
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index f8b473f..17ad5f5 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -34,6 +34,7 @@
kFloat,
kDouble,
kVoid,
+ kOpaque,
kStruct,
kHandle,
}
@@ -60,6 +61,7 @@
'Float',
'Double',
'Void',
+ 'Opaque',
'Struct',
'Handle'
];
@@ -86,6 +88,7 @@
4, // Float
8, // Double
UNKNOWN, // Void
+ UNKNOWN, // Opaque
UNKNOWN, // Struct
WORD_SIZE, // Handle
];
@@ -205,9 +208,13 @@
final Procedure numAddition;
final Library ffiLibrary;
+ final Class allocatorClass;
final Class nativeFunctionClass;
+ final Class opaqueClass;
final Class pointerClass;
final Class structClass;
+ final Procedure allocateMethod;
+ final Procedure allocatorAllocateMethod;
final Procedure castMethod;
final Procedure offsetByMethod;
final Procedure elementAtMethod;
@@ -228,6 +235,7 @@
final Map<NativeType, Procedure> elementAtMethods;
final Procedure loadStructMethod;
final Procedure memCopy;
+ final Procedure allocationTearoff;
final Procedure asFunctionTearoff;
final Procedure lookupFunctionTearoff;
@@ -257,9 +265,14 @@
listElementAt = coreTypes.index.getMember('dart:core', 'List', '[]'),
numAddition = coreTypes.index.getMember('dart:core', 'num', '+'),
ffiLibrary = index.getLibrary('dart:ffi'),
+ allocatorClass = index.getClass('dart:ffi', 'Allocator'),
nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
+ opaqueClass = index.getClass('dart:ffi', 'Opaque'),
pointerClass = index.getClass('dart:ffi', 'Pointer'),
structClass = index.getClass('dart:ffi', 'Struct'),
+ allocateMethod = index.getMember('dart:ffi', 'AllocatorAlloc', 'call'),
+ allocatorAllocateMethod =
+ index.getMember('dart:ffi', 'Allocator', 'allocate'),
castMethod = index.getMember('dart:ffi', 'Pointer', 'cast'),
offsetByMethod = index.getMember('dart:ffi', 'Pointer', '_offsetBy'),
elementAtMethod = index.getMember('dart:ffi', 'Pointer', 'elementAt'),
@@ -301,6 +314,8 @@
}),
loadStructMethod = index.getTopLevelMember('dart:ffi', '_loadStruct'),
memCopy = index.getTopLevelMember('dart:ffi', '_memCopy'),
+ allocationTearoff = index.getMember(
+ 'dart:ffi', 'AllocatorAlloc', LibraryIndex.tearoffPrefix + 'call'),
asFunctionTearoff = index.getMember('dart:ffi', 'NativeFunctionPointer',
LibraryIndex.tearoffPrefix + 'asFunction'),
lookupFunctionTearoff = index.getMember(
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 3260c0a..7bfd6a2 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -128,7 +128,9 @@
@override
visitProcedure(Procedure node) {
if (isFfiLibrary && node.isExtensionMember) {
- if (node == asFunctionTearoff || node == lookupFunctionTearoff) {
+ if (node == allocationTearoff ||
+ node == asFunctionTearoff ||
+ node == lookupFunctionTearoff) {
// Skip static checks and transformation for the tearoffs.
return node;
}
@@ -279,6 +281,13 @@
}
}
return _replaceFromFunction(node);
+ } else if (target == allocateMethod) {
+ final DartType nativeType = node.arguments.types[0];
+
+ _ensureNativeTypeValid(nativeType, node);
+
+ // TODO(http://dartbug.com/38721): Inline the body to get rid of a
+ // generic invocation of sizeOf.
}
} on _FfiStaticTypeError {
// It's OK to swallow the exception because the diagnostics issued will
@@ -479,10 +488,15 @@
Class _extendsOrImplementsSealedClass(Class klass) {
final Class superClass = klass.supertype?.classNode;
- // The Struct class can be extended, but subclasses of Struct cannot be (nor
- // implemented).
- if (klass != structClass && hierarchy.isSubtypeOf(klass, structClass)) {
- return superClass != structClass ? superClass : null;
+ // The Opaque and Struct classes can be extended, but subclasses
+ // cannot be (nor implemented).
+ if (klass != opaqueClass &&
+ klass != structClass &&
+ (hierarchy.isSubtypeOf(klass, opaqueClass) ||
+ hierarchy.isSubtypeOf(klass, structClass))) {
+ return superClass != opaqueClass && superClass != structClass
+ ? superClass
+ : null;
}
if (!nativeTypesClasses.contains(klass)) {
diff --git a/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
index f2e8a70..25e0199 100644
--- a/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
+++ b/runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -14,6 +14,7 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../../tests/ffi/calloc.dart';
import '../../../../../tests/ffi/dylib_utils.dart';
final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
@@ -62,7 +63,7 @@
Expect.isTrue(isolate.address != 0);
return isolate;
} finally {
- free(cname);
+ calloc.free(cname);
}
}
@@ -86,8 +87,8 @@
onError != null ? onError.nativePort : 0,
onExit != null ? onExit.nativePort : 0);
- free(libraryUri);
- free(functionName);
+ calloc.free(libraryUri);
+ calloc.free(functionName);
}
}
@@ -120,7 +121,7 @@
// wait a little here to ensure the write of the callback has arrived.
await Future.delayed(const Duration(milliseconds: 100));
Expect.equals('xbz', Utf8.fromUtf8(peer.cast()));
- free(peer);
+ calloc.free(peer);
}
}
diff --git a/runtime/tests/vm/dart/regress_41971_test.dart b/runtime/tests/vm/dart/regress_41971_test.dart
index 28f63ad..7979d0d 100644
--- a/runtime/tests/vm/dart/regress_41971_test.dart
+++ b/runtime/tests/vm/dart/regress_41971_test.dart
@@ -11,6 +11,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../tests/ffi/calloc.dart';
+
class X {
int field;
X(this.field);
@@ -35,8 +37,8 @@
}
void main() {
- final p = allocate<Int32>(count: 128);
+ final p = calloc<Int32>(128);
p[0] = 42;
Expect.equals(42, loadFrom(p));
- free(p);
+ calloc.free(p);
}
diff --git a/runtime/tests/vm/dart/thread_priority_macos_test.dart b/runtime/tests/vm/dart/thread_priority_macos_test.dart
index b7c8280..473c1ce 100644
--- a/runtime/tests/vm/dart/thread_priority_macos_test.dart
+++ b/runtime/tests/vm/dart/thread_priority_macos_test.dart
@@ -10,6 +10,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../tests/ffi/calloc.dart';
+
// pthread_t pthread_self()
typedef PthreadSelfFT = int Function();
typedef PthreadSelfNFT = IntPtr Function();
@@ -34,11 +36,11 @@
main(args) {
if (Platform.isMacOS) {
- final policy = allocate<Int32>(count: 1);
- final param = allocate<SchedParam>(count: 1);
+ final policy = calloc<Int32>(1);
+ final param = calloc<SchedParam>(1);
Expect.equals(0, pthreadGetSchedParam(pthreadSelf(), policy, param));
Expect.equals(15, param.ref.schedPriority);
- free(policy);
- free(param);
+ calloc.free(policy);
+ calloc.free(param);
}
}
diff --git a/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
index 0daead0..d35474e 100644
--- a/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/dart_api_create_lightweight_isolate_test.dart
@@ -14,6 +14,7 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../../tests/ffi/calloc.dart';
import '../../../../../tests/ffi/dylib_utils.dart';
final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
@@ -62,7 +63,7 @@
Expect.isTrue(isolate.address != 0);
return isolate;
} finally {
- free(cname);
+ calloc.free(cname);
}
}
@@ -86,8 +87,8 @@
onError != null ? onError.nativePort : 0,
onExit != null ? onExit.nativePort : 0);
- free(libraryUri);
- free(functionName);
+ calloc.free(libraryUri);
+ calloc.free(functionName);
}
}
@@ -120,7 +121,7 @@
// wait a little here to ensure the write of the callback has arrived.
await Future.delayed(const Duration(milliseconds: 100));
Expect.equals('xbz', Utf8.fromUtf8(peer.cast()));
- free(peer);
+ calloc.free(peer);
}
}
diff --git a/runtime/tests/vm/dart_2/regress_41971_test.dart b/runtime/tests/vm/dart_2/regress_41971_test.dart
index 28f63ad..7979d0d 100644
--- a/runtime/tests/vm/dart_2/regress_41971_test.dart
+++ b/runtime/tests/vm/dart_2/regress_41971_test.dart
@@ -11,6 +11,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../tests/ffi/calloc.dart';
+
class X {
int field;
X(this.field);
@@ -35,8 +37,8 @@
}
void main() {
- final p = allocate<Int32>(count: 128);
+ final p = calloc<Int32>(128);
p[0] = 42;
Expect.equals(42, loadFrom(p));
- free(p);
+ calloc.free(p);
}
diff --git a/runtime/tests/vm/dart_2/thread_priority_macos_test.dart b/runtime/tests/vm/dart_2/thread_priority_macos_test.dart
index b466eb0..fdce726 100644
--- a/runtime/tests/vm/dart_2/thread_priority_macos_test.dart
+++ b/runtime/tests/vm/dart_2/thread_priority_macos_test.dart
@@ -10,6 +10,8 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
+import '../../../../tests/ffi/calloc.dart';
+
// pthread_t pthread_self()
typedef PthreadSelfFT = int Function();
typedef PthreadSelfNFT = IntPtr Function();
@@ -34,11 +36,11 @@
main(args) {
if (Platform.isMacOS) {
- final policy = allocate<Int32>(count: 1);
- final param = allocate<SchedParam>(count: 1);
+ final policy = calloc<Int32>(1);
+ final param = calloc<SchedParam>(1);
Expect.equals(0, pthreadGetSchedParam(pthreadSelf(), policy, param));
Expect.equals(15, param.ref.schedPriority);
- free(policy);
- free(param);
+ calloc.free(policy);
+ calloc.free(param);
}
}
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index bfff86b..2836127 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -243,7 +243,7 @@
}
s->WriteCid(class_id);
if (s->kind() == Snapshot::kFullCore &&
- RequireLegacyErasureOfConstants(cls)) {
+ RequireCanonicalTypeErasureOfConstants(cls)) {
s->UnexpectedObject(cls, "Class with non mode agnostic constants");
}
if (s->kind() != Snapshot::kFullAOT) {
@@ -268,10 +268,10 @@
GrowableArray<ClassPtr> predefined_;
GrowableArray<ClassPtr> objects_;
- bool RequireLegacyErasureOfConstants(ClassPtr cls) {
+ bool RequireCanonicalTypeErasureOfConstants(ClassPtr cls) {
// Do not generate a core snapshot containing constants that would require
- // a legacy erasure of their types if loaded in an isolate running in weak
- // mode.
+ // a canonical erasure of their types if loaded in an isolate running in
+ // unsound nullability mode.
if (cls->ptr()->host_type_arguments_field_offset_in_words_ ==
Class::kNoTypeArguments ||
cls->ptr()->constants_ == Array::null()) {
@@ -279,7 +279,7 @@
}
Zone* zone = Thread::Current()->zone();
const Class& clazz = Class::Handle(zone, cls);
- return clazz.RequireLegacyErasureOfConstants(zone);
+ return clazz.RequireCanonicalTypeErasureOfConstants(zone);
}
};
#endif // !DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index eab7f31..af38fcf 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -199,7 +199,7 @@
// Build type from the raw bytes (needs temporary translator).
TypeTranslator type_translator(
&reader, this, active_class_, true,
- active_class_->RequireLegacyErasure(null_safety));
+ active_class_->RequireConstCanonicalTypeErasure(null_safety));
auto& type_arguments =
TypeArguments::Handle(Z, TypeArguments::New(1, Heap::kOld));
AbstractType& type = type_translator.BuildType();
@@ -242,7 +242,7 @@
// Build type from the raw bytes (needs temporary translator).
TypeTranslator type_translator(
&reader, this, active_class_, true,
- active_class_->RequireLegacyErasure(null_safety));
+ active_class_->RequireConstCanonicalTypeErasure(null_safety));
const intptr_t number_of_type_arguments = reader.ReadUInt();
if (klass.NumTypeArguments() > 0) {
auto& type_arguments = TypeArguments::Handle(
@@ -285,7 +285,7 @@
// Build type from the raw bytes (needs temporary translator).
TypeTranslator type_translator(
&reader, this, active_class_, true,
- active_class_->RequireLegacyErasure(null_safety));
+ active_class_->RequireConstCanonicalTypeErasure(null_safety));
const intptr_t number_of_type_arguments = reader.ReadUInt();
ASSERT(number_of_type_arguments > 0);
auto& type_arguments = TypeArguments::Handle(
@@ -318,7 +318,11 @@
}
case kTypeLiteralConstant: {
// Build type from the raw bytes (needs temporary translator).
- // Legacy erasure is not applied to type literals. See issue #42262.
+ // Const canonical type erasure is not applied to constant type literals.
+ // However, CFE must ensure that constant type literals can be
+ // canonicalized to an identical representant independently of the null
+ // safety mode currently in use (sound or unsound) or migration state of
+ // the declaring library (legacy or opted-in).
TypeTranslator type_translator(&reader, this, active_class_, true);
instance = type_translator.BuildType().raw();
break;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 6e6216e..ae03f6e 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2925,7 +2925,7 @@
ConstantReader* constant_reader,
ActiveClass* active_class,
bool finalize,
- bool apply_legacy_erasure)
+ bool apply_canonical_type_erasure)
: helper_(helper),
constant_reader_(constant_reader),
translation_helper_(helper->translation_helper_),
@@ -2936,7 +2936,7 @@
zone_(translation_helper_.zone()),
result_(AbstractType::Handle(translation_helper_.zone())),
finalize_(finalize),
- apply_legacy_erasure_(apply_legacy_erasure) {}
+ apply_canonical_type_erasure_(apply_canonical_type_erasure) {}
AbstractType& TypeTranslator::BuildType() {
BuildTypeInternal();
@@ -2968,13 +2968,13 @@
result_ = Object::void_type().raw();
break;
case kNeverType: {
- const Nullability nullability = helper_->ReadNullability();
- if (apply_legacy_erasure_) {
- result_ = IG->object_store()->null_type();
- } else {
- result_ = Type::Handle(Z, IG->object_store()->never_type())
- .ToNullability(nullability, Heap::kOld);
+ Nullability nullability = helper_->ReadNullability();
+ if (apply_canonical_type_erasure_ &&
+ nullability != Nullability::kNullable) {
+ nullability = Nullability::kLegacy;
}
+ result_ = Type::Handle(Z, IG->object_store()->never_type())
+ .ToNullability(nullability, Heap::kOld);
break;
}
case kBottomType:
@@ -3009,7 +3009,7 @@
// => We therefore ignore errors in `A` or `B`.
Nullability nullability = helper_->ReadNullability();
- if (apply_legacy_erasure_) {
+ if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
nullability = Nullability::kLegacy;
}
@@ -3050,7 +3050,7 @@
? active_class_->enclosing->NumTypeArguments()
: 0;
Nullability nullability = helper_->ReadNullability();
- if (apply_legacy_erasure_) {
+ if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
nullability = Nullability::kLegacy;
}
FunctionType& signature = FunctionType::ZoneHandle(
@@ -3120,8 +3120,7 @@
const uint8_t flags = helper_->ReadFlags(); // read flags
signature.SetParameterTypeAt(pos, result_);
signature.SetParameterNameAt(pos, name);
- if (!apply_legacy_erasure_ &&
- (flags & static_cast<uint8_t>(NamedTypeFlags::kIsRequired)) != 0) {
+ if ((flags & static_cast<uint8_t>(NamedTypeFlags::kIsRequired)) != 0) {
signature.SetIsRequiredAt(pos);
}
}
@@ -3146,7 +3145,7 @@
void TypeTranslator::BuildTypeParameterType() {
Nullability nullability = helper_->ReadNullability();
- if (apply_legacy_erasure_) {
+ if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
nullability = Nullability::kLegacy;
}
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 52454ac..044e034 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1330,7 +1330,7 @@
return member->IsFactory();
}
- bool RequireLegacyErasure(bool null_safety) const {
+ bool RequireConstCanonicalTypeErasure(bool null_safety) const {
return klass != nullptr && !null_safety &&
Library::Handle(klass->library()).nnbd_compiled_mode() ==
NNBDCompiledMode::kAgnostic;
@@ -1459,7 +1459,7 @@
ConstantReader* constant_reader,
ActiveClass* active_class,
bool finalize = false,
- bool apply_legacy_erasure = false);
+ bool apply_canonical_type_erasure = false);
AbstractType& BuildType();
AbstractType& BuildTypeWithoutFinalization();
@@ -1533,7 +1533,7 @@
Zone* zone_;
AbstractType& result_;
bool finalize_;
- const bool apply_legacy_erasure_;
+ const bool apply_canonical_type_erasure_;
friend class ScopeBuilder;
friend class KernelLoader;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index dfa5bba..129d71f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -5828,38 +5828,29 @@
set.Release();
}
-bool Class::RequireLegacyErasureOfConstants(Zone* zone) const {
+bool Class::RequireCanonicalTypeErasureOfConstants(Zone* zone) const {
const intptr_t num_type_params = NumTypeParameters();
const intptr_t num_type_args = NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
Instance& constant = Instance::Handle(zone);
TypeArguments& type_arguments = TypeArguments::Handle(zone);
- AbstractType& type = AbstractType::Handle(zone);
CanonicalInstancesSet set(zone, constants());
CanonicalInstancesSet::Iterator it(&set);
+ bool result = false;
while (it.MoveNext()) {
constant ^= set.GetKey(it.Current());
ASSERT(!constant.IsNull());
ASSERT(!constant.IsTypeArguments());
ASSERT(!constant.IsType());
type_arguments = constant.GetTypeArguments();
- if (type_arguments.IsNull()) {
- continue;
- }
- for (intptr_t i = 0; i < num_type_params; i++) {
- type = type_arguments.TypeAt(from_index + i);
- if (!type.IsLegacy() && !type.IsVoidType() && !type.IsDynamicType() &&
- !type.IsNullType()) {
- set.Release();
- return true;
- }
- // It is not possible for a legacy type to have non-legacy type
- // arguments or for a legacy function type to have non-legacy parameter
- // types, non-legacy type parameters, or required named parameters.
+ if (type_arguments.RequireConstCanonicalTypeErasure(zone, from_index,
+ num_type_params)) {
+ result = true;
+ break;
}
}
set.Release();
- return false;
+ return result;
}
intptr_t TypeArguments::ComputeNullability() const {
@@ -6067,6 +6058,27 @@
return false;
}
+bool TypeArguments::RequireConstCanonicalTypeErasure(Zone* zone,
+ intptr_t from_index,
+ intptr_t len,
+ TrailPtr trail) const {
+ if (IsNull()) return false;
+ ASSERT(Length() >= (from_index + len));
+ AbstractType& type = AbstractType::Handle(zone);
+ for (intptr_t i = 0; i < len; i++) {
+ type = TypeAt(from_index + i);
+ if (type.IsNonNullable() ||
+ (type.IsNullable() &&
+ type.RequireConstCanonicalTypeErasure(zone, trail))) {
+ // It is not possible for a legacy type to have non-nullable type
+ // arguments or for a legacy function type to have non-nullable type in
+ // its signature.
+ return true;
+ }
+ }
+ return false;
+}
+
bool TypeArguments::IsDynamicTypes(bool raw_instantiated,
intptr_t from_index,
intptr_t len) const {
@@ -19060,6 +19072,13 @@
return false;
}
+bool AbstractType::RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail) const {
+ // AbstractType is an abstract class.
+ UNREACHABLE();
+ return false;
+}
+
AbstractTypePtr AbstractType::InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
@@ -20059,6 +20078,24 @@
return TypeArguments::Handle(arguments()).IsRecursive(trail);
}
+bool Type::RequireConstCanonicalTypeErasure(Zone* zone, TrailPtr trail) const {
+ if (IsNonNullable()) {
+ return true;
+ }
+ if (IsLegacy()) {
+ // It is not possible for a legacy type parameter to have a non-nullable
+ // bound or non-nullable default argument.
+ return false;
+ }
+ const Class& cls = Class::Handle(zone, type_class());
+ const intptr_t num_type_params = cls.NumTypeParameters();
+ const intptr_t num_type_args = cls.NumTypeArguments();
+ const intptr_t from_index = num_type_args - num_type_params;
+ return TypeArguments::Handle(zone, arguments())
+ .RequireConstCanonicalTypeErasure(zone, from_index, num_type_params,
+ trail);
+}
+
bool Type::IsDeclarationTypeOf(const Class& cls) const {
ASSERT(type_class() == cls.raw());
if (cls.IsNullClass()) {
@@ -20413,6 +20450,47 @@
return false;
}
+bool FunctionType::RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail) const {
+ if (IsNonNullable()) {
+ return true;
+ }
+ if (IsLegacy()) {
+ // It is not possible for a function type to have a non-nullable type in
+ // its signature.
+ return false;
+ }
+ AbstractType& type = AbstractType::Handle(zone);
+ const intptr_t num_type_params = NumTypeParameters();
+ if (num_type_params > 0) {
+ const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
+ TypeParameter& type_param = TypeParameter::Handle(zone);
+ for (intptr_t i = 0; i < num_type_params; i++) {
+ type_param ^= type_params.TypeAt(i);
+ type = type_param.bound();
+ if (type.RequireConstCanonicalTypeErasure(zone, trail)) {
+ return true;
+ }
+ type = type_param.default_argument();
+ if (type.RequireConstCanonicalTypeErasure(zone, trail)) {
+ return true;
+ }
+ }
+ }
+ type = result_type();
+ if (type.RequireConstCanonicalTypeErasure(zone, trail)) {
+ return true;
+ }
+ const intptr_t num_params = NumParameters();
+ for (intptr_t i = 0; i < num_params; i++) {
+ type = ParameterTypeAt(i);
+ if (type.RequireConstCanonicalTypeErasure(zone, trail)) {
+ return true;
+ }
+ }
+ return false;
+}
+
AbstractTypePtr FunctionType::Canonicalize(Thread* thread,
TrailPtr trail) const {
ASSERT(IsFinalized());
@@ -20552,6 +20630,16 @@
type.EnumerateURIs(uris);
}
+bool TypeRef::RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail) const {
+ if (TestAndAddToTrail(&trail)) {
+ return false;
+ }
+ const AbstractType& ref_type = AbstractType::Handle(zone, type());
+ return !ref_type.IsNull() &&
+ ref_type.RequireConstCanonicalTypeErasure(zone, trail);
+}
+
bool TypeRef::IsInstantiated(Genericity genericity,
intptr_t num_free_fun_type_params,
TrailPtr trail) const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1b8150e..ec29673 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1328,7 +1328,7 @@
void RehashConstants(Zone* zone) const;
- bool RequireLegacyErasureOfConstants(Zone* zone) const;
+ bool RequireCanonicalTypeErasureOfConstants(Zone* zone) const;
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(ClassLayout));
@@ -7404,6 +7404,15 @@
return IsDynamicTypes(true, 0, len);
}
+ // Return true if this vector contains a TypeRef.
+ bool IsRecursive(TrailPtr trail = nullptr) const;
+
+ // Return true if this vector contains a non-nullable type.
+ bool RequireConstCanonicalTypeErasure(Zone* zone,
+ intptr_t from_index,
+ intptr_t len,
+ TrailPtr trail = nullptr) const;
+
TypeArgumentsPtr Prepend(Zone* zone,
const TypeArguments& other,
intptr_t other_length,
@@ -7461,9 +7470,6 @@
// Return true if all types of this vector are finalized.
bool IsFinalized() const;
- // Return true if this vector contains a recursive type argument.
- bool IsRecursive(TrailPtr trail = nullptr) const;
-
// Caller must hold Isolate::constant_canonicalization_mutex_.
virtual InstancePtr CanonicalizeLocked(Thread* thread) const {
return Canonicalize(thread, nullptr);
@@ -7633,6 +7639,8 @@
TypeEquality kind,
TrailPtr trail = nullptr) const;
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
+ virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail = nullptr) const;
// Instantiate this type using the given type argument vectors.
//
@@ -7890,6 +7898,8 @@
TypeEquality kind,
TrailPtr trail = nullptr) const;
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
+ virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail = nullptr) const;
// Return true if this type can be used as the declaration type of cls after
// canonicalization (passed-in cls must match type_class()).
@@ -8034,6 +8044,8 @@
TypeEquality kind,
TrailPtr trail = nullptr) const;
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
+ virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail = nullptr) const;
virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
@@ -8277,6 +8289,8 @@
TypeEquality kind,
TrailPtr trail = nullptr) const;
virtual bool IsRecursive(TrailPtr trail = nullptr) const { return true; }
+ virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
+ TrailPtr trail = nullptr) const;
virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
@@ -8386,6 +8400,11 @@
TypeEquality kind,
TrailPtr trail = nullptr) const;
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
+ virtual bool RequireConstCanonicalTypeErasure(
+ Zone* zone,
+ TrailPtr trail = nullptr) const {
+ return IsNonNullable();
+ }
virtual AbstractTypePtr InstantiateFrom(
const TypeArguments& instantiator_type_arguments,
const TypeArguments& function_type_arguments,
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index e5b845a..a660f5c 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -2064,7 +2064,8 @@
Type& type = Type::Handle();
type ^= Api::UnwrapHandle(cls); // Dart_GetClass actually returns a Type.
const Class& clazz = Class::Handle(type.type_class());
- const bool required = clazz.RequireLegacyErasureOfConstants(zone.GetZone());
+ const bool required =
+ clazz.RequireCanonicalTypeErasureOfConstants(zone.GetZone());
EXPECT(required == isolate->group()->null_safety());
// Verify that snapshot writing succeeds if erasure is not required.
diff --git a/samples/ffi/async/sample_async_callback.dart b/samples/ffi/async/sample_async_callback.dart
index 59ae31b..4901c55 100644
--- a/samples/ffi/async/sample_async_callback.dart
+++ b/samples/ffi/async/sample_async_callback.dart
@@ -105,7 +105,7 @@
final executeCallback = dl.lookupFunction<Void Function(Pointer<Work>),
void Function(Pointer<Work>)>('ExecuteCallback');
-class Work extends Struct {}
+class Work extends Opaque {}
Future asyncSleep(int ms) {
return new Future.delayed(Duration(milliseconds: ms));
diff --git a/samples/ffi/calloc.dart b/samples/ffi/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/samples/ffi/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/samples/ffi/coordinate.dart b/samples/ffi/coordinate.dart
index 8a54ba9..01f8ec3 100644
--- a/samples/ffi/coordinate.dart
+++ b/samples/ffi/coordinate.dart
@@ -16,8 +16,9 @@
external Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/samples/ffi/resource_management/pool.dart b/samples/ffi/resource_management/pool.dart
index 7064f9f..3bc0e2a 100644
--- a/samples/ffi/resource_management/pool.dart
+++ b/samples/ffi/resource_management/pool.dart
@@ -5,48 +5,36 @@
// Explicit pool used for managing resources.
import "dart:async";
-import 'dart:convert';
import 'dart:ffi';
-import 'dart:typed_data';
-import 'package:ffi/ffi.dart' as packageFfi;
-import 'package:ffi/ffi.dart' show Utf8;
+import 'package:ffi/ffi.dart';
-/// Manages native resources.
+import '../calloc.dart';
+
+/// Keeps track of all allocated memory and frees all allocated memory on
+/// [releaseAll].
///
-/// Primary implementations are [Pool] and [Unmanaged].
-abstract class ResourceManager {
- /// Allocates memory on the native heap.
- ///
- /// The native memory is under management by this [ResourceManager].
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count: 1});
-}
+/// Wraps an [Allocator] to do the actual allocation and freeing.
+class Pool implements Allocator {
+ /// The [Allocator] used for allocation and freeing.
+ final Allocator _wrappedAllocator;
-/// Manages native resources.
-class Pool implements ResourceManager {
+ Pool(this._wrappedAllocator);
+
/// Native memory under management by this [Pool].
final List<Pointer<NativeType>> _managedMemoryPointers = [];
/// Callbacks for releasing native resources under management by this [Pool].
final List<Function()> _managedResourceReleaseCallbacks = [];
- /// Allocates memory on the native heap.
+ /// Allocates memory on the native heap by using the allocator supplied to
+ /// the constructor.
///
- /// The native memory is under management by this [Pool].
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count: 1}) {
- final p = Unmanaged().allocate<T>(count: count);
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int numBytes, {int? alignment}) {
+ final p = _wrappedAllocator.allocate<T>(numBytes, alignment: alignment);
_managedMemoryPointers.add(p);
return p;
}
@@ -71,17 +59,21 @@
}
_managedResourceReleaseCallbacks.clear();
for (final p in _managedMemoryPointers) {
- Unmanaged().free(p);
+ _wrappedAllocator.free(p);
}
_managedMemoryPointers.clear();
}
+
+ @override
+ void free(Pointer<NativeType> pointer) => throw UnsupportedError(
+ "Individually freeing Pool allocated memory is not allowed");
}
/// Creates a [Pool] to manage native resources.
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
-R using<R>(R Function(Pool) f) {
- final p = Pool();
+R using<R>(R Function(Pool) f, [Allocator wrappedAllocator = calloc]) {
+ final p = Pool(wrappedAllocator);
try {
return f(p);
} finally {
@@ -96,8 +88,8 @@
/// Please note that all throws are caught and packaged in [RethrownError].
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
-R usePool<R>(R Function() f) {
- final p = Pool();
+R usePool<R>(R Function() f, [Allocator wrappedAllocator = calloc]) {
+ final p = Pool(wrappedAllocator);
try {
return runZoned(() => f(),
zoneValues: {#_pool: p},
@@ -117,78 +109,3 @@
toString() => """RethrownError(${original})
${originalStackTrace}""";
}
-
-/// Does not manage it's resources.
-class Unmanaged implements ResourceManager {
- /// Allocates memory on the native heap.
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count = 1}) =>
- packageFfi.allocate(count: count);
-
- /// Releases memory on the native heap.
- ///
- /// For POSIX-based systems, this uses free. On Windows, it uses HeapFree
- /// against the default public heap. It may only be used against pointers
- /// allocated in a manner equivalent to [allocate].
- ///
- /// Throws an ArgumentError on failure to free.
- ///
- void free(Pointer pointer) => packageFfi.free(pointer);
-}
-
-/// Does not manage it's resources.
-final Unmanaged unmanaged = Unmanaged();
-
-extension Utf8InPool on String {
- /// Convert a [String] to a Utf8-encoded null-terminated C string.
- ///
- /// If 'string' contains NULL bytes, the converted string will be truncated
- /// prematurely. Unpaired surrogate code points in [string] will be preserved
- /// in the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
- ///
- /// Returns a malloc-allocated pointer to the result.
- ///
- /// The memory is managed by the [Pool] passed in as [pool].
- Pointer<Utf8> toUtf8(ResourceManager pool) {
- final units = utf8.encode(this);
- final Pointer<Uint8> result = pool.allocate<Uint8>(count: units.length + 1);
- final Uint8List nativeString = result.asTypedList(units.length + 1);
- nativeString.setAll(0, units);
- nativeString[units.length] = 0;
- return result.cast();
- }
-}
-
-extension Utf8Helpers on Pointer<Utf8> {
- /// Returns the length of a null-terminated string -- the number of (one-byte)
- /// characters before the first null byte.
- int strlen() {
- final Pointer<Uint8> array = this.cast<Uint8>();
- final Uint8List nativeString = array.asTypedList(_maxSize);
- return nativeString.indexWhere((char) => char == 0);
- }
-
- /// Creates a [String] containing the characters UTF-8 encoded in [this].
- ///
- /// [this] must be a zero-terminated byte sequence of valid UTF-8
- /// encodings of Unicode code points. It may also contain UTF-8 encodings of
- /// unpaired surrogate code points, which is not otherwise valid UTF-8, but
- /// which may be created when encoding a Dart string containing an unpaired
- /// surrogate. See [Utf8Decoder] for details on decoding.
- ///
- /// Returns a Dart string containing the decoded code points.
- String contents() {
- final int length = strlen();
- return utf8.decode(Uint8List.view(
- this.cast<Uint8>().asTypedList(length).buffer, 0, length));
- }
-}
-
-const int _kMaxSmi64 = (1 << 62) - 1;
-const int _kMaxSmi32 = (1 << 30) - 1;
-final int _maxSize = sizeOf<IntPtr>() == 8 ? _kMaxSmi64 : _kMaxSmi32;
diff --git a/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart b/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
index cab2cb0..39de01d 100644
--- a/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
+++ b/samples/ffi/resource_management/pool_isolate_shutdown_sample.dart
@@ -86,4 +86,4 @@
void Function(Pointer<SomeResource>)>("ReleaseResource");
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples/ffi/resource_management/pool_sample.dart b/samples/ffi/resource_management/pool_sample.dart
index 00ee1ae..ef8b415 100644
--- a/samples/ffi/resource_management/pool_sample.dart
+++ b/samples/ffi/resource_management/pool_sample.dart
@@ -9,6 +9,7 @@
import 'package:expect/expect.dart';
import 'pool.dart';
+import 'utf8_helpers.dart';
import '../dylib_utils.dart';
main() {
@@ -21,7 +22,7 @@
// To ensure resources are freed, wrap them in a [using] call.
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
p[0] = 24;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
@@ -31,14 +32,14 @@
// Resources are freed also when abnormal control flow occurs.
try {
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
p[0] = 25;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
Expect.equals(25, p[1]);
throw Exception("Some random exception");
});
- // `free(p)` has been called.
+ // `calloc.free(p)` has been called.
} on Exception catch (e) {
print("Caught exception: $e");
}
@@ -46,8 +47,8 @@
// In a pool multiple resources can be allocated, which will all be freed
// at the end of the scope.
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
- final p2 = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
+ final p2 = pool<Int64>(2);
p[0] = 1;
p[1] = 2;
MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
@@ -58,7 +59,7 @@
// If the resource allocation happens in a different scope, then one either
// needs to pass the pool to that scope.
f1(Pool pool) {
- return pool.allocate<Int64>(count: 2);
+ return pool<Int64>(2);
}
using((Pool pool) {
@@ -110,4 +111,4 @@
}
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples/ffi/resource_management/pool_zoned_sample.dart b/samples/ffi/resource_management/pool_zoned_sample.dart
index 05f1794..4c99fdc 100644
--- a/samples/ffi/resource_management/pool_zoned_sample.dart
+++ b/samples/ffi/resource_management/pool_zoned_sample.dart
@@ -9,6 +9,7 @@
import 'package:expect/expect.dart';
import 'pool.dart';
+import 'utf8_helpers.dart';
import '../dylib_utils.dart';
main() {
@@ -21,7 +22,7 @@
// To ensure resources are freed, wrap them in a [using] call.
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
p[0] = 24;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
@@ -31,7 +32,7 @@
// Resources are freed also when abnormal control flow occurs.
try {
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
p[0] = 25;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
@@ -46,8 +47,8 @@
// In a pool multiple resources can be allocated, which will all be freed
// at the end of the scope.
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
- final p2 = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
+ final p2 = currentPool<Int64>(2);
p[0] = 1;
p[1] = 2;
MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
@@ -58,7 +59,7 @@
// If the resource allocation happens in a different scope, it is in the
// same zone, so it's lifetime is automatically managed by the pool.
f1() {
- return currentPool.allocate<Int64>(count: 2);
+ return currentPool<Int64>(2);
}
usePool(() {
@@ -111,4 +112,4 @@
}
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples/ffi/resource_management/unmanaged_sample.dart b/samples/ffi/resource_management/unmanaged_sample.dart
index 9c3e0f0..04c20cb 100644
--- a/samples/ffi/resource_management/unmanaged_sample.dart
+++ b/samples/ffi/resource_management/unmanaged_sample.dart
@@ -7,30 +7,32 @@
import 'dart:ffi';
import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
-import 'pool.dart';
+import 'utf8_helpers.dart';
+import '../calloc.dart';
import '../dylib_utils.dart';
main() {
final ffiTestDynamicLibrary =
dlopenPlatformSpecific("ffi_test_dynamic_library");
- final MemMove = ffiTestDynamicLibrary.lookupFunction<
+ final memMove = ffiTestDynamicLibrary.lookupFunction<
Void Function(Pointer<Void>, Pointer<Void>, IntPtr),
void Function(Pointer<Void>, Pointer<Void>, int)>("MemMove");
// To ensure resources are freed, call free manually.
//
// For automatic management use a Pool.
- final p = unmanaged.allocate<Int64>(count: 2);
+ final p = calloc<Int64>(2);
p[0] = 24;
- MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
+ memMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
Expect.equals(24, p[1]);
- unmanaged.free(p);
+ calloc.free(p);
// Using Strings.
- final p2 = "Hello world!".toUtf8(unmanaged);
+ final p2 = "Hello world!".toUtf8(calloc);
print(p2.contents());
- unmanaged.free(p2);
+ calloc.free(p2);
}
diff --git a/samples/ffi/resource_management/utf8_helpers.dart b/samples/ffi/resource_management/utf8_helpers.dart
new file mode 100644
index 0000000..ed7b4a1
--- /dev/null
+++ b/samples/ffi/resource_management/utf8_helpers.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, 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.
+
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:typed_data';
+
+import 'package:ffi/ffi.dart';
+
+extension Utf8InPool on String {
+ /// Convert a [String] to a Utf8-encoded null-terminated C string.
+ ///
+ /// If 'string' contains NULL bytes, the converted string will be truncated
+ /// prematurely. See [Utf8Encoder] for details on encoding.
+ ///
+ /// Returns a [allocator]-allocated pointer to the result.
+ Pointer<Utf8> toUtf8(Allocator allocator) {
+ final units = utf8.encode(this);
+ final Pointer<Uint8> result = allocator<Uint8>(units.length + 1);
+ final Uint8List nativeString = result.asTypedList(units.length + 1);
+ nativeString.setAll(0, units);
+ nativeString[units.length] = 0;
+ return result.cast();
+ }
+}
+
+extension Utf8Helpers on Pointer<Utf8> {
+ /// The length of a null-terminated string — the number of (one-byte)
+ /// characters before the first null byte.
+ int get strlen {
+ final Pointer<Uint8> array = this.cast<Uint8>();
+ final Uint8List nativeString = array.asTypedList(_maxSize);
+ return nativeString.indexWhere((char) => char == 0);
+ }
+
+ /// Creates a [String] containing the characters UTF-8 encoded in [this].
+ ///
+ /// [this] must be a zero-terminated byte sequence of valid UTF-8
+ /// encodings of Unicode code points. See [Utf8Decoder] for details on
+ /// decoding.
+ ///
+ /// Returns a Dart string containing the decoded code points.
+ String contents() {
+ final int length = strlen;
+ return utf8.decode(Uint8List.view(
+ this.cast<Uint8>().asTypedList(length).buffer, 0, length));
+ }
+}
+
+const int _kMaxSmi64 = (1 << 62) - 1;
+const int _kMaxSmi32 = (1 << 30) - 1;
+final int _maxSize = sizeOf<IntPtr>() == 8 ? _kMaxSmi64 : _kMaxSmi32;
diff --git a/samples/ffi/sample_ffi_bitfield.dart b/samples/ffi/sample_ffi_bitfield.dart
index cc10a2d..67ce69e 100644
--- a/samples/ffi/sample_ffi_bitfield.dart
+++ b/samples/ffi/sample_ffi_bitfield.dart
@@ -7,6 +7,8 @@
import 'package:ffi/ffi.dart';
import 'package:expect/expect.dart';
+import 'calloc.dart';
+
/// typedef struct {
/// unsigned int bold : 1;
/// unsigned int underline : 2;
@@ -93,7 +95,7 @@
}
main() {
- final p = allocate<ScreenCellAttrs>(count: 3);
+ final p = calloc<ScreenCellAttrs>(3);
// Zeroes out all fields.
p.ref.bits = 0;
@@ -119,5 +121,5 @@
// A check for automated testing.
Expect.equals(1933, p.ref.bits);
- free(p);
+ calloc.free(p);
}
diff --git a/samples/ffi/sample_ffi_data.dart b/samples/ffi/sample_ffi_data.dart
index 8e713d0..e5b0497 100644
--- a/samples/ffi/sample_ffi_data.dart
+++ b/samples/ffi/sample_ffi_data.dart
@@ -5,29 +5,31 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
+
main() {
print('start main');
{
// Basic operation: allocate, get, set, and free.
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 42;
int pValue = p.value;
print('${p.runtimeType} value: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
// Undefined behavior before set.
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
int pValue = p.value;
print('If not set, returns garbage: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
// Pointers can be created from an address.
- Pointer<Int64> pHelper = allocate();
+ Pointer<Int64> pHelper = calloc();
pHelper.value = 1337;
int address = pHelper.address;
@@ -36,13 +38,13 @@
Pointer<Int64> p = Pointer.fromAddress(address);
print('${p.runtimeType} value: ${p.value}');
- free(pHelper);
+ calloc.free(pHelper);
}
{
// Address is zeroed out after free.
- Pointer<Int64> p = allocate();
- free(p);
+ Pointer<Int64> p = calloc();
+ calloc.free(p);
print('After free, address is zero: ${p.address}');
}
@@ -50,13 +52,13 @@
// Allocating too much throws an exception.
try {
int maxMint = 9223372036854775807; // 2^63 - 1
- allocate<Int64>(count: maxMint);
+ calloc<Int64>(maxMint);
} on Error {
print('Expected exception on allocating too much');
}
try {
int maxInt1_8 = 1152921504606846975; // 2^60 -1
- allocate<Int64>(count: maxInt1_8);
+ calloc<Int64>(maxInt1_8);
} on Error {
print('Expected exception on allocating too much');
}
@@ -65,7 +67,7 @@
{
// Pointers can be cast into another type,
// resulting in the corresponding bits read.
- Pointer<Int64> p1 = allocate();
+ Pointer<Int64> p1 = calloc();
p1.value = 9223372036854775807; // 2^63 - 1
Pointer<Int32> p2 = p1.cast();
@@ -74,61 +76,61 @@
Pointer<Int32> p3 = p2.elementAt(1);
print('${p3.runtimeType} value: ${p3.value}'); // 2^31 - 1
- free(p1);
+ calloc.free(p1);
}
{
// Data can be tightly packed in memory.
- Pointer<Int8> p = allocate(count: 8);
+ Pointer<Int8> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p.elementAt(i).value = i * 3;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
print('p.elementAt($i) value: ${p.elementAt(i).value}');
}
- free(p);
+ calloc.free(p);
}
{
// Values that don't fit are truncated.
- Pointer<Int32> p11 = allocate();
+ Pointer<Int32> p11 = calloc();
p11.value = 9223372036854775807;
print(p11);
- free(p11);
+ calloc.free(p11);
}
{
// Doubles.
- Pointer<Double> p = allocate();
+ Pointer<Double> p = calloc();
p.value = 3.14159265359;
print('${p.runtimeType} value: ${p.value}');
p.value = 3.14;
print('${p.runtimeType} value: ${p.value}');
- free(p);
+ calloc.free(p);
}
{
// Floats.
- Pointer<Float> p = allocate();
+ Pointer<Float> p = calloc();
p.value = 3.14159265359;
print('${p.runtimeType} value: ${p.value}');
p.value = 3.14;
print('${p.runtimeType} value: ${p.value}');
- free(p);
+ calloc.free(p);
}
{
// IntPtr varies in size based on whether the platform is 32 or 64 bit.
// Addresses of pointers fit in this size.
- Pointer<IntPtr> p = allocate();
+ Pointer<IntPtr> p = calloc();
int p14addr = p.address;
p.value = p14addr;
int pValue = p.value;
print('${p.runtimeType} value: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
@@ -136,19 +138,19 @@
// The size of the element it is pointing to is undefined,
// they cannot be allocated, read, or written.
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
print('${p2.runtimeType} address: ${p2.address}');
- free(p1);
+ calloc.free(p1);
}
{
// Pointer to a pointer to something.
- Pointer<Int16> pHelper = allocate();
+ Pointer<Int16> pHelper = calloc();
pHelper.value = 17;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// Storing into a pointer pointer automatically unboxes.
p.value = pHelper;
@@ -160,31 +162,31 @@
int pValue = p.value.value;
print('${p.runtimeType} value\'s value: ${pValue}');
- free(p);
- free(pHelper);
+ calloc.free(p);
+ calloc.free(pHelper);
}
{
// The pointer to pointer types must match up.
- Pointer<Int8> pHelper = allocate();
+ Pointer<Int8> pHelper = calloc();
pHelper.value = 123;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// Trying to store `pHelper` into `p.val` would result in a type mismatch.
- free(pHelper);
- free(p);
+ calloc.free(pHelper);
+ calloc.free(p);
}
{
// `nullptr` points to address 0 in c++.
- Pointer<Pointer<Int8>> pointerToPointer = allocate();
+ Pointer<Pointer<Int8>> pointerToPointer = calloc();
Pointer<Int8> value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
print("Loading a pointer to the 0 address is null: ${value}");
- free(pointerToPointer);
+ calloc.free(pointerToPointer);
}
{
@@ -205,7 +207,7 @@
head.value = value;
return;
}
- Pointer<IntPtr> next = allocate<IntPtr>();
+ Pointer<IntPtr> next = calloc<IntPtr>();
head.value = next.address;
createChain(next, length - 1, value);
}
@@ -220,7 +222,7 @@
void freeChain(Pointer<IntPtr> head, int length) {
Pointer<IntPtr> next = Pointer.fromAddress(head.value);
- free(head);
+ calloc.free(head);
if (length == 0) {
return;
}
@@ -228,7 +230,7 @@
}
int length = 10;
- Pointer<IntPtr> head = allocate();
+ Pointer<IntPtr> head = calloc();
createChain(head, length, 512);
int tailValue = getChainValue(head, length);
print('tailValue: ${tailValue}');
diff --git a/samples/ffi/sample_ffi_functions.dart b/samples/ffi/sample_ffi_functions.dart
index bff74eb..5038ba8 100644
--- a/samples/ffi/sample_ffi_functions.dart
+++ b/samples/ffi/sample_ffi_functions.dart
@@ -6,6 +6,7 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'dylib_utils.dart';
typedef NativeUnaryOp = Int32 Function(Int32);
@@ -184,7 +185,7 @@
// pass an array / pointer as argument
Int64PointerUnOp assign1337Index1 = ffiTestFunctions
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
p2.value = 42;
p2[1] = 1000;
print(p2.elementAt(1).address.toRadixString(16));
@@ -209,11 +210,11 @@
print(result);
print(result.runtimeType);
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
result = nullableInt64ElemAt1(p2);
print(result);
print(result.runtimeType);
- free(p2);
+ calloc.free(p2);
}
print("end main");
diff --git a/samples/ffi/sample_ffi_functions_callbacks.dart b/samples/ffi/sample_ffi_functions_callbacks.dart
index affdcef..de6d05a 100644
--- a/samples/ffi/sample_ffi_functions_callbacks.dart
+++ b/samples/ffi/sample_ffi_functions_callbacks.dart
@@ -4,6 +4,9 @@
import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+import 'calloc.dart';
import 'coordinate.dart';
import 'dylib_utils.dart';
@@ -43,7 +46,7 @@
Pointer<NativeFunction<CoordinateTrice>> p2 =
ffiTestFunctions.lookup("CoordinateUnOpTrice");
CoordinateTrice coordinateUnOpTrice = p2.asFunction();
- Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 20.0, nullptr);
c1.next = c1.addressOf;
Coordinate result =
coordinateUnOpTrice(transposeCoordinatePointer, c1.addressOf).ref;
diff --git a/samples/ffi/sample_ffi_functions_structs.dart b/samples/ffi/sample_ffi_functions_structs.dart
index 9aefb57..9185040 100644
--- a/samples/ffi/sample_ffi_functions_structs.dart
+++ b/samples/ffi/sample_ffi_functions_structs.dart
@@ -4,11 +4,12 @@
import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+import 'calloc.dart';
import 'coordinate.dart';
import 'dylib_utils.dart';
-import 'package:ffi/ffi.dart';
-
typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
main() {
@@ -23,8 +24,8 @@
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
- Coordinate c2 = Coordinate.allocate(42.0, 84.0, c1.addressOf);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 20.0, nullptr);
+ Coordinate c2 = Coordinate.allocate(calloc, 42.0, 84.0, c1.addressOf);
c1.next = c2.addressOf;
Coordinate result = f1(c1.addressOf).ref;
@@ -44,7 +45,7 @@
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
- Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+ Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
diff --git a/samples/ffi/sample_ffi_structs.dart b/samples/ffi/sample_ffi_structs.dart
index bd6d7c7..f6de82c 100644
--- a/samples/ffi/sample_ffi_structs.dart
+++ b/samples/ffi/sample_ffi_structs.dart
@@ -6,6 +6,7 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'coordinate.dart';
main() {
@@ -13,9 +14,9 @@
{
// Allocates each coordinate separately in c memory.
- Coordinate c1 = Coordinate.allocate(10.0, 10.0, nullptr);
- Coordinate c2 = Coordinate.allocate(20.0, 20.0, c1.addressOf);
- Coordinate c3 = Coordinate.allocate(30.0, 30.0, c2.addressOf);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 10.0, nullptr);
+ Coordinate c2 = Coordinate.allocate(calloc, 20.0, 20.0, c1.addressOf);
+ Coordinate c3 = Coordinate.allocate(calloc, 30.0, 30.0, c2.addressOf);
c1.next = c3.addressOf;
Coordinate currentCoordinate = c1;
@@ -24,14 +25,14 @@
print("${currentCoordinate.x}; ${currentCoordinate.y}");
}
- free(c1.addressOf);
- free(c2.addressOf);
- free(c3.addressOf);
+ calloc.free(c1.addressOf);
+ calloc.free(c2.addressOf);
+ calloc.free(c3.addressOf);
}
{
// Allocates coordinates consecutively in c memory.
- Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+ Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
@@ -50,15 +51,15 @@
print("${currentCoordinate.x}; ${currentCoordinate.y}");
}
- free(c1);
+ calloc.free(c1);
}
{
- Coordinate c = Coordinate.allocate(10, 10, nullptr);
+ Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
print(c is Coordinate);
print(c is Pointer<Void>);
print(c is Pointer);
- free(c.addressOf);
+ calloc.free(c.addressOf);
}
print("end main");
diff --git a/samples/ffi/sqlite/lib/sqlite.dart b/samples/ffi/sqlite/lib/sqlite.dart
index d6bac5b..1e60f9f 100644
--- a/samples/ffi/sqlite/lib/sqlite.dart
+++ b/samples/ffi/sqlite/lib/sqlite.dart
@@ -8,3 +8,5 @@
library sqlite;
export "src/database.dart";
+
+export "src/ffi/calloc.dart" show calloc;
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
index 494cdef..40edc87 100644
--- a/samples/ffi/sqlite/lib/src/bindings/types.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/types.dart
@@ -13,7 +13,7 @@
/// is its destructor. There are many other interfaces (such as
/// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
/// [sqlite3_busy_timeout()] to name but three) that are methods on an
-class Database extends Struct {}
+class Database extends Opaque {}
/// SQL Statement Object
///
@@ -36,7 +36,7 @@
///
/// Refer to documentation on individual methods above for additional
/// information.
-class Statement extends Struct {}
+class Statement extends Opaque {}
/// Dynamically Typed Value Object
///
@@ -72,4 +72,4 @@
/// [sqlite3_result_value()] and [sqlite3_bind_value()].
/// The [sqlite3_value_blob | sqlite3_value_type()] family of
/// interfaces require protected sqlite3_value objects.
-class Value extends Struct {}
+class Value extends Opaque {}
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index 7725609..59da929 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -15,6 +15,8 @@
import "bindings/constants.dart";
import "collections/closable_iterator.dart";
+import 'ffi/calloc.dart';
+
/// [Database] represents an open connection to a SQLite database.
///
/// All functions against a database may throw [SQLiteError].
@@ -27,13 +29,13 @@
/// Open a database located at the file [path].
Database(String path,
[int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
- Pointer<Pointer<types.Database>> dbOut = allocate();
+ Pointer<Pointer<types.Database>> dbOut = calloc();
final pathC = Utf8.toUtf8(path);
final int resultCode =
bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
_database = dbOut.value;
- free(dbOut);
- free(pathC);
+ calloc.free(dbOut);
+ calloc.free(pathC);
if (resultCode == Errors.SQLITE_OK) {
_open = true;
@@ -63,13 +65,13 @@
/// Execute a query, discarding any returned rows.
void execute(String query) {
- Pointer<Pointer<Statement>> statementOut = allocate();
+ Pointer<Pointer<Statement>> statementOut = calloc();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
- free(statementOut);
- free(queryC);
+ calloc.free(statementOut);
+ calloc.free(queryC);
while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
resultCode = bindings.sqlite3_step(statement);
@@ -82,13 +84,13 @@
/// Evaluate a query and return the resulting rows as an iterable.
Result query(String query) {
- Pointer<Pointer<Statement>> statementOut = allocate();
+ Pointer<Pointer<Statement>> statementOut = calloc();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
- free(statementOut);
- free(queryC);
+ calloc.free(statementOut);
+ calloc.free(queryC);
if (resultCode != Errors.SQLITE_OK) {
bindings.sqlite3_finalize(statement);
diff --git a/samples/ffi/sqlite/lib/src/ffi/arena.dart b/samples/ffi/sqlite/lib/src/ffi/arena.dart
index d01b64f..5369a22 100644
--- a/samples/ffi/sqlite/lib/src/ffi/arena.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/arena.dart
@@ -7,6 +7,8 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
+
/// [Arena] manages allocated C memory.
///
/// Arenas are zoned.
@@ -24,7 +26,7 @@
/// Frees all memory pointed to by [Pointer]s in this arena.
void finalize() {
for (final ptr in _allocations) {
- free(ptr);
+ calloc.free(ptr);
}
}
diff --git a/samples/ffi/sqlite/lib/src/ffi/calloc.dart b/samples/ffi/sqlite/lib/src/ffi/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/ffi/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/samples/ffi/sqlite/test/sqlite_test.dart b/samples/ffi/sqlite/test/sqlite_test.dart
index 130c95f..fedc9e5 100644
--- a/samples/ffi/sqlite/test/sqlite_test.dart
+++ b/samples/ffi/sqlite/test/sqlite_test.dart
@@ -168,6 +168,6 @@
final String test = 'Hasta Mañana';
final medium = Utf8.toUtf8(test);
expect(test, medium.ref.toString());
- free(medium);
+ calloc.free(medium);
});
}
diff --git a/samples_2/ffi/async/sample_async_callback.dart b/samples_2/ffi/async/sample_async_callback.dart
index 5e6d79a..2405a8a 100644
--- a/samples_2/ffi/async/sample_async_callback.dart
+++ b/samples_2/ffi/async/sample_async_callback.dart
@@ -107,7 +107,7 @@
final executeCallback = dl.lookupFunction<Void Function(Pointer<Work>),
void Function(Pointer<Work>)>('ExecuteCallback');
-class Work extends Struct {}
+class Work extends Opaque {}
Future asyncSleep(int ms) {
return new Future.delayed(Duration(milliseconds: ms));
diff --git a/samples_2/ffi/calloc.dart b/samples_2/ffi/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/samples_2/ffi/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/samples_2/ffi/coordinate.dart b/samples_2/ffi/coordinate.dart
index 4ff34f5..4d9d300 100644
--- a/samples_2/ffi/coordinate.dart
+++ b/samples_2/ffi/coordinate.dart
@@ -18,8 +18,9 @@
Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/samples_2/ffi/resource_management/pool.dart b/samples_2/ffi/resource_management/pool.dart
index 776c331..477a78e 100644
--- a/samples_2/ffi/resource_management/pool.dart
+++ b/samples_2/ffi/resource_management/pool.dart
@@ -7,48 +7,36 @@
// @dart = 2.9
import "dart:async";
-import 'dart:convert';
import 'dart:ffi';
-import 'dart:typed_data';
-import 'package:ffi/ffi.dart' as packageFfi;
-import 'package:ffi/ffi.dart' show Utf8;
+import 'package:ffi/ffi.dart';
-/// Manages native resources.
+import '../calloc.dart';
+
+/// Keeps track of all allocated memory and frees all allocated memory on
+/// [releaseAll].
///
-/// Primary implementations are [Pool] and [Unmanaged].
-abstract class ResourceManager {
- /// Allocates memory on the native heap.
- ///
- /// The native memory is under management by this [ResourceManager].
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count: 1});
-}
+/// Wraps an [Allocator] to do the actual allocation and freeing.
+class Pool implements Allocator {
+ /// The [Allocator] used for allocation and freeing.
+ final Allocator _wrappedAllocator;
-/// Manages native resources.
-class Pool implements ResourceManager {
+ Pool(this._wrappedAllocator);
+
/// Native memory under management by this [Pool].
final List<Pointer<NativeType>> _managedMemoryPointers = [];
/// Callbacks for releasing native resources under management by this [Pool].
final List<Function()> _managedResourceReleaseCallbacks = [];
- /// Allocates memory on the native heap.
+ /// Allocates memory on the native heap by using the allocator supplied to
+ /// the constructor.
///
- /// The native memory is under management by this [Pool].
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count: 1}) {
- final p = Unmanaged().allocate<T>(count: count);
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int numBytes, {int alignment}) {
+ final p = _wrappedAllocator.allocate<T>(numBytes, alignment: alignment);
_managedMemoryPointers.add(p);
return p;
}
@@ -73,17 +61,21 @@
}
_managedResourceReleaseCallbacks.clear();
for (final p in _managedMemoryPointers) {
- Unmanaged().free(p);
+ _wrappedAllocator.free(p);
}
_managedMemoryPointers.clear();
}
+
+ @override
+ void free(Pointer<NativeType> pointer) => throw UnsupportedError(
+ "Individually freeing Pool allocated memory is not allowed");
}
/// Creates a [Pool] to manage native resources.
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
-R using<R>(R Function(Pool) f) {
- final p = Pool();
+R using<R>(R Function(Pool) f, [Allocator wrappedAllocator = calloc]) {
+ final p = Pool(wrappedAllocator);
try {
return f(p);
} finally {
@@ -98,8 +90,8 @@
/// Please note that all throws are caught and packaged in [RethrownError].
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
-R usePool<R>(R Function() f) {
- final p = Pool();
+R usePool<R>(R Function() f, [Allocator wrappedAllocator = calloc]) {
+ final p = Pool(wrappedAllocator);
try {
return runZoned(() => f(),
zoneValues: {#_pool: p},
@@ -119,78 +111,3 @@
toString() => """RethrownError(${original})
${originalStackTrace}""";
}
-
-/// Does not manage it's resources.
-class Unmanaged implements ResourceManager {
- /// Allocates memory on the native heap.
- ///
- /// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
- /// against the default public heap. Allocation of either element size or count
- /// of 0 is undefined.
- ///
- /// Throws an ArgumentError on failure to allocate.
- Pointer<T> allocate<T extends NativeType>({int count = 1}) =>
- packageFfi.allocate(count: count);
-
- /// Releases memory on the native heap.
- ///
- /// For POSIX-based systems, this uses free. On Windows, it uses HeapFree
- /// against the default public heap. It may only be used against pointers
- /// allocated in a manner equivalent to [allocate].
- ///
- /// Throws an ArgumentError on failure to free.
- ///
- void free(Pointer pointer) => packageFfi.free(pointer);
-}
-
-/// Does not manage it's resources.
-final Unmanaged unmanaged = Unmanaged();
-
-extension Utf8InPool on String {
- /// Convert a [String] to a Utf8-encoded null-terminated C string.
- ///
- /// If 'string' contains NULL bytes, the converted string will be truncated
- /// prematurely. Unpaired surrogate code points in [string] will be preserved
- /// in the UTF-8 encoded result. See [Utf8Encoder] for details on encoding.
- ///
- /// Returns a malloc-allocated pointer to the result.
- ///
- /// The memory is managed by the [Pool] passed in as [pool].
- Pointer<Utf8> toUtf8(ResourceManager pool) {
- final units = utf8.encode(this);
- final Pointer<Uint8> result = pool.allocate<Uint8>(count: units.length + 1);
- final Uint8List nativeString = result.asTypedList(units.length + 1);
- nativeString.setAll(0, units);
- nativeString[units.length] = 0;
- return result.cast();
- }
-}
-
-extension Utf8Helpers on Pointer<Utf8> {
- /// Returns the length of a null-terminated string -- the number of (one-byte)
- /// characters before the first null byte.
- int strlen() {
- final Pointer<Uint8> array = this.cast<Uint8>();
- final Uint8List nativeString = array.asTypedList(_maxSize);
- return nativeString.indexWhere((char) => char == 0);
- }
-
- /// Creates a [String] containing the characters UTF-8 encoded in [this].
- ///
- /// [this] must be a zero-terminated byte sequence of valid UTF-8
- /// encodings of Unicode code points. It may also contain UTF-8 encodings of
- /// unpaired surrogate code points, which is not otherwise valid UTF-8, but
- /// which may be created when encoding a Dart string containing an unpaired
- /// surrogate. See [Utf8Decoder] for details on decoding.
- ///
- /// Returns a Dart string containing the decoded code points.
- String contents() {
- final int length = strlen();
- return utf8.decode(Uint8List.view(
- this.cast<Uint8>().asTypedList(length).buffer, 0, length));
- }
-}
-
-const int _kMaxSmi64 = (1 << 62) - 1;
-const int _kMaxSmi32 = (1 << 30) - 1;
-final int _maxSize = sizeOf<IntPtr>() == 8 ? _kMaxSmi64 : _kMaxSmi32;
diff --git a/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart b/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart
index 8d3401b..4c8eb0f 100644
--- a/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart
+++ b/samples_2/ffi/resource_management/pool_isolate_shutdown_sample.dart
@@ -88,4 +88,4 @@
void Function(Pointer<SomeResource>)>("ReleaseResource");
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples_2/ffi/resource_management/pool_sample.dart b/samples_2/ffi/resource_management/pool_sample.dart
index 87c5e39..c794a40 100644
--- a/samples_2/ffi/resource_management/pool_sample.dart
+++ b/samples_2/ffi/resource_management/pool_sample.dart
@@ -11,6 +11,7 @@
import 'package:expect/expect.dart';
import 'pool.dart';
+import 'utf8_helpers.dart';
import '../dylib_utils.dart';
main() {
@@ -23,7 +24,7 @@
// To ensure resources are freed, wrap them in a [using] call.
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
p[0] = 24;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
@@ -33,14 +34,14 @@
// Resources are freed also when abnormal control flow occurs.
try {
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
p[0] = 25;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
Expect.equals(25, p[1]);
throw Exception("Some random exception");
});
- // `free(p)` has been called.
+ // `calloc.free(p)` has been called.
} on Exception catch (e) {
print("Caught exception: $e");
}
@@ -48,8 +49,8 @@
// In a pool multiple resources can be allocated, which will all be freed
// at the end of the scope.
using((Pool pool) {
- final p = pool.allocate<Int64>(count: 2);
- final p2 = pool.allocate<Int64>(count: 2);
+ final p = pool<Int64>(2);
+ final p2 = pool<Int64>(2);
p[0] = 1;
p[1] = 2;
MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
@@ -60,7 +61,7 @@
// If the resource allocation happens in a different scope, then one either
// needs to pass the pool to that scope.
f1(Pool pool) {
- return pool.allocate<Int64>(count: 2);
+ return pool<Int64>(2);
}
using((Pool pool) {
@@ -112,4 +113,4 @@
}
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples_2/ffi/resource_management/pool_zoned_sample.dart b/samples_2/ffi/resource_management/pool_zoned_sample.dart
index 0b4e8ff..a1dc9c1 100644
--- a/samples_2/ffi/resource_management/pool_zoned_sample.dart
+++ b/samples_2/ffi/resource_management/pool_zoned_sample.dart
@@ -11,6 +11,7 @@
import 'package:expect/expect.dart';
import 'pool.dart';
+import 'utf8_helpers.dart';
import '../dylib_utils.dart';
main() {
@@ -23,7 +24,7 @@
// To ensure resources are freed, wrap them in a [using] call.
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
p[0] = 24;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
@@ -33,7 +34,7 @@
// Resources are freed also when abnormal control flow occurs.
try {
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
p[0] = 25;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
@@ -48,8 +49,8 @@
// In a pool multiple resources can be allocated, which will all be freed
// at the end of the scope.
usePool(() {
- final p = currentPool.allocate<Int64>(count: 2);
- final p2 = currentPool.allocate<Int64>(count: 2);
+ final p = currentPool<Int64>(2);
+ final p2 = currentPool<Int64>(2);
p[0] = 1;
p[1] = 2;
MemMove(p2.cast<Void>(), p.cast<Void>(), 2 * sizeOf<Int64>());
@@ -60,7 +61,7 @@
// If the resource allocation happens in a different scope, it is in the
// same zone, so it's lifetime is automatically managed by the pool.
f1() {
- return currentPool.allocate<Int64>(count: 2);
+ return currentPool<Int64>(2);
}
usePool(() {
@@ -113,4 +114,4 @@
}
/// Represents some opaque resource being managed by a library.
-class SomeResource extends Struct {}
+class SomeResource extends Opaque {}
diff --git a/samples_2/ffi/resource_management/unmanaged_sample.dart b/samples_2/ffi/resource_management/unmanaged_sample.dart
index b8c9971..e73f7cc 100644
--- a/samples_2/ffi/resource_management/unmanaged_sample.dart
+++ b/samples_2/ffi/resource_management/unmanaged_sample.dart
@@ -9,8 +9,10 @@
import 'dart:ffi';
import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
-import 'pool.dart';
+import 'utf8_helpers.dart';
+import '../calloc.dart';
import '../dylib_utils.dart';
main() {
@@ -24,15 +26,15 @@
// To ensure resources are freed, call free manually.
//
// For automatic management use a Pool.
- final p = unmanaged.allocate<Int64>(count: 2);
+ final p = calloc<Int64>(2);
p[0] = 24;
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), sizeOf<Int64>());
print(p[1]);
Expect.equals(24, p[1]);
- unmanaged.free(p);
+ calloc.free(p);
// Using Strings.
- final p2 = "Hello world!".toUtf8(unmanaged);
+ final p2 = "Hello world!".toUtf8(calloc);
print(p2.contents());
- unmanaged.free(p2);
+ calloc.free(p2);
}
diff --git a/samples_2/ffi/resource_management/utf8_helpers.dart b/samples_2/ffi/resource_management/utf8_helpers.dart
new file mode 100644
index 0000000..e1d555b
--- /dev/null
+++ b/samples_2/ffi/resource_management/utf8_helpers.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2021, 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.
+//
+// Explicit pool used for managing resources.
+
+// @dart = 2.9
+
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:typed_data';
+
+import 'package:ffi/ffi.dart';
+
+extension Utf8InPool on String {
+ /// Convert a [String] to a Utf8-encoded null-terminated C string.
+ ///
+ /// If 'string' contains NULL bytes, the converted string will be truncated
+ /// prematurely. See [Utf8Encoder] for details on encoding.
+ ///
+ /// Returns a [allocator]-allocated pointer to the result.
+ Pointer<Utf8> toUtf8(Allocator allocator) {
+ final units = utf8.encode(this);
+ final Pointer<Uint8> result = allocator<Uint8>(units.length + 1);
+ final Uint8List nativeString = result.asTypedList(units.length + 1);
+ nativeString.setAll(0, units);
+ nativeString[units.length] = 0;
+ return result.cast();
+ }
+}
+
+extension Utf8Helpers on Pointer<Utf8> {
+ /// The length of a null-terminated string — the number of (one-byte)
+ /// characters before the first null byte.
+ int get strlen {
+ final Pointer<Uint8> array = this.cast<Uint8>();
+ final Uint8List nativeString = array.asTypedList(_maxSize);
+ return nativeString.indexWhere((char) => char == 0);
+ }
+
+ /// Creates a [String] containing the characters UTF-8 encoded in [this].
+ ///
+ /// [this] must be a zero-terminated byte sequence of valid UTF-8
+ /// encodings of Unicode code points.See [Utf8Decoder] for details on
+ /// decoding.
+ ///
+ /// Returns a Dart string containing the decoded code points.
+ String contents() {
+ final int length = strlen;
+ return utf8.decode(Uint8List.view(
+ this.cast<Uint8>().asTypedList(length).buffer, 0, length));
+ }
+}
+
+const int _kMaxSmi64 = (1 << 62) - 1;
+const int _kMaxSmi32 = (1 << 30) - 1;
+final int _maxSize = sizeOf<IntPtr>() == 8 ? _kMaxSmi64 : _kMaxSmi32;
diff --git a/samples_2/ffi/sample_ffi_bitfield.dart b/samples_2/ffi/sample_ffi_bitfield.dart
index 91bb65d..78c41df 100644
--- a/samples_2/ffi/sample_ffi_bitfield.dart
+++ b/samples_2/ffi/sample_ffi_bitfield.dart
@@ -9,6 +9,8 @@
import 'package:ffi/ffi.dart';
import 'package:expect/expect.dart';
+import 'calloc.dart';
+
/// typedef struct {
/// unsigned int bold : 1;
/// unsigned int underline : 2;
@@ -95,7 +97,7 @@
}
main() {
- final p = allocate<ScreenCellAttrs>(count: 3);
+ final p = calloc<ScreenCellAttrs>(3);
// Zeroes out all fields.
p.ref.bits = 0;
@@ -121,5 +123,5 @@
// A check for automated testing.
Expect.equals(1933, p.ref.bits);
- free(p);
+ calloc.free(p);
}
diff --git a/samples_2/ffi/sample_ffi_data.dart b/samples_2/ffi/sample_ffi_data.dart
index 09dba76..2d22011 100644
--- a/samples_2/ffi/sample_ffi_data.dart
+++ b/samples_2/ffi/sample_ffi_data.dart
@@ -7,29 +7,31 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
+
main() {
print('start main');
{
// Basic operation: allocate, get, set, and free.
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 42;
int pValue = p.value;
print('${p.runtimeType} value: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
// Undefined behavior before set.
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
int pValue = p.value;
print('If not set, returns garbage: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
// Pointers can be created from an address.
- Pointer<Int64> pHelper = allocate();
+ Pointer<Int64> pHelper = calloc();
pHelper.value = 1337;
int address = pHelper.address;
@@ -38,13 +40,13 @@
Pointer<Int64> p = Pointer.fromAddress(address);
print('${p.runtimeType} value: ${p.value}');
- free(pHelper);
+ calloc.free(pHelper);
}
{
// Address is zeroed out after free.
- Pointer<Int64> p = allocate();
- free(p);
+ Pointer<Int64> p = calloc();
+ calloc.free(p);
print('After free, address is zero: ${p.address}');
}
@@ -52,13 +54,13 @@
// Allocating too much throws an exception.
try {
int maxMint = 9223372036854775807; // 2^63 - 1
- allocate<Int64>(count: maxMint);
+ calloc<Int64>(maxMint);
} on Error {
print('Expected exception on allocating too much');
}
try {
int maxInt1_8 = 1152921504606846975; // 2^60 -1
- allocate<Int64>(count: maxInt1_8);
+ calloc<Int64>(maxInt1_8);
} on Error {
print('Expected exception on allocating too much');
}
@@ -67,7 +69,7 @@
{
// Pointers can be cast into another type,
// resulting in the corresponding bits read.
- Pointer<Int64> p1 = allocate();
+ Pointer<Int64> p1 = calloc();
p1.value = 9223372036854775807; // 2^63 - 1
Pointer<Int32> p2 = p1.cast();
@@ -76,61 +78,61 @@
Pointer<Int32> p3 = p2.elementAt(1);
print('${p3.runtimeType} value: ${p3.value}'); // 2^31 - 1
- free(p1);
+ calloc.free(p1);
}
{
// Data can be tightly packed in memory.
- Pointer<Int8> p = allocate(count: 8);
+ Pointer<Int8> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p.elementAt(i).value = i * 3;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
print('p.elementAt($i) value: ${p.elementAt(i).value}');
}
- free(p);
+ calloc.free(p);
}
{
// Values that don't fit are truncated.
- Pointer<Int32> p11 = allocate();
+ Pointer<Int32> p11 = calloc();
p11.value = 9223372036854775807;
print(p11);
- free(p11);
+ calloc.free(p11);
}
{
// Doubles.
- Pointer<Double> p = allocate();
+ Pointer<Double> p = calloc();
p.value = 3.14159265359;
print('${p.runtimeType} value: ${p.value}');
p.value = 3.14;
print('${p.runtimeType} value: ${p.value}');
- free(p);
+ calloc.free(p);
}
{
// Floats.
- Pointer<Float> p = allocate();
+ Pointer<Float> p = calloc();
p.value = 3.14159265359;
print('${p.runtimeType} value: ${p.value}');
p.value = 3.14;
print('${p.runtimeType} value: ${p.value}');
- free(p);
+ calloc.free(p);
}
{
// IntPtr varies in size based on whether the platform is 32 or 64 bit.
// Addresses of pointers fit in this size.
- Pointer<IntPtr> p = allocate();
+ Pointer<IntPtr> p = calloc();
int p14addr = p.address;
p.value = p14addr;
int pValue = p.value;
print('${p.runtimeType} value: ${pValue}');
- free(p);
+ calloc.free(p);
}
{
@@ -138,19 +140,19 @@
// The size of the element it is pointing to is undefined,
// they cannot be allocated, read, or written.
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
print('${p2.runtimeType} address: ${p2.address}');
- free(p1);
+ calloc.free(p1);
}
{
// Pointer to a pointer to something.
- Pointer<Int16> pHelper = allocate();
+ Pointer<Int16> pHelper = calloc();
pHelper.value = 17;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// Storing into a pointer pointer automatically unboxes.
p.value = pHelper;
@@ -162,31 +164,31 @@
int pValue = p.value.value;
print('${p.runtimeType} value\'s value: ${pValue}');
- free(p);
- free(pHelper);
+ calloc.free(p);
+ calloc.free(pHelper);
}
{
// The pointer to pointer types must match up.
- Pointer<Int8> pHelper = allocate();
+ Pointer<Int8> pHelper = calloc();
pHelper.value = 123;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// Trying to store `pHelper` into `p.val` would result in a type mismatch.
- free(pHelper);
- free(p);
+ calloc.free(pHelper);
+ calloc.free(p);
}
{
// `nullptr` points to address 0 in c++.
- Pointer<Pointer<Int8>> pointerToPointer = allocate();
+ Pointer<Pointer<Int8>> pointerToPointer = calloc();
Pointer<Int8> value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
print("Loading a pointer to the 0 address is null: ${value}");
- free(pointerToPointer);
+ calloc.free(pointerToPointer);
}
{
@@ -207,7 +209,7 @@
head.value = value;
return;
}
- Pointer<IntPtr> next = allocate<IntPtr>();
+ Pointer<IntPtr> next = calloc<IntPtr>();
head.value = next.address;
createChain(next, length - 1, value);
}
@@ -222,7 +224,7 @@
void freeChain(Pointer<IntPtr> head, int length) {
Pointer<IntPtr> next = Pointer.fromAddress(head.value);
- free(head);
+ calloc.free(head);
if (length == 0) {
return;
}
@@ -230,7 +232,7 @@
}
int length = 10;
- Pointer<IntPtr> head = allocate();
+ Pointer<IntPtr> head = calloc();
createChain(head, length, 512);
int tailValue = getChainValue(head, length);
print('tailValue: ${tailValue}');
diff --git a/samples_2/ffi/sample_ffi_functions.dart b/samples_2/ffi/sample_ffi_functions.dart
index 4cd30b0..1bf8ecc 100644
--- a/samples_2/ffi/sample_ffi_functions.dart
+++ b/samples_2/ffi/sample_ffi_functions.dart
@@ -8,6 +8,7 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'dylib_utils.dart';
typedef NativeUnaryOp = Int32 Function(Int32);
@@ -186,7 +187,7 @@
// pass an array / pointer as argument
Int64PointerUnOp assign1337Index1 = ffiTestFunctions
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
p2.value = 42;
p2[1] = 1000;
print(p2.elementAt(1).address.toRadixString(16));
@@ -251,11 +252,11 @@
print(result);
print(result.runtimeType);
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
result = nullableInt64ElemAt1(p2);
print(result);
print(result.runtimeType);
- free(p2);
+ calloc.free(p2);
}
print("end main");
diff --git a/samples_2/ffi/sample_ffi_functions_callbacks.dart b/samples_2/ffi/sample_ffi_functions_callbacks.dart
index 79f9a41..1d9dc12 100644
--- a/samples_2/ffi/sample_ffi_functions_callbacks.dart
+++ b/samples_2/ffi/sample_ffi_functions_callbacks.dart
@@ -6,6 +6,9 @@
import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+import 'calloc.dart';
import 'coordinate.dart';
import 'dylib_utils.dart';
@@ -45,7 +48,7 @@
Pointer<NativeFunction<CoordinateTrice>> p2 =
ffiTestFunctions.lookup("CoordinateUnOpTrice");
CoordinateTrice coordinateUnOpTrice = p2.asFunction();
- Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 20.0, nullptr);
c1.next = c1.addressOf;
Coordinate result =
coordinateUnOpTrice(transposeCoordinatePointer, c1.addressOf).ref;
diff --git a/samples_2/ffi/sample_ffi_functions_structs.dart b/samples_2/ffi/sample_ffi_functions_structs.dart
index 7129658..41b608d 100644
--- a/samples_2/ffi/sample_ffi_functions_structs.dart
+++ b/samples_2/ffi/sample_ffi_functions_structs.dart
@@ -6,11 +6,12 @@
import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+import 'calloc.dart';
import 'coordinate.dart';
import 'dylib_utils.dart';
-import 'package:ffi/ffi.dart';
-
typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
main() {
@@ -25,8 +26,8 @@
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = Coordinate.allocate(10.0, 20.0, nullptr);
- Coordinate c2 = Coordinate.allocate(42.0, 84.0, c1.addressOf);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 20.0, nullptr);
+ Coordinate c2 = Coordinate.allocate(calloc, 42.0, 84.0, c1.addressOf);
c1.next = c2.addressOf;
Coordinate result = f1(c1.addressOf).ref;
@@ -46,7 +47,7 @@
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
- Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+ Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
diff --git a/samples_2/ffi/sample_ffi_structs.dart b/samples_2/ffi/sample_ffi_structs.dart
index d5af59e..94b19cc 100644
--- a/samples_2/ffi/sample_ffi_structs.dart
+++ b/samples_2/ffi/sample_ffi_structs.dart
@@ -8,6 +8,7 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
import 'coordinate.dart';
main() {
@@ -15,9 +16,9 @@
{
// Allocates each coordinate separately in c memory.
- Coordinate c1 = Coordinate.allocate(10.0, 10.0, nullptr);
- Coordinate c2 = Coordinate.allocate(20.0, 20.0, c1.addressOf);
- Coordinate c3 = Coordinate.allocate(30.0, 30.0, c2.addressOf);
+ Coordinate c1 = Coordinate.allocate(calloc, 10.0, 10.0, nullptr);
+ Coordinate c2 = Coordinate.allocate(calloc, 20.0, 20.0, c1.addressOf);
+ Coordinate c3 = Coordinate.allocate(calloc, 30.0, 30.0, c2.addressOf);
c1.next = c3.addressOf;
Coordinate currentCoordinate = c1;
@@ -26,14 +27,14 @@
print("${currentCoordinate.x}; ${currentCoordinate.y}");
}
- free(c1.addressOf);
- free(c2.addressOf);
- free(c3.addressOf);
+ calloc.free(c1.addressOf);
+ calloc.free(c2.addressOf);
+ calloc.free(c3.addressOf);
}
{
// Allocates coordinates consecutively in c memory.
- Pointer<Coordinate> c1 = allocate<Coordinate>(count: 3);
+ Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
@@ -52,15 +53,15 @@
print("${currentCoordinate.x}; ${currentCoordinate.y}");
}
- free(c1);
+ calloc.free(c1);
}
{
- Coordinate c = Coordinate.allocate(10, 10, nullptr);
+ Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
print(c is Coordinate);
print(c is Pointer<Void>);
print(c is Pointer);
- free(c.addressOf);
+ calloc.free(c.addressOf);
}
print("end main");
diff --git a/samples_2/ffi/sqlite/lib/sqlite.dart b/samples_2/ffi/sqlite/lib/sqlite.dart
index 825e434..0e0669b 100644
--- a/samples_2/ffi/sqlite/lib/sqlite.dart
+++ b/samples_2/ffi/sqlite/lib/sqlite.dart
@@ -10,3 +10,5 @@
library sqlite;
export "src/database.dart";
+
+export "src/ffi/calloc.dart" show calloc;
diff --git a/samples_2/ffi/sqlite/lib/src/bindings/types.dart b/samples_2/ffi/sqlite/lib/src/bindings/types.dart
index f6a1736..763f47e 100644
--- a/samples_2/ffi/sqlite/lib/src/bindings/types.dart
+++ b/samples_2/ffi/sqlite/lib/src/bindings/types.dart
@@ -15,7 +15,7 @@
/// is its destructor. There are many other interfaces (such as
/// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
/// [sqlite3_busy_timeout()] to name but three) that are methods on an
-class Database extends Struct {}
+class Database extends Opaque {}
/// SQL Statement Object
///
@@ -38,7 +38,7 @@
///
/// Refer to documentation on individual methods above for additional
/// information.
-class Statement extends Struct {}
+class Statement extends Opaque {}
/// Dynamically Typed Value Object
///
@@ -74,4 +74,4 @@
/// [sqlite3_result_value()] and [sqlite3_bind_value()].
/// The [sqlite3_value_blob | sqlite3_value_type()] family of
/// interfaces require protected sqlite3_value objects.
-class Value extends Struct {}
+class Value extends Opaque {}
diff --git a/samples_2/ffi/sqlite/lib/src/database.dart b/samples_2/ffi/sqlite/lib/src/database.dart
index 38121a9..49f229f 100644
--- a/samples_2/ffi/sqlite/lib/src/database.dart
+++ b/samples_2/ffi/sqlite/lib/src/database.dart
@@ -17,6 +17,8 @@
import "bindings/constants.dart";
import "collections/closable_iterator.dart";
+import 'ffi/calloc.dart';
+
/// [Database] represents an open connection to a SQLite database.
///
/// All functions against a database may throw [SQLiteError].
@@ -29,13 +31,13 @@
/// Open a database located at the file [path].
Database(String path,
[int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
- Pointer<Pointer<types.Database>> dbOut = allocate();
+ Pointer<Pointer<types.Database>> dbOut = calloc();
final pathC = Utf8.toUtf8(path);
final int resultCode =
bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
_database = dbOut.value;
- free(dbOut);
- free(pathC);
+ calloc.free(dbOut);
+ calloc.free(pathC);
if (resultCode == Errors.SQLITE_OK) {
_open = true;
@@ -65,13 +67,13 @@
/// Execute a query, discarding any returned rows.
void execute(String query) {
- Pointer<Pointer<Statement>> statementOut = allocate();
+ Pointer<Pointer<Statement>> statementOut = calloc();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
- free(statementOut);
- free(queryC);
+ calloc.free(statementOut);
+ calloc.free(queryC);
while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
resultCode = bindings.sqlite3_step(statement);
@@ -84,13 +86,13 @@
/// Evaluate a query and return the resulting rows as an iterable.
Result query(String query) {
- Pointer<Pointer<Statement>> statementOut = allocate();
+ Pointer<Pointer<Statement>> statementOut = calloc();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
- free(statementOut);
- free(queryC);
+ calloc.free(statementOut);
+ calloc.free(queryC);
if (resultCode != Errors.SQLITE_OK) {
bindings.sqlite3_finalize(statement);
diff --git a/samples_2/ffi/sqlite/lib/src/ffi/arena.dart b/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
index a26e807..39e3035 100644
--- a/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
+++ b/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
@@ -9,6 +9,8 @@
import 'package:ffi/ffi.dart';
+import 'calloc.dart';
+
/// [Arena] manages allocated C memory.
///
/// Arenas are zoned.
@@ -26,7 +28,7 @@
/// Frees all memory pointed to by [Pointer]s in this arena.
void finalize() {
for (final ptr in _allocations) {
- free(ptr);
+ calloc.free(ptr);
}
}
diff --git a/samples_2/ffi/sqlite/lib/src/ffi/calloc.dart b/samples_2/ffi/sqlite/lib/src/ffi/calloc.dart
new file mode 100644
index 0000000..c6be280
--- /dev/null
+++ b/samples_2/ffi/sqlite/lib/src/ffi/calloc.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/samples_2/ffi/sqlite/test/sqlite_test.dart b/samples_2/ffi/sqlite/test/sqlite_test.dart
index f7d3744..f27336bd 100644
--- a/samples_2/ffi/sqlite/test/sqlite_test.dart
+++ b/samples_2/ffi/sqlite/test/sqlite_test.dart
@@ -172,6 +172,6 @@
final String test = 'Hasta Mañana';
final medium = Utf8.toUtf8(test);
expect(test, medium.ref.toString());
- free(medium);
+ calloc.free(medium);
});
}
diff --git a/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart b/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
new file mode 100644
index 0000000..5b794e6
--- /dev/null
+++ b/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, 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;
+import 'dart:typed_data';
+import 'dart:isolate';
+
+extension AllocatorAlloc on Allocator {
+ // TODO(http://dartbug.com/38721): Implement this in the CFE to remove the
+ // invocation of sizeOf<T> to enable tree shaking.
+ // TODO(http://dartbug.com/39964): Add `alignmentOf<T>()` call.
+ @patch
+ Pointer<T> call<T extends NativeType>([int count = 1]) {
+ return this.allocate(sizeOf<T>() * count);
+ }
+}
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index b050a48..ce3d87f 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -5,9 +5,9 @@
/// Classes and utilities that supplement the collection support in dart:core.
///
/// To use this library in your code:
-///
-/// import 'dart:collection';
-///
+/// ```dart
+/// import 'dart:collection';
+/// ```
/// {@category Core}
library dart.collection;
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index 3990cd2..c9c9d8e 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -24,8 +24,6 @@
/// symmetric, transitive, and consistent over time), and that `hashCode`
/// must be the same for objects that are considered equal by `==`.
///
-/// The map allows `null` as a key.
-///
/// Iterating the map's keys, values or entries (through [forEach])
/// may happen in any order.
/// The iteration order only changes when the map is modified.
@@ -56,10 +54,10 @@
/// [K] instance.
///
/// Example:
- ///
- /// new HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
- /// hashCode: (int e) => e % 5)
- ///
+ /// ```dart
+ /// HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+ /// hashCode: (int e) => e % 5)
+ /// ```
/// This example map does not need an `isValidKey` function to be passed.
/// The default function accepts only `int` values, which can safely be
/// passed to both the `equals` and `hashCode` functions.
@@ -90,9 +88,10 @@
/// Creates an unordered identity-based map.
///
/// Effectively a shorthand for:
- ///
- /// new HashMap<K, V>(equals: identical,
- /// hashCode: identityHashCode)
+ /// ```dart
+ /// HashMap<K, V>(equals: identical,
+ /// hashCode: identityHashCode)
+ /// ```
external factory HashMap.identity();
/// Creates a [HashMap] that contains all key/value pairs of [other].
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index 6ebb04e..075627f 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -13,8 +13,6 @@
/// must consistent with equality, so that the same for objects that are
/// considered equal.
///
-/// The set allows `null` as an element.
-///
/// Most simple operations on `HashSet` are done in (potentially amortized)
/// constant time: [add], [contains], [remove], and [length], provided the hash
/// codes of objects are well distributed.
@@ -47,10 +45,10 @@
///
/// If [isValidKey] is omitted, it defaults to testing if the object is an
/// [E] instance. That means that:
- ///
- /// new HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
- /// hashCode: (int e) => e % 5)
- ///
+ /// ```dart
+ /// HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
+ /// hashCode: (int e) => e % 5)
+ /// ```
/// does not need an `isValidKey` argument, because it defaults to only
/// accepting `int` values which are accepted by both `equals` and `hashCode`.
///
@@ -71,9 +69,10 @@
/// Creates an unordered identity-based set.
///
/// Effectively a shorthand for:
- ///
- /// new HashSet<E>(equals: identical,
- /// hashCode: identityHashCode)
+ /// ```dart
+ /// HashSet<E>(equals: identical,
+ /// hashCode: identityHashCode)
+ /// ```
external factory HashSet.identity();
/// Create a hash set containing all [elements].
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 9dfdb99..872248e 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -19,8 +19,6 @@
/// must define a stable equivalence relation on the keys (reflexive,
/// symmetric, transitive, and consistent over time), and that `hashCode`
/// must be the same for objects that are considered equal by `==`.
-///
-/// The map allows `null` as a key.
abstract class LinkedHashMap<K, V> implements Map<K, V> {
/// Creates an insertion-ordered hash-table based [Map].
///
@@ -41,10 +39,10 @@
/// [K] instance.
///
/// Example:
- ///
- /// new LinkedHashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
- /// hashCode: (int e) => e % 5)
- ///
+ /// ```dart
+ /// LinkedHashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+ /// hashCode: (int e) => e % 5)
+ /// ```
/// This example map does not need an `isValidKey` function to be passed.
/// The default function accepts only `int` values, which can safely be
/// passed to both the `equals` and `hashCode` functions.
@@ -74,9 +72,10 @@
/// Creates an insertion-ordered identity-based map.
///
/// Effectively a shorthand for:
- ///
- /// new LinkedHashMap<K, V>(equals: identical,
- /// hashCode: identityHashCode)
+ /// ```dart
+ /// LinkedHashMap<K, V>(equals: identical,
+ /// hashCode: identityHashCode)
+ /// ```
external factory LinkedHashMap.identity();
/// Creates a [LinkedHashMap] that contains all key value pairs of [other].
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index c4f6818..a27a89b 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -15,8 +15,6 @@
/// symmetric, transitive, and consistent over time), and that `hashCode`
/// must be the same for objects that are considered equal by `==`.
///
-/// The set allows `null` as an element.
-///
/// Iteration of elements is done in element insertion order.
/// An element that was added after another will occur later in the iteration.
/// Adding an element that is already in the set
@@ -54,10 +52,10 @@
///
/// If [isValidKey] is omitted, it defaults to testing if the object is an
/// [E] instance. That means that:
- ///
- /// new LinkedHashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
- /// hashCode: (int e) => e % 5)
- ///
+ /// ```dart
+ /// LinkedHashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
+ /// hashCode: (int e) => e % 5)
+ /// ```
/// does not need an `isValidKey` argument, because it defaults to only
/// accepting `int` values which are accepted by both `equals` and `hashCode`.
///
@@ -78,9 +76,10 @@
/// Creates an insertion-ordered identity-based set.
///
/// Effectively a shorthand for:
- ///
- /// new LinkedHashSet<E>(equals: identical,
- /// hashCode: identityHashCode)
+ /// ```dart
+ /// LinkedHashSet<E>(equals: identical,
+ /// hashCode: identityHashCode)
+ /// ```
external factory LinkedHashSet.identity();
/// Create a linked hash set containing all [elements].
@@ -91,10 +90,11 @@
/// All the [elements] should be instances of [E].
/// The `elements` iterable itself may have any element type,
/// so this constructor can be used to down-cast a `Set`, for example as:
- ///
- /// Set<SuperType> superSet = ...;
- /// Iterable<SuperType> tmp = superSet.where((e) => e is SubType);
- /// Set<SubType> subSet = new LinkedHashSet<SubType>.from(tmp);
+ /// ```dart
+ /// Set<SuperType> superSet = ...;
+ /// Iterable<SuperType> tmp = superSet.where((e) => e is SubType);
+ /// Set<SubType> subSet = LinkedHashSet<SubType>.from(tmp);
+ /// ```
factory LinkedHashSet.from(Iterable<dynamic> elements) {
LinkedHashSet<E> result = LinkedHashSet<E>();
for (final element in elements) {
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 0445807..3e77646 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -33,16 +33,16 @@
int _length = 0;
E? _first;
- /// Construct a new empty linked list.
+ /// Constructs a new empty linked list.
LinkedList();
- /// Add [entry] to the beginning of the linked list.
+ /// Adds [entry] to the beginning of the linked list.
void addFirst(E entry) {
_insertBefore(_first, entry, updateFirst: true);
_first = entry;
}
- /// Add [entry] to the end of the linked list.
+ /// Adds [entry] to the end of the linked list.
void add(E entry) {
_insertBefore(_first, entry, updateFirst: false);
}
@@ -52,7 +52,7 @@
entries.forEach(add);
}
- /// Remove [entry] from the linked list.
+ /// Removes [entry] from the linked list.
///
/// Returns false and does nothing if [entry] is not in this linked list.
///
@@ -225,9 +225,9 @@
E? _next;
E? _previous;
- /// Get the linked list containing this element.
+ /// The linked list containing this element.
///
- /// Returns `null` if this entry is not currently in any list.
+ /// The value is `null` if this entry is not currently in any list.
LinkedList<E>? get list => _list;
/// Unlink the element from its linked list.
@@ -237,19 +237,19 @@
_list!._unlink(this as E);
}
- /// Return the successor of this element in its linked list.
+ /// The successor of this element in its linked list.
///
- /// Returns `null` if there is no successor in the linked list, or if this
- /// entry is not currently in any list.
+ /// The value is `null` if there is no successor in the linked list,
+ /// or if this entry is not currently in any list.
E? get next {
if (_list == null || identical(_list!.first, _next)) return null;
return _next;
}
- /// Return the predecessor of this element in its linked list.
+ /// The predecessor of this element in its linked list.
///
- /// Returns `null` if there is no predecessor in the linked list, or if this
- /// entry is not currently in any list.
+ /// The value is `null` if there is no predecessor in the linked list,
+ /// or if this entry is not currently in any list.
E? get previous {
if (_list == null || identical(this, _list!.first)) return null;
return _previous;
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index c238840..bb545b9 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -30,7 +30,7 @@
/// ```dart
/// Queue<SuperType> superQueue = ...;
/// Queue<SubType> subQueue =
- /// new Queue<SubType>.from(superQueue.whereType<SubType>());
+ /// Queue<SubType>.from(superQueue.whereType<SubType>());
/// ```
factory Queue.from(Iterable elements) = ListQueue<E>.from;
@@ -286,7 +286,7 @@
/// ```dart
/// Queue<SuperType> superQueue = ...;
/// Queue<SubType> subQueue =
- /// new DoubleLinkedQueue<SubType>.from(superQueue.whereType<SubType>());
+ /// DoubleLinkedQueue<SubType>.from(superQueue.whereType<SubType>());
/// ```
factory DoubleLinkedQueue.from(Iterable<dynamic> elements) {
DoubleLinkedQueue<E> list = DoubleLinkedQueue<E>();
@@ -565,7 +565,7 @@
/// ```dart
/// Queue<SuperType> superQueue = ...;
/// Queue<SubType> subQueue =
- /// new ListQueue<SubType>.from(superQueue.whereType<SubType>());
+ /// ListQueue<SubType>.from(superQueue.whereType<SubType>());
/// ```
factory ListQueue.from(Iterable<dynamic> elements) {
if (elements is List<dynamic>) {
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index a019b64..2ad35f6 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -474,20 +474,25 @@
Iterable<V> get values => _SplayTreeValueIterable<K, V>(this);
- /// Get the first key in the map. Returns `null` if the map is empty.
+ /// The first key in the map.
+ ///
+ /// Returns `null` if the map is empty.
K? firstKey() {
if (_root == null) return null;
return _first!.key;
}
- /// Get the last key in the map. Returns `null` if the map is empty.
+ /// The last key in the map.
+ ///
+ /// Returns `null` if the map is empty.
K? lastKey() {
if (_root == null) return null;
return _last!.key;
}
- /// Get the last key in the map that is strictly smaller than [key]. Returns
- /// `null` if no key was not found.
+ /// The last key in the map that is strictly smaller than [key].
+ ///
+ /// Returns `null` if no key was not found.
K? lastKeyBefore(K key) {
if (key == null) throw ArgumentError(key);
if (_root == null) return null;
@@ -729,7 +734,7 @@
/// ```dart
/// Set<SuperType> superSet = ...;
/// Set<SubType> subSet =
- /// new SplayTreeSet<SubType>.from(superSet.whereType<SubType>());
+ /// SplayTreeSet<SubType>.from(superSet.whereType<SubType>());
/// ```
factory SplayTreeSet.from(Iterable elements,
[int Function(E key1, E key2)? compare,
diff --git a/sdk/lib/ffi/allocation.dart b/sdk/lib/ffi/allocation.dart
new file mode 100644
index 0000000..fc5fce4
--- /dev/null
+++ b/sdk/lib/ffi/allocation.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, 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.
+
+part of dart.ffi;
+
+/// Manages memory on the native heap.
+abstract class Allocator {
+ /// This interface is meant to be implemented, not extended or mixed in.
+ Allocator._() {
+ throw UnsupportedError("Cannot be instantiated");
+ }
+
+ /// Allocates [byteCount] bytes of memory on the native heap.
+ ///
+ /// If [alignment] is provided, the allocated memory will be at least aligned
+ /// to [alignment] bytes.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment});
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ void free(Pointer pointer);
+}
+
+/// Extension on [Allocator] to provide allocation with [NativeType].
+extension AllocatorAlloc on Allocator {
+ /// Allocates `sizeOf<T>() * count` bytes of memory using
+ /// `allocator.allocate`.
+ ///
+ /// This extension method must be invoked with a compile-time constant [T].
+ external Pointer<T> call<T extends NativeType>([int count = 1]);
+}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 68424f8..bce5feb 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -17,6 +17,7 @@
import 'dart:typed_data';
part "native_type.dart";
+part "allocation.dart";
part "annotations.dart";
part "dynamic_library.dart";
part "struct.dart";
@@ -558,7 +559,7 @@
}
/// Opaque, not exposing it's members.
-class Dart_CObject extends Struct {}
+class Dart_CObject extends Opaque {}
typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer<Dart_CObject>);
diff --git a/sdk/lib/ffi/ffi_sources.gni b/sdk/lib/ffi/ffi_sources.gni
index 5b34b9c..db03071 100644
--- a/sdk/lib/ffi/ffi_sources.gni
+++ b/sdk/lib/ffi/ffi_sources.gni
@@ -6,6 +6,7 @@
"ffi.dart",
# The above file needs to be first as it lists the parts below.
+ "allocation.dart",
"annotations.dart",
"dynamic_library.dart",
"native_type.dart",
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index e319342..31e4b72 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -12,6 +12,12 @@
const NativeType();
}
+/// [Opaque]'s subtypes represent opaque types in C.
+///
+/// [Opaque]'s subtypes are not constructible in the Dart code and serve purely
+/// as markers in type signatures.
+abstract class Opaque extends NativeType {}
+
/// [_NativeInteger]'s subtypes represent a native integer in C.
///
/// [_NativeInteger]'s subtypes are not constructible in the Dart code and serve
diff --git a/sdk/lib/isolate/capability.dart b/sdk/lib/isolate/capability.dart
index a51eec2..6678fc4 100644
--- a/sdk/lib/isolate/capability.dart
+++ b/sdk/lib/isolate/capability.dart
@@ -4,31 +4,26 @@
part of dart.isolate;
-/**
- * An unforgeable object that comes back as equal when passed through other
- * isolates.
- *
- * Sending a capability object to another isolate, and getting it back,
- * will produce an object that is equal to the original.
- * There is no other way to create objects equal to a capability object.
- *
- * Capabilities can be used as access guards: A remote isolate can send
- * a request for an operation, but it is only allowed if the request contains
- * the correct capability object.
- *
- * This allows exposing the same interface to multiple clients,
- * but restricting some operations to only those clients
- * that have also been given the corresponding capability.
- *
- * Capabilities can be used inside a single isolate,
- * but they have no advantage over
- * just using `new Object` to create a unique object,
- * and it offers no real security against other code
- * running in the same isolate.
- */
+/// An unforgeable object that comes back as equal when passed through other
+/// isolates.
+///
+/// Sending a capability object to another isolate, and getting it back,
+/// will produce an object that is equal to the original.
+/// There is no other way to create objects equal to a capability object.
+///
+/// Capabilities can be used as access guards.
+/// An isolate can receive requests for operations from other isolates,
+/// but only allow them if the request contains the correct capability object.
+/// This allows exposing the same interface to multiple clients,
+/// but restricting some operations to only those clients
+/// that have also been given the corresponding capability.
+///
+/// Capabilities can be used inside a single isolate,
+/// but they have no advantage over
+/// just using `Object()` to create a unique object,
+/// and it offers no real security against other code
+/// running in the same isolate.
class Capability {
- /**
- * Create a new unforgeable capability object.
- */
+ /// Create a new unforgeable capability object.
external factory Capability();
}
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index b7650dd..7a15d7b 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -2,18 +2,16 @@
// 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.
-/**
- * Concurrent programming using _isolates_:
- * independent workers that are similar to threads
- * but don't share memory,
- * communicating only via messages.
- *
- * To use this library in your code:
- *
- * import 'dart:isolate';
- *
- * {@category VM}
- */
+/// Concurrent programming using _isolates_:
+/// independent workers that are similar to threads
+/// but don't share memory,
+/// communicating only via messages.
+///
+/// To use this library in your code:
+/// ```dart
+/// import 'dart:isolate';
+/// ```
+/// {@category VM}
library dart.isolate;
import "dart:async";
@@ -22,230 +20,207 @@
part "capability.dart";
-/**
- * Thrown when an isolate cannot be created.
- */
+/// Thrown when an isolate cannot be created.
class IsolateSpawnException implements Exception {
- /** Error message reported by the spawn operation. */
+ /// Error message reported by the spawn operation.
final String message;
@pragma("vm:entry-point")
IsolateSpawnException(this.message);
String toString() => "IsolateSpawnException: $message";
}
-/**
- * An isolated Dart execution context.
- *
- * All Dart code runs in an isolate, and code can access classes and values
- * only from the same isolate. Different isolates can communicate by sending
- * values through ports (see [ReceivePort], [SendPort]).
- *
- * An `Isolate` object is a reference to an isolate, usually different from
- * the current isolate.
- * It represents, and can be used to control, the other isolate.
- *
- * When spawning a new isolate, the spawning isolate receives an `Isolate`
- * object representing the new isolate when the spawn operation succeeds.
- *
- * Isolates run code in its own event loop, and each event may run smaller tasks
- * in a nested microtask queue.
- *
- * An `Isolate` object allows other isolates to control the event loop
- * of the isolate that it represents, and to inspect the isolate,
- * for example by pausing the isolate or by getting events when the isolate
- * has an uncaught error.
- *
- * The [controlPort] identifies and gives access to controlling the isolate,
- * and the [pauseCapability] and [terminateCapability] guard access
- * to some control operations.
- * For example, calling [pause] on an `Isolate` object created without a
- * [pauseCapability], has no effect.
- *
- * The `Isolate` object provided by a spawn operation will have the
- * control port and capabilities needed to control the isolate.
- * New isolate objects can be created without some of these capabilities
- * if necessary, using the [Isolate.Isolate] constructor.
- *
- * An `Isolate` object cannot be sent over a `SendPort`, but the control port
- * and capabilities can be sent, and can be used to create a new functioning
- * `Isolate` object in the receiving port's isolate.
- */
+/// An isolated Dart execution context.
+///
+/// All Dart code runs in an isolate, and code can access classes and values
+/// only from the same isolate. Different isolates can communicate by sending
+/// values through ports (see [ReceivePort], [SendPort]).
+///
+/// An `Isolate` object is a reference to an isolate, usually different from
+/// the current isolate.
+/// It represents, and can be used to control, the other isolate.
+///
+/// When spawning a new isolate, the spawning isolate receives an `Isolate`
+/// object representing the new isolate when the spawn operation succeeds.
+///
+/// Isolates run code in its own event loop, and each event may run smaller tasks
+/// in a nested microtask queue.
+///
+/// An `Isolate` object allows other isolates to control the event loop
+/// of the isolate that it represents, and to inspect the isolate,
+/// for example by pausing the isolate or by getting events when the isolate
+/// has an uncaught error.
+///
+/// The [controlPort] identifies and gives access to controlling the isolate,
+/// and the [pauseCapability] and [terminateCapability] guard access
+/// to some control operations.
+/// For example, calling [pause] on an `Isolate` object created without a
+/// [pauseCapability], has no effect.
+///
+/// The `Isolate` object provided by a spawn operation will have the
+/// control port and capabilities needed to control the isolate.
+/// New isolate objects can be created without some of these capabilities
+/// if necessary, using the [Isolate.Isolate] constructor.
+///
+/// An `Isolate` object cannot be sent over a `SendPort`, but the control port
+/// and capabilities can be sent, and can be used to create a new functioning
+/// `Isolate` object in the receiving port's isolate.
class Isolate {
- /** Argument to `ping` and `kill`: Ask for immediate action. */
+ /// Argument to `ping` and `kill`: Ask for immediate action.
static const int immediate = 0;
- /** Argument to `ping` and `kill`: Ask for action before the next event. */
+
+ /// Argument to `ping` and `kill`: Ask for action before the next event.
static const int beforeNextEvent = 1;
- /**
- * Control port used to send control messages to the isolate.
- *
- * The control port identifies the isolate.
- *
- * An `Isolate` object allows sending control messages
- * through the control port.
- *
- * Some control messages require a specific capability to be passed along
- * with the message (see [pauseCapability] and [terminateCapability]),
- * otherwise the message is ignored by the isolate.
- */
+ /// Control port used to send control messages to the isolate.
+ ///
+ /// The control port identifies the isolate.
+ ///
+ /// An `Isolate` object allows sending control messages
+ /// through the control port.
+ ///
+ /// Some control messages require a specific capability to be passed along
+ /// with the message (see [pauseCapability] and [terminateCapability]),
+ /// otherwise the message is ignored by the isolate.
final SendPort controlPort;
- /**
- * Capability granting the ability to pause the isolate.
- *
- * This capability is required by [pause].
- * If the capability is `null`, or if it is not the correct pause capability
- * of the isolate identified by [controlPort],
- * then calls to [pause] will have no effect.
- *
- * If the isolate is spawned in a paused state, use this capability as
- * argument to the [resume] method in order to resume the paused isolate.
- */
+ /// Capability granting the ability to pause the isolate.
+ ///
+ /// This capability is required by [pause].
+ /// If the capability is `null`, or if it is not the correct pause capability
+ /// of the isolate identified by [controlPort],
+ /// then calls to [pause] will have no effect.
+ ///
+ /// If the isolate is spawned in a paused state, use this capability as
+ /// argument to the [resume] method in order to resume the paused isolate.
final Capability? pauseCapability;
- /**
- * Capability granting the ability to terminate the isolate.
- *
- * This capability is required by [kill] and [setErrorsFatal].
- * If the capability is `null`, or if it is not the correct termination
- * capability of the isolate identified by [controlPort],
- * then calls to those methods will have no effect.
- */
+ /// Capability granting the ability to terminate the isolate.
+ ///
+ /// This capability is required by [kill] and [setErrorsFatal].
+ /// If the capability is `null`, or if it is not the correct termination
+ /// capability of the isolate identified by [controlPort],
+ /// then calls to those methods will have no effect.
final Capability? terminateCapability;
- /**
- * The name of the [Isolate] displayed for debug purposes.
- *
- * This can be set using the `debugName` parameter in [spawn] and [spawnUri].
- *
- * This name does not uniquely identify an isolate. Multiple isolates in the
- * same process may have the same `debugName`.
- *
- * For a given isolate, this value will be the same as the values returned by
- * `Dart_DebugName` in the C embedding API and the `debugName` property in
- * [IsolateMirror].
- */
+ /// The name of the [Isolate] displayed for debug purposes.
+ ///
+ /// This can be set using the `debugName` parameter in [spawn] and [spawnUri].
+ ///
+ /// This name does not uniquely identify an isolate. Multiple isolates in the
+ /// same process may have the same `debugName`.
+ ///
+ /// For a given isolate, this value will be the same as the values returned by
+ /// `Dart_DebugName` in the C embedding API and the `debugName` property in
+ /// [IsolateMirror].
@Since("2.3")
external String? get debugName;
- /**
- * Create a new [Isolate] object with a restricted set of capabilities.
- *
- * The port should be a control port for an isolate, as taken from
- * another `Isolate` object.
- *
- * The capabilities should be the subset of the capabilities that are
- * available to the original isolate.
- * Capabilities of an isolate are locked to that isolate, and have no effect
- * anywhere else, so the capabilities should come from the same isolate as
- * the control port.
- *
- * Can also be used to create an [Isolate] object from a control port, and
- * any available capabilities, that have been sent through a [SendPort].
- *
- * Example:
- * ```dart
- * Isolate isolate = findSomeIsolate();
- * Isolate restrictedIsolate = new Isolate(isolate.controlPort);
- * untrustedCode(restrictedIsolate);
- * ```
- * This example creates a new `Isolate` object that cannot be used to
- * pause or terminate the isolate. All the untrusted code can do is to
- * inspect the isolate and see uncaught errors or when it terminates.
- */
+ /// Creates a new [Isolate] object with a restricted set of capabilities.
+ ///
+ /// The port should be a control port for an isolate, as taken from
+ /// another `Isolate` object.
+ ///
+ /// The capabilities should be the subset of the capabilities that are
+ /// available to the original isolate.
+ /// Capabilities of an isolate are locked to that isolate, and have no effect
+ /// anywhere else, so the capabilities should come from the same isolate as
+ /// the control port.
+ ///
+ /// Can also be used to create an [Isolate] object from a control port, and
+ /// any available capabilities, that have been sent through a [SendPort].
+ ///
+ /// Example:
+ /// ```dart
+ /// Isolate isolate = findSomeIsolate();
+ /// Isolate restrictedIsolate = Isolate(isolate.controlPort);
+ /// untrustedCode(restrictedIsolate);
+ /// ```
+ /// This example creates a new `Isolate` object that cannot be used to
+ /// pause or terminate the isolate. All the untrusted code can do is to
+ /// inspect the isolate and see uncaught errors or when it terminates.
Isolate(this.controlPort, {this.pauseCapability, this.terminateCapability});
- /**
- * Return an [Isolate] object representing the current isolate.
- *
- * The current isolate for code using [current]
- * is the isolate running the code.
- *
- * The isolate object provides the capabilities required to inspect,
- * pause or kill the isolate, and allows granting these capabilities
- * to others.
- *
- * It is possible to pause the current isolate, but doing so *without*
- * first passing the ability to resume it again to another isolate,
- * is a sure way to hang your program.
- */
+ /// An [Isolate] object representing the current isolate.
+ ///
+ /// The current isolate for code using [current]
+ /// is the isolate running the code.
+ ///
+ /// The isolate object provides the capabilities required to inspect,
+ /// pause or kill the isolate, and allows granting these capabilities
+ /// to others.
+ ///
+ /// It is possible to pause the current isolate, but doing so *without*
+ /// first passing the ability to resume it again to another isolate,
+ /// is a sure way to hang your program.
external static Isolate get current;
- /**
- * The location of the package configuration of the current isolate, if any.
- *
- * This getter returns `null`, as the `packages/` directory is not supported
- * in Dart 2.
- */
+ /// The package root of the current isolate, if any.
+ ///
+ /// This getter returns `null`, as the `packages/` directory is not supported
+ /// in Dart 2.
@Deprecated('packages/ directory resolution is not supported in Dart 2.')
external static Future<Uri?> get packageRoot;
- /**
- * The package root of the current isolate, if any.
- *
- * If the isolate is using a [packageRoot] or the isolate has not been
- * setup for package resolution, this getter returns `null`, otherwise it
- * returns the package config URI.
- */
+ /// The location of the package configuration of the current isolate, if any.
+ ///
+ /// If the isolate has not been setup for package resolution,
+ /// this location is `null`,
+ /// otherwise it is a URI referencing the package config file.
external static Future<Uri?> get packageConfig;
- /**
- * Maps a package: URI to a non-package Uri.
- *
- * If there is no valid mapping from the package: URI in the current
- * isolate, then this call returns `null`. Non-package: URIs are
- * returned unmodified.
- */
+ /// Maps a `package:` URI to a non-package Uri.
+ ///
+ /// If there is no valid mapping from the `package:` URI in the current
+ /// isolate, then this call returns `null`. Non-`package:` URIs are
+ /// returned unmodified.
external static Future<Uri?> resolvePackageUri(Uri packageUri);
- /**
- * Creates and spawns an isolate that shares the same code as the current
- * isolate.
- *
- * The argument [entryPoint] specifies the initial function to call
- * in the spawned isolate.
- * The entry-point function is invoked in the new isolate with [message]
- * as the only argument.
- *
- * The function must be a top-level function or a static method
- * that can be called with a single argument,
- * that is, a compile-time constant function value
- * which accepts at least one positional parameter
- * and has at most one required positional parameter.
- * The function may accept any number of optional parameters,
- * as long as it *can* be called with just a single argument.
- * The function must not be the value of a function expression
- * or an instance method tear-off.
- *
- * Usually the initial [message] contains a [SendPort] so
- * that the spawner and spawnee can communicate with each other.
- *
- * If the [paused] parameter is set to `true`,
- * the isolate will start up in a paused state,
- * just before calling the [entryPoint] function with the [message],
- * as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
- * To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
- *
- * If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
- * the isolate will act as if, respectively, [setErrorsFatal],
- * [addOnExitListener] and [addErrorListener] were called with the
- * corresponding parameter and was processed before the isolate starts
- * running.
- *
- * If [debugName] is provided, the spawned [Isolate] will be identifiable by
- * this name in debuggers and logging.
- *
- * If [errorsAreFatal] is omitted, the platform may choose a default behavior
- * or inherit the current isolate's behavior.
- *
- * You can also call the [setErrorsFatal], [addOnExitListener] and
- * [addErrorListener] methods on the returned isolate, but unless the
- * isolate was started as [paused], it may already have terminated
- * before those methods can complete.
- *
- * Returns a future which will complete with an [Isolate] instance if the
- * spawning succeeded. It will complete with an error otherwise.
- */
+ /// Creates and spawns an isolate that shares the same code as the current
+ /// isolate.
+ ///
+ /// The argument [entryPoint] specifies the initial function to call
+ /// in the spawned isolate.
+ /// The entry-point function is invoked in the new isolate with [message]
+ /// as the only argument.
+ ///
+ /// The function must be a top-level function or a static method
+ /// that can be called with a single argument,
+ /// that is, a compile-time constant function value
+ /// which accepts at least one positional parameter
+ /// and has at most one required positional parameter.
+ /// The function may accept any number of optional parameters,
+ /// as long as it *can* be called with just a single argument.
+ /// The function must not be the value of a function expression
+ /// or an instance method tear-off.
+ ///
+ /// Usually the initial [message] contains a [SendPort] so
+ /// that the spawner and spawnee can communicate with each other.
+ ///
+ /// If the [paused] parameter is set to `true`,
+ /// the isolate will start up in a paused state,
+ /// just before calling the [entryPoint] function with the [message],
+ /// as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
+ /// To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
+ ///
+ /// If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
+ /// the isolate will act as if, respectively, [setErrorsFatal],
+ /// [addOnExitListener] and [addErrorListener] were called with the
+ /// corresponding parameter and was processed before the isolate starts
+ /// running.
+ ///
+ /// If [debugName] is provided, the spawned [Isolate] will be identifiable by
+ /// this name in debuggers and logging.
+ ///
+ /// If [errorsAreFatal] is omitted, the platform may choose a default behavior
+ /// or inherit the current isolate's behavior.
+ ///
+ /// You can also call the [setErrorsFatal], [addOnExitListener] and
+ /// [addErrorListener] methods on the returned isolate, but unless the
+ /// isolate was started as [paused], it may already have terminated
+ /// before those methods can complete.
+ ///
+ /// Returns a future which will complete with an [Isolate] instance if the
+ /// spawning succeeded. It will complete with an error otherwise.
external static Future<Isolate> spawn<T>(
void entryPoint(T message), T message,
{bool paused = false,
@@ -254,78 +229,76 @@
SendPort? onError,
@Since("2.3") String? debugName});
- /**
- * Creates and spawns an isolate that runs the code from the library with
- * the specified URI.
- *
- * The isolate starts executing the top-level `main` function of the library
- * with the given URI.
- *
- * The target `main` must be callable with zero, one or two arguments.
- * Examples:
- *
- * * `main()`
- * * `main(args)`
- * * `main(args, message)`
- *
- * When present, the parameter `args` is set to the provided [args] list.
- * When present, the parameter `message` is set to the initial [message].
- *
- * If the [paused] parameter is set to `true`,
- * the isolate will start up in a paused state,
- * as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
- * To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
- *
- * If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
- * the isolate will act as if, respectively, [setErrorsFatal],
- * [addOnExitListener] and [addErrorListener] were called with the
- * corresponding parameter and was processed before the isolate starts
- * running.
- *
- * You can also call the [setErrorsFatal], [addOnExitListener] and
- * [addErrorListener] methods on the returned isolate, but unless the
- * isolate was started as [paused], it may already have terminated
- * before those methods can complete.
- *
- * If the [checked] parameter is set to `true` or `false`,
- * the new isolate will run code in checked mode (enabling asserts and type
- * checks), respectively in production mode (disabling asserts and type
- * checks), if possible. If the parameter is omitted, the new isolate will
- * inherit the value from the current isolate.
- *
- * In Dart2 strong mode, the `checked` parameter only controls asserts, but
- * not type checks.
- *
- * It may not always be possible to honor the `checked` parameter.
- * If the isolate code was pre-compiled, it may not be possible to change
- * the checked mode setting dynamically.
- * In that case, the `checked` parameter is ignored.
- *
- * WARNING: The [checked] parameter is not implemented on all platforms yet.
- *
- * If the [packageConfig] parameter is provided, then it is used to find the
- * location of a package resolution configuration file for the spawned
- * isolate.
- *
- * If the [automaticPackageResolution] parameter is provided, then the
- * location of the package sources in the spawned isolate is automatically
- * determined.
- *
- * The [environment] is a mapping from strings to strings which the
- * spawned isolate uses when looking up [String.fromEnvironment] values.
- * The system may add its own entries to environment as well.
- * If `environment` is omitted, the spawned isolate has the same environment
- * declarations as the spawning isolate.
- *
- * WARNING: The [environment] parameter is not implemented on all
- * platforms yet.
- *
- * If [debugName] is provided, the spawned [Isolate] will be identifiable by
- * this name in debuggers and logging.
- *
- * Returns a future that will complete with an [Isolate] instance if the
- * spawning succeeded. It will complete with an error otherwise.
- */
+ /// Creates and spawns an isolate that runs the code from the library with
+ /// the specified URI.
+ ///
+ /// The isolate starts executing the top-level `main` function of the library
+ /// with the given URI.
+ ///
+ /// The target `main` must be callable with zero, one or two arguments.
+ /// Examples:
+ ///
+ /// * `main()`
+ /// * `main(args)`
+ /// * `main(args, message)`
+ ///
+ /// When present, the parameter `args` is set to the provided [args] list.
+ /// When present, the parameter `message` is set to the initial [message].
+ ///
+ /// If the [paused] parameter is set to `true`,
+ /// the isolate will start up in a paused state,
+ /// as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
+ /// To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
+ ///
+ /// If the [errorsAreFatal], [onExit] and/or [onError] parameters are provided,
+ /// the isolate will act as if, respectively, [setErrorsFatal],
+ /// [addOnExitListener] and [addErrorListener] were called with the
+ /// corresponding parameter and was processed before the isolate starts
+ /// running.
+ ///
+ /// You can also call the [setErrorsFatal], [addOnExitListener] and
+ /// [addErrorListener] methods on the returned isolate, but unless the
+ /// isolate was started as [paused], it may already have terminated
+ /// before those methods can complete.
+ ///
+ /// If the [checked] parameter is set to `true` or `false`,
+ /// the new isolate will run code in checked mode (enabling asserts and type
+ /// checks), respectively in production mode (disabling asserts and type
+ /// checks), if possible. If the parameter is omitted, the new isolate will
+ /// inherit the value from the current isolate.
+ ///
+ /// In Dart2 strong mode, the `checked` parameter only controls asserts, but
+ /// not type checks.
+ ///
+ /// It may not always be possible to honor the `checked` parameter.
+ /// If the isolate code was pre-compiled, it may not be possible to change
+ /// the checked mode setting dynamically.
+ /// In that case, the `checked` parameter is ignored.
+ ///
+ /// WARNING: The [checked] parameter is not implemented on all platforms yet.
+ ///
+ /// If the [packageConfig] parameter is provided, then it is used to find the
+ /// location of a package resolution configuration file for the spawned
+ /// isolate.
+ ///
+ /// If the [automaticPackageResolution] parameter is provided, then the
+ /// location of the package sources in the spawned isolate is automatically
+ /// determined.
+ ///
+ /// The [environment] is a mapping from strings to strings which the
+ /// spawned isolate uses when looking up [String.fromEnvironment] values.
+ /// The system may add its own entries to environment as well.
+ /// If `environment` is omitted, the spawned isolate has the same environment
+ /// declarations as the spawning isolate.
+ ///
+ /// WARNING: The [environment] parameter is not implemented on all
+ /// platforms yet.
+ ///
+ /// If [debugName] is provided, the spawned [Isolate] will be identifiable by
+ /// this name in debuggers and logging.
+ ///
+ /// Returns a future that will complete with an [Isolate] instance if the
+ /// spawning succeeded. It will complete with an error otherwise.
external static Future<Isolate> spawnUri(
Uri uri,
List<String> args,
@@ -343,239 +316,219 @@
@Since("2.3")
String? debugName});
- /**
- * Requests the isolate to pause.
- *
- * When the isolate receives the pause command, it stops
- * processing events from the event loop queue.
- * It may still add new events to the queue in response to, e.g., timers
- * or receive-port messages. When the isolate is resumed,
- * it starts handling the already enqueued events.
- *
- * The pause request is sent through the isolate's command port,
- * which bypasses the receiving isolate's event loop.
- * The pause takes effect when it is received, pausing the event loop
- * as it is at that time.
- *
- * The [resumeCapability] is used to identity the pause,
- * and must be used again to end the pause using [resume].
- * If [resumeCapability] is omitted, a new capability object is created
- * and used instead.
- *
- * If an isolate is paused more than once using the same capability,
- * only one resume with that capability is needed to end the pause.
- *
- * If an isolate is paused using more than one capability,
- * each pause must be individually ended before the isolate resumes.
- *
- * Returns the capability that must be used to end the pause.
- * This is either [resumeCapability], or a new capability when
- * [resumeCapability] is omitted.
- *
- * If [pauseCapability] is `null`, or it's not the pause capability
- * of the isolate identified by [controlPort],
- * the pause request is ignored by the receiving isolate.
- */
+ /// Requests the isolate to pause.
+ ///
+ /// When the isolate receives the pause command, it stops
+ /// processing events from the event loop queue.
+ /// It may still add new events to the queue in response to, e.g., timers
+ /// or receive-port messages. When the isolate is resumed,
+ /// it starts handling the already enqueued events.
+ ///
+ /// The pause request is sent through the isolate's command port,
+ /// which bypasses the receiving isolate's event loop.
+ /// The pause takes effect when it is received, pausing the event loop
+ /// as it is at that time.
+ ///
+ /// The [resumeCapability] is used to identity the pause,
+ /// and must be used again to end the pause using [resume].
+ /// If [resumeCapability] is omitted, a new capability object is created
+ /// and used instead.
+ ///
+ /// If an isolate is paused more than once using the same capability,
+ /// only one resume with that capability is needed to end the pause.
+ ///
+ /// If an isolate is paused using more than one capability,
+ /// each pause must be individually ended before the isolate resumes.
+ ///
+ /// Returns the capability that must be used to end the pause.
+ /// This is either [resumeCapability], or a new capability when
+ /// [resumeCapability] is omitted.
+ ///
+ /// If [pauseCapability] is `null`, or it's not the pause capability
+ /// of the isolate identified by [controlPort],
+ /// the pause request is ignored by the receiving isolate.
Capability pause([Capability? resumeCapability]) {
resumeCapability ??= new Capability();
_pause(resumeCapability);
return resumeCapability;
}
- /** Internal implementation of [pause]. */
+ /// Internal implementation of [pause].
external void _pause(Capability resumeCapability);
- /**
- * Resumes a paused isolate.
- *
- * Sends a message to an isolate requesting that it ends a pause
- * that was previously requested.
- *
- * When all active pause requests have been cancelled, the isolate
- * will continue processing events and handling normal messages.
- *
- * If the [resumeCapability] is not one that has previously been used
- * to pause the isolate, or it has already been used to resume from
- * that pause, the resume call has no effect.
- */
+ /// Resumes a paused isolate.
+ ///
+ /// Sends a message to an isolate requesting that it ends a pause
+ /// that was previously requested.
+ ///
+ /// When all active pause requests have been cancelled, the isolate
+ /// will continue processing events and handling normal messages.
+ ///
+ /// If the [resumeCapability] is not one that has previously been used
+ /// to pause the isolate, or it has already been used to resume from
+ /// that pause, the resume call has no effect.
external void resume(Capability resumeCapability);
- /**
- * Requests an exit message on [responsePort] when the isolate terminates.
- *
- * The isolate will send [response] as a message on [responsePort] as the last
- * thing before it terminates. It will run no further code after the message
- * has been sent.
- *
- * Adding the same port more than once will only cause it to receive one exit
- * message, using the last response value that was added,
- * and it only needs to be removed once using [removeOnExitListener].
- *
- * If the isolate has terminated before it can receive this request,
- * no exit message will be sent.
- *
- * The [response] object must follow the same restrictions as enforced by
- * [SendPort.send].
- * It is recommended to only use simple values that can be sent to all
- * isolates, like `null`, booleans, numbers or strings.
- *
- * Since isolates run concurrently, it's possible for it to exit before the
- * exit listener is established, and in that case no response will be
- * sent on [responsePort].
- * To avoid this, either use the corresponding parameter to the spawn
- * function, or start the isolate paused, add the listener and
- * then resume the isolate.
- */
+ /// Requests an exit message on [responsePort] when the isolate terminates.
+ ///
+ /// The isolate will send [response] as a message on [responsePort] as the last
+ /// thing before it terminates. It will run no further code after the message
+ /// has been sent.
+ ///
+ /// Adding the same port more than once will only cause it to receive one exit
+ /// message, using the last response value that was added,
+ /// and it only needs to be removed once using [removeOnExitListener].
+ ///
+ /// If the isolate has terminated before it can receive this request,
+ /// no exit message will be sent.
+ ///
+ /// The [response] object must follow the same restrictions as enforced by
+ /// [SendPort.send].
+ /// It is recommended to only use simple values that can be sent to all
+ /// isolates, like `null`, booleans, numbers or strings.
+ ///
+ /// Since isolates run concurrently, it's possible for it to exit before the
+ /// exit listener is established, and in that case no response will be
+ /// sent on [responsePort].
+ /// To avoid this, either use the corresponding parameter to the spawn
+ /// function, or start the isolate paused, add the listener and
+ /// then resume the isolate.
/* TODO(lrn): Can we do better? Can the system recognize this message and
* send a reply if the receiving isolate is dead?
*/
external void addOnExitListener(SendPort responsePort, {Object? response});
- /**
- * Stops listening for exit messages from the isolate.
- *
- * Requests for the isolate to not send exit messages on [responsePort].
- * If the isolate isn't expecting to send exit messages on [responsePort],
- * because the port hasn't been added using [addOnExitListener],
- * or because it has already been removed, the request is ignored.
- *
- * If the same port has been passed via [addOnExitListener] more than once,
- * only one call to `removeOnExitListener` is needed to stop it from receiving
- * exit messages.
- *
- * Closing the receive port that is associated with the [responsePort] does
- * not stop the isolate from sending uncaught errors, they are just going to
- * be lost.
- *
- * An exit message may still be sent if the isolate terminates
- * before this request is received and processed.
- */
+ /// Stops listening for exit messages from the isolate.
+ ///
+ /// Requests for the isolate to not send exit messages on [responsePort].
+ /// If the isolate isn't expecting to send exit messages on [responsePort],
+ /// because the port hasn't been added using [addOnExitListener],
+ /// or because it has already been removed, the request is ignored.
+ ///
+ /// If the same port has been passed via [addOnExitListener] more than once,
+ /// only one call to `removeOnExitListener` is needed to stop it from receiving
+ /// exit messages.
+ ///
+ /// Closing the receive port that is associated with the [responsePort] does
+ /// not stop the isolate from sending uncaught errors, they are just going to
+ /// be lost.
+ ///
+ /// An exit message may still be sent if the isolate terminates
+ /// before this request is received and processed.
external void removeOnExitListener(SendPort responsePort);
- /**
- * Sets whether uncaught errors will terminate the isolate.
- *
- * If errors are fatal, any uncaught error will terminate the isolate
- * event loop and shut down the isolate.
- *
- * This call requires the [terminateCapability] for the isolate.
- * If the capability is absent or incorrect, no change is made.
- *
- * Since isolates run concurrently, it's possible for the receiving isolate
- * to exit due to an error, before a request, using this method, has been
- * received and processed.
- * To avoid this, either use the corresponding parameter to the spawn
- * function, or start the isolate paused, set errors non-fatal and
- * then resume the isolate.
- */
+ /// Sets whether uncaught errors will terminate the isolate.
+ ///
+ /// If errors are fatal, any uncaught error will terminate the isolate
+ /// event loop and shut down the isolate.
+ ///
+ /// This call requires the [terminateCapability] for the isolate.
+ /// If the capability is absent or incorrect, no change is made.
+ ///
+ /// Since isolates run concurrently, it's possible for the receiving isolate
+ /// to exit due to an error, before a request, using this method, has been
+ /// received and processed.
+ /// To avoid this, either use the corresponding parameter to the spawn
+ /// function, or start the isolate paused, set errors non-fatal and
+ /// then resume the isolate.
external void setErrorsFatal(bool errorsAreFatal);
- /**
- * Requests the isolate to shut down.
- *
- * The isolate is requested to terminate itself.
- * The [priority] argument specifies when this must happen.
- *
- * The [priority], when provided, must be one of [immediate] or
- * [beforeNextEvent] (the default).
- * The shutdown is performed at different times depending on the priority:
- *
- * * `immediate`: The isolate shuts down as soon as possible.
- * Control messages are handled in order, so all previously sent control
- * events from this isolate will all have been processed.
- * The shutdown should happen no later than if sent with
- * `beforeNextEvent`.
- * It may happen earlier if the system has a way to shut down cleanly
- * at an earlier time, even during the execution of another event.
- * * `beforeNextEvent`: The shutdown is scheduled for the next time
- * control returns to the event loop of the receiving isolate,
- * after the current event, and any already scheduled control events,
- * are completed.
- *
- * If [terminateCapability] is `null`, or it's not the terminate capability
- * of the isolate identified by [controlPort],
- * the kill request is ignored by the receiving isolate.
- */
+ /// Requests the isolate to shut down.
+ ///
+ /// The isolate is requested to terminate itself.
+ /// The [priority] argument specifies when this must happen.
+ ///
+ /// The [priority], when provided, must be one of [immediate] or
+ /// [beforeNextEvent] (the default).
+ /// The shutdown is performed at different times depending on the priority:
+ ///
+ /// * `immediate`: The isolate shuts down as soon as possible.
+ /// Control messages are handled in order, so all previously sent control
+ /// events from this isolate will all have been processed.
+ /// The shutdown should happen no later than if sent with
+ /// `beforeNextEvent`.
+ /// It may happen earlier if the system has a way to shut down cleanly
+ /// at an earlier time, even during the execution of another event.
+ /// * `beforeNextEvent`: The shutdown is scheduled for the next time
+ /// control returns to the event loop of the receiving isolate,
+ /// after the current event, and any already scheduled control events,
+ /// are completed.
+ ///
+ /// If [terminateCapability] is `null`, or it's not the terminate capability
+ /// of the isolate identified by [controlPort],
+ /// the kill request is ignored by the receiving isolate.
external void kill({int priority = beforeNextEvent});
- /**
- * Requests that the isolate send [response] on the [responsePort].
- *
- * The [response] object must follow the same restrictions as enforced by
- * [SendPort.send].
- * It is recommended to only use simple values that can be sent to all
- * isolates, like `null`, booleans, numbers or strings.
- *
- * If the isolate is alive, it will eventually send `response`
- * (defaulting to `null`) on the response port.
- *
- * The [priority] must be one of [immediate] or [beforeNextEvent].
- * The response is sent at different times depending on the ping type:
- *
- * * `immediate`: The isolate responds as soon as it receives the
- * control message. This is after any previous control message
- * from the same isolate has been received and processed,
- * but may be during execution of another event.
- * * `beforeNextEvent`: The response is scheduled for the next time
- * control returns to the event loop of the receiving isolate,
- * after the current event, and any already scheduled control events,
- * are completed.
- */
+ /// Requests that the isolate send [response] on the [responsePort].
+ ///
+ /// The [response] object must follow the same restrictions as enforced by
+ /// [SendPort.send].
+ /// It is recommended to only use simple values that can be sent to all
+ /// isolates, like `null`, booleans, numbers or strings.
+ ///
+ /// If the isolate is alive, it will eventually send `response`
+ /// (defaulting to `null`) on the response port.
+ ///
+ /// The [priority] must be one of [immediate] or [beforeNextEvent].
+ /// The response is sent at different times depending on the ping type:
+ ///
+ /// * `immediate`: The isolate responds as soon as it receives the
+ /// control message. This is after any previous control message
+ /// from the same isolate has been received and processed,
+ /// but may be during execution of another event.
+ /// * `beforeNextEvent`: The response is scheduled for the next time
+ /// control returns to the event loop of the receiving isolate,
+ /// after the current event, and any already scheduled control events,
+ /// are completed.
external void ping(SendPort responsePort,
{Object? response, int priority = immediate});
- /**
- * Requests that uncaught errors of the isolate are sent back to [port].
- *
- * The errors are sent back as two elements lists.
- * The first element is a `String` representation of the error, usually
- * created by calling `toString` on the error.
- * The second element is a `String` representation of an accompanying
- * stack trace, or `null` if no stack trace was provided.
- * To convert this back to a [StackTrace] object, use [StackTrace.fromString].
- *
- * Listening using the same port more than once does nothing.
- * A port will only receive each error once,
- * and will only need to be removed once using [removeErrorListener].
-
- * Closing the receive port that is associated with the port does not stop
- * the isolate from sending uncaught errors, they are just going to be lost.
- * Instead use [removeErrorListener] to stop receiving errors on [port].
- *
- * Since isolates run concurrently, it's possible for it to exit before the
- * error listener is established. To avoid this, start the isolate paused,
- * add the listener and then resume the isolate.
- */
+ /// Requests that uncaught errors of the isolate are sent back to [port].
+ ///
+ /// The errors are sent back as two-element lists.
+ /// The first element is a `String` representation of the error, usually
+ /// created by calling `toString` on the error.
+ /// The second element is a `String` representation of an accompanying
+ /// stack trace, or `null` if no stack trace was provided.
+ /// To convert this back to a [StackTrace] object, use [StackTrace.fromString].
+ ///
+ /// Listening using the same port more than once does nothing.
+ /// A port will only receive each error once,
+ /// and will only need to be removed once using [removeErrorListener].
+ ///
+ /// Closing the receive port that is associated with the port does not stop
+ /// the isolate from sending uncaught errors, they are just going to be lost.
+ /// Instead use [removeErrorListener] to stop receiving errors on [port].
+ ///
+ /// Since isolates run concurrently, it's possible for it to exit before the
+ /// error listener is established. To avoid this, start the isolate paused,
+ /// add the listener and then resume the isolate.
external void addErrorListener(SendPort port);
- /**
- * Stops listening for uncaught errors from the isolate.
- *
- * Requests for the isolate to not send uncaught errors on [port].
- * If the isolate isn't expecting to send uncaught errors on [port],
- * because the port hasn't been added using [addErrorListener],
- * or because it has already been removed, the request is ignored.
- *
- * If the same port has been passed via [addErrorListener] more than once,
- * only one call to `removeErrorListener` is needed to stop it from receiving
- * uncaught errors.
- *
- * Uncaught errors message may still be sent by the isolate
- * until this request is received and processed.
- */
+ /// Stops listening for uncaught errors from the isolate.
+ ///
+ /// Requests for the isolate to not send uncaught errors on [port].
+ /// If the isolate isn't expecting to send uncaught errors on [port],
+ /// because the port hasn't been added using [addErrorListener],
+ /// or because it has already been removed, the request is ignored.
+ ///
+ /// If the same port has been passed via [addErrorListener] more than once,
+ /// only one call to `removeErrorListener` is needed to stop it from receiving
+ /// uncaught errors.
+ ///
+ /// Uncaught errors message may still be sent by the isolate
+ /// until this request is received and processed.
external void removeErrorListener(SendPort port);
- /**
- * Returns a broadcast stream of uncaught errors from the isolate.
- *
- * Each error is provided as an error event on the stream.
- *
- * The actual error object and stackTraces will not necessarily
- * be the same object types as in the actual isolate, but they will
- * always have the same [Object.toString] result.
- *
- * This stream is based on [addErrorListener] and [removeErrorListener].
- */
+ /// Returns a broadcast stream of uncaught errors from the isolate.
+ ///
+ /// Each error is provided as an error event on the stream.
+ ///
+ /// The actual error object and stackTraces will not necessarily
+ /// be the same object types as in the actual isolate, but they will
+ /// always have the same [Object.toString] result.
+ ///
+ /// This stream is based on [addErrorListener] and [removeErrorListener].
Stream get errors {
StreamController controller = StreamController.broadcast(sync: true);
RawReceivePort? port;
@@ -602,158 +555,159 @@
}
}
-/**
- * Sends messages to its [ReceivePort]s.
- *
- * [SendPort]s are created from [ReceivePort]s. Any message sent through
- * a [SendPort] is delivered to its corresponding [ReceivePort]. There might be
- * many [SendPort]s for the same [ReceivePort].
- *
- * [SendPort]s can be transmitted to other isolates, and they preserve equality
- * when sent.
- */
+/// Sends messages to its [ReceivePort]s.
+///
+/// [SendPort]s are created from [ReceivePort]s. Any message sent through
+/// a [SendPort] is delivered to its corresponding [ReceivePort]. There might be
+/// many [SendPort]s for the same [ReceivePort].
+///
+/// [SendPort]s can be transmitted to other isolates, and they preserve equality
+/// when sent.
abstract class SendPort implements Capability {
- /**
- * Sends an asynchronous [message] through this send port, to its
- * corresponding `ReceivePort`.
- *
- * The content of [message] can be: primitive values (null, num, bool, double,
- * String), instances of [SendPort], and lists and maps whose elements are any
- * of these. List and maps are also allowed to be cyclic.
- *
- * In the special circumstances when two isolates share the same code and are
- * running in the same process (e.g. isolates created via [Isolate.spawn]), it
- * is also possible to send object instances (which would be copied in the
- * process). This is currently only supported by the
- * [Dart Native](https://dart.dev/platforms#dart-native-vm-jit-and-aot)
- * platform.
- *
- * The send happens immediately and doesn't block. The corresponding receive
- * port can receive the message as soon as its isolate's event loop is ready
- * to deliver it, independently of what the sending isolate is doing.
- */
+ /// Sends an asynchronous [message] through this send port, to its
+ /// corresponding `ReceivePort`.
+ ///
+ /// The content of [message] can be: primitive values
+ /// (null, num, bool, double, String), instances of [SendPort],
+ /// and lists and maps whose elements are any of these.
+ /// List and maps are also allowed to contain cyclic references.
+ ///
+ /// In the special circumstances when two isolates share the same code and are
+ /// running in the same process (e.g. isolates created via [Isolate.spawn]),
+ /// it is also possible to send object instances (which would be copied in the
+ /// process). This is currently only supported by the
+ /// [Dart Native](https://dart.dev/platforms#dart-native-vm-jit-and-aot)
+ /// platform.
+ ///
+ /// The send happens immediately and doesn't block. The corresponding receive
+ /// port can receive the message as soon as its isolate's event loop is ready
+ /// to deliver it, independently of what the sending isolate is doing.
void send(Object? message);
- /**
- * Tests whether [other] is a [SendPort] pointing to the same
- * [ReceivePort] as this one.
- */
+ /// Tests whether [other] is a [SendPort] pointing to the same
+ /// [ReceivePort] as this one.
bool operator ==(var other);
- /**
- * Returns an immutable hash code for this send port that is
- * consistent with the == operator.
- */
+ /// A hash code for this send port that is consistent with the == operator.
int get hashCode;
}
-/**
- * Together with [SendPort], the only means of communication between isolates.
- *
- * [ReceivePort]s have a `sendPort` getter which returns a [SendPort].
- * Any message that is sent through this [SendPort]
- * is delivered to the [ReceivePort] it has been created from. There, the
- * message is dispatched to the `ReceivePort`'s listener.
- *
- * A [ReceivePort] is a non-broadcast stream. This means that it buffers
- * incoming messages until a listener is registered. Only one listener can
- * receive messages. See [Stream.asBroadcastStream] for transforming the port
- * to a broadcast stream.
- *
- * A [ReceivePort] may have many [SendPort]s.
- */
+/// Together with [SendPort], the only means of communication between isolates.
+///
+/// [ReceivePort]s have a `sendPort` getter which returns a [SendPort].
+/// Any message that is sent through this [SendPort]
+/// is delivered to the [ReceivePort] it has been created from. There, the
+/// message is dispatched to the `ReceivePort`'s listener.
+///
+/// A [ReceivePort] is a non-broadcast stream. This means that it buffers
+/// incoming messages until a listener is registered. Only one listener can
+/// receive messages. See [Stream.asBroadcastStream] for transforming the port
+/// to a broadcast stream.
+///
+/// A [ReceivePort] may have many [SendPort]s.
abstract class ReceivePort implements Stream<dynamic> {
- /**
- * Opens a long-lived port for receiving messages.
- *
- * A [ReceivePort] is a non-broadcast stream. This means that it buffers
- * incoming messages until a listener is registered. Only one listener can
- * receive messages. See [Stream.asBroadcastStream] for transforming the port
- * to a broadcast stream.
- *
- * The optional `debugName` parameter can be set to associate a name with
- * this port that can be displayed in tooling.
- *
- * A receive port is closed by canceling its subscription.
- */
+ /// Opens a long-lived port for receiving messages.
+ ///
+ /// A [ReceivePort] is a non-broadcast stream. This means that it buffers
+ /// incoming messages until a listener is registered. Only one listener can
+ /// receive messages. See [Stream.asBroadcastStream] for transforming the port
+ /// to a broadcast stream.
+ ///
+ /// The optional `debugName` parameter can be set to associate a name with
+ /// this port that can be displayed in tooling.
+ ///
+ /// A receive port is closed by canceling its subscription.
external factory ReceivePort([String debugName = '']);
- /**
- * Creates a [ReceivePort] from a [RawReceivePort].
- *
- * The handler of the given [rawPort] is overwritten during the construction
- * of the result.
- */
+ /// Creates a [ReceivePort] from a [RawReceivePort].
+ ///
+ /// The handler of the given [rawPort] is overwritten during the construction
+ /// of the result.
external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
- /**
- * Inherited from [Stream].
- *
- * Note that [onError] and [cancelOnError] are ignored since a ReceivePort
- * will never receive an error.
- *
- * The [onDone] handler will be called when the stream closes.
- * The stream closes when [close] is called.
- */
+ /// Listen for events from [Stream].
+ ///
+ /// See [Stream.listen].
+ ///
+ /// Note that [onError] and [cancelOnError] are ignored since a [ReceivePort]
+ /// will never receive an error.
+ ///
+ /// The [onDone] handler will be called when the stream closes.
+ /// The stream closes when [close] is called.
StreamSubscription<dynamic> listen(void onData(var message)?,
{Function? onError, void onDone()?, bool? cancelOnError});
- /**
- * Closes `this`.
- *
- * If the stream has not been canceled yet, adds a close-event to the event
- * queue and discards any further incoming messages.
- *
- * If the stream has already been canceled this method has no effect.
- */
+ /// Closes the receive port.
+ ///
+ /// No further events will be received by the receive port,
+ /// or emitted as stream events.
+ ///
+ /// If [listen] has been called and the [StreamSubscription] has not
+ /// been canceled yet, the subscription will be closed with a "done"
+ /// event.
+ ///
+ /// If the stream has already been canceled this method has no effect.
void close();
- /**
- * Returns a [SendPort] that sends to this receive port.
- */
+ /// A [SendPort] which sends messages to this receive port.
SendPort get sendPort;
}
+/// A low-level asynchronous message receiver.
+///
+/// A [RawReceivePort] is low level feature, and is not [Zone] aware.
+/// The [handler] will always be invoked in the [Zone.root] zone.
+///
+/// The port cannot be paused. The data-handler must be set before the first
+/// messsage is received, otherwise the message is lost.
+///
+/// Messages can be sent to this port using [sendPort].
abstract class RawReceivePort {
- /**
- * Opens a long-lived port for receiving messages.
- *
- * A [RawReceivePort] is low level and does not work with [Zone]s. It
- * can not be paused. The data-handler must be set before the first
- * event is received.
- *
- * The optional `debugName` parameter can be set to associate a name with
- * this port that can be displayed in tooling.
- *
- */
+ /// Opens a long-lived port for receiving messages.
+ ///
+ /// A [RawReceivePort] is low level and does not work with [Zone]s. It
+ /// cannot be paused. The data-handler must be set before the first
+ /// messsage is received, otherwise the message is lost.
+ ///
+ /// If [handler] is provided, it's set as the [RawReceivePort.handler].
+ ///
+ /// The optional `debugName` parameter can be set to associate a name with
+ /// this port that can be displayed in tooling.
external factory RawReceivePort([Function? handler, String debugName = '']);
- /**
- * Sets the handler that is invoked for every incoming message.
- *
- * The handler is invoked in the root-zone ([Zone.root]).
- */
+ /// Sets the handler that is invoked for every incoming message.
+ ///
+ /// The handler is invoked in the [Zone.root] zone.
+ /// If the handler should be invoked in the current zone, do:
+ /// ```dart
+ /// rawPort.handler = Zone.current.bind(actualHandler);
+ /// ```
+ ///
+ /// The handler must be a function which can accept one argument
+ /// of the type of the messages sent to this port.
+ /// This means that if it is known that messages will all be [String]s,
+ /// a handler of type `void Function(String)` can be used.
+ /// The function is invoked dynamically with the actual messages,
+ /// and if this invocation fails,
+ /// the error becomes a top-level uncaught error in the [Zone.root] zone.
+ // TODO(44659): Change parameter type to `void Function(Never)` to only
+ // accept functions which can be called with one argument.
void set handler(Function? newHandler);
- /**
- * Closes the port.
- *
- * After a call to this method any incoming message is silently dropped.
- */
+ /// Closes the port.
+ ///
+ /// After a call to this method, any incoming message is silently dropped.
+ /// The [handler] will never be called again.
void close();
- /**
- * Returns a [SendPort] that sends to this raw receive port.
- */
+ /// Returns a [SendPort] that sends messages to this raw receive port.
SendPort get sendPort;
}
-/**
- * Description of an error from another isolate.
- *
- * This error has the same `toString()` and `stackTrace.toString()` behavior
- * as the original error, but has no other features of the original error.
- */
+/// Description of an error from another isolate.
+///
+/// This error has the same `toString()` and `stackTrace.toString()` behavior
+/// as the original error, but has no other features of the original error.
class RemoteError implements Error {
final String _description;
final StackTrace stackTrace;
@@ -763,35 +717,29 @@
String toString() => _description;
}
-/**
- * An efficiently transferable sequence of byte values.
- *
- * A [TransferableTypedData] is created from a number of bytes.
- * This will take time proportional to the number of bytes.
- *
- * The [TransferableTypedData] can be moved between isolates, so
- * sending it through a send port will only take constant time.
- *
- * When sent this way, the local transferable can no longer be materialized,
- * and the received object is now the only way to materialize the data.
- */
+/// An efficiently transferable sequence of byte values.
+///
+/// A [TransferableTypedData] is created from a number of bytes.
+/// This will take time proportional to the number of bytes.
+///
+/// The [TransferableTypedData] can be moved between isolates, so
+/// sending it through a send port will only take constant time.
+///
+/// When sent this way, the local transferable can no longer be materialized,
+/// and the received object is now the only way to materialize the data.
@Since("2.3.2")
abstract class TransferableTypedData {
- /**
- * Creates a new [TransferableTypedData] containing the bytes of [list].
- *
- * It must be possible to create a single [Uint8List] containing the
- * bytes, so if there are more bytes than what the platform allows in
- * a single [Uint8List], then creation fails.
- */
+ /// Creates a new [TransferableTypedData] containing the bytes of [list].
+ ///
+ /// It must be possible to create a single [Uint8List] containing the
+ /// bytes, so if there are more bytes than what the platform allows in
+ /// a single [Uint8List], then creation fails.
external factory TransferableTypedData.fromList(List<TypedData> list);
- /**
- * Creates a new [ByteBuffer] containing the bytes stored in this [TransferableTypedData].
- *
- * The [TransferableTypedData] is a cross-isolate single-use resource.
- * This method must not be called more than once on the same underlying
- * transferable bytes, even if the calls occur in different isolates.
- */
+ /// Creates a new [ByteBuffer] containing the bytes stored in this [TransferableTypedData].
+ ///
+ /// The [TransferableTypedData] is a cross-isolate single-use resource.
+ /// This method must not be called more than once on the same underlying
+ /// transferable bytes, even if the calls occur in different isolates.
ByteBuffer materialize();
}
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 0b9d207..8f584e2 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -86,6 +86,7 @@
"uri": "ffi/ffi.dart",
"patches": [
"_internal/vm/lib/ffi_patch.dart",
+ "_internal/vm/lib/ffi_allocation_patch.dart",
"_internal/vm/lib/ffi_dynamic_library_patch.dart",
"_internal/vm/lib/ffi_native_type_patch.dart",
"_internal/vm/lib/ffi_struct_patch.dart"
@@ -470,4 +471,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index f6cb8c3..89e3640 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -91,6 +91,7 @@
uri: "ffi/ffi.dart"
patches:
- "_internal/vm/lib/ffi_patch.dart"
+ - "_internal/vm/lib/ffi_allocation_patch.dart"
- "_internal/vm/lib/ffi_dynamic_library_patch.dart"
- "_internal/vm/lib/ffi_native_type_patch.dart"
- "_internal/vm/lib/ffi_struct_patch.dart"
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 8f847b1..ad1da4d 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -5,9 +5,9 @@
/// Mathematical constants and functions, plus a random number generator.
///
/// To use this library in your code:
-///
-/// import 'dart:math';
-///
+/// ```dart
+/// import 'dart:math';
+/// ```
/// {@category Core}
library dart.math;
diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart
index f092fc8..b3e9432 100644
--- a/sdk/lib/math/point.dart
+++ b/sdk/lib/math/point.dart
@@ -9,6 +9,7 @@
final T x;
final T y;
+ /// Creates a point with the provided [x] and [y] coordinates.
const Point(T x, T y)
: this.x = x,
this.y = y;
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index c796465..20d17f8 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -6,9 +6,9 @@
/// (for example, unsigned 8 byte integers) and SIMD numeric types.
///
/// To use this library in your code:
-///
-/// import 'dart:typed_data';
-///
+/// ```dart
+/// import 'dart:typed_data';
+/// ```
/// {@category Core}
library dart.typed_data;
@@ -18,407 +18,357 @@
part "unmodifiable_typed_data.dart";
-/**
- * A sequence of bytes underlying a typed data object.
- *
- * Used to process large quantities of binary or numerical data
- * more efficiently using a typed view.
- */
+/// A sequence of bytes underlying a typed data object.
+///
+/// Used to process large quantities of binary or numerical data
+/// more efficiently using a typed view.
abstract class ByteBuffer {
- /**
- * Returns the length of this byte buffer, in bytes.
- */
+ /// Returns the length of this byte buffer, in bytes.
int get lengthInBytes;
- /**
- * Creates a [Uint8List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Uint8List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes] and contains [length] bytes.
- * If [length] is omitted, the range extends to the end of the buffer.
- *
- * The start index and length must describe a valid range of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `length` must not be negative, and
- * * `offsetInBytes + length` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Uint8List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Uint8List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes] and contains [length] bytes.
+ /// If [length] is omitted, the range extends to the end of the buffer.
+ ///
+ /// The start index and length must describe a valid range of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length` must not be greater than [lengthInBytes].
Uint8List asUint8List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Int8List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Int8List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes] and contains [length] bytes.
- * If [length] is omitted, the range extends to the end of the buffer.
- *
- * The start index and length must describe a valid range of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `length` must not be negative, and
- * * `offsetInBytes + length` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Int8List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Int8List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes] and contains [length] bytes.
+ /// If [length] is omitted, the range extends to the end of the buffer.
+ ///
+ /// The start index and length must describe a valid range of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length` must not be greater than [lengthInBytes].
Int8List asInt8List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Uint8ClampedList] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Uint8ClampedList` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes] and contains [length] bytes.
- * If [length] is omitted, the range extends to the end of the buffer.
- *
- * The start index and length must describe a valid range of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `length` must not be negative, and
- * * `offsetInBytes + length` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Uint8ClampedList] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Uint8ClampedList` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes] and contains [length] bytes.
+ /// If [length] is omitted, the range extends to the end of the buffer.
+ ///
+ /// The start index and length must describe a valid range of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length` must not be greater than [lengthInBytes].
Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Uint16List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Uint16List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
- * and contains [length] 16-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not even, the last byte can't be part of the view.
- *
- * The start index and length must describe a valid 16-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by two,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Uint16List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Uint16List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 16-bit aligned,
+ /// and contains [length] 16-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not even, the last byte can't be part of the view.
+ ///
+ /// The start index and length must describe a valid 16-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by two,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
Uint16List asUint16List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Int16List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Int16List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
- * and contains [length] 16-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not even, the last byte can't be part of the view.
- *
- * The start index and length must describe a valid 16-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by two,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Int16List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Int16List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 16-bit aligned,
+ /// and contains [length] 16-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not even, the last byte can't be part of the view.
+ ///
+ /// The start index and length must describe a valid 16-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by two,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
Int16List asInt16List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Uint32List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Uint32List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
- * and contains [length] 32-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by four, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 32-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by four,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Uint32List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Uint32List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+ /// and contains [length] 32-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by four, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 32-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by four,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
Uint32List asUint32List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Int32List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Int32List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
- * and contains [length] 32-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by four, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 32-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by four,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Int32List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Int32List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+ /// and contains [length] 32-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by four, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 32-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by four,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
Int32List asInt32List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Uint64List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Uint64List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
- * and contains [length] 64-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 64-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by eight,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Uint64List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Uint64List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+ /// and contains [length] 64-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 64-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by eight,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
Uint64List asUint64List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Int64List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Int64List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
- * and contains [length] 64-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 64-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by eight,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Int64List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Int64List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+ /// and contains [length] 64-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 64-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by eight,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
Int64List asInt64List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Int32x4List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Int32x4List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
- * and contains [length] 128-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 128-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by sixteen,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Int32x4List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Int32x4List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+ /// and contains [length] 128-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 128-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by sixteen,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Float32List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Float32List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
- * and contains [length] 32-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by four, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 32-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by four,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Float32List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Float32List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 32-bit aligned,
+ /// and contains [length] 32-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by four, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 32-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by four,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
Float32List asFloat32List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Float64List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Float64List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
- * and contains [length] 64-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 64-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by eight,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Float64List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Float64List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 64-bit aligned,
+ /// and contains [length] 64-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by eight, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 64-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by eight,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
Float64List asFloat64List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Float32x4List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Float32x4List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
- * and contains [length] 128-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 128-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by sixteen,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Float32x4List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Float32x4List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+ /// and contains [length] 128-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 128-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by sixteen,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [Float64x2List] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `Float64x2List` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
- * and contains [length] 128-bit integers.
- * If [length] is omitted, the range extends as far towards the end of
- * the buffer as possible -
- * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
- * of the view.
- *
- * The start index and length must describe a valid 128-bit aligned range
- * of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `offsetInBytes` must be divisible by sixteen,
- * * `length` must not be negative, and
- * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
- */
+ /// Creates a [Float64x2List] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `Float64x2List` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes], which must be 128-bit aligned,
+ /// and contains [length] 128-bit integers.
+ /// If [length] is omitted, the range extends as far towards the end of
+ /// the buffer as possible -
+ /// if [lengthInBytes] is not divisible by 16, the last bytes can't be part
+ /// of the view.
+ ///
+ /// The start index and length must describe a valid 128-bit aligned range
+ /// of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `offsetInBytes` must be divisible by sixteen,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]);
- /**
- * Creates a [ByteData] _view_ of a region of this byte buffer.
- *
- * The view is backed by the bytes of this byte buffer.
- * Any changes made to the `ByteData` will also change the buffer,
- * and vice versa.
- *
- * The viewed region start at [offsetInBytes] and contains [length] bytes.
- * If [length] is omitted, the range extends to the end of the buffer.
- *
- * The start index and length must describe a valid range of the buffer:
- *
- * * `offsetInBytes` must not be negative,
- * * `length` must not be negative, and
- * * `offsetInBytes + length` must not be greater than [lengthInBytes].
- */
+ /// Creates a [ByteData] _view_ of a region of this byte buffer.
+ ///
+ /// The view is backed by the bytes of this byte buffer.
+ /// Any changes made to the `ByteData` will also change the buffer,
+ /// and vice versa.
+ ///
+ /// The viewed region start at [offsetInBytes] and contains [length] bytes.
+ /// If [length] is omitted, the range extends to the end of the buffer.
+ ///
+ /// The start index and length must describe a valid range of the buffer:
+ ///
+ /// * `offsetInBytes` must not be negative,
+ /// * `length` must not be negative, and
+ /// * `offsetInBytes + length` must not be greater than [lengthInBytes].
ByteData asByteData([int offsetInBytes = 0, int? length]);
}
-/**
- * A typed view of a sequence of bytes.
- */
+/// A typed view of a sequence of bytes.
abstract class TypedData {
- /**
- * Returns the number of bytes in the representation of each element in this
- * list.
- */
+ /// Returns the number of bytes in the representation of each element in this
+ /// list.
int get elementSizeInBytes;
- /**
- * Returns the offset in bytes into the underlying byte buffer of this view.
- */
+ /// Returns the offset in bytes into the underlying byte buffer of this view.
int get offsetInBytes;
- /**
- * Returns the length of this view, in bytes.
- */
+ /// Returns the length of this view, in bytes.
int get lengthInBytes;
- /**
- * Returns the byte buffer associated with this object.
- */
+ /// Returns the byte buffer associated with this object.
ByteBuffer get buffer;
}
abstract class _TypedIntList extends TypedData {
- /**
- * Returns the concatenation of this list and [other].
- *
- * If other is also a typed-data integer list, the returned list will
- * be a type-data integer list capable of containing all the elements of
- * this list and of [other].
- * Otherwise the returned list will be a normal growable `List<int>`.
- */
+ /// Returns the concatenation of this list and [other].
+ ///
+ /// If other is also a typed-data integer list, the returned list will
+ /// be a type-data integer list capable of containing all the elements of
+ /// this list and of [other].
+ /// Otherwise the returned list will be a normal growable `List<int>`.
List<int> operator +(List<int> other);
}
abstract class _TypedFloatList extends TypedData {
- /**
- * Returns the concatenation of this list and [other].
- *
- * If other is also a typed-data floating point number list,
- * the returned list will be a type-data float list capable of containing
- * all the elements of this list and of [other].
- * Otherwise the returned list will be a normal growable `List<double>`.
- */
+ /// Returns the concatenation of this list and [other].
+ ///
+ /// If other is also a typed-data floating point number list,
+ /// the returned list will be a type-data float list capable of containing
+ /// all the elements of this list and of [other].
+ /// Otherwise the returned list will be a normal growable `List<double>`.
List<double> operator +(List<double> other);
}
-/**
- * Describes endianness to be used when accessing or updating a
- * sequence of bytes.
- */
+/// Describes endianness to be used when accessing or updating a
+/// sequence of bytes.
class Endian {
final bool _littleEndian;
const Endian._(this._littleEndian);
@@ -431,102 +381,94 @@
: big;
}
-/**
- * A fixed-length, random-access sequence of bytes that also provides random
- * and unaligned access to the fixed-width integers and floating point
- * numbers represented by those bytes.
- *
- * `ByteData` may be used to pack and unpack data from external sources
- * (such as networks or files systems), and to process large quantities
- * of numerical data more efficiently than would be possible
- * with ordinary [List] implementations.
- * `ByteData` can save space, by eliminating the need for object headers,
- * and time, by eliminating the need for data copies.
- *
- * If data comes in as bytes, they can be converted to `ByteData` by
- * sharing the same buffer.
- * ```dart
- * Uint8List bytes = ...;
- * var blob = ByteData.sublistView(bytes);
- * if (blob.getUint32(0, Endian.little) == 0x04034b50) { // Zip file marker
- * ...
- * }
- *
- * ```
- *
- * Finally, `ByteData` may be used to intentionally reinterpret the bytes
- * representing one arithmetic type as another.
- * For example this code fragment determine what 32-bit signed integer
- * is represented by the bytes of a 32-bit floating point number
- * (both stored as big endian):
- * ```dart
- * var bdata = new ByteData(8);
- * bdata.setFloat32(0, 3.04);
- * int huh = bdata.getInt32(0); // 0x40428f5c
- * ```
- */
+/// A fixed-length, random-access sequence of bytes that also provides random
+/// and unaligned access to the fixed-width integers and floating point
+/// numbers represented by those bytes.
+///
+/// `ByteData` may be used to pack and unpack data from external sources
+/// (such as networks or files systems), and to process large quantities
+/// of numerical data more efficiently than would be possible
+/// with ordinary [List] implementations.
+/// `ByteData` can save space, by eliminating the need for object headers,
+/// and time, by eliminating the need for data copies.
+///
+/// If data comes in as bytes, they can be converted to `ByteData` by
+/// sharing the same buffer.
+/// ```dart
+/// Uint8List bytes = ...;
+/// var blob = ByteData.sublistView(bytes);
+/// if (blob.getUint32(0, Endian.little) == 0x04034b50) { // Zip file marker
+/// ...
+/// }
+///
+/// ```
+///
+/// Finally, `ByteData` may be used to intentionally reinterpret the bytes
+/// representing one arithmetic type as another.
+/// For example this code fragment determine what 32-bit signed integer
+/// is represented by the bytes of a 32-bit floating point number
+/// (both stored as big endian):
+/// ```dart
+/// var bdata = ByteData(8);
+/// bdata.setFloat32(0, 3.04);
+/// int huh = bdata.getInt32(0); // 0x40428f5c
+/// ```
abstract class ByteData implements TypedData {
- /**
- * Creates a [ByteData] of the specified length (in elements), all of
- * whose bytes are initially zero.
- */
+ /// Creates a [ByteData] of the specified length (in elements), all of
+ /// whose bytes are initially zero.
@pragma("vm:entry-point")
external factory ByteData(int length);
- /**
- * Creates an [ByteData] _view_ of the specified region in [buffer].
- *
- * Changes in the [ByteData] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `ByteData.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * ByteData.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [ByteData.sublistView]
- * which includes this computation:
- * ```dart
- * ByteData.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [ByteData] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [ByteData] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + [length] must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `ByteData.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// ByteData.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [ByteData.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// ByteData.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory ByteData.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asByteData(offsetInBytes, length);
}
- /**
- * Creates a [ByteData] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- */
+ /// Creates a [ByteData] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
@Since("2.8")
factory ByteData.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -538,341 +480,291 @@
data.offsetInBytes + start * elementSize, (end - start) * elementSize);
}
- /**
- * Returns the (possibly negative) integer represented by the byte at the
- * specified [byteOffset] in this object, in two's complement binary
- * representation.
- *
- * The return value will be between -128 and 127, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * less than the length of this object.
- */
+ /// Returns the (possibly negative) integer represented by the byte at the
+ /// specified [byteOffset] in this object, in two's complement binary
+ /// representation.
+ ///
+ /// The return value will be between -128 and 127, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// less than the length of this object.
int getInt8(int byteOffset);
- /**
- * Sets the byte at the specified [byteOffset] in this object to the
- * two's complement binary representation of the specified [value], which
- * must fit in a single byte.
- *
- * In other words, [value] must be between -128 and 127, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * less than the length of this object.
- */
+ /// Sets the byte at the specified [byteOffset] in this object to the
+ /// two's complement binary representation of the specified [value], which
+ /// must fit in a single byte.
+ ///
+ /// In other words, [value] must be between -128 and 127, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// less than the length of this object.
void setInt8(int byteOffset, int value);
- /**
- * Returns the positive integer represented by the byte at the specified
- * [byteOffset] in this object, in unsigned binary form.
- *
- * The return value will be between 0 and 255, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * less than the length of this object.
- */
+ /// Returns the positive integer represented by the byte at the specified
+ /// [byteOffset] in this object, in unsigned binary form.
+ ///
+ /// The return value will be between 0 and 255, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// less than the length of this object.
int getUint8(int byteOffset);
- /**
- * Sets the byte at the specified [byteOffset] in this object to the
- * unsigned binary representation of the specified [value], which must fit
- * in a single byte.
- *
- * In other words, [value] must be between 0 and 255, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * less than the length of this object.
- */
+ /// Sets the byte at the specified [byteOffset] in this object to the
+ /// unsigned binary representation of the specified [value], which must fit
+ /// in a single byte.
+ ///
+ /// In other words, [value] must be between 0 and 255, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// less than the length of this object.
void setUint8(int byteOffset, int value);
- /**
- * Returns the (possibly negative) integer represented by the two bytes at
- * the specified [byteOffset] in this object, in two's complement binary
- * form.
- *
- * The return value will be between -2<sup>15</sup> and 2<sup>15</sup> - 1,
- * inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 2` must be less than or equal to the length of this object.
- */
+ /// Returns the (possibly negative) integer represented by the two bytes at
+ /// the specified [byteOffset] in this object, in two's complement binary
+ /// form.
+ ///
+ /// The return value will be between -2<sup>15</sup> and 2<sup>15</sup> - 1,
+ /// inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 2` must be less than or equal to the length of this object.
int getInt16(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the two bytes starting at the specified [byteOffset] in this
- * object to the two's complement binary representation of the specified
- * [value], which must fit in two bytes.
- *
- * In other words, [value] must lie
- * between -2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 2` must be less than or equal to the length of this object.
- */
+ /// Sets the two bytes starting at the specified [byteOffset] in this
+ /// object to the two's complement binary representation of the specified
+ /// [value], which must fit in two bytes.
+ ///
+ /// In other words, [value] must lie
+ /// between -2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 2` must be less than or equal to the length of this object.
void setInt16(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the positive integer represented by the two bytes starting
- * at the specified [byteOffset] in this object, in unsigned binary
- * form.
- *
- * The return value will be between 0 and 2<sup>16</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 2` must be less than or equal to the length of this object.
- */
+ /// Returns the positive integer represented by the two bytes starting
+ /// at the specified [byteOffset] in this object, in unsigned binary
+ /// form.
+ ///
+ /// The return value will be between 0 and 2<sup>16</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 2` must be less than or equal to the length of this object.
int getUint16(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the two bytes starting at the specified [byteOffset] in this object
- * to the unsigned binary representation of the specified [value],
- * which must fit in two bytes.
- *
- * In other words, [value] must be between
- * 0 and 2<sup>16</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 2` must be less than or equal to the length of this object.
- */
+ /// Sets the two bytes starting at the specified [byteOffset] in this object
+ /// to the unsigned binary representation of the specified [value],
+ /// which must fit in two bytes.
+ ///
+ /// In other words, [value] must be between
+ /// 0 and 2<sup>16</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 2` must be less than or equal to the length of this object.
void setUint16(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the (possibly negative) integer represented by the four bytes at
- * the specified [byteOffset] in this object, in two's complement binary
- * form.
- *
- * The return value will be between -2<sup>31</sup> and 2<sup>31</sup> - 1,
- * inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Returns the (possibly negative) integer represented by the four bytes at
+ /// the specified [byteOffset] in this object, in two's complement binary
+ /// form.
+ ///
+ /// The return value will be between -2<sup>31</sup> and 2<sup>31</sup> - 1,
+ /// inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
int getInt32(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the four bytes starting at the specified [byteOffset] in this
- * object to the two's complement binary representation of the specified
- * [value], which must fit in four bytes.
- *
- * In other words, [value] must lie
- * between -2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Sets the four bytes starting at the specified [byteOffset] in this
+ /// object to the two's complement binary representation of the specified
+ /// [value], which must fit in four bytes.
+ ///
+ /// In other words, [value] must lie
+ /// between -2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
void setInt32(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the positive integer represented by the four bytes starting
- * at the specified [byteOffset] in this object, in unsigned binary
- * form.
- *
- * The return value will be between 0 and 2<sup>32</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Returns the positive integer represented by the four bytes starting
+ /// at the specified [byteOffset] in this object, in unsigned binary
+ /// form.
+ ///
+ /// The return value will be between 0 and 2<sup>32</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
int getUint32(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the four bytes starting at the specified [byteOffset] in this object
- * to the unsigned binary representation of the specified [value],
- * which must fit in four bytes.
- *
- * In other words, [value] must be between
- * 0 and 2<sup>32</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Sets the four bytes starting at the specified [byteOffset] in this object
+ /// to the unsigned binary representation of the specified [value],
+ /// which must fit in four bytes.
+ ///
+ /// In other words, [value] must be between
+ /// 0 and 2<sup>32</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
void setUint32(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the (possibly negative) integer represented by the eight bytes at
- * the specified [byteOffset] in this object, in two's complement binary
- * form.
- *
- * The return value will be between -2<sup>63</sup> and 2<sup>63</sup> - 1,
- * inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Returns the (possibly negative) integer represented by the eight bytes at
+ /// the specified [byteOffset] in this object, in two's complement binary
+ /// form.
+ ///
+ /// The return value will be between -2<sup>63</sup> and 2<sup>63</sup> - 1,
+ /// inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
int getInt64(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the eight bytes starting at the specified [byteOffset] in this
- * object to the two's complement binary representation of the specified
- * [value], which must fit in eight bytes.
- *
- * In other words, [value] must lie
- * between -2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Sets the eight bytes starting at the specified [byteOffset] in this
+ /// object to the two's complement binary representation of the specified
+ /// [value], which must fit in eight bytes.
+ ///
+ /// In other words, [value] must lie
+ /// between -2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
void setInt64(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the positive integer represented by the eight bytes starting
- * at the specified [byteOffset] in this object, in unsigned binary
- * form.
- *
- * The return value will be between 0 and 2<sup>64</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Returns the positive integer represented by the eight bytes starting
+ /// at the specified [byteOffset] in this object, in unsigned binary
+ /// form.
+ ///
+ /// The return value will be between 0 and 2<sup>64</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
int getUint64(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the eight bytes starting at the specified [byteOffset] in this object
- * to the unsigned binary representation of the specified [value],
- * which must fit in eight bytes.
- *
- * In other words, [value] must be between
- * 0 and 2<sup>64</sup> - 1, inclusive.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Sets the eight bytes starting at the specified [byteOffset] in this object
+ /// to the unsigned binary representation of the specified [value],
+ /// which must fit in eight bytes.
+ ///
+ /// In other words, [value] must be between
+ /// 0 and 2<sup>64</sup> - 1, inclusive.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
void setUint64(int byteOffset, int value, [Endian endian = Endian.big]);
- /**
- * Returns the floating point number represented by the four bytes at
- * the specified [byteOffset] in this object, in IEEE 754
- * single-precision binary floating-point format (binary32).
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Returns the floating point number represented by the four bytes at
+ /// the specified [byteOffset] in this object, in IEEE 754
+ /// single-precision binary floating-point format (binary32).
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
double getFloat32(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the four bytes starting at the specified [byteOffset] in this
- * object to the IEEE 754 single-precision binary floating-point
- * (binary32) representation of the specified [value].
- *
- * **Note that this method can lose precision.** The input [value] is
- * a 64-bit floating point value, which will be converted to 32-bit
- * floating point value by IEEE 754 rounding rules before it is stored.
- * If [value] cannot be represented exactly as a binary32, it will be
- * converted to the nearest binary32 value. If two binary32 values are
- * equally close, the one whose least significant bit is zero will be used.
- * Note that finite (but large) values can be converted to infinity, and
- * small non-zero values can be converted to zero.
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 4` must be less than or equal to the length of this object.
- */
+ /// Sets the four bytes starting at the specified [byteOffset] in this
+ /// object to the IEEE 754 single-precision binary floating-point
+ /// (binary32) representation of the specified [value].
+ ///
+ /// **Note that this method can lose precision.** The input [value] is
+ /// a 64-bit floating point value, which will be converted to 32-bit
+ /// floating point value by IEEE 754 rounding rules before it is stored.
+ /// If [value] cannot be represented exactly as a binary32, it will be
+ /// converted to the nearest binary32 value. If two binary32 values are
+ /// equally close, the one whose least significant bit is zero will be used.
+ /// Note that finite (but large) values can be converted to infinity, and
+ /// small non-zero values can be converted to zero.
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 4` must be less than or equal to the length of this object.
void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]);
- /**
- * Returns the floating point number represented by the eight bytes at
- * the specified [byteOffset] in this object, in IEEE 754
- * double-precision binary floating-point format (binary64).
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Returns the floating point number represented by the eight bytes at
+ /// the specified [byteOffset] in this object, in IEEE 754
+ /// double-precision binary floating-point format (binary64).
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
double getFloat64(int byteOffset, [Endian endian = Endian.big]);
- /**
- * Sets the eight bytes starting at the specified [byteOffset] in this
- * object to the IEEE 754 double-precision binary floating-point
- * (binary64) representation of the specified [value].
- *
- * The [byteOffset] must be non-negative, and
- * `byteOffset + 8` must be less than or equal to the length of this object.
- */
+ /// Sets the eight bytes starting at the specified [byteOffset] in this
+ /// object to the IEEE 754 double-precision binary floating-point
+ /// (binary64) representation of the specified [value].
+ ///
+ /// The [byteOffset] must be non-negative, and
+ /// `byteOffset + 8` must be less than or equal to the length of this object.
void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]);
}
-/**
- * A fixed-length list of 8-bit signed integers.
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low eight bits,
- * interpreted as a signed 8-bit two's complement integer with values in the
- * range -128 to +127.
- */
+/// A fixed-length list of 8-bit signed integers.
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low eight bits,
+/// interpreted as a signed 8-bit two's complement integer with values in the
+/// range -128 to +127.
abstract class Int8List implements List<int>, _TypedIntList {
- /**
- * Creates an [Int8List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
- */
+ /// Creates an [Int8List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely [length] bytes.
external factory Int8List(int length);
- /**
- * Creates a [Int8List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely `elements.length`
- * bytes.
- */
+ /// Creates a [Int8List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely `elements.length`
+ /// bytes.
external factory Int8List.fromList(List<int> elements);
- /**
- * Creates an [Int8List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Int8List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Int8List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Int8List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Int8List.sublistView]
- * which includes this computation:
- * ```dart
- * Int8List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [Int8List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Int8List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Int8List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Int8List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Int8List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Int8List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Int8List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asInt8List(offsetInBytes, length);
}
- /**
- * Creates an [Int8List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- */
+ /// Creates an [Int8List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
@Since("2.8")
factory Int8List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -883,119 +775,107 @@
data.offsetInBytes + start * elementSize, (end - start) * elementSize);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is an `Int8List` containing the elements of this list at
- * positions greater than or equal to [start] and less than [end] in the same
- * order as they occur in this list.
- *
- * ```dart
- * var numbers = Int8List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Int8List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is an `Int8List` containing the elements of this list at
+ /// positions greater than or equal to [start] and less than [end] in the same
+ /// order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Int8List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Int8List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Int8List sublist(int start, [int? end]);
static const int bytesPerElement = 1;
}
-/**
- * A fixed-length list of 8-bit unsigned integers.
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low eight bits,
- * interpreted as an unsigned 8-bit integer with values in the
- * range 0 to 255.
- */
+/// A fixed-length list of 8-bit unsigned integers.
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low eight bits,
+/// interpreted as an unsigned 8-bit integer with values in the
+/// range 0 to 255.
abstract class Uint8List implements List<int>, _TypedIntList {
- /**
- * Creates a [Uint8List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
- */
+ /// Creates a [Uint8List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely [length] bytes.
external factory Uint8List(int length);
- /**
- * Creates a [Uint8List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely `elements.length`
- * bytes.
- */
+ /// Creates a [Uint8List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely `elements.length`
+ /// bytes.
external factory Uint8List.fromList(List<int> elements);
- /**
- * Creates a [Uint8List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Uint8List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Uint8List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Uint8List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Uint8List.sublistView]
- * which includes this computation:
- * ```dart
- * Uint8List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Uint8List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Uint8List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Uint8List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Uint8List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Uint8List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Uint8List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Uint8List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asUint8List(offsetInBytes, length);
}
- /**
- * Creates a [Uint8List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- */
+ /// Creates a [Uint8List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
@Since("2.8")
factory Uint8List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1006,129 +886,115 @@
data.offsetInBytes + start * elementSize, (end - start) * elementSize);
}
- /**
- * Returns a concatenation of this list and [other].
- *
- * If [other] is also a typed-data list, then the return list will be a
- * typed data list capable of holding both unsigned 8-bit integers and
- * the elements of [other], otherwise it'll be a normal list of integers.
- */
+ /// Returns a concatenation of this list and [other].
+ ///
+ /// If [other] is also a typed-data list, then the return list will be a
+ /// typed data list capable of holding both unsigned 8-bit integers and
+ /// the elements of [other], otherwise it'll be a normal list of integers.
List<int> operator +(List<int> other);
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Uint8List` containing the elements of this list at
- * positions greater than or equal to [start] and less than [end] in the same
- * order as they occur in this list.
- *
- * ```dart
- * var numbers = Uint8List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Uint8List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Uint8List` containing the elements of this list at
+ /// positions greater than or equal to [start] and less than [end] in the same
+ /// order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Uint8List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Uint8List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Uint8List sublist(int start, [int? end]);
static const int bytesPerElement = 1;
}
-/**
- * A fixed-length list of 8-bit unsigned integers.
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are clamped to an unsigned eight bit value.
- * That is, all values below zero are stored as zero
- * and all values above 255 are stored as 255.
- */
+/// A fixed-length list of 8-bit unsigned integers.
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are clamped to an unsigned eight bit value.
+/// That is, all values below zero are stored as zero
+/// and all values above 255 are stored as 255.
abstract class Uint8ClampedList implements List<int>, _TypedIntList {
- /**
- * Creates a [Uint8ClampedList] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
- */
+ /// Creates a [Uint8ClampedList] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely [length] bytes.
external factory Uint8ClampedList(int length);
- /**
- * Creates a [Uint8ClampedList] of the same size as the [elements]
- * list and copies over the values clamping when needed.
- *
- * Values are clamped to fit in the list when they are copied,
- * the same way storing values clamps them.
- *
- * The list is backed by a [ByteBuffer] containing precisely `elements.length`
- * bytes.
- */
+ /// Creates a [Uint8ClampedList] of the same size as the [elements]
+ /// list and copies over the values clamping when needed.
+ ///
+ /// Values are clamped to fit in the list when they are copied,
+ /// the same way storing values clamps them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely `elements.length`
+ /// bytes.
external factory Uint8ClampedList.fromList(List<int> elements);
- /**
- * Creates a [Uint8ClampedList] _view_ of the specified region in the
- * specified byte [buffer].
- *
- * Changes in the [Uint8List] will be visible in the byte buffer
- * and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Uint8ClampedList.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Uint8ClampedList.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Uint8ClampedList.sublistView]
- * which includes this computation:
- * ```dart
- * Uint8ClampedList.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Uint8ClampedList] _view_ of the specified region in the
+ /// specified byte [buffer].
+ ///
+ /// Changes in the [Uint8List] will be visible in the byte buffer
+ /// and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Uint8ClampedList.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Uint8ClampedList.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Uint8ClampedList.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Uint8ClampedList.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Uint8ClampedList.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asUint8ClampedList(offsetInBytes, length);
}
- /**
- * Creates a [Uint8ClampedList] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- */
+ /// Creates a [Uint8ClampedList] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
@Since("2.8")
factory Uint8ClampedList.sublistView(TypedData data,
[int start = 0, int? end]) {
@@ -1140,126 +1006,114 @@
data.offsetInBytes + start * elementSize, (end - start) * elementSize);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Uint8ClampedList` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Uint8ClampedList.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Uint8ClampedList
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Uint8ClampedList` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Uint8ClampedList.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Uint8ClampedList
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Uint8ClampedList sublist(int start, [int? end]);
static const int bytesPerElement = 1;
}
-/**
- * A fixed-length list of 16-bit signed integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 16 bits,
- * interpreted as a signed 16-bit two's complement integer with values in the
- * range -32768 to +32767.
- */
+/// A fixed-length list of 16-bit signed integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 16 bits,
+/// interpreted as a signed 16-bit two's complement integer with values in the
+/// range -32768 to +32767.
abstract class Int16List implements List<int>, _TypedIntList {
- /**
- * Creates an [Int16List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 2 bytes.
- */
+ /// Creates an [Int16List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 2 bytes.
external factory Int16List(int length);
- /**
- * Creates a [Int16List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 2 bytes.
- */
+ /// Creates a [Int16List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 2 bytes.
external factory Int16List.fromList(List<int> elements);
- /**
- * Creates an [Int16List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Int16List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Int16List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Int16List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Int16List.sublistView]
- * which includes this computation:
- * ```dart
- * Int16List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [Int16List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Int16List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Int16List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Int16List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Int16List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Int16List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Int16List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asInt16List(offsetInBytes, length);
}
- /**
- * Creates an [Int16List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of two.
- */
+ /// Creates an [Int16List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of two.
@Since("2.8")
factory Int16List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1275,127 +1129,115 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is an `Int16List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Int16List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Int16List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is an `Int16List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Int16List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Int16List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Int16List sublist(int start, [int? end]);
static const int bytesPerElement = 2;
}
-/**
- * A fixed-length list of 16-bit unsigned integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 16 bits,
- * interpreted as an unsigned 16-bit integer with values in the
- * range 0 to 65535.
- */
+/// A fixed-length list of 16-bit unsigned integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 16 bits,
+/// interpreted as an unsigned 16-bit integer with values in the
+/// range 0 to 65535.
abstract class Uint16List implements List<int>, _TypedIntList {
- /**
- * Creates a [Uint16List] of the specified length (in elements), all
- * of whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 2 bytes.
- */
+ /// Creates a [Uint16List] of the specified length (in elements), all
+ /// of whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 2 bytes.
external factory Uint16List(int length);
- /**
- * Creates a [Uint16List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 2 bytes.
- */
+ /// Creates a [Uint16List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 2 bytes.
external factory Uint16List.fromList(List<int> elements);
- /**
- * Creates a [Uint16List] _view_ of the specified region in
- * the specified byte buffer.
- *
- * Changes in the [Uint16List] will be visible in the byte buffer
- * and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Uint16List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Uint16List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Uint16List.sublistView]
- * which includes this computation:
- * ```dart
- * Uint16List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Uint16List] _view_ of the specified region in
+ /// the specified byte buffer.
+ ///
+ /// Changes in the [Uint16List] will be visible in the byte buffer
+ /// and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Uint16List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Uint16List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Uint16List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Uint16List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Uint16List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asUint16List(offsetInBytes, length);
}
- /**
- * Creates a [Uint16List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of two.
- */
+ /// Creates a [Uint16List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of two.
@Since("2.8")
factory Uint16List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1411,126 +1253,114 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Uint16List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Uint16List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Uint16List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Uint16List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Uint16List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Uint16List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Uint16List sublist(int start, [int? end]);
static const int bytesPerElement = 2;
}
-/**
- * A fixed-length list of 32-bit signed integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 32 bits,
- * interpreted as a signed 32-bit two's complement integer with values in the
- * range -2147483648 to 2147483647.
- */
+/// A fixed-length list of 32-bit signed integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 32 bits,
+/// interpreted as a signed 32-bit two's complement integer with values in the
+/// range -2147483648 to 2147483647.
abstract class Int32List implements List<int>, _TypedIntList {
- /**
- * Creates an [Int32List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 4 bytes.
- */
+ /// Creates an [Int32List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 4 bytes.
external factory Int32List(int length);
- /**
- * Creates a [Int32List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 4 bytes.
- */
+ /// Creates a [Int32List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 4 bytes.
external factory Int32List.fromList(List<int> elements);
- /**
- * Creates an [Int32List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Int32List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Int32List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Int32List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Int32List.sublistView]
- * which includes this computation:
- * ```dart
- * Int32List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [Int32List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Int32List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Int32List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Int32List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Int32List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Int32List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Int32List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asInt32List(offsetInBytes, length);
}
- /**
- * Creates an [Int32List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of four.
- */
+ /// Creates an [Int32List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of four.
@Since("2.8")
factory Int32List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1546,127 +1376,115 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is an `Int32List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Int32List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Int32List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is an `Int32List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Int32List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Int32List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Int32List sublist(int start, [int? end]);
static const int bytesPerElement = 4;
}
-/**
- * A fixed-length list of 32-bit unsigned integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 32 bits,
- * interpreted as an unsigned 32-bit integer with values in the
- * range 0 to 4294967295.
- */
+/// A fixed-length list of 32-bit unsigned integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 32 bits,
+/// interpreted as an unsigned 32-bit integer with values in the
+/// range 0 to 4294967295.
abstract class Uint32List implements List<int>, _TypedIntList {
- /**
- * Creates a [Uint32List] of the specified length (in elements), all
- * of whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 4 bytes.
- */
+ /// Creates a [Uint32List] of the specified length (in elements), all
+ /// of whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 4 bytes.
external factory Uint32List(int length);
- /**
- * Creates a [Uint32List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 4 bytes.
- */
+ /// Creates a [Uint32List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 4 bytes.
external factory Uint32List.fromList(List<int> elements);
- /**
- * Creates a [Uint32List] _view_ of the specified region in
- * the specified byte buffer.
- *
- * Changes in the [Uint32List] will be visible in the byte buffer
- * and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Uint32List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Uint32List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Uint32List.sublistView]
- * which includes this computation:
- * ```dart
- * Uint32List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Uint32List] _view_ of the specified region in
+ /// the specified byte buffer.
+ ///
+ /// Changes in the [Uint32List] will be visible in the byte buffer
+ /// and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Uint32List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Uint32List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Uint32List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Uint32List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Uint32List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asUint32List(offsetInBytes, length);
}
- /**
- * Creates a [Uint32List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of four.
- */
+ /// Creates a [Uint32List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of four.
@Since("2.8")
factory Uint32List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1682,126 +1500,114 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Uint32List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Uint32List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Uint32List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Uint32List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Uint32List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Uint32List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Uint32List sublist(int start, [int? end]);
static const int bytesPerElement = 4;
}
-/**
- * A fixed-length list of 64-bit signed integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 64 bits,
- * interpreted as a signed 64-bit two's complement integer with values in the
- * range -9223372036854775808 to +9223372036854775807.
- */
+/// A fixed-length list of 64-bit signed integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 64 bits,
+/// interpreted as a signed 64-bit two's complement integer with values in the
+/// range -9223372036854775808 to +9223372036854775807.
abstract class Int64List implements List<int>, _TypedIntList {
- /**
- * Creates an [Int64List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 8 bytes.
- */
+ /// Creates an [Int64List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 8 bytes.
external factory Int64List(int length);
- /**
- * Creates a [Int64List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 8 bytes.
- */
+ /// Creates a [Int64List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 8 bytes.
external factory Int64List.fromList(List<int> elements);
- /**
- * Creates an [Int64List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Int64List] will be visible in the byte buffer
- * and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Int64List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Int64List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Int64List.sublistView]
- * which includes this computation:
- * ```dart
- * Int64List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [Int64List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Int64List] will be visible in the byte buffer
+ /// and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Int64List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Int64List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Int64List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Int64List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Int64List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asInt64List(offsetInBytes, length);
}
- /**
- * Creates an [Int64List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of eight.
- */
+ /// Creates an [Int64List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of eight.
@Since("2.8")
factory Int64List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1817,127 +1623,115 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is an `Int64List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Int64List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Int64List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is an `Int64List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Int64List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Int64List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Int64List sublist(int start, [int? end]);
static const int bytesPerElement = 8;
}
-/**
- * A fixed-length list of 64-bit unsigned integers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation can be considerably
- * more space- and time-efficient than the default [List] implementation.
- *
- * Integers stored in the list are truncated to their low 64 bits,
- * interpreted as an unsigned 64-bit integer with values in the
- * range 0 to 18446744073709551615.
- */
+/// A fixed-length list of 64-bit unsigned integers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation can be considerably
+/// more space- and time-efficient than the default [List] implementation.
+///
+/// Integers stored in the list are truncated to their low 64 bits,
+/// interpreted as an unsigned 64-bit integer with values in the
+/// range 0 to 18446744073709551615.
abstract class Uint64List implements List<int>, _TypedIntList {
- /**
- * Creates a [Uint64List] of the specified length (in elements), all
- * of whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 8 bytes.
- */
+ /// Creates a [Uint64List] of the specified length (in elements), all
+ /// of whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 8 bytes.
external factory Uint64List(int length);
- /**
- * Creates a [Uint64List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 8 bytes.
- */
+ /// Creates a [Uint64List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 8 bytes.
external factory Uint64List.fromList(List<int> elements);
- /**
- * Creates an [Uint64List] _view_ of the specified region in
- * the specified byte buffer.
- *
- * Changes in the [Uint64List] will be visible in the byte buffer
- * and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Uint64List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Uint64List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Uint64List.sublistView]
- * which includes this computation:
- * ```dart
- * Uint64List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates an [Uint64List] _view_ of the specified region in
+ /// the specified byte buffer.
+ ///
+ /// Changes in the [Uint64List] will be visible in the byte buffer
+ /// and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Uint64List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Uint64List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Uint64List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Uint64List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Uint64List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asUint64List(offsetInBytes, length);
}
- /**
- * Creates a [Uint64List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of eight.
- */
+ /// Creates a [Uint64List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of eight.
@Since("2.8")
factory Uint64List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -1953,127 +1747,115 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Uint64List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Uint64List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Uint64List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Uint64List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Uint64List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Uint64List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Uint64List sublist(int start, [int? end]);
static const int bytesPerElement = 8;
}
-/**
- * A fixed-length list of IEEE 754 single-precision binary floating-point
- * numbers that is viewable as a [TypedData].
- *
- * For long lists, this
- * implementation can be considerably more space- and time-efficient than
- * the default [List] implementation.
- *
- * Double values stored in the list are converted to the nearest
- * single-precision value. Values read are converted to a double
- * value with the same value.
- */
+/// A fixed-length list of IEEE 754 single-precision binary floating-point
+/// numbers that is viewable as a [TypedData].
+///
+/// For long lists, this
+/// implementation can be considerably more space- and time-efficient than
+/// the default [List] implementation.
+///
+/// Double values stored in the list are converted to the nearest
+/// single-precision value. Values read are converted to a double
+/// value with the same value.
abstract class Float32List implements List<double>, _TypedFloatList {
- /**
- * Creates a [Float32List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 4 bytes.
- */
+ /// Creates a [Float32List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 4 bytes.
external factory Float32List(int length);
- /**
- * Creates a [Float32List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * Values are truncated to fit in the list when they are copied,
- * the same way storing values truncates them.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 4 bytes.
- */
+ /// Creates a [Float32List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// Values are truncated to fit in the list when they are copied,
+ /// the same way storing values truncates them.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 4 bytes.
external factory Float32List.fromList(List<double> elements);
- /**
- * Creates a [Float32List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Float32List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Float32List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Float32List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Float32List.sublistView]
- * which includes this computation:
- * ```dart
- * Float32List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Float32List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Float32List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Float32List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Float32List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Float32List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Float32List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Float32List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asFloat32List(offsetInBytes, length);
}
- /**
- * Creates an [Float32List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of four.
- */
+ /// Creates an [Float32List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of four.
@Since("2.8")
factory Float32List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -2089,120 +1871,108 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Float32List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Float32List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Float32List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Float32List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Float32List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Float32List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Float32List sublist(int start, [int? end]);
static const int bytesPerElement = 4;
}
-/**
- * A fixed-length list of IEEE 754 double-precision binary floating-point
- * numbers that is viewable as a [TypedData].
- *
- * For long lists, this
- * implementation can be considerably more space- and time-efficient than
- * the default [List] implementation.
- */
+/// A fixed-length list of IEEE 754 double-precision binary floating-point
+/// numbers that is viewable as a [TypedData].
+///
+/// For long lists, this
+/// implementation can be considerably more space- and time-efficient than
+/// the default [List] implementation.
abstract class Float64List implements List<double>, _TypedFloatList {
- /**
- * Creates a [Float64List] of the specified length (in elements), all of
- * whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 8 bytes.
- */
+ /// Creates a [Float64List] of the specified length (in elements), all of
+ /// whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 8 bytes.
external factory Float64List(int length);
- /**
- * Creates a [Float64List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 8 bytes.
- */
+ /// Creates a [Float64List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 8 bytes.
external factory Float64List.fromList(List<double> elements);
- /**
- * Creates a [Float64List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Float64List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Float64List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Float64List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Float64List.sublistView]
- * which includes this computation:
- * ```dart
- * Float64List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Float64List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Float64List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Float64List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Float64List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Float64List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Float64List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Float64List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asFloat64List(offsetInBytes, length);
}
- /**
- * Creates a [Float64List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of eight.
- */
+ /// Creates a [Float64List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of eight.
@Since("2.8")
factory Float64List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -2218,119 +1988,107 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Float64List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Float64List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Float64List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Float64List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Float64List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Float64List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Float64List sublist(int start, [int? end]);
static const int bytesPerElement = 8;
}
-/**
- * A fixed-length list of Float32x4 numbers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation will be considerably more
- * space- and time-efficient than the default [List] implementation.
- */
+/// A fixed-length list of Float32x4 numbers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
abstract class Float32x4List implements List<Float32x4>, TypedData {
- /**
- * Creates a [Float32x4List] of the specified length (in elements),
- * all of whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 16 bytes.
- */
+ /// Creates a [Float32x4List] of the specified length (in elements),
+ /// all of whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 16 bytes.
external factory Float32x4List(int length);
- /**
- * Creates a [Float32x4List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 16 bytes.
- */
+ /// Creates a [Float32x4List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 16 bytes.
external factory Float32x4List.fromList(List<Float32x4> elements);
- /**
- * Creates a [Float32x4List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Float32x4List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Float32x4List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Float32x4List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Float32x4List.sublistView]
- * which includes this computation:
- * ```dart
- * Float32x4List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Float32x4List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Float32x4List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Float32x4List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Float32x4List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Float32x4List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Float32x4List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Float32x4List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asFloat32x4List(offsetInBytes, length);
}
- /**
- * Creates a [Float32x4List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of sixteen.
- */
+ /// Creates a [Float32x4List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of sixteen.
@Since("2.8")
factory Float32x4List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -2346,127 +2104,113 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns the concatenation of this list and [other].
- *
- * If [other] is also a [Float32x4List], the result is a new [Float32x4List],
- * otherwise the result is a normal growable `List<Float32x4>`.
- */
+ /// Returns the concatenation of this list and [other].
+ ///
+ /// If [other] is also a [Float32x4List], the result is a new [Float32x4List],
+ /// otherwise the result is a normal growable `List<Float32x4>`.
List<Float32x4> operator +(List<Float32x4> other);
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Float32x4List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Float32x4List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Float32x4List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Float32x4List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Float32x4List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Float32x4List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Float32x4List sublist(int start, [int? end]);
static const int bytesPerElement = 16;
}
-/**
- * A fixed-length list of Int32x4 numbers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation will be considerably more
- * space- and time-efficient than the default [List] implementation.
- */
+/// A fixed-length list of Int32x4 numbers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
abstract class Int32x4List implements List<Int32x4>, TypedData {
- /**
- * Creates a [Int32x4List] of the specified length (in elements),
- * all of whose elements are initially zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 16 bytes.
- */
+ /// Creates a [Int32x4List] of the specified length (in elements),
+ /// all of whose elements are initially zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 16 bytes.
external factory Int32x4List(int length);
- /**
- * Creates a [Int32x4List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 16 bytes.
- */
+ /// Creates a [Int32x4List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 16 bytes.
external factory Int32x4List.fromList(List<Int32x4> elements);
- /**
- * Creates a [Int32x4List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Int32x4List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Int32x4List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Int32x4List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Int32x4List.sublistView]
- * which includes this computation:
- * ```dart
- * Int32x4List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Int32x4List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Int32x4List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Int32x4List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Int32x4List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Int32x4List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Int32x4List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Int32x4List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asInt32x4List(offsetInBytes, length);
}
- /**
- * Creates an [Int32x4List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of sixteen.
- */
+ /// Creates an [Int32x4List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of sixteen.
@Since("2.8")
factory Int32x4List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -2482,135 +2226,119 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns the concatenation of this list and [other].
- *
- * If [other] is also a [Int32x4List], the result is a new [Int32x4List],
- * otherwise the result is a normal growable `List<Int32x4>`.
- */
+ /// Returns the concatenation of this list and [other].
+ ///
+ /// If [other] is also a [Int32x4List], the result is a new [Int32x4List],
+ /// otherwise the result is a normal growable `List<Int32x4>`.
List<Int32x4> operator +(List<Int32x4> other);
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is an `Int32x4list` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Int32x4list.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Int32x4list
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is an `Int32x4list` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Int32x4list.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Int32x4list
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Int32x4List sublist(int start, [int? end]);
static const int bytesPerElement = 16;
}
-/**
- * A fixed-length list of Float64x2 numbers that is viewable as a
- * [TypedData].
- *
- * For long lists, this implementation will be considerably more
- * space- and time-efficient than the default [List] implementation.
- */
+/// A fixed-length list of Float64x2 numbers that is viewable as a
+/// [TypedData].
+///
+/// For long lists, this implementation will be considerably more
+/// space- and time-efficient than the default [List] implementation.
abstract class Float64x2List implements List<Float64x2>, TypedData {
- /**
- * Creates a [Float64x2List] of the specified length (in elements),
- * all of whose elements have all lanes set to zero.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * [length] times 16 bytes.
- */
+ /// Creates a [Float64x2List] of the specified length (in elements),
+ /// all of whose elements have all lanes set to zero.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// [length] times 16 bytes.
external factory Float64x2List(int length);
- /**
- * Creates a [Float64x2List] with the same length as the [elements] list
- * and copies over the elements.
- *
- * The list is backed by a [ByteBuffer] containing precisely
- * `elements.length` times 16 bytes.
- */
+ /// Creates a [Float64x2List] with the same length as the [elements] list
+ /// and copies over the elements.
+ ///
+ /// The list is backed by a [ByteBuffer] containing precisely
+ /// `elements.length` times 16 bytes.
external factory Float64x2List.fromList(List<Float64x2> elements);
- /**
- * Returns the concatenation of this list and [other].
- *
- * If [other] is also a [Float64x2List], the result is a new [Float64x2List],
- * otherwise the result is a normal growable `List<Float64x2>`.
- */
+ /// Returns the concatenation of this list and [other].
+ ///
+ /// If [other] is also a [Float64x2List], the result is a new [Float64x2List],
+ /// otherwise the result is a normal growable `List<Float64x2>`.
List<Float64x2> operator +(List<Float64x2> other);
- /**
- * Creates a [Float64x2List] _view_ of the specified region in [buffer].
- *
- * Changes in the [Float64x2List] will be visible in the byte
- * buffer and vice versa.
- * If the [offsetInBytes] index of the region is not specified,
- * it defaults to zero (the first byte in the byte buffer).
- * If the length is not specified, it defaults to `null`,
- * which indicates that the view extends to the end of the byte buffer.
- *
- * The [offsetInBytes] and [length] must be non-negative, and
- * [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or
- * equal to the length of [buffer].
- *
- * The [offsetInBytes] must be a multiple of [bytesPerElement].
- *
- * Note that when creating a view from a [TypedData] list or byte data,
- * that list or byte data may itself be a view on a larger buffer
- * with a [TypedData.offsetInBytes] greater than zero.
- * Merely doing `Float64x2List.view(other.buffer, 0, count)` may not
- * point to the bytes you intended. Instead you may need to do:
- * ```dart
- * Float64x2List.view(other.buffer, other.offsetInBytes, count)
- * ```
- * Alternatively, use [Float64x2List.sublistView]
- * which includes this computation:
- * ```dart
- * Float64x2List.sublistView(other, 0, count);
- * ```
- * (The third argument is an end index rather than a length, so if
- * you start from a position greater than zero, you need not
- * reduce the count correspondingly).
- */
+ /// Creates a [Float64x2List] _view_ of the specified region in [buffer].
+ ///
+ /// Changes in the [Float64x2List] will be visible in the byte
+ /// buffer and vice versa.
+ /// If the [offsetInBytes] index of the region is not specified,
+ /// it defaults to zero (the first byte in the byte buffer).
+ /// If the length is not provided,
+ /// the view extends to the end of the byte buffer.
+ ///
+ /// The [offsetInBytes] and [length] must be non-negative, and
+ /// [offsetInBytes] + ([length] * [bytesPerElement]) must be less than or
+ /// equal to the length of [buffer].
+ ///
+ /// The [offsetInBytes] must be a multiple of [bytesPerElement].
+ ///
+ /// Note that when creating a view from a [TypedData] list or byte data,
+ /// that list or byte data may itself be a view on a larger buffer
+ /// with a [TypedData.offsetInBytes] greater than zero.
+ /// Merely doing `Float64x2List.view(other.buffer, 0, count)` may not
+ /// point to the bytes you intended. Instead you may need to do:
+ /// ```dart
+ /// Float64x2List.view(other.buffer, other.offsetInBytes, count)
+ /// ```
+ /// Alternatively, use [Float64x2List.sublistView]
+ /// which includes this computation:
+ /// ```dart
+ /// Float64x2List.sublistView(other, 0, count);
+ /// ```
+ /// (The third argument is an end index rather than a length, so if
+ /// you start from a position greater than zero, you need not
+ /// reduce the count correspondingly).
factory Float64x2List.view(ByteBuffer buffer,
[int offsetInBytes = 0, int? length]) {
return buffer.asFloat64x2List(offsetInBytes, length);
}
- /**
- * Creates an [Float64x2List] view on a range of elements of [data].
- *
- * Creates a view on the range of `data.buffer` which corresponds
- * to the elements of [data] from [start] until [end].
- * If [data] is a typed data list, like [Uint16List], then the view is on
- * the bytes of the elements with indices from [start] until [end].
- * If [data] is a [ByteData], it's treated like a list of bytes.
- *
- * If provided, [start] and [end] must satisfy
- *
- * 0 ≤ `start` ≤ `end` ≤ *elementCount*
- *
- * where *elementCount* is the number of elements in [data], which
- * is the same as the [List.length] of a typed data list.
- *
- * If omitted, [start] defaults to zero and [end] to *elementCount*.
- *
- * The start and end indices of the range of bytes being viewed must be
- * multiples of sixteen.
- */
+ /// Creates an [Float64x2List] view on a range of elements of [data].
+ ///
+ /// Creates a view on the range of `data.buffer` which corresponds
+ /// to the elements of [data] from [start] until [end].
+ /// If [data] is a typed data list, like [Uint16List], then the view is on
+ /// the bytes of the elements with indices from [start] until [end].
+ /// If [data] is a [ByteData], it's treated like a list of bytes.
+ ///
+ /// If provided, [start] and [end] must satisfy
+ ///
+ /// 0 ≤ `start` ≤ `end` ≤ *elementCount*
+ ///
+ /// where *elementCount* is the number of elements in [data], which
+ /// is the same as the [List.length] of a typed data list.
+ ///
+ /// If omitted, [start] defaults to zero and [end] to *elementCount*.
+ ///
+ /// The start and end indices of the range of bytes being viewed must be
+ /// multiples of sixteen.
@Since("2.8")
factory Float64x2List.sublistView(TypedData data, [int start = 0, int? end]) {
int elementSize = data.elementSizeInBytes;
@@ -2626,40 +2354,36 @@
byteLength ~/ bytesPerElement);
}
- /**
- * Returns a new list containing the elements between [start] and [end].
- *
- * The new list is a `Float64x2List` containing the elements of this
- * list at positions greater than or equal to [start] and less than [end] in
- * the same order as they occur in this list.
- *
- * ```dart
- * var numbers = Float64x2List.fromList([0, 1, 2, 3, 4]);
- * print(numbers.sublist(1, 3)); // [1, 2]
- * print(numbers.sublist(1, 3).runtimeType); // Float64x2List
- * ```
- *
- * If [end] is omitted, it defaults to the [length] of this list.
- *
- * ```dart
- * print(numbers.sublist(1)); // [1, 2, 3, 4]
- * ```
- *
- * The `start` and `end` positions must satisfy the relations
- * 0 ≤ `start` ≤ `end` ≤ `this.length`
- * If `end` is equal to `start`, then the returned list is empty.
- */
+ /// Returns a new list containing the elements between [start] and [end].
+ ///
+ /// The new list is a `Float64x2List` containing the elements of this
+ /// list at positions greater than or equal to [start] and less than [end] in
+ /// the same order as they occur in this list.
+ ///
+ /// ```dart
+ /// var numbers = Float64x2List.fromList([0, 1, 2, 3, 4]);
+ /// print(numbers.sublist(1, 3)); // [1, 2]
+ /// print(numbers.sublist(1, 3).runtimeType); // Float64x2List
+ /// ```
+ ///
+ /// If [end] is omitted, it defaults to the [length] of this list.
+ ///
+ /// ```dart
+ /// print(numbers.sublist(1)); // [1, 2, 3, 4]
+ /// ```
+ ///
+ /// The `start` and `end` positions must satisfy the relations
+ /// 0 ≤ `start` ≤ `end` ≤ `this.length`
+ /// If `end` is equal to `start`, then the returned list is empty.
Float64x2List sublist(int start, [int? end]);
static const int bytesPerElement = 16;
}
-/**
- * Float32x4 immutable value type and operations.
- *
- * Float32x4 stores 4 32-bit floating point values in "lanes".
- * The lanes are "x", "y", "z", and "w" respectively.
- */
+/// Float32x4 immutable value type and operations.
+///
+/// Float32x4 stores 4 32-bit floating point values in "lanes".
+/// The lanes are "x", "y", "z", and "w" respectively.
abstract class Float32x4 {
external factory Float32x4(double x, double y, double z, double w);
external factory Float32x4.splat(double v);
@@ -3026,12 +2750,10 @@
Float32x4 reciprocalSqrt();
}
-/**
- * Int32x4 and operations.
- *
- * Int32x4 stores 4 32-bit bit-masks in "lanes".
- * The lanes are "x", "y", "z", and "w" respectively.
- */
+/// Int32x4 and operations.
+///
+/// Int32x4 stores 4 32-bit bit-masks in "lanes".
+/// The lanes are "x", "y", "z", and "w" respectively.
abstract class Int32x4 {
external factory Int32x4(int x, int y, int z, int w);
external factory Int32x4.bool(bool x, bool y, bool z, bool w);
@@ -3379,12 +3101,10 @@
Float32x4 select(Float32x4 trueValue, Float32x4 falseValue);
}
-/**
- * Float64x2 immutable value type and operations.
- *
- * Float64x2 stores 2 64-bit floating point values in "lanes".
- * The lanes are "x" and "y" respectively.
- */
+/// Float64x2 immutable value type and operations.
+///
+/// Float64x2 stores 2 64-bit floating point values in "lanes".
+/// The lanes are "x" and "y" respectively.
abstract class Float64x2 {
external factory Float64x2(double x, double y);
external factory Float64x2.splat(double v);
diff --git a/sdk/lib/typed_data/unmodifiable_typed_data.dart b/sdk/lib/typed_data/unmodifiable_typed_data.dart
index 30bdf51..43aaa84 100644
--- a/sdk/lib/typed_data/unmodifiable_typed_data.dart
+++ b/sdk/lib/typed_data/unmodifiable_typed_data.dart
@@ -4,9 +4,7 @@
part of dart.typed_data;
-/**
- * A read-only view of a [ByteBuffer].
- */
+/// A read-only view of a [ByteBuffer].
class UnmodifiableByteBufferView implements ByteBuffer {
final ByteBuffer _data;
@@ -66,9 +64,7 @@
new UnmodifiableByteDataView(_data.asByteData(offsetInBytes, length));
}
-/**
- * A read-only view of a [ByteData].
- */
+/// A read-only view of a [ByteData].
class UnmodifiableByteDataView implements ByteData {
final ByteData _data;
@@ -173,9 +169,7 @@
}
}
-/**
- * View of a [Uint8List] that disallows modification.
- */
+/// View of a [Uint8List] that disallows modification.
class UnmodifiableUint8ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint8List, Uint8List>
implements Uint8List {
@@ -185,9 +179,7 @@
Uint8List _createList(int length) => Uint8List(length);
}
-/**
- * View of a [Int8List] that disallows modification.
- */
+/// View of a [Int8List] that disallows modification.
class UnmodifiableInt8ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int8List, Int8List>
implements Int8List {
@@ -197,9 +189,7 @@
Int8List _createList(int length) => Int8List(length);
}
-/**
- * View of a [Uint8ClampedList] that disallows modification.
- */
+/// View of a [Uint8ClampedList] that disallows modification.
class UnmodifiableUint8ClampedListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint8ClampedList, Uint8ClampedList>
implements Uint8ClampedList {
@@ -209,9 +199,7 @@
Uint8ClampedList _createList(int length) => Uint8ClampedList(length);
}
-/**
- * View of a [Uint16List] that disallows modification.
- */
+/// View of a [Uint16List] that disallows modification.
class UnmodifiableUint16ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint16List, Uint16List>
implements Uint16List {
@@ -221,9 +209,7 @@
Uint16List _createList(int length) => Uint16List(length);
}
-/**
- * View of a [Int16List] that disallows modification.
- */
+/// View of a [Int16List] that disallows modification.
class UnmodifiableInt16ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int16List, Int16List>
implements Int16List {
@@ -233,9 +219,7 @@
Int16List _createList(int length) => Int16List(length);
}
-/**
- * View of a [Uint32List] that disallows modification.
- */
+/// View of a [Uint32List] that disallows modification.
class UnmodifiableUint32ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint32List, Uint32List>
implements Uint32List {
@@ -245,9 +229,7 @@
Uint32List _createList(int length) => Uint32List(length);
}
-/**
- * View of a [Int32List] that disallows modification.
- */
+/// View of a [Int32List] that disallows modification.
class UnmodifiableInt32ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int32List, Int32List>
implements Int32List {
@@ -257,9 +239,7 @@
Int32List _createList(int length) => Int32List(length);
}
-/**
- * View of a [Uint64List] that disallows modification.
- */
+/// View of a [Uint64List] that disallows modification.
class UnmodifiableUint64ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint64List, Uint64List>
implements Uint64List {
@@ -269,9 +249,7 @@
Uint64List _createList(int length) => Uint64List(length);
}
-/**
- * View of a [Int64List] that disallows modification.
- */
+/// View of a [Int64List] that disallows modification.
class UnmodifiableInt64ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int64List, Int64List>
implements Int64List {
@@ -281,9 +259,7 @@
Int64List _createList(int length) => Int64List(length);
}
-/**
- * View of a [Int32x4List] that disallows modification.
- */
+/// View of a [Int32x4List] that disallows modification.
class UnmodifiableInt32x4ListView extends UnmodifiableListBase<Int32x4>
with _UnmodifiableListMixin<Int32x4, Int32x4List, Int32x4List>
implements Int32x4List {
@@ -293,9 +269,7 @@
Int32x4List _createList(int length) => Int32x4List(length);
}
-/**
- * View of a [Float32x4List] that disallows modification.
- */
+/// View of a [Float32x4List] that disallows modification.
class UnmodifiableFloat32x4ListView extends UnmodifiableListBase<Float32x4>
with _UnmodifiableListMixin<Float32x4, Float32x4List, Float32x4List>
implements Float32x4List {
@@ -305,9 +279,7 @@
Float32x4List _createList(int length) => Float32x4List(length);
}
-/**
- * View of a [Float64x2List] that disallows modification.
- */
+/// View of a [Float64x2List] that disallows modification.
class UnmodifiableFloat64x2ListView extends UnmodifiableListBase<Float64x2>
with _UnmodifiableListMixin<Float64x2, Float64x2List, Float64x2List>
implements Float64x2List {
@@ -317,9 +289,7 @@
Float64x2List _createList(int length) => Float64x2List(length);
}
-/**
- * View of a [Float32List] that disallows modification.
- */
+/// View of a [Float32List] that disallows modification.
class UnmodifiableFloat32ListView extends UnmodifiableListBase<double>
with _UnmodifiableListMixin<double, Float32List, Float32List>
implements Float32List {
@@ -329,9 +299,7 @@
Float32List _createList(int length) => Float32List(length);
}
-/**
- * View of a [Float64List] that disallows modification.
- */
+/// View of a [Float64List] that disallows modification.
class UnmodifiableFloat64ListView extends UnmodifiableListBase<double>
with _UnmodifiableListMixin<double, Float64List, Float64List>
implements Float64List {
diff --git a/tests/ffi/aliasing_test.dart b/tests/ffi/aliasing_test.dart
index 6c2f698..946e1e4 100644
--- a/tests/ffi/aliasing_test.dart
+++ b/tests/ffi/aliasing_test.dart
@@ -13,6 +13,7 @@
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'calloc.dart';
import 'ffi_test_helpers.dart';
void main() {
@@ -35,28 +36,28 @@
}
void testNonAlias() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
source.value = 42;
final int a = source.value;
source.value = 1984;
// alias.value should be re-executed, as we wrote to alias.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasCast() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = source.cast<Int8>().cast<Int64>();
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasCast2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = source.cast<Int16>().cast<Int64>();
final alias2 = source.cast<Int8>().cast<Int64>();
alias.value = 42;
@@ -64,22 +65,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasOffsetBy() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final alias = source.offsetBy(8).offsetBy(-8);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasOffsetBy2() {
- final source = allocate<Int64>(count: 3);
+ final source = calloc<Int64>(3);
final alias = source.offsetBy(16).offsetBy(-16);
final alias2 = source.offsetBy(8).offsetBy(-8);
alias.value = 42;
@@ -87,22 +88,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasElementAt() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final alias = source.elementAt(1).elementAt(-1);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasElementAt2() {
- final source = allocate<Int64>(count: 3);
+ final source = calloc<Int64>(3);
final alias = source.elementAt(2).elementAt(-2);
final alias2 = source.elementAt(1).elementAt(-1);
alias.value = 42;
@@ -110,22 +111,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddress() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = Pointer<Int64>.fromAddress(source.address);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddress2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = Pointer<Int64>.fromAddress(source.address);
final alias2 = Pointer<Int64>.fromAddress(source.address);
alias.value = 42;
@@ -133,12 +134,12 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddressViaMemory() {
- final helper = allocate<IntPtr>();
- final source = allocate<Int64>();
+ final helper = calloc<IntPtr>();
+ final source = calloc<Int64>();
helper.value = source.address;
final alias = Pointer<Int64>.fromAddress(helper.value);
source.value = 42;
@@ -146,13 +147,13 @@
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(helper);
- free(source);
+ calloc.free(helper);
+ calloc.free(source);
}
void testAliasFromAddressViaMemory2() {
- final helper = allocate<IntPtr>();
- final source = allocate<Int64>();
+ final helper = calloc<IntPtr>();
+ final source = calloc<Int64>();
helper.value = source.address;
final alias = Pointer<Int64>.fromAddress(helper.value);
final alias2 = Pointer<Int64>.fromAddress(helper.value);
@@ -161,8 +162,8 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(helper);
- free(source);
+ calloc.free(helper);
+ calloc.free(source);
}
typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
@@ -172,7 +173,7 @@
.lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
void testAliasFromAddressViaNativeFunction() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias =
Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
source.value = 42;
@@ -180,11 +181,11 @@
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddressViaNativeFunction2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias =
Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
final alias2 =
@@ -194,7 +195,7 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
@pragma('vm:never-inline')
@@ -202,11 +203,11 @@
source.offsetBy(7).cast<Int8>();
testPartialOverlap() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final derived = makeDerived(source);
source.value = 0x1122334455667788;
final int value = source.value;
derived.value = 0xaa;
Expect.notEquals(value, source.value);
- free(source);
+ calloc.free(source);
}
diff --git a/tests/ffi/allocator_test.dart b/tests/ffi/allocator_test.dart
new file mode 100644
index 0000000..ab2e8db
--- /dev/null
+++ b/tests/ffi/allocator_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, 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.
+
+// Tests that we can implement the Allocator interface.
+
+import 'dart:ffi';
+
+class MyAllocator implements Allocator {
+ const MyAllocator();
+
+ @override
+ Pointer<T> allocate<T extends NativeType>(int numBytes, {int? alignment}) {
+ throw "Not implemented";
+ }
+
+ void free(Pointer pointer) {}
+}
+
+const myAllocator = MyAllocator();
+
+void main() {
+ print(myAllocator);
+}
diff --git a/tests/ffi/calloc.dart b/tests/ffi/calloc.dart
new file mode 100644
index 0000000..e17238a
--- /dev/null
+++ b/tests/ffi/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/tests/ffi/calloc_test.dart b/tests/ffi/calloc_test.dart
new file mode 100644
index 0000000..b8b9bbf
--- /dev/null
+++ b/tests/ffi/calloc_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, 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.
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'calloc.dart';
+import 'coordinate.dart';
+
+void main() {
+ testZeroInt();
+ testZeroFloat();
+ testZeroStruct();
+}
+
+void testZeroInt() {
+ final p = calloc<Uint8>();
+ Expect.equals(0, p.value);
+ calloc.free(p);
+}
+
+void testZeroFloat() {
+ final p = calloc<Float>();
+ Expect.approxEquals(0.0, p.value);
+ calloc.free(p);
+}
+
+void testZeroStruct() {
+ final p = calloc<Coordinate>();
+ Expect.approxEquals(0, p.ref.x);
+ Expect.approxEquals(0, p.ref.y);
+ Expect.equals(nullptr, p.ref.next);
+ calloc.free(p);
+}
diff --git a/tests/ffi/coordinate.dart b/tests/ffi/coordinate.dart
index 9507312..abd6ecd 100644
--- a/tests/ffi/coordinate.dart
+++ b/tests/ffi/coordinate.dart
@@ -17,8 +17,9 @@
external Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/tests/ffi/coordinate_nnbd_workaround.dart b/tests/ffi/coordinate_nnbd_workaround.dart
index 515badd..abd8dba 100644
--- a/tests/ffi/coordinate_nnbd_workaround.dart
+++ b/tests/ffi/coordinate_nnbd_workaround.dart
@@ -20,8 +20,9 @@
external Pointer<Coordinate> get next;
external set next(Pointer<Coordinate> v);
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/tests/ffi/data_not_asan_test.dart b/tests/ffi/data_not_asan_test.dart
index e95658f..69257d6 100644
--- a/tests/ffi/data_not_asan_test.dart
+++ b/tests/ffi/data_not_asan_test.dart
@@ -4,7 +4,7 @@
//
// Dart test program for testing dart:ffi primitive data pointers.
//
-// These mallocs trigger an asan alarm, so these tests are in a separate file
+// These callocs trigger an asan alarm, so these tests are in a separate file
// which is excluded in asan mode.
import 'dart:ffi';
@@ -12,6 +12,8 @@
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'calloc.dart';
+
void main() {
testPointerAllocateTooLarge();
testPointerAllocateNegative();
@@ -20,16 +22,16 @@
void testPointerAllocateTooLarge() {
// Try to allocate something that doesn't fit in 64 bit address space.
int maxInt = 9223372036854775807; // 2^63 - 1
- Expect.throws(() => allocate<Int64>(count: maxInt));
+ Expect.throws(() => calloc<Int64>(maxInt));
// Try to allocate almost the full 64 bit address space.
int maxInt1_8 = 1152921504606846975; // 2^60 -1
- Expect.throws(() => allocate<Int64>(count: maxInt1_8));
+ Expect.throws(() => calloc<Int64>(maxInt1_8));
}
void testPointerAllocateNegative() {
// Passing in -1 will be converted into an unsigned integer. So, it will try
// to allocate SIZE_MAX - 1 + 1 bytes. This will fail as it is the max amount
// of addressable memory on the system.
- Expect.throws(() => allocate<Int8>(count: -1));
+ Expect.throws(() => calloc<Int8>(-1));
}
diff --git a/tests/ffi/data_test.dart b/tests/ffi/data_test.dart
index b2d304d..47b88c5 100644
--- a/tests/ffi/data_test.dart
+++ b/tests/ffi/data_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'ffi_test_helpers.dart';
void main() {
@@ -44,10 +45,8 @@
testTypeTest();
testToString();
testEquality();
- testAllocateGeneric();
testAllocateVoid();
testAllocateNativeFunction();
- testAllocateNativeType();
testSizeOfGeneric();
testSizeOfVoid();
testSizeOfNativeFunction();
@@ -58,66 +57,66 @@
}
void testPointerBasic() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 42;
Expect.equals(42, p.value);
- free(p);
+ calloc.free(p);
}
void testPointerFromPointer() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 1337;
int ptr = p.address;
Pointer<Int64> p2 = Pointer.fromAddress(ptr);
Expect.equals(1337, p2.value);
- free(p);
+ calloc.free(p);
}
void testPointerPointerArithmetic() {
- Pointer<Int64> p = allocate(count: 2);
+ Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p.elementAt(1);
p2.value = 100;
Pointer<Int64> p3 = p.offsetBy(8);
Expect.equals(100, p3.value);
- free(p);
+ calloc.free(p);
}
void testPointerPointerArithmeticSizes() {
- Pointer<Int64> p = allocate(count: 2);
+ Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p.elementAt(1);
int addr = p.address;
Expect.equals(addr + 8, p2.address);
- free(p);
+ calloc.free(p);
- Pointer<Int32> p3 = allocate(count: 2);
+ Pointer<Int32> p3 = calloc(2);
Pointer<Int32> p4 = p3.elementAt(1);
addr = p3.address;
Expect.equals(addr + 4, p4.address);
- free(p3);
+ calloc.free(p3);
}
void testPointerAllocateZero() {
// > If size is 0, either a null pointer or a unique pointer that can be
- // > successfully passed to free() shall be returned.
- // http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
+ // > successfully passed to calloc.free() shall be returned.
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/calloc.html
//
// Null pointer throws a Dart exception.
bool returnedNullPointer = false;
Pointer<Int8> p = nullptr;
try {
- p = allocate<Int8>(count: 0);
+ p = calloc<Int8>(0);
} on Exception {
returnedNullPointer = true;
}
if (!returnedNullPointer) {
- free(p);
+ calloc.free(p);
}
}
void testPointerCast() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.cast<Int32>(); // gets the correct type args back
- free(p);
+ calloc.free(p);
}
void testCastGeneric() {
@@ -125,9 +124,9 @@
return p.cast();
}
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Pointer<Int64> p2 = generic(p);
- free(p);
+ calloc.free(p);
}
void testCastGeneric2() {
@@ -135,41 +134,41 @@
return p.cast();
}
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Pointer<Int64> p2 = generic(p);
- free(p);
+ calloc.free(p);
}
void testCastNativeType() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.cast<Pointer>();
- free(p);
+ calloc.free(p);
}
void testCondensedNumbersInt8() {
- Pointer<Int8> p = allocate(count: 8);
+ Pointer<Int8> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p[i] = i * 3;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
Expect.equals(i * 3, p[i]);
}
- free(p);
+ calloc.free(p);
}
void testCondensedNumbersFloat() {
- Pointer<Float> p = allocate(count: 8);
+ Pointer<Float> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p[i] = 1.511366173271439e-13;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
Expect.equals(1.511366173271439e-13, p[i]);
}
- free(p);
+ calloc.free(p);
}
void testRangeInt8() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 127;
Expect.equals(127, p.value);
p.value = -128;
@@ -184,11 +183,11 @@
Expect.equals(0x000000000000007F, 127);
p.value = -129;
Expect.equals(127, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint8() {
- Pointer<Uint8> p = allocate();
+ Pointer<Uint8> p = calloc();
p.value = 255;
Expect.equals(255, p.value);
p.value = 0;
@@ -203,11 +202,11 @@
Expect.equals(0x00000000000000FF, 255);
p.value = -1;
Expect.equals(255, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt16() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
p.value = 0x7FFF;
Expect.equals(0x7FFF, p.value);
p.value = -0x8000;
@@ -216,11 +215,11 @@
Expect.equals(0xFFFFFFFFFFFF8000, p.value); // truncated and sign extended
p.value = -0x8001;
Expect.equals(0x7FFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint16() {
- Pointer<Uint16> p = allocate();
+ Pointer<Uint16> p = calloc();
p.value = 0xFFFF;
Expect.equals(0xFFFF, p.value);
p.value = 0;
@@ -229,11 +228,11 @@
Expect.equals(0, p.value); // truncated
p.value = -1;
Expect.equals(0xFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt32() {
- Pointer<Int32> p = allocate();
+ Pointer<Int32> p = calloc();
p.value = 0x7FFFFFFF;
Expect.equals(0x7FFFFFFF, p.value);
p.value = -0x80000000;
@@ -242,11 +241,11 @@
Expect.equals(0xFFFFFFFF80000000, p.value); // truncated and sign extended
p.value = -0x80000001;
Expect.equals(0x7FFFFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint32() {
- Pointer<Uint32> p = allocate();
+ Pointer<Uint32> p = calloc();
p.value = 0xFFFFFFFF;
Expect.equals(0xFFFFFFFF, p.value);
p.value = 0;
@@ -255,20 +254,20 @@
Expect.equals(0, p.value); // truncated
p.value = -1;
Expect.equals(0xFFFFFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt64() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.value);
p.value = -0x8000000000000000; // -2 ^ 63
Expect.equals(-0x8000000000000000, p.value);
- free(p);
+ calloc.free(p);
}
void testRangeUint64() {
- Pointer<Uint64> p = allocate();
+ Pointer<Uint64> p = calloc();
p.value = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.value);
p.value = -0x8000000000000000; // -2 ^ 63 interpreted as 2 ^ 63
@@ -279,69 +278,69 @@
p.value = -1; // -1 interpreted as 2 ^ 64 - 1
Expect.equals(-1, p.value);
Expect.equals(0xFFFFFFFFFFFFFFFF, p.value);
- free(p);
+ calloc.free(p);
}
void testRangeIntPtr() {
- Pointer<IntPtr> p = allocate();
+ Pointer<IntPtr> p = calloc();
int pAddr = p.address;
p.value = pAddr; // its own address should fit
p.value = 0x7FFFFFFF; // and 32 bit addresses should fit
Expect.equals(0x7FFFFFFF, p.value);
p.value = -0x80000000;
Expect.equals(-0x80000000, p.value);
- free(p);
+ calloc.free(p);
}
void testFloat() {
- Pointer<Float> p = allocate();
+ Pointer<Float> p = calloc();
p.value = 1.511366173271439e-13;
Expect.equals(1.511366173271439e-13, p.value);
p.value = 1.4260258159703532e-105; // float does not have enough precision
Expect.notEquals(1.4260258159703532e-105, p.value);
- free(p);
+ calloc.free(p);
}
void testDouble() {
- Pointer<Double> p = allocate();
+ Pointer<Double> p = calloc();
p.value = 1.4260258159703532e-105;
Expect.equals(1.4260258159703532e-105, p.value);
- free(p);
+ calloc.free(p);
}
void testVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast(); // make this dart pointer opaque
p2.address; // we can print the address
- free(p2);
+ calloc.free(p2);
}
void testPointerPointer() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
p.value = 17;
- Pointer<Pointer<Int16>> p2 = allocate();
+ Pointer<Pointer<Int16>> p2 = calloc();
p2.value = p;
Expect.equals(17, p2.value.value);
- free(p2);
- free(p);
+ calloc.free(p2);
+ calloc.free(p);
}
void testPointerPointerNull() {
- Pointer<Pointer<Int8>> pointerToPointer = allocate();
+ Pointer<Pointer<Int8>> pointerToPointer = calloc();
Pointer<Int8> value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
- value = allocate();
+ value = calloc();
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.isNotNull(value);
- free(value);
+ calloc.free(value);
value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
- free(pointerToPointer);
+ calloc.free(pointerToPointer);
}
void testSizeOf() {
@@ -365,7 +364,7 @@
head.value = value;
return;
}
- Pointer<IntPtr> next = allocate();
+ Pointer<IntPtr> next = calloc();
head.value = next.address;
createChain(next, length - 1, value);
}
@@ -380,14 +379,14 @@
void freeChain(Pointer<IntPtr> head, int length) {
Pointer<IntPtr> next = Pointer.fromAddress(head.value);
- free(head);
+ calloc.free(head);
if (length == 0) {
return;
}
freeChain(next, length - 1);
}
- Pointer<IntPtr> head = allocate();
+ Pointer<IntPtr> head = calloc();
createChain(head, length, 512);
int tailValue = getChainValue(head, length);
Expect.equals(512, tailValue);
@@ -395,16 +394,16 @@
}
void testTypeTest() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Expect.isTrue(p is Pointer);
- free(p);
+ calloc.free(p);
}
void testToString() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Expect.stringEquals(
"Pointer<Int16>: address=0x", p.toString().substring(0, 26));
- free(p);
+ calloc.free(p);
Pointer<Int64> p2 = Pointer.fromAddress(0x123abc);
Expect.stringEquals("Pointer<Int64>: address=0x123abc", p2.toString());
}
@@ -423,32 +422,15 @@
typedef Int8UnOp = Int8 Function(Int8);
-void testAllocateGeneric() {
- Pointer<T> generic<T extends NativeType>() {
- Pointer<T> pointer;
- pointer = allocate();
- return pointer;
- }
-
- Pointer p = generic<Int64>();
- free(p);
-}
-
void testAllocateVoid() {
Expect.throws(() {
- Pointer<Void> p = allocate();
+ Pointer<Void> p = calloc();
});
}
void testAllocateNativeFunction() {
Expect.throws(() {
- Pointer<NativeFunction<Int8UnOp>> p = allocate();
- });
-}
-
-void testAllocateNativeType() {
- Expect.throws(() {
- allocate();
+ Pointer<NativeFunction<Int8UnOp>> p = calloc();
});
}
@@ -482,7 +464,7 @@
}
void testDynamicInvocation() {
- dynamic p = allocate<Int8>();
+ dynamic p = calloc<Int8>();
Expect.throws(() {
final int i = p.value;
});
@@ -490,7 +472,7 @@
p.elementAt(5); // Works, but is slow.
final int addr = p.address;
final Pointer<Int16> p2 = p.cast<Int16>();
- free(p);
+ calloc.free(p);
}
final nullableInt64ElementAt1 = ffiTestFunctions.lookupFunction<
diff --git a/tests/ffi/extension_methods_test.dart b/tests/ffi/extension_methods_test.dart
index d4e8e4a..5c688e0e 100644
--- a/tests/ffi/extension_methods_test.dart
+++ b/tests/ffi/extension_methods_test.dart
@@ -7,6 +7,8 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
main(List<String> arguments) {
for (int i = 0; i < 100; i++) {
testStoreLoad();
@@ -15,7 +17,7 @@
}
testStoreLoad() {
- final p = allocate<Int8>(count: 2);
+ final p = calloc<Int8>(2);
p.value = 10;
Expect.equals(10, p.value);
p[1] = 20;
@@ -30,33 +32,33 @@
final pUseNegative = p.elementAt(1);
Expect.equals(10, pUseNegative[-1]);
- final p1 = allocate<Double>(count: 2);
+ final p1 = calloc<Double>(2);
p1.value = 10.0;
Expect.approxEquals(10.0, p1.value);
p1[1] = 20.0;
Expect.approxEquals(20.0, p1[1]);
- free(p1);
+ calloc.free(p1);
- final p2 = allocate<Pointer<Int8>>(count: 2);
+ final p2 = calloc<Pointer<Int8>>(2);
p2.value = p;
Expect.equals(p, p2.value);
p2[1] = p;
Expect.equals(p, p2[1]);
- free(p2);
- free(p);
+ calloc.free(p2);
+ calloc.free(p);
- final p3 = allocate<Foo>();
+ final p3 = calloc<Foo>();
Foo foo = p3.ref;
foo.a = 1;
Expect.equals(1, foo.a);
- free(p3);
+ calloc.free(p3);
}
testReifiedGeneric() {
- final p = allocate<Pointer<Int8>>();
+ final p = calloc<Pointer<Int8>>();
Pointer<Pointer<NativeType>> p2 = p;
Expect.isTrue(p2.value is Pointer<Int8>);
- free(p);
+ calloc.free(p);
}
class Foo extends Struct {
diff --git a/tests/ffi/external_typed_data_test.dart b/tests/ffi/external_typed_data_test.dart
index 2b584b4..1327dea 100644
--- a/tests/ffi/external_typed_data_test.dart
+++ b/tests/ffi/external_typed_data_test.dart
@@ -9,6 +9,8 @@
import 'package:expect/expect.dart';
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
main() {
testInt8Load();
testInt8Store();
@@ -41,162 +43,162 @@
void testInt8Load() {
// Load
- Pointer<Int8> ptr = allocate();
+ Pointer<Int8> ptr = calloc();
ptr.value = 0xff;
Int8List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt8Store() {
// Store
- Pointer<Int8> ptr = allocate();
+ Pointer<Int8> ptr = calloc();
Int8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint8Load() {
// Load
- Pointer<Uint8> ptr = allocate();
+ Pointer<Uint8> ptr = calloc();
ptr.value = 0xff;
Uint8List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint8Store() {
// Store
- Pointer<Uint8> ptr = allocate();
+ Pointer<Uint8> ptr = calloc();
Uint8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt16Load() {
// Load
- Pointer<Int16> ptr = allocate();
+ Pointer<Int16> ptr = calloc();
ptr.value = 0xffff;
Int16List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt16Store() {
// Store
- Pointer<Int16> ptr = allocate();
+ Pointer<Int16> ptr = calloc();
Int16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint16Load() {
// Load
- Pointer<Uint16> ptr = allocate();
+ Pointer<Uint16> ptr = calloc();
ptr.value = 0xffff;
Uint16List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint16Store() {
// Store
- Pointer<Uint16> ptr = allocate();
+ Pointer<Uint16> ptr = calloc();
Uint16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt32Load() {
// Load
- Pointer<Int32> ptr = allocate();
+ Pointer<Int32> ptr = calloc();
ptr.value = 0xffffffff;
Int32List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt32Store() {
// Store
- Pointer<Int32> ptr = allocate();
+ Pointer<Int32> ptr = calloc();
Int32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint32Load() {
// Load
- Pointer<Uint32> ptr = allocate();
+ Pointer<Uint32> ptr = calloc();
ptr.value = 0xffffffff;
Uint32List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint32Store() {
// Store
- Pointer<Uint32> ptr = allocate();
+ Pointer<Uint32> ptr = calloc();
Uint32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt64Load() {
// Load
- Pointer<Int64> ptr = allocate();
+ Pointer<Int64> ptr = calloc();
ptr.value = 0xffffffffffffffff;
Int64List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt64Store() {
// Store
- Pointer<Int64> ptr = allocate();
+ Pointer<Int64> ptr = calloc();
Int64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint64Load() {
// Load
- Pointer<Uint64> ptr = allocate();
+ Pointer<Uint64> ptr = calloc();
ptr.value = 0xffffffffffffffff;
Uint64List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffffffffffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint64Store() {
// Store
- Pointer<Uint64> ptr = allocate();
+ Pointer<Uint64> ptr = calloc();
Uint64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffffffffffff);
- free(ptr);
+ calloc.free(ptr);
}
double maxFloat = (2 - pow(2, -23)) * pow(2, 127) as double;
@@ -204,47 +206,47 @@
void testFloatLoad() {
// Load
- Pointer<Float> ptr = allocate();
+ Pointer<Float> ptr = calloc();
ptr.value = maxFloat;
Float32List list = ptr.asTypedList(1);
Expect.equals(list[0], maxFloat);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testFloatStore() {
// Store
- Pointer<Float> ptr = allocate();
+ Pointer<Float> ptr = calloc();
Float32List list = ptr.asTypedList(1);
list[0] = maxFloat;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxFloat);
- free(ptr);
+ calloc.free(ptr);
}
void testDoubleLoad() {
// Load
- Pointer<Double> ptr = allocate();
+ Pointer<Double> ptr = calloc();
ptr.value = maxDouble;
Float64List list = ptr.asTypedList(1);
Expect.equals(list[0], maxDouble);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testDoubleStore() {
// Store
- Pointer<Double> ptr = allocate();
+ Pointer<Double> ptr = calloc();
Float64List list = ptr.asTypedList(1);
list[0] = maxDouble;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxDouble);
- free(ptr);
+ calloc.free(ptr);
}
void testArrayLoad() {
const int count = 0x100;
- Pointer<Int32> ptr = allocate(count: count);
+ Pointer<Int32> ptr = calloc(count);
for (int i = 0; i < count; ++i) {
ptr[i] = i;
}
@@ -252,12 +254,12 @@
for (int i = 0; i < count; ++i) {
Expect.equals(array[i], i);
}
- free(ptr);
+ calloc.free(ptr);
}
void testArrayStore() {
const int count = 0x100;
- Pointer<Int32> ptr = allocate(count: count);
+ Pointer<Int32> ptr = calloc(count);
Int32List array = ptr.asTypedList(count);
for (int i = 0; i < count; ++i) {
array[i] = i;
@@ -265,7 +267,7 @@
for (int i = 0; i < count; ++i) {
Expect.equals(ptr[i], i);
}
- free(ptr);
+ calloc.free(ptr);
}
void testNegativeArray() {
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
index 75ef76f..785f03a 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -16,6 +16,7 @@
import "package:ffi/ffi.dart";
import 'callback_tests_utils.dart';
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
@@ -5244,7 +5245,7 @@
Struct1ByteInt returnStruct1ByteIntResult = Struct1ByteInt();
Struct1ByteInt returnStruct1ByteIntCalculateResult() {
- Struct1ByteInt result = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt result = calloc<Struct1ByteInt>().ref;
result.a0 = returnStruct1ByteInt_a0;
@@ -5275,13 +5276,13 @@
}
void returnStruct1ByteIntAfterCallback() {
- free(returnStruct1ByteIntResult.addressOf);
+ calloc.free(returnStruct1ByteIntResult.addressOf);
final result = returnStruct1ByteIntCalculateResult();
print("after callback result = $result");
- free(returnStruct1ByteIntResult.addressOf);
+ calloc.free(returnStruct1ByteIntResult.addressOf);
}
typedef ReturnStruct3BytesHomogeneousUint8Type = Struct3BytesHomogeneousUint8
@@ -5299,7 +5300,7 @@
Struct3BytesHomogeneousUint8
returnStruct3BytesHomogeneousUint8CalculateResult() {
Struct3BytesHomogeneousUint8 result =
- allocate<Struct3BytesHomogeneousUint8>().ref;
+ calloc<Struct3BytesHomogeneousUint8>().ref;
result.a0 = returnStruct3BytesHomogeneousUint8_a0;
result.a1 = returnStruct3BytesHomogeneousUint8_a1;
@@ -5335,13 +5336,13 @@
}
void returnStruct3BytesHomogeneousUint8AfterCallback() {
- free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct3BytesHomogeneousUint8Result.addressOf);
final result = returnStruct3BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct3BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct3BytesInt2ByteAlignedType = Struct3BytesInt2ByteAligned
@@ -5357,7 +5358,7 @@
Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedCalculateResult() {
Struct3BytesInt2ByteAligned result =
- allocate<Struct3BytesInt2ByteAligned>().ref;
+ calloc<Struct3BytesInt2ByteAligned>().ref;
result.a0 = returnStruct3BytesInt2ByteAligned_a0;
result.a1 = returnStruct3BytesInt2ByteAligned_a1;
@@ -5391,13 +5392,13 @@
}
void returnStruct3BytesInt2ByteAlignedAfterCallback() {
- free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+ calloc.free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+ calloc.free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
}
typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
@@ -5414,7 +5415,7 @@
Struct4BytesHomogeneousInt16
returnStruct4BytesHomogeneousInt16CalculateResult() {
Struct4BytesHomogeneousInt16 result =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ calloc<Struct4BytesHomogeneousInt16>().ref;
result.a0 = returnStruct4BytesHomogeneousInt16_a0;
result.a1 = returnStruct4BytesHomogeneousInt16_a1;
@@ -5448,13 +5449,13 @@
}
void returnStruct4BytesHomogeneousInt16AfterCallback() {
- free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+ calloc.free(returnStruct4BytesHomogeneousInt16Result.addressOf);
final result = returnStruct4BytesHomogeneousInt16CalculateResult();
print("after callback result = $result");
- free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+ calloc.free(returnStruct4BytesHomogeneousInt16Result.addressOf);
}
typedef ReturnStruct7BytesHomogeneousUint8Type = Struct7BytesHomogeneousUint8
@@ -5476,7 +5477,7 @@
Struct7BytesHomogeneousUint8
returnStruct7BytesHomogeneousUint8CalculateResult() {
Struct7BytesHomogeneousUint8 result =
- allocate<Struct7BytesHomogeneousUint8>().ref;
+ calloc<Struct7BytesHomogeneousUint8>().ref;
result.a0 = returnStruct7BytesHomogeneousUint8_a0;
result.a1 = returnStruct7BytesHomogeneousUint8_a1;
@@ -5521,13 +5522,13 @@
}
void returnStruct7BytesHomogeneousUint8AfterCallback() {
- free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct7BytesHomogeneousUint8Result.addressOf);
final result = returnStruct7BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct7BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct7BytesInt4ByteAlignedType = Struct7BytesInt4ByteAligned
@@ -5544,7 +5545,7 @@
Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedCalculateResult() {
Struct7BytesInt4ByteAligned result =
- allocate<Struct7BytesInt4ByteAligned>().ref;
+ calloc<Struct7BytesInt4ByteAligned>().ref;
result.a0 = returnStruct7BytesInt4ByteAligned_a0;
result.a1 = returnStruct7BytesInt4ByteAligned_a1;
@@ -5581,13 +5582,13 @@
}
void returnStruct7BytesInt4ByteAlignedAfterCallback() {
- free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+ calloc.free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+ calloc.free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
}
typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
@@ -5602,7 +5603,7 @@
Struct8BytesInt returnStruct8BytesIntResult = Struct8BytesInt();
Struct8BytesInt returnStruct8BytesIntCalculateResult() {
- Struct8BytesInt result = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt result = calloc<Struct8BytesInt>().ref;
result.a0 = returnStruct8BytesInt_a0;
result.a1 = returnStruct8BytesInt_a1;
@@ -5637,13 +5638,13 @@
}
void returnStruct8BytesIntAfterCallback() {
- free(returnStruct8BytesIntResult.addressOf);
+ calloc.free(returnStruct8BytesIntResult.addressOf);
final result = returnStruct8BytesIntCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesIntResult.addressOf);
+ calloc.free(returnStruct8BytesIntResult.addressOf);
}
typedef ReturnStruct8BytesHomogeneousFloatType = Struct8BytesHomogeneousFloat
@@ -5660,7 +5661,7 @@
Struct8BytesHomogeneousFloat
returnStruct8BytesHomogeneousFloatCalculateResult() {
Struct8BytesHomogeneousFloat result =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ calloc<Struct8BytesHomogeneousFloat>().ref;
result.a0 = returnStruct8BytesHomogeneousFloat_a0;
result.a1 = returnStruct8BytesHomogeneousFloat_a1;
@@ -5694,13 +5695,13 @@
}
void returnStruct8BytesHomogeneousFloatAfterCallback() {
- free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct8BytesHomogeneousFloatResult.addressOf);
final result = returnStruct8BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct8BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct8BytesMixedType = Struct8BytesMixed Function(
@@ -5715,7 +5716,7 @@
Struct8BytesMixed returnStruct8BytesMixedResult = Struct8BytesMixed();
Struct8BytesMixed returnStruct8BytesMixedCalculateResult() {
- Struct8BytesMixed result = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed result = calloc<Struct8BytesMixed>().ref;
result.a0 = returnStruct8BytesMixed_a0;
result.a1 = returnStruct8BytesMixed_a1;
@@ -5750,13 +5751,13 @@
}
void returnStruct8BytesMixedAfterCallback() {
- free(returnStruct8BytesMixedResult.addressOf);
+ calloc.free(returnStruct8BytesMixedResult.addressOf);
final result = returnStruct8BytesMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesMixedResult.addressOf);
+ calloc.free(returnStruct8BytesMixedResult.addressOf);
}
typedef ReturnStruct9BytesHomogeneousUint8Type = Struct9BytesHomogeneousUint8
@@ -5780,7 +5781,7 @@
Struct9BytesHomogeneousUint8
returnStruct9BytesHomogeneousUint8CalculateResult() {
Struct9BytesHomogeneousUint8 result =
- allocate<Struct9BytesHomogeneousUint8>().ref;
+ calloc<Struct9BytesHomogeneousUint8>().ref;
result.a0 = returnStruct9BytesHomogeneousUint8_a0;
result.a1 = returnStruct9BytesHomogeneousUint8_a1;
@@ -5831,13 +5832,13 @@
}
void returnStruct9BytesHomogeneousUint8AfterCallback() {
- free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct9BytesHomogeneousUint8Result.addressOf);
final result = returnStruct9BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct9BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct9BytesInt4Or8ByteAlignedType
@@ -5854,7 +5855,7 @@
Struct9BytesInt4Or8ByteAligned
returnStruct9BytesInt4Or8ByteAlignedCalculateResult() {
Struct9BytesInt4Or8ByteAligned result =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
result.a0 = returnStruct9BytesInt4Or8ByteAligned_a0;
result.a1 = returnStruct9BytesInt4Or8ByteAligned_a1;
@@ -5890,13 +5891,13 @@
}
void returnStruct9BytesInt4Or8ByteAlignedAfterCallback() {
- free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+ calloc.free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+ calloc.free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
}
typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
@@ -5914,7 +5915,7 @@
Struct12BytesHomogeneousFloat
returnStruct12BytesHomogeneousFloatCalculateResult() {
Struct12BytesHomogeneousFloat result =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
result.a0 = returnStruct12BytesHomogeneousFloat_a0;
result.a1 = returnStruct12BytesHomogeneousFloat_a1;
@@ -5951,13 +5952,13 @@
}
void returnStruct12BytesHomogeneousFloatAfterCallback() {
- free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct12BytesHomogeneousFloatResult.addressOf);
final result = returnStruct12BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct12BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct16BytesHomogeneousFloatType = Struct16BytesHomogeneousFloat
@@ -5976,7 +5977,7 @@
Struct16BytesHomogeneousFloat
returnStruct16BytesHomogeneousFloatCalculateResult() {
Struct16BytesHomogeneousFloat result =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
result.a0 = returnStruct16BytesHomogeneousFloat_a0;
result.a1 = returnStruct16BytesHomogeneousFloat_a1;
@@ -6014,13 +6015,13 @@
}
void returnStruct16BytesHomogeneousFloatAfterCallback() {
- free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct16BytesHomogeneousFloatResult.addressOf);
final result = returnStruct16BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct16BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct16BytesMixedType = Struct16BytesMixed Function(
@@ -6034,7 +6035,7 @@
Struct16BytesMixed returnStruct16BytesMixedResult = Struct16BytesMixed();
Struct16BytesMixed returnStruct16BytesMixedCalculateResult() {
- Struct16BytesMixed result = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed result = calloc<Struct16BytesMixed>().ref;
result.a0 = returnStruct16BytesMixed_a0;
result.a1 = returnStruct16BytesMixed_a1;
@@ -6067,13 +6068,13 @@
}
void returnStruct16BytesMixedAfterCallback() {
- free(returnStruct16BytesMixedResult.addressOf);
+ calloc.free(returnStruct16BytesMixedResult.addressOf);
final result = returnStruct16BytesMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesMixedResult.addressOf);
+ calloc.free(returnStruct16BytesMixedResult.addressOf);
}
typedef ReturnStruct16BytesMixed2Type = Struct16BytesMixed2 Function(
@@ -6089,7 +6090,7 @@
Struct16BytesMixed2 returnStruct16BytesMixed2Result = Struct16BytesMixed2();
Struct16BytesMixed2 returnStruct16BytesMixed2CalculateResult() {
- Struct16BytesMixed2 result = allocate<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 result = calloc<Struct16BytesMixed2>().ref;
result.a0 = returnStruct16BytesMixed2_a0;
result.a1 = returnStruct16BytesMixed2_a1;
@@ -6128,13 +6129,13 @@
}
void returnStruct16BytesMixed2AfterCallback() {
- free(returnStruct16BytesMixed2Result.addressOf);
+ calloc.free(returnStruct16BytesMixed2Result.addressOf);
final result = returnStruct16BytesMixed2CalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesMixed2Result.addressOf);
+ calloc.free(returnStruct16BytesMixed2Result.addressOf);
}
typedef ReturnStruct17BytesIntType = Struct17BytesInt Function(
@@ -6149,7 +6150,7 @@
Struct17BytesInt returnStruct17BytesIntResult = Struct17BytesInt();
Struct17BytesInt returnStruct17BytesIntCalculateResult() {
- Struct17BytesInt result = allocate<Struct17BytesInt>().ref;
+ Struct17BytesInt result = calloc<Struct17BytesInt>().ref;
result.a0 = returnStruct17BytesInt_a0;
result.a1 = returnStruct17BytesInt_a1;
@@ -6186,13 +6187,13 @@
}
void returnStruct17BytesIntAfterCallback() {
- free(returnStruct17BytesIntResult.addressOf);
+ calloc.free(returnStruct17BytesIntResult.addressOf);
final result = returnStruct17BytesIntCalculateResult();
print("after callback result = $result");
- free(returnStruct17BytesIntResult.addressOf);
+ calloc.free(returnStruct17BytesIntResult.addressOf);
}
typedef ReturnStruct19BytesHomogeneousUint8Type
@@ -6245,7 +6246,7 @@
Struct19BytesHomogeneousUint8
returnStruct19BytesHomogeneousUint8CalculateResult() {
Struct19BytesHomogeneousUint8 result =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
result.a0 = returnStruct19BytesHomogeneousUint8_a0;
result.a1 = returnStruct19BytesHomogeneousUint8_a1;
@@ -6334,13 +6335,13 @@
}
void returnStruct19BytesHomogeneousUint8AfterCallback() {
- free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct19BytesHomogeneousUint8Result.addressOf);
final result = returnStruct19BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct19BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct20BytesHomogeneousInt32Type = Struct20BytesHomogeneousInt32
@@ -6360,7 +6361,7 @@
Struct20BytesHomogeneousInt32
returnStruct20BytesHomogeneousInt32CalculateResult() {
Struct20BytesHomogeneousInt32 result =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
result.a0 = returnStruct20BytesHomogeneousInt32_a0;
result.a1 = returnStruct20BytesHomogeneousInt32_a1;
@@ -6401,13 +6402,13 @@
}
void returnStruct20BytesHomogeneousInt32AfterCallback() {
- free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousInt32Result.addressOf);
final result = returnStruct20BytesHomogeneousInt32CalculateResult();
print("after callback result = $result");
- free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousInt32Result.addressOf);
}
typedef ReturnStruct20BytesHomogeneousFloatType = Struct20BytesHomogeneousFloat
@@ -6427,7 +6428,7 @@
Struct20BytesHomogeneousFloat
returnStruct20BytesHomogeneousFloatCalculateResult() {
Struct20BytesHomogeneousFloat result =
- allocate<Struct20BytesHomogeneousFloat>().ref;
+ calloc<Struct20BytesHomogeneousFloat>().ref;
result.a0 = returnStruct20BytesHomogeneousFloat_a0;
result.a1 = returnStruct20BytesHomogeneousFloat_a1;
@@ -6468,13 +6469,13 @@
}
void returnStruct20BytesHomogeneousFloatAfterCallback() {
- free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousFloatResult.addressOf);
final result = returnStruct20BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct32BytesHomogeneousDoubleType
@@ -6493,7 +6494,7 @@
Struct32BytesHomogeneousDouble
returnStruct32BytesHomogeneousDoubleCalculateResult() {
Struct32BytesHomogeneousDouble result =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
result.a0 = returnStruct32BytesHomogeneousDouble_a0;
result.a1 = returnStruct32BytesHomogeneousDouble_a1;
@@ -6532,13 +6533,13 @@
}
void returnStruct32BytesHomogeneousDoubleAfterCallback() {
- free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
print("after callback result = $result");
- free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
}
typedef ReturnStruct40BytesHomogeneousDoubleType
@@ -6559,7 +6560,7 @@
Struct40BytesHomogeneousDouble
returnStruct40BytesHomogeneousDoubleCalculateResult() {
Struct40BytesHomogeneousDouble result =
- allocate<Struct40BytesHomogeneousDouble>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
result.a0 = returnStruct40BytesHomogeneousDouble_a0;
result.a1 = returnStruct40BytesHomogeneousDouble_a1;
@@ -6601,13 +6602,13 @@
}
void returnStruct40BytesHomogeneousDoubleAfterCallback() {
- free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
print("after callback result = $result");
- free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
}
typedef ReturnStruct1024BytesHomogeneousUint64Type
@@ -6878,7 +6879,7 @@
Struct1024BytesHomogeneousUint64
returnStruct1024BytesHomogeneousUint64CalculateResult() {
Struct1024BytesHomogeneousUint64 result =
- allocate<Struct1024BytesHomogeneousUint64>().ref;
+ calloc<Struct1024BytesHomogeneousUint64>().ref;
result.a0 = returnStruct1024BytesHomogeneousUint64_a0;
result.a1 = returnStruct1024BytesHomogeneousUint64_a1;
@@ -7293,13 +7294,13 @@
}
void returnStruct1024BytesHomogeneousUint64AfterCallback() {
- free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+ calloc.free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
print("after callback result = $result");
- free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+ calloc.free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
}
typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
@@ -7618,7 +7619,7 @@
StructAlignmentInt16 returnStructAlignmentInt16Result = StructAlignmentInt16();
StructAlignmentInt16 returnStructAlignmentInt16CalculateResult() {
- StructAlignmentInt16 result = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 result = calloc<StructAlignmentInt16>().ref;
result.a0 = returnStructAlignmentInt16_a0;
result.a1 = returnStructAlignmentInt16_a1;
@@ -7653,13 +7654,13 @@
}
void returnStructAlignmentInt16AfterCallback() {
- free(returnStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructAlignmentInt16Result.addressOf);
final result = returnStructAlignmentInt16CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructAlignmentInt16Result.addressOf);
}
typedef ReturnStructAlignmentInt32Type = StructAlignmentInt32 Function(
@@ -7674,7 +7675,7 @@
StructAlignmentInt32 returnStructAlignmentInt32Result = StructAlignmentInt32();
StructAlignmentInt32 returnStructAlignmentInt32CalculateResult() {
- StructAlignmentInt32 result = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 result = calloc<StructAlignmentInt32>().ref;
result.a0 = returnStructAlignmentInt32_a0;
result.a1 = returnStructAlignmentInt32_a1;
@@ -7709,13 +7710,13 @@
}
void returnStructAlignmentInt32AfterCallback() {
- free(returnStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructAlignmentInt32Result.addressOf);
final result = returnStructAlignmentInt32CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructAlignmentInt32Result.addressOf);
}
typedef ReturnStructAlignmentInt64Type = StructAlignmentInt64 Function(
@@ -7730,7 +7731,7 @@
StructAlignmentInt64 returnStructAlignmentInt64Result = StructAlignmentInt64();
StructAlignmentInt64 returnStructAlignmentInt64CalculateResult() {
- StructAlignmentInt64 result = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 result = calloc<StructAlignmentInt64>().ref;
result.a0 = returnStructAlignmentInt64_a0;
result.a1 = returnStructAlignmentInt64_a1;
@@ -7765,13 +7766,13 @@
}
void returnStructAlignmentInt64AfterCallback() {
- free(returnStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructAlignmentInt64Result.addressOf);
final result = returnStructAlignmentInt64CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructAlignmentInt64Result.addressOf);
}
typedef ReturnStruct8BytesNestedIntType = Struct8BytesNestedInt Function(
@@ -7788,7 +7789,7 @@
Struct8BytesNestedInt();
Struct8BytesNestedInt returnStruct8BytesNestedIntCalculateResult() {
- Struct8BytesNestedInt result = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt result = calloc<Struct8BytesNestedInt>().ref;
result.a0.a0 = returnStruct8BytesNestedInt_a0.a0;
result.a0.a1 = returnStruct8BytesNestedInt_a0.a1;
@@ -7824,13 +7825,13 @@
}
void returnStruct8BytesNestedIntAfterCallback() {
- free(returnStruct8BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct8BytesNestedIntResult.addressOf);
final result = returnStruct8BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct8BytesNestedIntResult.addressOf);
}
typedef ReturnStruct8BytesNestedFloatType = Struct8BytesNestedFloat Function(
@@ -7845,7 +7846,7 @@
Struct8BytesNestedFloat();
Struct8BytesNestedFloat returnStruct8BytesNestedFloatCalculateResult() {
- Struct8BytesNestedFloat result = allocate<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat result = calloc<Struct8BytesNestedFloat>().ref;
result.a0.a0 = returnStruct8BytesNestedFloat_a0.a0;
result.a1.a0 = returnStruct8BytesNestedFloat_a1.a0;
@@ -7879,13 +7880,13 @@
}
void returnStruct8BytesNestedFloatAfterCallback() {
- free(returnStruct8BytesNestedFloatResult.addressOf);
+ calloc.free(returnStruct8BytesNestedFloatResult.addressOf);
final result = returnStruct8BytesNestedFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedFloatResult.addressOf);
+ calloc.free(returnStruct8BytesNestedFloatResult.addressOf);
}
typedef ReturnStruct8BytesNestedFloat2Type = Struct8BytesNestedFloat2 Function(
@@ -7900,7 +7901,7 @@
Struct8BytesNestedFloat2();
Struct8BytesNestedFloat2 returnStruct8BytesNestedFloat2CalculateResult() {
- Struct8BytesNestedFloat2 result = allocate<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 result = calloc<Struct8BytesNestedFloat2>().ref;
result.a0.a0 = returnStruct8BytesNestedFloat2_a0.a0;
result.a1 = returnStruct8BytesNestedFloat2_a1;
@@ -7935,13 +7936,13 @@
}
void returnStruct8BytesNestedFloat2AfterCallback() {
- free(returnStruct8BytesNestedFloat2Result.addressOf);
+ calloc.free(returnStruct8BytesNestedFloat2Result.addressOf);
final result = returnStruct8BytesNestedFloat2CalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedFloat2Result.addressOf);
+ calloc.free(returnStruct8BytesNestedFloat2Result.addressOf);
}
typedef ReturnStruct8BytesNestedMixedType = Struct8BytesNestedMixed Function(
@@ -7957,7 +7958,7 @@
Struct8BytesNestedMixed();
Struct8BytesNestedMixed returnStruct8BytesNestedMixedCalculateResult() {
- Struct8BytesNestedMixed result = allocate<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed result = calloc<Struct8BytesNestedMixed>().ref;
result.a0.a0 = returnStruct8BytesNestedMixed_a0.a0;
result.a0.a1 = returnStruct8BytesNestedMixed_a0.a1;
@@ -7992,13 +7993,13 @@
}
void returnStruct8BytesNestedMixedAfterCallback() {
- free(returnStruct8BytesNestedMixedResult.addressOf);
+ calloc.free(returnStruct8BytesNestedMixedResult.addressOf);
final result = returnStruct8BytesNestedMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedMixedResult.addressOf);
+ calloc.free(returnStruct8BytesNestedMixedResult.addressOf);
}
typedef ReturnStruct16BytesNestedIntType = Struct16BytesNestedInt Function(
@@ -8013,7 +8014,7 @@
Struct16BytesNestedInt();
Struct16BytesNestedInt returnStruct16BytesNestedIntCalculateResult() {
- Struct16BytesNestedInt result = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt result = calloc<Struct16BytesNestedInt>().ref;
result.a0.a0.a0 = returnStruct16BytesNestedInt_a0.a0.a0;
result.a0.a0.a1 = returnStruct16BytesNestedInt_a0.a0.a1;
@@ -8053,13 +8054,13 @@
}
void returnStruct16BytesNestedIntAfterCallback() {
- free(returnStruct16BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct16BytesNestedIntResult.addressOf);
final result = returnStruct16BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct16BytesNestedIntResult.addressOf);
}
typedef ReturnStruct32BytesNestedIntType = Struct32BytesNestedInt Function(
@@ -8076,7 +8077,7 @@
Struct32BytesNestedInt();
Struct32BytesNestedInt returnStruct32BytesNestedIntCalculateResult() {
- Struct32BytesNestedInt result = allocate<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt result = calloc<Struct32BytesNestedInt>().ref;
result.a0.a0.a0.a0 = returnStruct32BytesNestedInt_a0.a0.a0.a0;
result.a0.a0.a0.a1 = returnStruct32BytesNestedInt_a0.a0.a0.a1;
@@ -8124,13 +8125,13 @@
}
void returnStruct32BytesNestedIntAfterCallback() {
- free(returnStruct32BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct32BytesNestedIntResult.addressOf);
final result = returnStruct32BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct32BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct32BytesNestedIntResult.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt16Type
@@ -8151,7 +8152,7 @@
StructNestedIntStructAlignmentInt16
returnStructNestedIntStructAlignmentInt16CalculateResult() {
StructNestedIntStructAlignmentInt16 result =
- allocate<StructNestedIntStructAlignmentInt16>().ref;
+ calloc<StructNestedIntStructAlignmentInt16>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt16_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt16_a0.a1;
@@ -8190,13 +8191,13 @@
}
void returnStructNestedIntStructAlignmentInt16AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt16CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt32Type
@@ -8217,7 +8218,7 @@
StructNestedIntStructAlignmentInt32
returnStructNestedIntStructAlignmentInt32CalculateResult() {
StructNestedIntStructAlignmentInt32 result =
- allocate<StructNestedIntStructAlignmentInt32>().ref;
+ calloc<StructNestedIntStructAlignmentInt32>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt32_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt32_a0.a1;
@@ -8256,13 +8257,13 @@
}
void returnStructNestedIntStructAlignmentInt32AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt32CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt64Type
@@ -8283,7 +8284,7 @@
StructNestedIntStructAlignmentInt64
returnStructNestedIntStructAlignmentInt64CalculateResult() {
StructNestedIntStructAlignmentInt64 result =
- allocate<StructNestedIntStructAlignmentInt64>().ref;
+ calloc<StructNestedIntStructAlignmentInt64>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt64_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt64_a0.a1;
@@ -8322,13 +8323,13 @@
}
void returnStructNestedIntStructAlignmentInt64AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt64CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
}
typedef ReturnStructNestedIrregularEvenBiggerType
@@ -8350,7 +8351,7 @@
StructNestedIrregularEvenBigger
returnStructNestedIrregularEvenBiggerCalculateResult() {
StructNestedIrregularEvenBigger result =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
result.a0 = returnStructNestedIrregularEvenBigger_a0;
result.a1.a0.a0 = returnStructNestedIrregularEvenBigger_a1.a0.a0;
@@ -8419,11 +8420,11 @@
}
void returnStructNestedIrregularEvenBiggerAfterCallback() {
- free(returnStructNestedIrregularEvenBiggerResult.addressOf);
+ calloc.free(returnStructNestedIrregularEvenBiggerResult.addressOf);
final result = returnStructNestedIrregularEvenBiggerCalculateResult();
print("after callback result = $result");
- free(returnStructNestedIrregularEvenBiggerResult.addressOf);
+ calloc.free(returnStructNestedIrregularEvenBiggerResult.addressOf);
}
diff --git a/tests/ffi/function_callbacks_structs_by_value_test.dart b/tests/ffi/function_callbacks_structs_by_value_test.dart
index 23c9946..5e9399a 100644
--- a/tests/ffi/function_callbacks_structs_by_value_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
@@ -23,7 +24,7 @@
}
void recursiveTest(int recursionCounter) {
- final struct = allocate<Struct20BytesHomogeneousInt32>().ref;
+ final struct = calloc<Struct20BytesHomogeneousInt32>().ref;
struct.a0 = 1;
struct.a1 = 2;
struct.a2 = 3;
@@ -35,7 +36,7 @@
Expect.equals(struct.a2, result.a2);
Expect.equals(struct.a3, result.a3);
Expect.equals(struct.a4, result.a4);
- free(struct.addressOf);
+ calloc.free(struct.addressOf);
}
Struct20BytesHomogeneousInt32 dartPassStructRecursive(
@@ -93,7 +94,7 @@
_invokeReceiveStructByValue(_receiveStructByValuePointer);
Expect.isTrue(typedDataBackedStructSet);
- final pointerBackedStruct = allocate<Struct8BytesNestedInt>().ref;
+ final pointerBackedStruct = calloc<Struct8BytesNestedInt>().ref;
void reset() {
pointerBackedStruct.a0.a0 = 1;
@@ -130,5 +131,5 @@
Expect.equals(5, typedDataBackedStruct.a1.a0);
Expect.equals(6, typedDataBackedStruct.a1.a1);
- free(pointerBackedStruct.addressOf);
+ calloc.free(pointerBackedStruct.addressOf);
}
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index 8e800fc..c8b91cb 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -15,6 +15,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -1053,16 +1054,16 @@
/// Smallest struct with data.
/// 10 struct arguments will exhaust available registers.
void testPassStruct1ByteIntx10() {
- Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a1 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a2 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a3 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a4 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a5 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a6 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a7 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a9 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a0 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a1 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a2 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a3 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a4 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a5 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a6 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a7 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a8 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a9 = calloc<Struct1ByteInt>().ref;
a0.a0 = -1;
a1.a0 = 2;
@@ -1081,16 +1082,16 @@
Expect.equals(5, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct3BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1120,26 +1121,16 @@
/// Not a multiple of word size, not a power of two.
/// 10 struct arguments will exhaust available registers.
void testPassStruct3BytesHomogeneousUint8x10() {
- Struct3BytesHomogeneousUint8 a0 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a1 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a2 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a3 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a4 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a5 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a6 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a7 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a8 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a9 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a0 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a1 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a2 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a3 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a4 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a5 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a6 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a7 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a8 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a9 = calloc<Struct3BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1179,16 +1170,16 @@
Expect.equals(465, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct3BytesInt2ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -1219,16 +1210,16 @@
/// With alignment rules taken into account size is 4 bytes.
/// 10 struct arguments will exhaust available registers.
void testPassStruct3BytesInt2ByteAlignedx10() {
- Struct3BytesInt2ByteAligned a0 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a1 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a2 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a3 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a4 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a5 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a6 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a7 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a8 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a9 = allocate<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a0 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a1 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a2 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a3 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a4 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a5 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a6 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a7 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a8 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a9 = calloc<Struct3BytesInt2ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1258,16 +1249,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct4BytesHomogeneousInt16x10 = ffiTestFunctions.lookupFunction<
@@ -1297,26 +1288,16 @@
/// Exactly word size on 32-bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct4BytesHomogeneousInt16x10() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a2 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a3 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a4 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a5 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a6 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a7 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a8 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a9 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a2 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a3 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a4 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a5 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a6 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a7 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a8 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a9 = calloc<Struct4BytesHomogeneousInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1346,16 +1327,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct7BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1385,26 +1366,16 @@
/// Sub word size on 64 bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct7BytesHomogeneousUint8x10() {
- Struct7BytesHomogeneousUint8 a0 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a1 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a2 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a3 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a4 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a5 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a6 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a7 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a8 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a9 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a0 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a1 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a2 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a3 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a4 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a5 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a6 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a7 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a8 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a9 = calloc<Struct7BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1484,16 +1455,16 @@
Expect.equals(2485, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct7BytesInt4ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -1524,16 +1495,16 @@
/// With alignment rules taken into account size is 8 bytes.
/// 10 struct arguments will exhaust available registers.
void testPassStruct7BytesInt4ByteAlignedx10() {
- Struct7BytesInt4ByteAligned a0 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a1 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a2 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a3 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a4 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a5 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a6 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a7 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a8 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a9 = allocate<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a0 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a1 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a2 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a3 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a4 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a5 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a6 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a7 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a8 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a9 = calloc<Struct7BytesInt4ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1573,16 +1544,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesIntx10 = ffiTestFunctions.lookupFunction<
@@ -1612,16 +1583,16 @@
/// Exactly word size struct on 64bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesIntx10() {
- Struct8BytesInt a0 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a1 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a2 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a3 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a4 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a5 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a6 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a7 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a8 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a9 = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt a0 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a1 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a2 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a3 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a4 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a5 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a6 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a7 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a8 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a9 = calloc<Struct8BytesInt>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1660,16 +1631,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesHomogeneousFloatx10 = ffiTestFunctions.lookupFunction<
@@ -1699,26 +1670,16 @@
/// Arguments passed in FP registers as long as they fit.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesHomogeneousFloatx10() {
- Struct8BytesHomogeneousFloat a0 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a1 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a2 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a3 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a4 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a5 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a6 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a7 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a8 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a9 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a0 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a1 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a2 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a3 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a4 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a5 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a6 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a7 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a8 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a9 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -1748,16 +1709,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesMixedx10 = ffiTestFunctions.lookupFunction<
@@ -1787,16 +1748,16 @@
/// On x64, arguments go in int registers because it is not only float.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesMixedx10() {
- Struct8BytesMixed a0 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a1 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a2 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a3 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a4 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a5 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a6 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a7 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a8 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a9 = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a0 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a1 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a2 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a3 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a4 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a5 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a6 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a7 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a8 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a9 = calloc<Struct8BytesMixed>().ref;
a0.a0 = -1.0;
a0.a1 = 2;
@@ -1836,16 +1797,16 @@
Expect.approxEquals(15.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct9BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1878,26 +1839,16 @@
/// Tests upper bytes in the integer registers that are partly filled.
/// Tests stack alignment of non word size stack arguments.
void testPassStruct9BytesHomogeneousUint8x10() {
- Struct9BytesHomogeneousUint8 a0 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a1 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a2 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a3 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a4 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a5 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a6 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a7 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a8 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a9 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a0 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a1 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a2 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a3 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a4 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a5 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a6 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a7 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a8 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a9 = calloc<Struct9BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1997,16 +1948,16 @@
Expect.equals(4095, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct9BytesInt4Or8ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -2040,25 +1991,25 @@
///
void testPassStruct9BytesInt4Or8ByteAlignedx10() {
Struct9BytesInt4Or8ByteAligned a0 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a1 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a2 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a3 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a4 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a5 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a6 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a7 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a8 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a9 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2088,16 +2039,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
@@ -2121,17 +2072,17 @@
/// The last argument is to test whether arguments are backfilled.
void testPassStruct12BytesHomogeneousFloatx6() {
Struct12BytesHomogeneousFloat a0 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a1 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a2 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a3 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a4 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a5 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2158,12 +2109,12 @@
Expect.approxEquals(9.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
}
final passStruct16BytesHomogeneousFloatx5 = ffiTestFunctions.lookupFunction<
@@ -2185,15 +2136,15 @@
/// 5 struct arguments will exhaust available registers.
void testPassStruct16BytesHomogeneousFloatx5() {
Struct16BytesHomogeneousFloat a0 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a1 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a2 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a3 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a4 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2222,11 +2173,11 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
}
final passStruct16BytesMixedx10 = ffiTestFunctions.lookupFunction<
@@ -2258,16 +2209,16 @@
/// The rest goes on the stack.
/// On arm, arguments are 8 byte aligned.
void testPassStruct16BytesMixedx10() {
- Struct16BytesMixed a0 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a2 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a0 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a1 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a2 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a3 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a4 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a8 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a9 = calloc<Struct16BytesMixed>().ref;
a0.a0 = -1.0;
a0.a1 = 2;
@@ -2297,16 +2248,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct16BytesMixed2x10 = ffiTestFunctions.lookupFunction<
@@ -2338,16 +2289,16 @@
/// The rest goes on the stack.
/// On arm, arguments are 4 byte aligned.
void testPassStruct16BytesMixed2x10() {
- Struct16BytesMixed2 a0 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a1 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a2 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a3 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a4 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a5 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a6 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a7 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a8 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a9 = allocate<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a0 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a1 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a2 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a3 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a4 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a5 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a6 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a7 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a8 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a9 = calloc<Struct16BytesMixed2>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2397,16 +2348,16 @@
Expect.approxEquals(20.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct17BytesIntx10 = ffiTestFunctions.lookupFunction<
@@ -2436,16 +2387,16 @@
/// Arguments are passed as pointer to copy on arm64.
/// Tests that the memory allocated for copies are rounded up to word size.
void testPassStruct17BytesIntx10() {
- Struct17BytesInt a0 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a1 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a2 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a3 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a4 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a5 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a6 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a7 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a8 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a9 = allocate<Struct17BytesInt>().ref;
+ Struct17BytesInt a0 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a1 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a2 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a3 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a4 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a5 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a6 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a7 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a8 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a9 = calloc<Struct17BytesInt>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2485,16 +2436,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct19BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -2526,25 +2477,25 @@
///
void testPassStruct19BytesHomogeneousUint8x10() {
Struct19BytesHomogeneousUint8 a0 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a1 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a2 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a3 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a4 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a5 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a6 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a7 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a8 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a9 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -2744,16 +2695,16 @@
Expect.equals(18145, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct20BytesHomogeneousInt32x10 = ffiTestFunctions.lookupFunction<
@@ -2786,25 +2737,25 @@
/// pointers to copies are also passed on the stack.
void testPassStruct20BytesHomogeneousInt32x10() {
Struct20BytesHomogeneousInt32 a0 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a1 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a2 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a3 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a4 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a5 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a6 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a7 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a8 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a9 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2864,16 +2815,16 @@
Expect.equals(25, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
@@ -2884,7 +2835,7 @@
/// Argument too big to go into FPU registers in hardfp and arm64.
void testPassStruct20BytesHomogeneousFloat() {
Struct20BytesHomogeneousFloat a0 =
- allocate<Struct20BytesHomogeneousFloat>().ref;
+ calloc<Struct20BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2898,7 +2849,7 @@
Expect.approxEquals(-3.0, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct32BytesHomogeneousDoublex5 = ffiTestFunctions.lookupFunction<
@@ -2920,15 +2871,15 @@
/// 5 struct arguments will exhaust available registers.
void testPassStruct32BytesHomogeneousDoublex5() {
Struct32BytesHomogeneousDouble a0 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a1 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a2 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a3 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a4 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2957,11 +2908,11 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
}
final passStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
@@ -2972,7 +2923,7 @@
/// Argument too big to go into FPU registers in arm64.
void testPassStruct40BytesHomogeneousDouble() {
Struct40BytesHomogeneousDouble a0 =
- allocate<Struct40BytesHomogeneousDouble>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2986,7 +2937,7 @@
Expect.approxEquals(-3.0, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
@@ -2997,7 +2948,7 @@
/// Test 1kb struct.
void testPassStruct1024BytesHomogeneousUint64() {
Struct1024BytesHomogeneousUint64 a0 =
- allocate<Struct1024BytesHomogeneousUint64>().ref;
+ calloc<Struct1024BytesHomogeneousUint64>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -3134,7 +3085,7 @@
Expect.equals(8256, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passFloatStruct16BytesHomogeneousFloatFloatStruct1 =
@@ -3164,16 +3115,16 @@
void testPassFloatStruct16BytesHomogeneousFloatFloatStruct1() {
double a0;
Struct16BytesHomogeneousFloat a1 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a2;
Struct16BytesHomogeneousFloat a3 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a4;
Struct16BytesHomogeneousFloat a5 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a6;
Struct16BytesHomogeneousFloat a7 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a8;
a0 = -1.0;
@@ -3205,10 +3156,10 @@
Expect.approxEquals(-11.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passFloatStruct32BytesHomogeneousDoubleFloatStruct =
@@ -3238,16 +3189,16 @@
void testPassFloatStruct32BytesHomogeneousDoubleFloatStruct() {
double a0;
Struct32BytesHomogeneousDouble a1 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a2;
Struct32BytesHomogeneousDouble a3 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a4;
Struct32BytesHomogeneousDouble a5 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a6;
Struct32BytesHomogeneousDouble a7 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a8;
a0 = -1.0;
@@ -3279,10 +3230,10 @@
Expect.approxEquals(-11.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passInt8Struct16BytesMixedInt8Struct16BytesMixedIn =
@@ -3307,13 +3258,13 @@
/// Test backfilling of integer registers.
void testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn() {
int a0;
- Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a1 = calloc<Struct16BytesMixed>().ref;
int a2;
- Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a3 = calloc<Struct16BytesMixed>().ref;
int a4;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
int a6;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
int a8;
a0 = -1;
@@ -3337,10 +3288,10 @@
Expect.approxEquals(-7.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passDoublex6Struct16BytesMixedx4Int32 = ffiTestFunctions.lookupFunction<
@@ -3379,10 +3330,10 @@
double a3;
double a4;
double a5;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a8 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a9 = calloc<Struct16BytesMixed>().ref;
int a10;
a0 = -1.0;
@@ -3408,10 +3359,10 @@
Expect.approxEquals(-8.0, result);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passInt32x4Struct16BytesMixedx4Double = ffiTestFunctions.lookupFunction<
@@ -3436,10 +3387,10 @@
int a1;
int a2;
int a3;
- Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a4 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
double a8;
a0 = -1;
@@ -3463,10 +3414,10 @@
Expect.approxEquals(-7.0, result);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
}
final passStruct40BytesHomogeneousDoubleStruct4BytesHomo =
@@ -3481,11 +3432,9 @@
/// Check that the other two arguments are allocated on registers.
void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
Struct40BytesHomogeneousDouble a0 =
- allocate<Struct40BytesHomogeneousDouble>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct8BytesHomogeneousFloat a2 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct8BytesHomogeneousFloat a2 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -3503,9 +3452,9 @@
Expect.approxEquals(-5.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
}
final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int =
@@ -3613,30 +3562,28 @@
double a15;
int a16;
int a17;
- Struct1ByteInt a18 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a18 = calloc<Struct1ByteInt>().ref;
int a19;
int a20;
- Struct4BytesHomogeneousInt16 a21 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a21 = calloc<Struct4BytesHomogeneousInt16>().ref;
int a22;
int a23;
- Struct8BytesInt a24 = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt a24 = calloc<Struct8BytesInt>().ref;
int a25;
int a26;
- Struct8BytesHomogeneousFloat a27 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a27 = calloc<Struct8BytesHomogeneousFloat>().ref;
int a28;
int a29;
- Struct8BytesMixed a30 = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a30 = calloc<Struct8BytesMixed>().ref;
int a31;
int a32;
- StructAlignmentInt16 a33 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a33 = calloc<StructAlignmentInt16>().ref;
int a34;
int a35;
- StructAlignmentInt32 a36 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a36 = calloc<StructAlignmentInt32>().ref;
int a37;
int a38;
- StructAlignmentInt64 a39 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a39 = calloc<StructAlignmentInt64>().ref;
a0 = -1;
a1 = 2;
@@ -3737,14 +3684,14 @@
Expect.approxEquals(26.0, result);
- free(a18.addressOf);
- free(a21.addressOf);
- free(a24.addressOf);
- free(a27.addressOf);
- free(a30.addressOf);
- free(a33.addressOf);
- free(a36.addressOf);
- free(a39.addressOf);
+ calloc.free(a18.addressOf);
+ calloc.free(a21.addressOf);
+ calloc.free(a24.addressOf);
+ calloc.free(a27.addressOf);
+ calloc.free(a30.addressOf);
+ calloc.free(a33.addressOf);
+ calloc.free(a36.addressOf);
+ calloc.free(a39.addressOf);
}
final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -3753,7 +3700,7 @@
/// Test alignment and padding of 16 byte int within struct.
void testPassStructAlignmentInt16() {
- StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a0 = calloc<StructAlignmentInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3765,7 +3712,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
@@ -3774,7 +3721,7 @@
/// Test alignment and padding of 32 byte int within struct.
void testPassStructAlignmentInt32() {
- StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a0 = calloc<StructAlignmentInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3786,7 +3733,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
@@ -3795,7 +3742,7 @@
/// Test alignment and padding of 64 byte int within struct.
void testPassStructAlignmentInt64() {
- StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a0 = calloc<StructAlignmentInt64>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3807,7 +3754,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct8BytesNestedIntx10 = ffiTestFunctions.lookupFunction<
@@ -3837,16 +3784,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust registers on all platforms.
void testPassStruct8BytesNestedIntx10() {
- Struct8BytesNestedInt a0 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a1 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a2 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a3 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a4 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a5 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a6 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a7 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a8 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a9 = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a0 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a1 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a2 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a3 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a4 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a5 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a6 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a7 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a8 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a9 = calloc<Struct8BytesNestedInt>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -3896,16 +3843,16 @@
Expect.equals(20, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedFloatx10 = ffiTestFunctions.lookupFunction<
@@ -3935,16 +3882,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust fpu registers on all platforms.
void testPassStruct8BytesNestedFloatx10() {
- Struct8BytesNestedFloat a0 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a1 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a2 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a3 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a4 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a5 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a6 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a7 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a8 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a9 = allocate<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a0 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a1 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a2 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a3 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a4 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a5 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a6 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a7 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a8 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a9 = calloc<Struct8BytesNestedFloat>().ref;
a0.a0.a0 = -1.0;
a0.a1.a0 = 2.0;
@@ -3974,16 +3921,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedFloat2x10 = ffiTestFunctions.lookupFunction<
@@ -4015,16 +3962,16 @@
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
/// and the fpu register usage on x64.
void testPassStruct8BytesNestedFloat2x10() {
- Struct8BytesNestedFloat2 a0 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a1 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a2 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a3 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a4 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a5 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a6 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a7 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a8 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a9 = allocate<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a0 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a1 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a2 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a3 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a4 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a5 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a6 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a7 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a8 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a9 = calloc<Struct8BytesNestedFloat2>().ref;
a0.a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -4054,16 +4001,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedMixedx10 = ffiTestFunctions.lookupFunction<
@@ -4093,16 +4040,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust all registers on all platforms.
void testPassStruct8BytesNestedMixedx10() {
- Struct8BytesNestedMixed a0 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a1 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a2 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a3 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a4 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a5 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a6 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a7 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a8 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a9 = allocate<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a0 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a1 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a2 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a3 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a4 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a5 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a6 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a7 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a8 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a9 = calloc<Struct8BytesNestedMixed>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4142,16 +4089,16 @@
Expect.approxEquals(15.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct16BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
@@ -4161,8 +4108,8 @@
/// Deeper nested struct to test recursive member access.
void testPassStruct16BytesNestedIntx2() {
- Struct16BytesNestedInt a0 = allocate<Struct16BytesNestedInt>().ref;
- Struct16BytesNestedInt a1 = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a0 = calloc<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a1 = calloc<Struct16BytesNestedInt>().ref;
a0.a0.a0.a0 = -1;
a0.a0.a0.a1 = 2;
@@ -4187,8 +4134,8 @@
Expect.equals(8, result);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final passStruct32BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
@@ -4198,8 +4145,8 @@
/// Even deeper nested struct to test recursive member access.
void testPassStruct32BytesNestedIntx2() {
- Struct32BytesNestedInt a0 = allocate<Struct32BytesNestedInt>().ref;
- Struct32BytesNestedInt a1 = allocate<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt a0 = calloc<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt a1 = calloc<Struct32BytesNestedInt>().ref;
a0.a0.a0.a0.a0 = -1;
a0.a0.a0.a0.a1 = 2;
@@ -4240,8 +4187,8 @@
Expect.equals(16, result);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final passStructNestedIntStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -4252,7 +4199,7 @@
/// Test alignment and padding of nested struct with 16 byte int.
void testPassStructNestedIntStructAlignmentInt16() {
StructNestedIntStructAlignmentInt16 a0 =
- allocate<StructNestedIntStructAlignmentInt16>().ref;
+ calloc<StructNestedIntStructAlignmentInt16>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4267,7 +4214,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIntStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
@@ -4278,7 +4225,7 @@
/// Test alignment and padding of nested struct with 32 byte int.
void testPassStructNestedIntStructAlignmentInt32() {
StructNestedIntStructAlignmentInt32 a0 =
- allocate<StructNestedIntStructAlignmentInt32>().ref;
+ calloc<StructNestedIntStructAlignmentInt32>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4293,7 +4240,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIntStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
@@ -4304,7 +4251,7 @@
/// Test alignment and padding of nested struct with 64 byte int.
void testPassStructNestedIntStructAlignmentInt64() {
StructNestedIntStructAlignmentInt64 a0 =
- allocate<StructNestedIntStructAlignmentInt64>().ref;
+ calloc<StructNestedIntStructAlignmentInt64>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4319,7 +4266,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIrregularEvenBiggerx4 = ffiTestFunctions.lookupFunction<
@@ -4338,13 +4285,13 @@
/// Return big irregular struct as smoke test.
void testPassStructNestedIrregularEvenBiggerx4() {
StructNestedIrregularEvenBigger a0 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a1 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a2 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a3 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
a0.a0 = 1;
a0.a1.a0.a0 = 2;
@@ -4489,10 +4436,10 @@
Expect.approxEquals(1572.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
}
final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
@@ -5922,7 +5869,7 @@
/// Especially for ffi callbacks.
/// Struct is passed in int registers in most ABIs.
void testReturnStructArgumentStruct1ByteInt() {
- Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a0 = calloc<Struct1ByteInt>().ref;
a0.a0 = -1;
@@ -5932,7 +5879,7 @@
Expect.equals(a0.a0, result.a0);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentInt32x8Struct1ByteInt =
@@ -5954,7 +5901,7 @@
int a5;
int a6;
int a7;
- Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a8 = calloc<Struct1ByteInt>().ref;
a0 = -1;
a1 = 2;
@@ -5973,7 +5920,7 @@
Expect.equals(a8.a0, result.a0);
- free(a8.addressOf);
+ calloc.free(a8.addressOf);
}
final returnStructArgumentStruct8BytesHomogeneousFloat =
@@ -5987,8 +5934,7 @@
/// Especially for ffi callbacks.
/// Struct is passed in float registers in most ABIs.
void testReturnStructArgumentStruct8BytesHomogeneousFloat() {
- Struct8BytesHomogeneousFloat a0 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a0 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -6000,7 +5946,7 @@
Expect.approxEquals(a0.a0, result.a0);
Expect.approxEquals(a0.a1, result.a1);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentStruct20BytesHomogeneousInt32 =
@@ -6015,7 +5961,7 @@
/// On arm64, both argument and return value are passed in by pointer.
void testReturnStructArgumentStruct20BytesHomogeneousInt32() {
Struct20BytesHomogeneousInt32 a0 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6033,7 +5979,7 @@
Expect.equals(a0.a3, result.a3);
Expect.equals(a0.a4, result.a4);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentInt32x8Struct20BytesHomogeneou =
@@ -6056,7 +6002,7 @@
int a6;
int a7;
Struct20BytesHomogeneousInt32 a8 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0 = -1;
a1 = 2;
@@ -6083,7 +6029,7 @@
Expect.equals(a8.a3, result.a3);
Expect.equals(a8.a4, result.a4);
- free(a8.addressOf);
+ calloc.free(a8.addressOf);
}
final returnStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -6163,10 +6109,8 @@
/// Simple nested struct.
void testReturnStruct8BytesNestedInt() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6182,8 +6126,8 @@
Expect.equals(a1.a0, result.a1.a0);
Expect.equals(a1.a1, result.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct8BytesNestedFloat = ffiTestFunctions.lookupFunction<
@@ -6193,8 +6137,8 @@
/// Simple nested struct with floats.
void testReturnStruct8BytesNestedFloat() {
- Struct4BytesFloat a0 = allocate<Struct4BytesFloat>().ref;
- Struct4BytesFloat a1 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a0 = calloc<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a1 = calloc<Struct4BytesFloat>().ref;
a0.a0 = -1.0;
a1.a0 = 2.0;
@@ -6206,8 +6150,8 @@
Expect.approxEquals(a0.a0, result.a0.a0);
Expect.approxEquals(a1.a0, result.a1.a0);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct8BytesNestedFloat2 = ffiTestFunctions.lookupFunction<
@@ -6218,7 +6162,7 @@
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
/// and the fpu register usage on x64.
void testReturnStruct8BytesNestedFloat2() {
- Struct4BytesFloat a0 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a0 = calloc<Struct4BytesFloat>().ref;
double a1;
a0.a0 = -1.0;
@@ -6231,7 +6175,7 @@
Expect.approxEquals(a0.a0, result.a0.a0);
Expect.approxEquals(a1, result.a1);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStruct8BytesNestedMixed = ffiTestFunctions.lookupFunction<
@@ -6242,9 +6186,8 @@
/// Simple nested struct with mixed members.
void testReturnStruct8BytesNestedMixed() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesFloat a1 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesFloat a1 = calloc<Struct4BytesFloat>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6258,8 +6201,8 @@
Expect.equals(a0.a1, result.a0.a1);
Expect.approxEquals(a1.a0, result.a1.a0);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct16BytesNestedInt = ffiTestFunctions.lookupFunction<
@@ -6270,8 +6213,8 @@
/// Deeper nested struct to test recursive member access.
void testReturnStruct16BytesNestedInt() {
- Struct8BytesNestedInt a0 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a1 = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a0 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a1 = calloc<Struct8BytesNestedInt>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -6295,8 +6238,8 @@
Expect.equals(a1.a1.a0, result.a1.a1.a0);
Expect.equals(a1.a1.a1, result.a1.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct32BytesNestedInt = ffiTestFunctions.lookupFunction<
@@ -6307,8 +6250,8 @@
/// Even deeper nested struct to test recursive member access.
void testReturnStruct32BytesNestedInt() {
- Struct16BytesNestedInt a0 = allocate<Struct16BytesNestedInt>().ref;
- Struct16BytesNestedInt a1 = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a0 = calloc<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a1 = calloc<Struct16BytesNestedInt>().ref;
a0.a0.a0.a0 = -1;
a0.a0.a0.a1 = 2;
@@ -6348,8 +6291,8 @@
Expect.equals(a1.a1.a1.a0, result.a1.a1.a1.a0);
Expect.equals(a1.a1.a1.a1, result.a1.a1.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt16 =
@@ -6361,8 +6304,8 @@
/// Test alignment and padding of nested struct with 16 byte int.
void testReturnStructNestedIntStructAlignmentInt16() {
- StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
- StructAlignmentInt16 a1 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a0 = calloc<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a1 = calloc<StructAlignmentInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6382,8 +6325,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt32 =
@@ -6395,8 +6338,8 @@
/// Test alignment and padding of nested struct with 32 byte int.
void testReturnStructNestedIntStructAlignmentInt32() {
- StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
- StructAlignmentInt32 a1 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a0 = calloc<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a1 = calloc<StructAlignmentInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6416,8 +6359,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt64 =
@@ -6429,8 +6372,8 @@
/// Test alignment and padding of nested struct with 64 byte int.
void testReturnStructNestedIntStructAlignmentInt64() {
- StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
- StructAlignmentInt64 a1 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a0 = calloc<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a1 = calloc<StructAlignmentInt64>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6450,8 +6393,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIrregularEvenBigger = ffiTestFunctions.lookupFunction<
@@ -6466,8 +6409,8 @@
/// Return big irregular struct as smoke test.
void testReturnStructNestedIrregularEvenBigger() {
int a0;
- StructNestedIrregularBigger a1 = allocate<StructNestedIrregularBigger>().ref;
- StructNestedIrregularBigger a2 = allocate<StructNestedIrregularBigger>().ref;
+ StructNestedIrregularBigger a1 = calloc<StructNestedIrregularBigger>().ref;
+ StructNestedIrregularBigger a2 = calloc<StructNestedIrregularBigger>().ref;
double a3;
a0 = 1;
@@ -6544,6 +6487,6 @@
Expect.approxEquals(a2.a3, result.a2.a3);
Expect.approxEquals(a3, result.a3);
- free(a1.addressOf);
- free(a2.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
}
diff --git a/tests/ffi/function_structs_test.dart b/tests/ffi/function_structs_test.dart
index bf9ea5f..ade55fb 100644
--- a/tests/ffi/function_structs_test.dart
+++ b/tests/ffi/function_structs_test.dart
@@ -14,6 +14,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'coordinate.dart';
import 'very_large_struct.dart';
@@ -33,8 +34,10 @@
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
- Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 20.0, nullptr).addressOf;
- Pointer<Coordinate> c2 = Coordinate.allocate(42.0, 84.0, c1).addressOf;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(calloc, 10.0, 20.0, nullptr).addressOf;
+ Pointer<Coordinate> c2 =
+ Coordinate.allocate(calloc, 42.0, 84.0, c1).addressOf;
c1.ref.next = c2;
Coordinate result = f1(c1).ref;
@@ -45,8 +48,8 @@
Expect.approxEquals(42.0, result.x);
Expect.approxEquals(84.0, result.y);
- free(c1);
- free(c2);
+ calloc.free(c1);
+ calloc.free(c2);
}
/// pass an array of structs to a c funtion
@@ -55,7 +58,7 @@
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = allocate<Coordinate>(count: 3).ref;
+ Coordinate c1 = calloc<Coordinate>(3).ref;
Coordinate c2 = c1.addressOf[1];
Coordinate c3 = c1.addressOf[2];
c1.x = 10.0;
@@ -72,7 +75,7 @@
Expect.approxEquals(20.0, result.x);
Expect.approxEquals(20.0, result.y);
- free(c1.addressOf);
+ calloc.free(c1.addressOf);
}
typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
@@ -83,7 +86,7 @@
ffiTestFunctions.lookup("SumVeryLargeStruct");
VeryLargeStructSum f = p1.asFunction();
- VeryLargeStruct vls1 = allocate<VeryLargeStruct>(count: 2).ref;
+ VeryLargeStruct vls1 = calloc<VeryLargeStruct>(2).ref;
VeryLargeStruct vls2 = vls1.addressOf[1];
List<VeryLargeStruct> structs = [vls1, vls2];
for (VeryLargeStruct struct in structs) {
@@ -114,5 +117,5 @@
result = f(vls2.addressOf);
Expect.equals(2048, result);
- free(vls1.addressOf);
+ calloc.free(vls1.addressOf);
}
diff --git a/tests/ffi/function_test.dart b/tests/ffi/function_test.dart
index bff456e..077be64 100644
--- a/tests/ffi/function_test.dart
+++ b/tests/ffi/function_test.dart
@@ -15,11 +15,12 @@
import 'dart:ffi';
-import 'dylib_utils.dart';
-
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'calloc.dart';
+import 'dylib_utils.dart';
+
void main() {
for (int i = 0; i < 100; ++i) {
testNativeFunctionFromCast();
@@ -50,11 +51,11 @@
typedef GenericBinaryOp<T> = int Function(int, T);
void testNativeFunctionFromCast() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<NativeFunction<NativeBinaryOp>> p2 = p1.cast();
p2.asFunction<BinaryOp>();
p2.asFunction<GenericBinaryOp<int>>();
- free(p1);
+ calloc.free(p1);
}
typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
@@ -394,14 +395,14 @@
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
void testNativeFunctionPointer() {
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
p2.value = 42;
p2[1] = 1000;
Pointer<Int64> result = assign1337Index1(p2);
Expect.equals(1337, result.value);
Expect.equals(1337, p2[1]);
Expect.equals(p2.elementAt(1).address, result.address);
- free(p2);
+ calloc.free(p2);
}
Int64PointerUnOp nullableInt64ElemAt1 = ffiTestFunctions
@@ -411,10 +412,10 @@
Pointer<Int64> result = nullableInt64ElemAt1(nullptr);
Expect.equals(result, nullptr);
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
result = nullableInt64ElemAt1(p2);
Expect.notEquals(result, nullptr);
- free(p2);
+ calloc.free(p2);
}
typedef NativeFloatPointerToBool = Uint8 Function(Pointer<Float>);
@@ -424,13 +425,13 @@
NativeFloatPointerToBool, FloatPointerToBool>("IsRoughly1337");
void testFloatRounding() {
- Pointer<Float> p2 = allocate();
+ Pointer<Float> p2 = calloc();
p2.value = 1337.0;
int result = isRoughly1337(p2);
Expect.equals(1, result);
- free(p2);
+ calloc.free(p2);
}
typedef NativeFloatToVoid = Void Function(Float);
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index f3f9f02..7bd7c83 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -197,7 +197,7 @@
return "${dartType} ${variableName};\n";
case StructType:
- return "${dartType} ${variableName} = allocate<$dartType>().ref;\n";
+ return "${dartType} ${variableName} = calloc<$dartType>().ref;\n";
}
throw Exception("Not implemented for ${this.runtimeType}");
@@ -243,7 +243,7 @@
return "";
case StructType:
- return "free($variableName.addressOf);\n";
+ return "calloc.free($variableName.addressOf);\n";
}
throw Exception("Not implemented for ${this.runtimeType}");
@@ -485,7 +485,7 @@
case TestType.structReturn:
// Allocate a struct.
buildReturnValue = """
- ${returnValue.dartType} result = allocate<${returnValue.dartType}>().ref;
+ ${returnValue.dartType} result = calloc<${returnValue.dartType}>().ref;
${arguments.copyValueStatements("${dartName}_", "result.")}
""";
@@ -749,6 +749,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -801,6 +802,7 @@
import "package:ffi/ffi.dart";
import 'callback_tests_utils.dart';
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
diff --git a/tests/ffi/regress_37254_test.dart b/tests/ffi/regress_37254_test.dart
index ce696af..62c71db 100644
--- a/tests/ffi/regress_37254_test.dart
+++ b/tests/ffi/regress_37254_test.dart
@@ -65,34 +65,36 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
// ===== a.value = b ======
// The tests follow table cells left to right, top to bottom.
void store1() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store2() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
final Pointer<NativeType> b =
- allocate<Int8>(); // Reified Pointer<Int8> at runtime.
+ calloc<Int8>(); // Reified Pointer<Int8> at runtime.
// Successful implicit downcast of argument at runtime.
// Should succeed now, should statically be rejected when NNBD lands.
a.value = b as Pointer<Int8>;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store3() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
// Failing implicit downcast of argument at runtime.
// Should fail now at runtime, should statically be rejected when NNBD lands.
@@ -100,124 +102,124 @@
a.value = b as Pointer<Int8>;
});
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store4() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store5() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
final Pointer<NativeType> b =
- allocate<Int8>(); // Reified as Pointer<Int8> at runtime.
+ calloc<Int8>(); // Reified as Pointer<Int8> at runtime.
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store6() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
// Fails on type check of argument.
Expect.throws(() {
a.value = b;
});
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store7() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store8() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
// Reified as Pointer<Int8> at runtime.
- final Pointer<NativeType> b = allocate<Int8>();
+ final Pointer<NativeType> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store9() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
// ====== b = a.value ======
// The tests follow table cells left to right, top to bottom.
void load1() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
Pointer<Int8> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load2() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
Pointer<NativeType> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load3() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
Pointer<Int8> b = a.value as Pointer<Int8>;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load4() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
// Return value runtime type is Pointer<Int8>.
Pointer<NativeType> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load5() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
// Failing implicit downcast of return value at runtime.
// Should fail now at runtime, should statically be rejected when NNBD lands.
@@ -225,16 +227,16 @@
Pointer<Int8> b = a.value as Pointer<Int8>;
});
- free(a);
+ calloc.free(a);
}
void load6() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
Pointer<NativeType> b = a.value;
Expect.type<Pointer<NativeType>>(b);
- free(a);
+ calloc.free(a);
}
void main() {
diff --git a/tests/ffi/regress_39885_test.dart b/tests/ffi/regress_39885_test.dart
index 7d960f2..ef73ca7 100644
--- a/tests/ffi/regress_39885_test.dart
+++ b/tests/ffi/regress_39885_test.dart
@@ -3,12 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:ffi';
-import "package:ffi/ffi.dart" show allocate, free;
+
+import "package:ffi/ffi.dart";
+
+import 'calloc.dart';
main() {
- final data = allocate<Uint8>(count: 3);
+ final data = calloc<Uint8>(3);
for (int i = 0; i < 3; ++i) {
data.elementAt(i).value = 1;
}
- free(data);
+ calloc.free(data);
}
diff --git a/tests/ffi/regress_43693_test.dart b/tests/ffi/regress_43693_test.dart
index a34e8f8..64b48bf 100644
--- a/tests/ffi/regress_43693_test.dart
+++ b/tests/ffi/regress_43693_test.dart
@@ -9,6 +9,7 @@
import 'package:ffi/ffi.dart';
import 'package:expect/expect.dart';
+import 'calloc.dart';
import 'dylib_utils.dart';
class Struct43693 extends Struct {
@@ -27,10 +28,10 @@
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
void main() {
- final myStructs = allocate<Struct43693>();
+ final myStructs = calloc<Struct43693>();
myStructs[0].somePtr = nullptr;
myStructs[0].someValue = 0xAAAAAAAABBBBBBBB;
final result = readMyStructSomeValue(myStructs);
Expect.equals(0xAAAAAAAABBBBBBBB, result);
- free(myStructs);
+ calloc.free(myStructs);
}
diff --git a/tests/ffi/structs_nested_test.dart b/tests/ffi/structs_nested_test.dart
index ea4b6db..2d5208d 100644
--- a/tests/ffi/structs_nested_test.dart
+++ b/tests/ffi/structs_nested_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -48,16 +49,16 @@
}
void testAllocate() {
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
Expect.type<Pointer<Struct8BytesNestedInt>>(p);
print(p);
- free(p);
+ calloc.free(p);
}
/// Test that reading does not segfault, even uninitialized.
void testRead() {
print("read");
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
print(p);
print(p.ref.runtimeType);
print(p.ref.addressOf);
@@ -65,13 +66,13 @@
print(p.ref.a0.runtimeType);
print(p.ref.a0.addressOf);
print(p.ref.a0.a0);
- free(p);
+ calloc.free(p);
print("read");
}
void testWrite() {
print("write");
- final p = allocate<Struct8BytesNestedInt>(count: 2);
+ final p = calloc<Struct8BytesNestedInt>(2);
p[0].a0.a0 = 12;
p[0].a0.a1 = 13;
p[0].a1.a0 = 14;
@@ -88,18 +89,18 @@
Expect.equals(17, p[1].a0.a1);
Expect.equals(18, p[1].a1.a0);
Expect.equals(19, p[1].a1.a1);
- free(p);
+ calloc.free(p);
print("written");
}
void testCopy() {
print("copy");
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
p.ref.a0.a0 = 12;
p.ref.a0.a1 = 13;
p.ref.a1 = p.ref.a0;
Expect.equals(12, p.ref.a1.a0);
Expect.equals(13, p.ref.a1.a1);
- free(p);
+ calloc.free(p);
print("copied");
}
diff --git a/tests/ffi/structs_nnbd_workaround_test.dart b/tests/ffi/structs_nnbd_workaround_test.dart
index 6501faf..06c6f29 100644
--- a/tests/ffi/structs_nnbd_workaround_test.dart
+++ b/tests/ffi/structs_nnbd_workaround_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'coordinate_nnbd_workaround.dart';
void main() {
@@ -25,9 +26,12 @@
/// allocates each coordinate separately in c memory
void testStructAllocate() {
- Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
- Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
- Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
+ Pointer<Coordinate> c2 =
+ Coordinate.allocate(calloc, 20.0, 20.0, c1).addressOf;
+ Pointer<Coordinate> c3 =
+ Coordinate.allocate(calloc, 30.0, 30.0, c2).addressOf;
c1.ref.next = c3;
Coordinate currentCoordinate = c1.ref;
@@ -39,14 +43,14 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
- free(c2);
- free(c3);
+ calloc.free(c1);
+ calloc.free(c2);
+ calloc.free(c3);
}
/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
- Pointer<Coordinate> c1 = allocate(count: 3);
+ Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref
@@ -71,30 +75,30 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
+ calloc.free(c1);
}
void testStructWithNulls() {
Pointer<Coordinate> coordinate =
- Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
Expect.equals(coordinate.ref.next, nullptr);
coordinate.ref.next = coordinate;
Expect.notEquals(coordinate.ref.next, nullptr);
coordinate.ref.next = nullptr;
Expect.equals(coordinate.ref.next, nullptr);
- free(coordinate);
+ calloc.free(coordinate);
}
void testTypeTest() {
- Coordinate c = Coordinate.allocate(10, 10, nullptr);
+ Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
Expect.isTrue(c is Struct);
Expect.isTrue(c.addressOf is Pointer<Coordinate>);
- free(c.addressOf);
+ calloc.free(c.addressOf);
}
void testUtf8() {
final String test = 'Hasta Mañana';
final Pointer<Utf8> medium = Utf8.toUtf8(test);
Expect.equals(test, Utf8.fromUtf8(medium));
- free(medium);
+ calloc.free(medium);
}
diff --git a/tests/ffi/structs_test.dart b/tests/ffi/structs_test.dart
index 83e617d..6bc1ed1 100644
--- a/tests/ffi/structs_test.dart
+++ b/tests/ffi/structs_test.dart
@@ -11,9 +11,10 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-import 'ffi_test_helpers.dart';
+import 'calloc.dart';
import 'coordinate_bare.dart' as bare;
import 'coordinate.dart';
+import 'ffi_test_helpers.dart';
void main() {
for (int i = 0; i < 100; i++) {
@@ -28,9 +29,12 @@
/// allocates each coordinate separately in c memory
void testStructAllocate() {
- Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
- Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
- Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
+ Pointer<Coordinate> c2 =
+ Coordinate.allocate(calloc, 20.0, 20.0, c1).addressOf;
+ Pointer<Coordinate> c3 =
+ Coordinate.allocate(calloc, 30.0, 30.0, c2).addressOf;
c1.ref.next = c3;
Coordinate currentCoordinate = c1.ref;
@@ -42,14 +46,14 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
- free(c2);
- free(c3);
+ calloc.free(c1);
+ calloc.free(c2);
+ calloc.free(c3);
}
/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
- Pointer<Coordinate> c1 = allocate(count: 3);
+ Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref
@@ -74,24 +78,24 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
+ calloc.free(c1);
}
void testStructWithNulls() {
Pointer<Coordinate> coordinate =
- Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
Expect.equals(coordinate.ref.next, nullptr);
coordinate.ref.next = coordinate;
Expect.notEquals(coordinate.ref.next, nullptr);
coordinate.ref.next = nullptr;
Expect.equals(coordinate.ref.next, nullptr);
- free(coordinate);
+ calloc.free(coordinate);
}
void testBareStruct() {
int structSize = sizeOf<Double>() * 2 + sizeOf<IntPtr>();
bare.Coordinate c1 =
- allocate<Uint8>(count: structSize * 3).cast<bare.Coordinate>().ref;
+ calloc<Uint8>(structSize * 3).cast<bare.Coordinate>().ref;
bare.Coordinate c2 =
c1.addressOf.offsetBy(structSize).cast<bare.Coordinate>().ref;
bare.Coordinate c3 =
@@ -115,19 +119,19 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1.addressOf);
+ calloc.free(c1.addressOf);
}
void testTypeTest() {
- Coordinate c = Coordinate.allocate(10, 10, nullptr);
+ Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
Expect.isTrue(c is Struct);
Expect.isTrue(c.addressOf is Pointer<Coordinate>);
- free(c.addressOf);
+ calloc.free(c.addressOf);
}
void testUtf8() {
final String test = 'Hasta Mañana';
final Pointer<Utf8> medium = Utf8.toUtf8(test);
Expect.equals(test, Utf8.fromUtf8(medium));
- free(medium);
+ calloc.free(medium);
}
diff --git a/tests/ffi/variance_function_test.dart b/tests/ffi/variance_function_test.dart
index 539c245..3db0147 100644
--- a/tests/ffi/variance_function_test.dart
+++ b/tests/ffi/variance_function_test.dart
@@ -12,11 +12,12 @@
import 'dart:ffi';
-import 'dylib_utils.dart';
-
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+import 'dylib_utils.dart';
+
typedef Int64PointerParamOpDart = void Function(Pointer<Int64>);
typedef Int64PointerParamOp = Void Function(Pointer<Int64>);
typedef NaTyPointerParamOpDart = void Function(Pointer<NativeType>);
@@ -38,19 +39,19 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<Int64PointerParamOp>>(paramOpName);
final f = fp.asFunction<Int64PointerParamOpDart>();
- final arg = allocate<Int64>();
+ final arg = calloc<Int64>();
f(arg);
- free(arg);
+ calloc.free(arg);
}
void paramInvariant2() {
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final arg = allocate<Int64>().cast<NativeType>();
+ final arg = calloc<Int64>().cast<NativeType>();
Expect.type<Pointer<NativeType>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
// Pass a statically and dynamically subtyped argument.
@@ -58,10 +59,10 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final arg = allocate<Int64>();
+ final arg = calloc<Int64>();
Expect.type<Pointer<Int64>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
// Pass a statically subtyped but dynamically invariant argument.
@@ -69,10 +70,10 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final Pointer<NativeType> arg = allocate<Int64>();
+ final Pointer<NativeType> arg = calloc<Int64>();
Expect.type<Pointer<Int64>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
void returnInvariant1() {
@@ -220,7 +221,7 @@
}
void fromFunctionTests() {
- data = allocate();
+ data = calloc();
for (int i = 0; i < 100; ++i) {
callbackParamInvariant1(); // Pointer<Int64> invariant
callbackParamInvariant2(); // Pointer<NativeType> invariant
@@ -229,7 +230,7 @@
callbackReturnInvariant1(); // Pointer<Int64> invariant
callbackReturnInvariant2(); // Pointer<NativeType> invariant
}
- free(data);
+ calloc.free(data);
}
void main() {
diff --git a/tests/ffi/vmspecific_enable_ffi_test.dart b/tests/ffi/vmspecific_enable_ffi_test.dart
index f44753d..ce90607 100644
--- a/tests/ffi/vmspecific_enable_ffi_test.dart
+++ b/tests/ffi/vmspecific_enable_ffi_test.dart
@@ -7,11 +7,14 @@
// VMOptions=--enable-ffi=false
import 'dart:ffi'; //# 01: compile-time error
+
import 'package:ffi/ffi.dart'; //# 01: compile-time error
+import 'calloc.dart'; //# 01: compile-time error
+
void main() {
Pointer<Int8> p = //# 01: compile-time error
- allocate(); //# 01: compile-time error
+ calloc(); //# 01: compile-time error
print(p.address); //# 01: compile-time error
- free(p); //# 01: compile-time error
+ calloc.free(p); //# 01: compile-time error
}
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index 870de9c..cbce8e6 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -10,6 +10,7 @@
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
void main() {
@@ -53,6 +54,8 @@
testEmptyStructAsFunctionReturn();
testEmptyStructFromFunctionArgument();
testEmptyStructFromFunctionReturn();
+ testAllocateGeneric();
+ testAllocateNativeType();
}
typedef Int8UnOp = Int8 Function(Int8);
@@ -65,20 +68,20 @@
return result;
}
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
- free(p);
+ calloc.free(p);
}
void testGetGeneric2() {
T? generic<T extends Object>() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
T? result;
result = p.value; //# 21: compile-time error
- free(p);
+ calloc.free(p);
return result;
}
@@ -86,12 +89,12 @@
}
void testGetVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value; //# 22: compile-time error
- free(p1);
+ calloc.free(p1);
}
void testGetNativeFunction() {
@@ -104,14 +107,14 @@
}
void testGetTypeMismatch() {
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
Pointer<Int16> typedNull = nullptr;
p.value = typedNull;
// this fails to compile due to type mismatch
Pointer<Int8> p2 = p.value; //# 25: compile-time error
- free(p);
+ calloc.free(p);
}
void testSetGeneric() {
@@ -119,30 +122,30 @@
p.value = 123; //# 26: compile-time error
}
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
- free(p);
+ calloc.free(p);
}
void testSetGeneric2() {
void generic<T extends Object>(T arg) {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = arg; //# 27: compile-time error
- free(p);
+ calloc.free(p);
}
generic<int>(123);
}
void testSetVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value = 1234; //# 28: compile-time error
- free(p1);
+ calloc.free(p1);
}
void testSetNativeFunction() {
@@ -157,16 +160,16 @@
void testSetTypeMismatch() {
// the pointer to pointer types must match up
- Pointer<Int8> pHelper = allocate();
+ Pointer<Int8> pHelper = calloc();
pHelper.value = 123;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// this fails to compile due to type mismatch
p.value = pHelper; //# 40: compile-time error
- free(pHelper);
- free(p);
+ calloc.free(pHelper);
+ calloc.free(p);
}
void testAsFunctionGeneric() {
@@ -475,6 +478,8 @@
class IStruct implements Struct {} //# 815: compile-time error
+class IOpaque implements Opaque {} //# 816: compile-time error
+
class MyClass {
int x;
MyClass(this.x);
@@ -550,3 +555,17 @@
class HasNestedEmptyStruct extends Struct {
external EmptyStruct nestedEmptyStruct; //# 1106: compile-time error
}
+
+void testAllocateGeneric() {
+ Pointer<T> generic<T extends NativeType>() {
+ Pointer<T> pointer = nullptr;
+ pointer = calloc(); //# 1320: compile-time error
+ return pointer;
+ }
+
+ Pointer p = generic<Int64>();
+}
+
+void testAllocateNativeType() {
+ calloc(); //# 1321: compile-time error
+}
diff --git a/tests/ffi_2/aliasing_test.dart b/tests/ffi_2/aliasing_test.dart
index 6c2f698..946e1e4 100644
--- a/tests/ffi_2/aliasing_test.dart
+++ b/tests/ffi_2/aliasing_test.dart
@@ -13,6 +13,7 @@
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'calloc.dart';
import 'ffi_test_helpers.dart';
void main() {
@@ -35,28 +36,28 @@
}
void testNonAlias() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
source.value = 42;
final int a = source.value;
source.value = 1984;
// alias.value should be re-executed, as we wrote to alias.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasCast() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = source.cast<Int8>().cast<Int64>();
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasCast2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = source.cast<Int16>().cast<Int64>();
final alias2 = source.cast<Int8>().cast<Int64>();
alias.value = 42;
@@ -64,22 +65,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasOffsetBy() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final alias = source.offsetBy(8).offsetBy(-8);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasOffsetBy2() {
- final source = allocate<Int64>(count: 3);
+ final source = calloc<Int64>(3);
final alias = source.offsetBy(16).offsetBy(-16);
final alias2 = source.offsetBy(8).offsetBy(-8);
alias.value = 42;
@@ -87,22 +88,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasElementAt() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final alias = source.elementAt(1).elementAt(-1);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasElementAt2() {
- final source = allocate<Int64>(count: 3);
+ final source = calloc<Int64>(3);
final alias = source.elementAt(2).elementAt(-2);
final alias2 = source.elementAt(1).elementAt(-1);
alias.value = 42;
@@ -110,22 +111,22 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddress() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = Pointer<Int64>.fromAddress(source.address);
source.value = 42;
final int a = source.value;
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddress2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias = Pointer<Int64>.fromAddress(source.address);
final alias2 = Pointer<Int64>.fromAddress(source.address);
alias.value = 42;
@@ -133,12 +134,12 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddressViaMemory() {
- final helper = allocate<IntPtr>();
- final source = allocate<Int64>();
+ final helper = calloc<IntPtr>();
+ final source = calloc<Int64>();
helper.value = source.address;
final alias = Pointer<Int64>.fromAddress(helper.value);
source.value = 42;
@@ -146,13 +147,13 @@
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(helper);
- free(source);
+ calloc.free(helper);
+ calloc.free(source);
}
void testAliasFromAddressViaMemory2() {
- final helper = allocate<IntPtr>();
- final source = allocate<Int64>();
+ final helper = calloc<IntPtr>();
+ final source = calloc<Int64>();
helper.value = source.address;
final alias = Pointer<Int64>.fromAddress(helper.value);
final alias2 = Pointer<Int64>.fromAddress(helper.value);
@@ -161,8 +162,8 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(helper);
- free(source);
+ calloc.free(helper);
+ calloc.free(source);
}
typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
@@ -172,7 +173,7 @@
.lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
void testAliasFromAddressViaNativeFunction() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias =
Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
source.value = 42;
@@ -180,11 +181,11 @@
alias.value = 1984;
// source.value should be re-executed, we wrote alias which aliases source.
Expect.notEquals(a, source.value);
- free(source);
+ calloc.free(source);
}
void testAliasFromAddressViaNativeFunction2() {
- final source = allocate<Int64>();
+ final source = calloc<Int64>();
final alias =
Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
final alias2 =
@@ -194,7 +195,7 @@
alias2.value = 1984;
// alias.value should be re-executed, we wrote alias2 which aliases alias.
Expect.notEquals(a, alias.value);
- free(source);
+ calloc.free(source);
}
@pragma('vm:never-inline')
@@ -202,11 +203,11 @@
source.offsetBy(7).cast<Int8>();
testPartialOverlap() {
- final source = allocate<Int64>(count: 2);
+ final source = calloc<Int64>(2);
final derived = makeDerived(source);
source.value = 0x1122334455667788;
final int value = source.value;
derived.value = 0xaa;
Expect.notEquals(value, source.value);
- free(source);
+ calloc.free(source);
}
diff --git a/tests/ffi_2/allocator_test.dart b/tests/ffi_2/allocator_test.dart
new file mode 100644
index 0000000..396f5c9
--- /dev/null
+++ b/tests/ffi_2/allocator_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, 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.
+
+// Tests that we can implement the Allocator interface.
+
+import 'dart:ffi';
+
+class MyAllocator implements Allocator {
+ const MyAllocator();
+
+ @override
+ Pointer<T> allocate<T extends NativeType>(int numBytes, {int alignment}) {
+ throw "Not implemented";
+ }
+
+ void free(Pointer pointer) {}
+}
+
+const myAllocator = MyAllocator();
+
+void main() {
+ print(myAllocator);
+}
diff --git a/tests/ffi_2/calloc.dart b/tests/ffi_2/calloc.dart
new file mode 100644
index 0000000..a433e39
--- /dev/null
+++ b/tests/ffi_2/calloc.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2021, 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.
+
+// TODO(https://dartbug.com/44621): Remove this copy when package:ffi can be
+// rolled. We need to wait until the `Allocator` interface has rolled into
+// Flutter.
+
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary stdlib = Platform.isWindows
+ ? DynamicLibrary.open('kernel32.dll')
+ : DynamicLibrary.process();
+
+typedef PosixCallocNative = Pointer Function(IntPtr num, IntPtr size);
+typedef PosixCalloc = Pointer Function(int num, int size);
+final PosixCalloc posixCalloc =
+ stdlib.lookupFunction<PosixCallocNative, PosixCalloc>('calloc');
+
+typedef PosixFreeNative = Void Function(Pointer);
+typedef PosixFree = void Function(Pointer);
+final PosixFree posixFree =
+ stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
+
+typedef WinGetProcessHeapFn = Pointer Function();
+final WinGetProcessHeapFn winGetProcessHeap = stdlib
+ .lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
+final Pointer processHeap = winGetProcessHeap();
+
+typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
+typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
+final WinHeapAlloc winHeapAlloc =
+ stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
+
+typedef WinHeapFreeNative = Int32 Function(
+ Pointer heap, Uint32 flags, Pointer memory);
+typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
+final WinHeapFree winHeapFree =
+ stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
+
+const int HEAP_ZERO_MEMORY = 8;
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+class _CallocAllocator implements Allocator {
+ const _CallocAllocator();
+
+ /// Allocates [byteCount] bytes of zero-initialized of memory on the native
+ /// heap.
+ ///
+ /// For POSIX-based systems, this uses `calloc`. On Windows, it uses
+ /// `HeapAlloc` against the default public heap.
+ ///
+ /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
+ /// satisfied.
+ // TODO: Stop ignoring alignment if it's large, for example for SSE data.
+ @override
+ Pointer<T> allocate<T extends NativeType>(int byteCount, {int alignment}) {
+ Pointer<T> result;
+ if (Platform.isWindows) {
+ result = winHeapAlloc(processHeap, /*flags=*/ HEAP_ZERO_MEMORY, byteCount)
+ .cast();
+ } else {
+ result = posixCalloc(byteCount, 1).cast();
+ }
+ if (result.address == 0) {
+ throw ArgumentError('Could not allocate $byteCount bytes.');
+ }
+ return result;
+ }
+
+ /// Releases memory allocated on the native heap.
+ ///
+ /// For POSIX-based systems, this uses `free`. On Windows, it uses `HeapFree`
+ /// against the default public heap. It may only be used against pointers
+ /// allocated in a manner equivalent to [allocate].
+ ///
+ /// Throws an [ArgumentError] if the memory pointed to by [pointer] cannot be
+ /// freed.
+ ///
+ // TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
+ // of testing the return integer to be non-zero.
+ @override
+ void free(Pointer pointer) {
+ if (Platform.isWindows) {
+ if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
+ throw ArgumentError('Could not free $pointer.');
+ }
+ } else {
+ posixFree(pointer);
+ }
+ }
+}
+
+/// Manages memory on the native heap.
+///
+/// Initializes newly allocated memory to zero. Use [malloc] for unintialized
+/// memory allocation.
+///
+/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
+/// `HeapAlloc` with [HEAP_ZERO_MEMORY] and `HeapFree` against the default
+/// public heap.
+const Allocator calloc = _CallocAllocator();
diff --git a/tests/ffi_2/calloc_test.dart b/tests/ffi_2/calloc_test.dart
new file mode 100644
index 0000000..b8b9bbf
--- /dev/null
+++ b/tests/ffi_2/calloc_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, 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.
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'calloc.dart';
+import 'coordinate.dart';
+
+void main() {
+ testZeroInt();
+ testZeroFloat();
+ testZeroStruct();
+}
+
+void testZeroInt() {
+ final p = calloc<Uint8>();
+ Expect.equals(0, p.value);
+ calloc.free(p);
+}
+
+void testZeroFloat() {
+ final p = calloc<Float>();
+ Expect.approxEquals(0.0, p.value);
+ calloc.free(p);
+}
+
+void testZeroStruct() {
+ final p = calloc<Coordinate>();
+ Expect.approxEquals(0, p.ref.x);
+ Expect.approxEquals(0, p.ref.y);
+ Expect.equals(nullptr, p.ref.next);
+ calloc.free(p);
+}
diff --git a/tests/ffi_2/coordinate.dart b/tests/ffi_2/coordinate.dart
index 92dd9d4..92dfbf0 100644
--- a/tests/ffi_2/coordinate.dart
+++ b/tests/ffi_2/coordinate.dart
@@ -17,8 +17,9 @@
Pointer<Coordinate> next;
- factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
- return allocate<Coordinate>().ref
+ factory Coordinate.allocate(
+ Allocator allocator, double x, double y, Pointer<Coordinate> next) {
+ return allocator<Coordinate>().ref
..x = x
..y = y
..next = next;
diff --git a/tests/ffi_2/data_not_asan_test.dart b/tests/ffi_2/data_not_asan_test.dart
index e95658f..69257d6 100644
--- a/tests/ffi_2/data_not_asan_test.dart
+++ b/tests/ffi_2/data_not_asan_test.dart
@@ -4,7 +4,7 @@
//
// Dart test program for testing dart:ffi primitive data pointers.
//
-// These mallocs trigger an asan alarm, so these tests are in a separate file
+// These callocs trigger an asan alarm, so these tests are in a separate file
// which is excluded in asan mode.
import 'dart:ffi';
@@ -12,6 +12,8 @@
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'calloc.dart';
+
void main() {
testPointerAllocateTooLarge();
testPointerAllocateNegative();
@@ -20,16 +22,16 @@
void testPointerAllocateTooLarge() {
// Try to allocate something that doesn't fit in 64 bit address space.
int maxInt = 9223372036854775807; // 2^63 - 1
- Expect.throws(() => allocate<Int64>(count: maxInt));
+ Expect.throws(() => calloc<Int64>(maxInt));
// Try to allocate almost the full 64 bit address space.
int maxInt1_8 = 1152921504606846975; // 2^60 -1
- Expect.throws(() => allocate<Int64>(count: maxInt1_8));
+ Expect.throws(() => calloc<Int64>(maxInt1_8));
}
void testPointerAllocateNegative() {
// Passing in -1 will be converted into an unsigned integer. So, it will try
// to allocate SIZE_MAX - 1 + 1 bytes. This will fail as it is the max amount
// of addressable memory on the system.
- Expect.throws(() => allocate<Int8>(count: -1));
+ Expect.throws(() => calloc<Int8>(-1));
}
diff --git a/tests/ffi_2/data_test.dart b/tests/ffi_2/data_test.dart
index a533ced..8fca1a1 100644
--- a/tests/ffi_2/data_test.dart
+++ b/tests/ffi_2/data_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'ffi_test_helpers.dart';
void main() {
@@ -44,10 +45,8 @@
testTypeTest();
testToString();
testEquality();
- testAllocateGeneric();
testAllocateVoid();
testAllocateNativeFunction();
- testAllocateNativeType();
testSizeOfGeneric();
testSizeOfVoid();
testSizeOfNativeFunction();
@@ -58,66 +57,66 @@
}
void testPointerBasic() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 42;
Expect.equals(42, p.value);
- free(p);
+ calloc.free(p);
}
void testPointerFromPointer() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 1337;
int ptr = p.address;
Pointer<Int64> p2 = Pointer.fromAddress(ptr);
Expect.equals(1337, p2.value);
- free(p);
+ calloc.free(p);
}
void testPointerPointerArithmetic() {
- Pointer<Int64> p = allocate(count: 2);
+ Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p.elementAt(1);
p2.value = 100;
Pointer<Int64> p3 = p.offsetBy(8);
Expect.equals(100, p3.value);
- free(p);
+ calloc.free(p);
}
void testPointerPointerArithmeticSizes() {
- Pointer<Int64> p = allocate(count: 2);
+ Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p.elementAt(1);
int addr = p.address;
Expect.equals(addr + 8, p2.address);
- free(p);
+ calloc.free(p);
- Pointer<Int32> p3 = allocate(count: 2);
+ Pointer<Int32> p3 = calloc(2);
Pointer<Int32> p4 = p3.elementAt(1);
addr = p3.address;
Expect.equals(addr + 4, p4.address);
- free(p3);
+ calloc.free(p3);
}
void testPointerAllocateZero() {
// > If size is 0, either a null pointer or a unique pointer that can be
- // > successfully passed to free() shall be returned.
- // http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
+ // > successfully passed to calloc.free() shall be returned.
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/calloc.html
//
// Null pointer throws a Dart exception.
bool returnedNullPointer = false;
Pointer<Int8> p;
try {
- p = allocate<Int8>(count: 0);
+ p = calloc<Int8>(0);
} on Exception {
returnedNullPointer = true;
}
if (!returnedNullPointer) {
- free(p);
+ calloc.free(p);
}
}
void testPointerCast() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.cast<Int32>(); // gets the correct type args back
- free(p);
+ calloc.free(p);
}
void testCastGeneric() {
@@ -125,9 +124,9 @@
return p.cast();
}
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Pointer<Int64> p2 = generic(p);
- free(p);
+ calloc.free(p);
}
void testCastGeneric2() {
@@ -135,41 +134,41 @@
return p.cast();
}
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Pointer<Int64> p2 = generic(p);
- free(p);
+ calloc.free(p);
}
void testCastNativeType() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.cast<Pointer>();
- free(p);
+ calloc.free(p);
}
void testCondensedNumbersInt8() {
- Pointer<Int8> p = allocate(count: 8);
+ Pointer<Int8> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p[i] = i * 3;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
Expect.equals(i * 3, p[i]);
}
- free(p);
+ calloc.free(p);
}
void testCondensedNumbersFloat() {
- Pointer<Float> p = allocate(count: 8);
+ Pointer<Float> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p[i] = 1.511366173271439e-13;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
Expect.equals(1.511366173271439e-13, p[i]);
}
- free(p);
+ calloc.free(p);
}
void testRangeInt8() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 127;
Expect.equals(127, p.value);
p.value = -128;
@@ -184,11 +183,11 @@
Expect.equals(0x000000000000007F, 127);
p.value = -129;
Expect.equals(127, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint8() {
- Pointer<Uint8> p = allocate();
+ Pointer<Uint8> p = calloc();
p.value = 255;
Expect.equals(255, p.value);
p.value = 0;
@@ -203,11 +202,11 @@
Expect.equals(0x00000000000000FF, 255);
p.value = -1;
Expect.equals(255, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt16() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
p.value = 0x7FFF;
Expect.equals(0x7FFF, p.value);
p.value = -0x8000;
@@ -216,11 +215,11 @@
Expect.equals(0xFFFFFFFFFFFF8000, p.value); // truncated and sign extended
p.value = -0x8001;
Expect.equals(0x7FFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint16() {
- Pointer<Uint16> p = allocate();
+ Pointer<Uint16> p = calloc();
p.value = 0xFFFF;
Expect.equals(0xFFFF, p.value);
p.value = 0;
@@ -229,11 +228,11 @@
Expect.equals(0, p.value); // truncated
p.value = -1;
Expect.equals(0xFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt32() {
- Pointer<Int32> p = allocate();
+ Pointer<Int32> p = calloc();
p.value = 0x7FFFFFFF;
Expect.equals(0x7FFFFFFF, p.value);
p.value = -0x80000000;
@@ -242,11 +241,11 @@
Expect.equals(0xFFFFFFFF80000000, p.value); // truncated and sign extended
p.value = -0x80000001;
Expect.equals(0x7FFFFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeUint32() {
- Pointer<Uint32> p = allocate();
+ Pointer<Uint32> p = calloc();
p.value = 0xFFFFFFFF;
Expect.equals(0xFFFFFFFF, p.value);
p.value = 0;
@@ -255,20 +254,20 @@
Expect.equals(0, p.value); // truncated
p.value = -1;
Expect.equals(0xFFFFFFFF, p.value); // truncated
- free(p);
+ calloc.free(p);
}
void testRangeInt64() {
- Pointer<Int64> p = allocate();
+ Pointer<Int64> p = calloc();
p.value = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.value);
p.value = -0x8000000000000000; // -2 ^ 63
Expect.equals(-0x8000000000000000, p.value);
- free(p);
+ calloc.free(p);
}
void testRangeUint64() {
- Pointer<Uint64> p = allocate();
+ Pointer<Uint64> p = calloc();
p.value = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.value);
p.value = -0x8000000000000000; // -2 ^ 63 interpreted as 2 ^ 63
@@ -279,69 +278,69 @@
p.value = -1; // -1 interpreted as 2 ^ 64 - 1
Expect.equals(-1, p.value);
Expect.equals(0xFFFFFFFFFFFFFFFF, p.value);
- free(p);
+ calloc.free(p);
}
void testRangeIntPtr() {
- Pointer<IntPtr> p = allocate();
+ Pointer<IntPtr> p = calloc();
int pAddr = p.address;
p.value = pAddr; // its own address should fit
p.value = 0x7FFFFFFF; // and 32 bit addresses should fit
Expect.equals(0x7FFFFFFF, p.value);
p.value = -0x80000000;
Expect.equals(-0x80000000, p.value);
- free(p);
+ calloc.free(p);
}
void testFloat() {
- Pointer<Float> p = allocate();
+ Pointer<Float> p = calloc();
p.value = 1.511366173271439e-13;
Expect.equals(1.511366173271439e-13, p.value);
p.value = 1.4260258159703532e-105; // float does not have enough precision
Expect.notEquals(1.4260258159703532e-105, p.value);
- free(p);
+ calloc.free(p);
}
void testDouble() {
- Pointer<Double> p = allocate();
+ Pointer<Double> p = calloc();
p.value = 1.4260258159703532e-105;
Expect.equals(1.4260258159703532e-105, p.value);
- free(p);
+ calloc.free(p);
}
void testVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast(); // make this dart pointer opaque
p2.address; // we can print the address
- free(p2);
+ calloc.free(p2);
}
void testPointerPointer() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
p.value = 17;
- Pointer<Pointer<Int16>> p2 = allocate();
+ Pointer<Pointer<Int16>> p2 = calloc();
p2.value = p;
Expect.equals(17, p2.value.value);
- free(p2);
- free(p);
+ calloc.free(p2);
+ calloc.free(p);
}
void testPointerPointerNull() {
- Pointer<Pointer<Int8>> pointerToPointer = allocate();
+ Pointer<Pointer<Int8>> pointerToPointer = calloc();
Pointer<Int8> value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
- value = allocate();
+ value = calloc();
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.isNotNull(value);
- free(value);
+ calloc.free(value);
value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
- free(pointerToPointer);
+ calloc.free(pointerToPointer);
}
void testSizeOf() {
@@ -365,7 +364,7 @@
head.value = value;
return;
}
- Pointer<IntPtr> next = allocate();
+ Pointer<IntPtr> next = calloc();
head.value = next.address;
createChain(next, length - 1, value);
}
@@ -380,14 +379,14 @@
void freeChain(Pointer<IntPtr> head, int length) {
Pointer<IntPtr> next = Pointer.fromAddress(head.value);
- free(head);
+ calloc.free(head);
if (length == 0) {
return;
}
freeChain(next, length - 1);
}
- Pointer<IntPtr> head = allocate();
+ Pointer<IntPtr> head = calloc();
createChain(head, length, 512);
int tailValue = getChainValue(head, length);
Expect.equals(512, tailValue);
@@ -395,16 +394,16 @@
}
void testTypeTest() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Expect.isTrue(p is Pointer);
- free(p);
+ calloc.free(p);
}
void testToString() {
- Pointer<Int16> p = allocate();
+ Pointer<Int16> p = calloc();
Expect.stringEquals(
"Pointer<Int16>: address=0x", p.toString().substring(0, 26));
- free(p);
+ calloc.free(p);
Pointer<Int64> p2 = Pointer.fromAddress(0x123abc);
Expect.stringEquals("Pointer<Int64>: address=0x123abc", p2.toString());
}
@@ -423,32 +422,15 @@
typedef Int8UnOp = Int8 Function(Int8);
-void testAllocateGeneric() {
- Pointer<T> generic<T extends NativeType>() {
- Pointer<T> pointer;
- pointer = allocate();
- return pointer;
- }
-
- Pointer p = generic<Int64>();
- free(p);
-}
-
void testAllocateVoid() {
Expect.throws(() {
- Pointer<Void> p = allocate();
+ Pointer<Void> p = calloc();
});
}
void testAllocateNativeFunction() {
Expect.throws(() {
- Pointer<NativeFunction<Int8UnOp>> p = allocate();
- });
-}
-
-void testAllocateNativeType() {
- Expect.throws(() {
- allocate();
+ Pointer<NativeFunction<Int8UnOp>> p = calloc();
});
}
@@ -482,7 +464,7 @@
}
void testDynamicInvocation() {
- dynamic p = allocate<Int8>();
+ dynamic p = calloc<Int8>();
Expect.throws(() {
final int i = p.value;
});
@@ -490,7 +472,7 @@
p.elementAt(5); // Works, but is slow.
final int addr = p.address;
final Pointer<Int16> p2 = p.cast<Int16>();
- free(p);
+ calloc.free(p);
}
final nullableInt64ElementAt1 = ffiTestFunctions.lookupFunction<
diff --git a/tests/ffi_2/extension_methods_test.dart b/tests/ffi_2/extension_methods_test.dart
index 19bc44b..3524a7f 100644
--- a/tests/ffi_2/extension_methods_test.dart
+++ b/tests/ffi_2/extension_methods_test.dart
@@ -7,6 +7,8 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
main(List<String> arguments) {
for (int i = 0; i < 100; i++) {
testStoreLoad();
@@ -15,7 +17,7 @@
}
testStoreLoad() {
- final p = allocate<Int8>(count: 2);
+ final p = calloc<Int8>(2);
p.value = 10;
Expect.equals(10, p.value);
p[1] = 20;
@@ -30,33 +32,33 @@
final pUseNegative = p.elementAt(1);
Expect.equals(10, pUseNegative[-1]);
- final p1 = allocate<Double>(count: 2);
+ final p1 = calloc<Double>(2);
p1.value = 10.0;
Expect.approxEquals(10.0, p1.value);
p1[1] = 20.0;
Expect.approxEquals(20.0, p1[1]);
- free(p1);
+ calloc.free(p1);
- final p2 = allocate<Pointer<Int8>>(count: 2);
+ final p2 = calloc<Pointer<Int8>>(2);
p2.value = p;
Expect.equals(p, p2.value);
p2[1] = p;
Expect.equals(p, p2[1]);
- free(p2);
- free(p);
+ calloc.free(p2);
+ calloc.free(p);
- final p3 = allocate<Foo>();
+ final p3 = calloc<Foo>();
Foo foo = p3.ref;
foo.a = 1;
Expect.equals(1, foo.a);
- free(p3);
+ calloc.free(p3);
}
testReifiedGeneric() {
- final p = allocate<Pointer<Int8>>();
+ final p = calloc<Pointer<Int8>>();
Pointer<Pointer<NativeType>> p2 = p;
Expect.isTrue(p2.value is Pointer<Int8>);
- free(p);
+ calloc.free(p);
}
class Foo extends Struct {
diff --git a/tests/ffi_2/external_typed_data_test.dart b/tests/ffi_2/external_typed_data_test.dart
index 8d19f79..18e8e3c 100644
--- a/tests/ffi_2/external_typed_data_test.dart
+++ b/tests/ffi_2/external_typed_data_test.dart
@@ -9,6 +9,8 @@
import 'package:expect/expect.dart';
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
main() {
testInt8Load();
testInt8Store();
@@ -41,162 +43,162 @@
void testInt8Load() {
// Load
- Pointer<Int8> ptr = allocate();
+ Pointer<Int8> ptr = calloc();
ptr.value = 0xff;
Int8List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt8Store() {
// Store
- Pointer<Int8> ptr = allocate();
+ Pointer<Int8> ptr = calloc();
Int8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint8Load() {
// Load
- Pointer<Uint8> ptr = allocate();
+ Pointer<Uint8> ptr = calloc();
ptr.value = 0xff;
Uint8List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint8Store() {
// Store
- Pointer<Uint8> ptr = allocate();
+ Pointer<Uint8> ptr = calloc();
Uint8List list = ptr.asTypedList(1);
list[0] = 0xff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt16Load() {
// Load
- Pointer<Int16> ptr = allocate();
+ Pointer<Int16> ptr = calloc();
ptr.value = 0xffff;
Int16List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt16Store() {
// Store
- Pointer<Int16> ptr = allocate();
+ Pointer<Int16> ptr = calloc();
Int16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint16Load() {
// Load
- Pointer<Uint16> ptr = allocate();
+ Pointer<Uint16> ptr = calloc();
ptr.value = 0xffff;
Uint16List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint16Store() {
// Store
- Pointer<Uint16> ptr = allocate();
+ Pointer<Uint16> ptr = calloc();
Uint16List list = ptr.asTypedList(1);
list[0] = 0xffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt32Load() {
// Load
- Pointer<Int32> ptr = allocate();
+ Pointer<Int32> ptr = calloc();
ptr.value = 0xffffffff;
Int32List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt32Store() {
// Store
- Pointer<Int32> ptr = allocate();
+ Pointer<Int32> ptr = calloc();
Int32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint32Load() {
// Load
- Pointer<Uint32> ptr = allocate();
+ Pointer<Uint32> ptr = calloc();
ptr.value = 0xffffffff;
Uint32List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint32Store() {
// Store
- Pointer<Uint32> ptr = allocate();
+ Pointer<Uint32> ptr = calloc();
Uint32List list = ptr.asTypedList(1);
list[0] = 0xffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffff);
- free(ptr);
+ calloc.free(ptr);
}
void testInt64Load() {
// Load
- Pointer<Int64> ptr = allocate();
+ Pointer<Int64> ptr = calloc();
ptr.value = 0xffffffffffffffff;
Int64List list = ptr.asTypedList(1);
Expect.equals(list[0], -1);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testInt64Store() {
// Store
- Pointer<Int64> ptr = allocate();
+ Pointer<Int64> ptr = calloc();
Int64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, -1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint64Load() {
// Load
- Pointer<Uint64> ptr = allocate();
+ Pointer<Uint64> ptr = calloc();
ptr.value = 0xffffffffffffffff;
Uint64List list = ptr.asTypedList(1);
Expect.equals(list[0], 0xffffffffffffffff);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testUint64Store() {
// Store
- Pointer<Uint64> ptr = allocate();
+ Pointer<Uint64> ptr = calloc();
Uint64List list = ptr.asTypedList(1);
list[0] = 0xffffffffffffffff;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, 0xffffffffffffffff);
- free(ptr);
+ calloc.free(ptr);
}
double maxFloat = (2 - pow(2, -23)) * pow(2, 127);
@@ -204,47 +206,47 @@
void testFloatLoad() {
// Load
- Pointer<Float> ptr = allocate();
+ Pointer<Float> ptr = calloc();
ptr.value = maxFloat;
Float32List list = ptr.asTypedList(1);
Expect.equals(list[0], maxFloat);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testFloatStore() {
// Store
- Pointer<Float> ptr = allocate();
+ Pointer<Float> ptr = calloc();
Float32List list = ptr.asTypedList(1);
list[0] = maxFloat;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxFloat);
- free(ptr);
+ calloc.free(ptr);
}
void testDoubleLoad() {
// Load
- Pointer<Double> ptr = allocate();
+ Pointer<Double> ptr = calloc();
ptr.value = maxDouble;
Float64List list = ptr.asTypedList(1);
Expect.equals(list[0], maxDouble);
Expect.equals(list.length, 1);
- free(ptr);
+ calloc.free(ptr);
}
void testDoubleStore() {
// Store
- Pointer<Double> ptr = allocate();
+ Pointer<Double> ptr = calloc();
Float64List list = ptr.asTypedList(1);
list[0] = maxDouble;
Expect.equals(list.length, 1);
Expect.equals(ptr.value, maxDouble);
- free(ptr);
+ calloc.free(ptr);
}
void testArrayLoad() {
const int count = 0x100;
- Pointer<Int32> ptr = allocate(count: count);
+ Pointer<Int32> ptr = calloc(count);
for (int i = 0; i < count; ++i) {
ptr[i] = i;
}
@@ -252,12 +254,12 @@
for (int i = 0; i < count; ++i) {
Expect.equals(array[i], i);
}
- free(ptr);
+ calloc.free(ptr);
}
void testArrayStore() {
const int count = 0x100;
- Pointer<Int32> ptr = allocate(count: count);
+ Pointer<Int32> ptr = calloc(count);
Int32List array = ptr.asTypedList(count);
for (int i = 0; i < count; ++i) {
array[i] = i;
@@ -265,7 +267,7 @@
for (int i = 0; i < count; ++i) {
Expect.equals(ptr[i], i);
}
- free(ptr);
+ calloc.free(ptr);
}
void testNegativeArray() {
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
index bebd119..e11d962 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -16,6 +16,7 @@
import "package:ffi/ffi.dart";
import 'callback_tests_utils.dart';
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
@@ -5412,7 +5413,7 @@
Struct1ByteInt returnStruct1ByteIntResult = Struct1ByteInt();
Struct1ByteInt returnStruct1ByteIntCalculateResult() {
- Struct1ByteInt result = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt result = calloc<Struct1ByteInt>().ref;
result.a0 = returnStruct1ByteInt_a0;
@@ -5447,13 +5448,13 @@
}
void returnStruct1ByteIntAfterCallback() {
- free(returnStruct1ByteIntResult.addressOf);
+ calloc.free(returnStruct1ByteIntResult.addressOf);
final result = returnStruct1ByteIntCalculateResult();
print("after callback result = $result");
- free(returnStruct1ByteIntResult.addressOf);
+ calloc.free(returnStruct1ByteIntResult.addressOf);
}
typedef ReturnStruct3BytesHomogeneousUint8Type = Struct3BytesHomogeneousUint8
@@ -5471,7 +5472,7 @@
Struct3BytesHomogeneousUint8
returnStruct3BytesHomogeneousUint8CalculateResult() {
Struct3BytesHomogeneousUint8 result =
- allocate<Struct3BytesHomogeneousUint8>().ref;
+ calloc<Struct3BytesHomogeneousUint8>().ref;
result.a0 = returnStruct3BytesHomogeneousUint8_a0;
result.a1 = returnStruct3BytesHomogeneousUint8_a1;
@@ -5511,13 +5512,13 @@
}
void returnStruct3BytesHomogeneousUint8AfterCallback() {
- free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct3BytesHomogeneousUint8Result.addressOf);
final result = returnStruct3BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct3BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct3BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct3BytesInt2ByteAlignedType = Struct3BytesInt2ByteAligned
@@ -5533,7 +5534,7 @@
Struct3BytesInt2ByteAligned returnStruct3BytesInt2ByteAlignedCalculateResult() {
Struct3BytesInt2ByteAligned result =
- allocate<Struct3BytesInt2ByteAligned>().ref;
+ calloc<Struct3BytesInt2ByteAligned>().ref;
result.a0 = returnStruct3BytesInt2ByteAligned_a0;
result.a1 = returnStruct3BytesInt2ByteAligned_a1;
@@ -5571,13 +5572,13 @@
}
void returnStruct3BytesInt2ByteAlignedAfterCallback() {
- free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+ calloc.free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
final result = returnStruct3BytesInt2ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
+ calloc.free(returnStruct3BytesInt2ByteAlignedResult.addressOf);
}
typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
@@ -5594,7 +5595,7 @@
Struct4BytesHomogeneousInt16
returnStruct4BytesHomogeneousInt16CalculateResult() {
Struct4BytesHomogeneousInt16 result =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ calloc<Struct4BytesHomogeneousInt16>().ref;
result.a0 = returnStruct4BytesHomogeneousInt16_a0;
result.a1 = returnStruct4BytesHomogeneousInt16_a1;
@@ -5632,13 +5633,13 @@
}
void returnStruct4BytesHomogeneousInt16AfterCallback() {
- free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+ calloc.free(returnStruct4BytesHomogeneousInt16Result.addressOf);
final result = returnStruct4BytesHomogeneousInt16CalculateResult();
print("after callback result = $result");
- free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+ calloc.free(returnStruct4BytesHomogeneousInt16Result.addressOf);
}
typedef ReturnStruct7BytesHomogeneousUint8Type = Struct7BytesHomogeneousUint8
@@ -5660,7 +5661,7 @@
Struct7BytesHomogeneousUint8
returnStruct7BytesHomogeneousUint8CalculateResult() {
Struct7BytesHomogeneousUint8 result =
- allocate<Struct7BytesHomogeneousUint8>().ref;
+ calloc<Struct7BytesHomogeneousUint8>().ref;
result.a0 = returnStruct7BytesHomogeneousUint8_a0;
result.a1 = returnStruct7BytesHomogeneousUint8_a1;
@@ -5709,13 +5710,13 @@
}
void returnStruct7BytesHomogeneousUint8AfterCallback() {
- free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct7BytesHomogeneousUint8Result.addressOf);
final result = returnStruct7BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct7BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct7BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct7BytesInt4ByteAlignedType = Struct7BytesInt4ByteAligned
@@ -5732,7 +5733,7 @@
Struct7BytesInt4ByteAligned returnStruct7BytesInt4ByteAlignedCalculateResult() {
Struct7BytesInt4ByteAligned result =
- allocate<Struct7BytesInt4ByteAligned>().ref;
+ calloc<Struct7BytesInt4ByteAligned>().ref;
result.a0 = returnStruct7BytesInt4ByteAligned_a0;
result.a1 = returnStruct7BytesInt4ByteAligned_a1;
@@ -5773,13 +5774,13 @@
}
void returnStruct7BytesInt4ByteAlignedAfterCallback() {
- free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+ calloc.free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
final result = returnStruct7BytesInt4ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
+ calloc.free(returnStruct7BytesInt4ByteAlignedResult.addressOf);
}
typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
@@ -5794,7 +5795,7 @@
Struct8BytesInt returnStruct8BytesIntResult = Struct8BytesInt();
Struct8BytesInt returnStruct8BytesIntCalculateResult() {
- Struct8BytesInt result = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt result = calloc<Struct8BytesInt>().ref;
result.a0 = returnStruct8BytesInt_a0;
result.a1 = returnStruct8BytesInt_a1;
@@ -5833,13 +5834,13 @@
}
void returnStruct8BytesIntAfterCallback() {
- free(returnStruct8BytesIntResult.addressOf);
+ calloc.free(returnStruct8BytesIntResult.addressOf);
final result = returnStruct8BytesIntCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesIntResult.addressOf);
+ calloc.free(returnStruct8BytesIntResult.addressOf);
}
typedef ReturnStruct8BytesHomogeneousFloatType = Struct8BytesHomogeneousFloat
@@ -5856,7 +5857,7 @@
Struct8BytesHomogeneousFloat
returnStruct8BytesHomogeneousFloatCalculateResult() {
Struct8BytesHomogeneousFloat result =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ calloc<Struct8BytesHomogeneousFloat>().ref;
result.a0 = returnStruct8BytesHomogeneousFloat_a0;
result.a1 = returnStruct8BytesHomogeneousFloat_a1;
@@ -5894,13 +5895,13 @@
}
void returnStruct8BytesHomogeneousFloatAfterCallback() {
- free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct8BytesHomogeneousFloatResult.addressOf);
final result = returnStruct8BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct8BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct8BytesMixedType = Struct8BytesMixed Function(
@@ -5915,7 +5916,7 @@
Struct8BytesMixed returnStruct8BytesMixedResult = Struct8BytesMixed();
Struct8BytesMixed returnStruct8BytesMixedCalculateResult() {
- Struct8BytesMixed result = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed result = calloc<Struct8BytesMixed>().ref;
result.a0 = returnStruct8BytesMixed_a0;
result.a1 = returnStruct8BytesMixed_a1;
@@ -5954,13 +5955,13 @@
}
void returnStruct8BytesMixedAfterCallback() {
- free(returnStruct8BytesMixedResult.addressOf);
+ calloc.free(returnStruct8BytesMixedResult.addressOf);
final result = returnStruct8BytesMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesMixedResult.addressOf);
+ calloc.free(returnStruct8BytesMixedResult.addressOf);
}
typedef ReturnStruct9BytesHomogeneousUint8Type = Struct9BytesHomogeneousUint8
@@ -5984,7 +5985,7 @@
Struct9BytesHomogeneousUint8
returnStruct9BytesHomogeneousUint8CalculateResult() {
Struct9BytesHomogeneousUint8 result =
- allocate<Struct9BytesHomogeneousUint8>().ref;
+ calloc<Struct9BytesHomogeneousUint8>().ref;
result.a0 = returnStruct9BytesHomogeneousUint8_a0;
result.a1 = returnStruct9BytesHomogeneousUint8_a1;
@@ -6039,13 +6040,13 @@
}
void returnStruct9BytesHomogeneousUint8AfterCallback() {
- free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct9BytesHomogeneousUint8Result.addressOf);
final result = returnStruct9BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct9BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct9BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct9BytesInt4Or8ByteAlignedType
@@ -6062,7 +6063,7 @@
Struct9BytesInt4Or8ByteAligned
returnStruct9BytesInt4Or8ByteAlignedCalculateResult() {
Struct9BytesInt4Or8ByteAligned result =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
result.a0 = returnStruct9BytesInt4Or8ByteAligned_a0;
result.a1 = returnStruct9BytesInt4Or8ByteAligned_a1;
@@ -6102,13 +6103,13 @@
}
void returnStruct9BytesInt4Or8ByteAlignedAfterCallback() {
- free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+ calloc.free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
final result = returnStruct9BytesInt4Or8ByteAlignedCalculateResult();
print("after callback result = $result");
- free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
+ calloc.free(returnStruct9BytesInt4Or8ByteAlignedResult.addressOf);
}
typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
@@ -6126,7 +6127,7 @@
Struct12BytesHomogeneousFloat
returnStruct12BytesHomogeneousFloatCalculateResult() {
Struct12BytesHomogeneousFloat result =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
result.a0 = returnStruct12BytesHomogeneousFloat_a0;
result.a1 = returnStruct12BytesHomogeneousFloat_a1;
@@ -6167,13 +6168,13 @@
}
void returnStruct12BytesHomogeneousFloatAfterCallback() {
- free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct12BytesHomogeneousFloatResult.addressOf);
final result = returnStruct12BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct12BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct16BytesHomogeneousFloatType = Struct16BytesHomogeneousFloat
@@ -6192,7 +6193,7 @@
Struct16BytesHomogeneousFloat
returnStruct16BytesHomogeneousFloatCalculateResult() {
Struct16BytesHomogeneousFloat result =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
result.a0 = returnStruct16BytesHomogeneousFloat_a0;
result.a1 = returnStruct16BytesHomogeneousFloat_a1;
@@ -6234,13 +6235,13 @@
}
void returnStruct16BytesHomogeneousFloatAfterCallback() {
- free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct16BytesHomogeneousFloatResult.addressOf);
final result = returnStruct16BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct16BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct16BytesMixedType = Struct16BytesMixed Function(
@@ -6254,7 +6255,7 @@
Struct16BytesMixed returnStruct16BytesMixedResult = Struct16BytesMixed();
Struct16BytesMixed returnStruct16BytesMixedCalculateResult() {
- Struct16BytesMixed result = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed result = calloc<Struct16BytesMixed>().ref;
result.a0 = returnStruct16BytesMixed_a0;
result.a1 = returnStruct16BytesMixed_a1;
@@ -6291,13 +6292,13 @@
}
void returnStruct16BytesMixedAfterCallback() {
- free(returnStruct16BytesMixedResult.addressOf);
+ calloc.free(returnStruct16BytesMixedResult.addressOf);
final result = returnStruct16BytesMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesMixedResult.addressOf);
+ calloc.free(returnStruct16BytesMixedResult.addressOf);
}
typedef ReturnStruct16BytesMixed2Type = Struct16BytesMixed2 Function(
@@ -6313,7 +6314,7 @@
Struct16BytesMixed2 returnStruct16BytesMixed2Result = Struct16BytesMixed2();
Struct16BytesMixed2 returnStruct16BytesMixed2CalculateResult() {
- Struct16BytesMixed2 result = allocate<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 result = calloc<Struct16BytesMixed2>().ref;
result.a0 = returnStruct16BytesMixed2_a0;
result.a1 = returnStruct16BytesMixed2_a1;
@@ -6356,13 +6357,13 @@
}
void returnStruct16BytesMixed2AfterCallback() {
- free(returnStruct16BytesMixed2Result.addressOf);
+ calloc.free(returnStruct16BytesMixed2Result.addressOf);
final result = returnStruct16BytesMixed2CalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesMixed2Result.addressOf);
+ calloc.free(returnStruct16BytesMixed2Result.addressOf);
}
typedef ReturnStruct17BytesIntType = Struct17BytesInt Function(
@@ -6377,7 +6378,7 @@
Struct17BytesInt returnStruct17BytesIntResult = Struct17BytesInt();
Struct17BytesInt returnStruct17BytesIntCalculateResult() {
- Struct17BytesInt result = allocate<Struct17BytesInt>().ref;
+ Struct17BytesInt result = calloc<Struct17BytesInt>().ref;
result.a0 = returnStruct17BytesInt_a0;
result.a1 = returnStruct17BytesInt_a1;
@@ -6418,13 +6419,13 @@
}
void returnStruct17BytesIntAfterCallback() {
- free(returnStruct17BytesIntResult.addressOf);
+ calloc.free(returnStruct17BytesIntResult.addressOf);
final result = returnStruct17BytesIntCalculateResult();
print("after callback result = $result");
- free(returnStruct17BytesIntResult.addressOf);
+ calloc.free(returnStruct17BytesIntResult.addressOf);
}
typedef ReturnStruct19BytesHomogeneousUint8Type
@@ -6477,7 +6478,7 @@
Struct19BytesHomogeneousUint8
returnStruct19BytesHomogeneousUint8CalculateResult() {
Struct19BytesHomogeneousUint8 result =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
result.a0 = returnStruct19BytesHomogeneousUint8_a0;
result.a1 = returnStruct19BytesHomogeneousUint8_a1;
@@ -6570,13 +6571,13 @@
}
void returnStruct19BytesHomogeneousUint8AfterCallback() {
- free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct19BytesHomogeneousUint8Result.addressOf);
final result = returnStruct19BytesHomogeneousUint8CalculateResult();
print("after callback result = $result");
- free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+ calloc.free(returnStruct19BytesHomogeneousUint8Result.addressOf);
}
typedef ReturnStruct20BytesHomogeneousInt32Type = Struct20BytesHomogeneousInt32
@@ -6596,7 +6597,7 @@
Struct20BytesHomogeneousInt32
returnStruct20BytesHomogeneousInt32CalculateResult() {
Struct20BytesHomogeneousInt32 result =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
result.a0 = returnStruct20BytesHomogeneousInt32_a0;
result.a1 = returnStruct20BytesHomogeneousInt32_a1;
@@ -6641,13 +6642,13 @@
}
void returnStruct20BytesHomogeneousInt32AfterCallback() {
- free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousInt32Result.addressOf);
final result = returnStruct20BytesHomogeneousInt32CalculateResult();
print("after callback result = $result");
- free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousInt32Result.addressOf);
}
typedef ReturnStruct20BytesHomogeneousFloatType = Struct20BytesHomogeneousFloat
@@ -6667,7 +6668,7 @@
Struct20BytesHomogeneousFloat
returnStruct20BytesHomogeneousFloatCalculateResult() {
Struct20BytesHomogeneousFloat result =
- allocate<Struct20BytesHomogeneousFloat>().ref;
+ calloc<Struct20BytesHomogeneousFloat>().ref;
result.a0 = returnStruct20BytesHomogeneousFloat_a0;
result.a1 = returnStruct20BytesHomogeneousFloat_a1;
@@ -6712,13 +6713,13 @@
}
void returnStruct20BytesHomogeneousFloatAfterCallback() {
- free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousFloatResult.addressOf);
final result = returnStruct20BytesHomogeneousFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+ calloc.free(returnStruct20BytesHomogeneousFloatResult.addressOf);
}
typedef ReturnStruct32BytesHomogeneousDoubleType
@@ -6737,7 +6738,7 @@
Struct32BytesHomogeneousDouble
returnStruct32BytesHomogeneousDoubleCalculateResult() {
Struct32BytesHomogeneousDouble result =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
result.a0 = returnStruct32BytesHomogeneousDouble_a0;
result.a1 = returnStruct32BytesHomogeneousDouble_a1;
@@ -6780,13 +6781,13 @@
}
void returnStruct32BytesHomogeneousDoubleAfterCallback() {
- free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
print("after callback result = $result");
- free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
}
typedef ReturnStruct40BytesHomogeneousDoubleType
@@ -6807,7 +6808,7 @@
Struct40BytesHomogeneousDouble
returnStruct40BytesHomogeneousDoubleCalculateResult() {
Struct40BytesHomogeneousDouble result =
- allocate<Struct40BytesHomogeneousDouble>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
result.a0 = returnStruct40BytesHomogeneousDouble_a0;
result.a1 = returnStruct40BytesHomogeneousDouble_a1;
@@ -6853,13 +6854,13 @@
}
void returnStruct40BytesHomogeneousDoubleAfterCallback() {
- free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
print("after callback result = $result");
- free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+ calloc.free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
}
typedef ReturnStruct1024BytesHomogeneousUint64Type
@@ -7130,7 +7131,7 @@
Struct1024BytesHomogeneousUint64
returnStruct1024BytesHomogeneousUint64CalculateResult() {
Struct1024BytesHomogeneousUint64 result =
- allocate<Struct1024BytesHomogeneousUint64>().ref;
+ calloc<Struct1024BytesHomogeneousUint64>().ref;
result.a0 = returnStruct1024BytesHomogeneousUint64_a0;
result.a1 = returnStruct1024BytesHomogeneousUint64_a1;
@@ -7549,13 +7550,13 @@
}
void returnStruct1024BytesHomogeneousUint64AfterCallback() {
- free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+ calloc.free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
print("after callback result = $result");
- free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+ calloc.free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
}
typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
@@ -7894,7 +7895,7 @@
StructAlignmentInt16 returnStructAlignmentInt16Result = StructAlignmentInt16();
StructAlignmentInt16 returnStructAlignmentInt16CalculateResult() {
- StructAlignmentInt16 result = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 result = calloc<StructAlignmentInt16>().ref;
result.a0 = returnStructAlignmentInt16_a0;
result.a1 = returnStructAlignmentInt16_a1;
@@ -7933,13 +7934,13 @@
}
void returnStructAlignmentInt16AfterCallback() {
- free(returnStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructAlignmentInt16Result.addressOf);
final result = returnStructAlignmentInt16CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructAlignmentInt16Result.addressOf);
}
typedef ReturnStructAlignmentInt32Type = StructAlignmentInt32 Function(
@@ -7954,7 +7955,7 @@
StructAlignmentInt32 returnStructAlignmentInt32Result = StructAlignmentInt32();
StructAlignmentInt32 returnStructAlignmentInt32CalculateResult() {
- StructAlignmentInt32 result = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 result = calloc<StructAlignmentInt32>().ref;
result.a0 = returnStructAlignmentInt32_a0;
result.a1 = returnStructAlignmentInt32_a1;
@@ -7993,13 +7994,13 @@
}
void returnStructAlignmentInt32AfterCallback() {
- free(returnStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructAlignmentInt32Result.addressOf);
final result = returnStructAlignmentInt32CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructAlignmentInt32Result.addressOf);
}
typedef ReturnStructAlignmentInt64Type = StructAlignmentInt64 Function(
@@ -8014,7 +8015,7 @@
StructAlignmentInt64 returnStructAlignmentInt64Result = StructAlignmentInt64();
StructAlignmentInt64 returnStructAlignmentInt64CalculateResult() {
- StructAlignmentInt64 result = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 result = calloc<StructAlignmentInt64>().ref;
result.a0 = returnStructAlignmentInt64_a0;
result.a1 = returnStructAlignmentInt64_a1;
@@ -8053,13 +8054,13 @@
}
void returnStructAlignmentInt64AfterCallback() {
- free(returnStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructAlignmentInt64Result.addressOf);
final result = returnStructAlignmentInt64CalculateResult();
print("after callback result = $result");
- free(returnStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructAlignmentInt64Result.addressOf);
}
typedef ReturnStruct8BytesNestedIntType = Struct8BytesNestedInt Function(
@@ -8076,7 +8077,7 @@
Struct8BytesNestedInt();
Struct8BytesNestedInt returnStruct8BytesNestedIntCalculateResult() {
- Struct8BytesNestedInt result = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt result = calloc<Struct8BytesNestedInt>().ref;
result.a0.a0 = returnStruct8BytesNestedInt_a0.a0;
result.a0.a1 = returnStruct8BytesNestedInt_a0.a1;
@@ -8116,13 +8117,13 @@
}
void returnStruct8BytesNestedIntAfterCallback() {
- free(returnStruct8BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct8BytesNestedIntResult.addressOf);
final result = returnStruct8BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct8BytesNestedIntResult.addressOf);
}
typedef ReturnStruct8BytesNestedFloatType = Struct8BytesNestedFloat Function(
@@ -8137,7 +8138,7 @@
Struct8BytesNestedFloat();
Struct8BytesNestedFloat returnStruct8BytesNestedFloatCalculateResult() {
- Struct8BytesNestedFloat result = allocate<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat result = calloc<Struct8BytesNestedFloat>().ref;
result.a0.a0 = returnStruct8BytesNestedFloat_a0.a0;
result.a1.a0 = returnStruct8BytesNestedFloat_a1.a0;
@@ -8175,13 +8176,13 @@
}
void returnStruct8BytesNestedFloatAfterCallback() {
- free(returnStruct8BytesNestedFloatResult.addressOf);
+ calloc.free(returnStruct8BytesNestedFloatResult.addressOf);
final result = returnStruct8BytesNestedFloatCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedFloatResult.addressOf);
+ calloc.free(returnStruct8BytesNestedFloatResult.addressOf);
}
typedef ReturnStruct8BytesNestedFloat2Type = Struct8BytesNestedFloat2 Function(
@@ -8196,7 +8197,7 @@
Struct8BytesNestedFloat2();
Struct8BytesNestedFloat2 returnStruct8BytesNestedFloat2CalculateResult() {
- Struct8BytesNestedFloat2 result = allocate<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 result = calloc<Struct8BytesNestedFloat2>().ref;
result.a0.a0 = returnStruct8BytesNestedFloat2_a0.a0;
result.a1 = returnStruct8BytesNestedFloat2_a1;
@@ -8235,13 +8236,13 @@
}
void returnStruct8BytesNestedFloat2AfterCallback() {
- free(returnStruct8BytesNestedFloat2Result.addressOf);
+ calloc.free(returnStruct8BytesNestedFloat2Result.addressOf);
final result = returnStruct8BytesNestedFloat2CalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedFloat2Result.addressOf);
+ calloc.free(returnStruct8BytesNestedFloat2Result.addressOf);
}
typedef ReturnStruct8BytesNestedMixedType = Struct8BytesNestedMixed Function(
@@ -8257,7 +8258,7 @@
Struct8BytesNestedMixed();
Struct8BytesNestedMixed returnStruct8BytesNestedMixedCalculateResult() {
- Struct8BytesNestedMixed result = allocate<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed result = calloc<Struct8BytesNestedMixed>().ref;
result.a0.a0 = returnStruct8BytesNestedMixed_a0.a0;
result.a0.a1 = returnStruct8BytesNestedMixed_a0.a1;
@@ -8296,13 +8297,13 @@
}
void returnStruct8BytesNestedMixedAfterCallback() {
- free(returnStruct8BytesNestedMixedResult.addressOf);
+ calloc.free(returnStruct8BytesNestedMixedResult.addressOf);
final result = returnStruct8BytesNestedMixedCalculateResult();
print("after callback result = $result");
- free(returnStruct8BytesNestedMixedResult.addressOf);
+ calloc.free(returnStruct8BytesNestedMixedResult.addressOf);
}
typedef ReturnStruct16BytesNestedIntType = Struct16BytesNestedInt Function(
@@ -8317,7 +8318,7 @@
Struct16BytesNestedInt();
Struct16BytesNestedInt returnStruct16BytesNestedIntCalculateResult() {
- Struct16BytesNestedInt result = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt result = calloc<Struct16BytesNestedInt>().ref;
result.a0.a0.a0 = returnStruct16BytesNestedInt_a0.a0.a0;
result.a0.a0.a1 = returnStruct16BytesNestedInt_a0.a0.a1;
@@ -8361,13 +8362,13 @@
}
void returnStruct16BytesNestedIntAfterCallback() {
- free(returnStruct16BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct16BytesNestedIntResult.addressOf);
final result = returnStruct16BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct16BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct16BytesNestedIntResult.addressOf);
}
typedef ReturnStruct32BytesNestedIntType = Struct32BytesNestedInt Function(
@@ -8384,7 +8385,7 @@
Struct32BytesNestedInt();
Struct32BytesNestedInt returnStruct32BytesNestedIntCalculateResult() {
- Struct32BytesNestedInt result = allocate<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt result = calloc<Struct32BytesNestedInt>().ref;
result.a0.a0.a0.a0 = returnStruct32BytesNestedInt_a0.a0.a0.a0;
result.a0.a0.a0.a1 = returnStruct32BytesNestedInt_a0.a0.a0.a1;
@@ -8436,13 +8437,13 @@
}
void returnStruct32BytesNestedIntAfterCallback() {
- free(returnStruct32BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct32BytesNestedIntResult.addressOf);
final result = returnStruct32BytesNestedIntCalculateResult();
print("after callback result = $result");
- free(returnStruct32BytesNestedIntResult.addressOf);
+ calloc.free(returnStruct32BytesNestedIntResult.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt16Type
@@ -8463,7 +8464,7 @@
StructNestedIntStructAlignmentInt16
returnStructNestedIntStructAlignmentInt16CalculateResult() {
StructNestedIntStructAlignmentInt16 result =
- allocate<StructNestedIntStructAlignmentInt16>().ref;
+ calloc<StructNestedIntStructAlignmentInt16>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt16_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt16_a0.a1;
@@ -8506,13 +8507,13 @@
}
void returnStructNestedIntStructAlignmentInt16AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt16CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt16Result.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt32Type
@@ -8533,7 +8534,7 @@
StructNestedIntStructAlignmentInt32
returnStructNestedIntStructAlignmentInt32CalculateResult() {
StructNestedIntStructAlignmentInt32 result =
- allocate<StructNestedIntStructAlignmentInt32>().ref;
+ calloc<StructNestedIntStructAlignmentInt32>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt32_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt32_a0.a1;
@@ -8576,13 +8577,13 @@
}
void returnStructNestedIntStructAlignmentInt32AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt32CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt32Result.addressOf);
}
typedef ReturnStructNestedIntStructAlignmentInt64Type
@@ -8603,7 +8604,7 @@
StructNestedIntStructAlignmentInt64
returnStructNestedIntStructAlignmentInt64CalculateResult() {
StructNestedIntStructAlignmentInt64 result =
- allocate<StructNestedIntStructAlignmentInt64>().ref;
+ calloc<StructNestedIntStructAlignmentInt64>().ref;
result.a0.a0 = returnStructNestedIntStructAlignmentInt64_a0.a0;
result.a0.a1 = returnStructNestedIntStructAlignmentInt64_a0.a1;
@@ -8646,13 +8647,13 @@
}
void returnStructNestedIntStructAlignmentInt64AfterCallback() {
- free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
final result = returnStructNestedIntStructAlignmentInt64CalculateResult();
print("after callback result = $result");
- free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
+ calloc.free(returnStructNestedIntStructAlignmentInt64Result.addressOf);
}
typedef ReturnStructNestedIrregularEvenBiggerType
@@ -8674,7 +8675,7 @@
StructNestedIrregularEvenBigger
returnStructNestedIrregularEvenBiggerCalculateResult() {
StructNestedIrregularEvenBigger result =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
result.a0 = returnStructNestedIrregularEvenBigger_a0;
result.a1.a0.a0 = returnStructNestedIrregularEvenBigger_a1.a0.a0;
@@ -8747,11 +8748,11 @@
}
void returnStructNestedIrregularEvenBiggerAfterCallback() {
- free(returnStructNestedIrregularEvenBiggerResult.addressOf);
+ calloc.free(returnStructNestedIrregularEvenBiggerResult.addressOf);
final result = returnStructNestedIrregularEvenBiggerCalculateResult();
print("after callback result = $result");
- free(returnStructNestedIrregularEvenBiggerResult.addressOf);
+ calloc.free(returnStructNestedIrregularEvenBiggerResult.addressOf);
}
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_test.dart
index 23c9946..5e9399a 100644
--- a/tests/ffi_2/function_callbacks_structs_by_value_test.dart
+++ b/tests/ffi_2/function_callbacks_structs_by_value_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
@@ -23,7 +24,7 @@
}
void recursiveTest(int recursionCounter) {
- final struct = allocate<Struct20BytesHomogeneousInt32>().ref;
+ final struct = calloc<Struct20BytesHomogeneousInt32>().ref;
struct.a0 = 1;
struct.a1 = 2;
struct.a2 = 3;
@@ -35,7 +36,7 @@
Expect.equals(struct.a2, result.a2);
Expect.equals(struct.a3, result.a3);
Expect.equals(struct.a4, result.a4);
- free(struct.addressOf);
+ calloc.free(struct.addressOf);
}
Struct20BytesHomogeneousInt32 dartPassStructRecursive(
@@ -93,7 +94,7 @@
_invokeReceiveStructByValue(_receiveStructByValuePointer);
Expect.isTrue(typedDataBackedStructSet);
- final pointerBackedStruct = allocate<Struct8BytesNestedInt>().ref;
+ final pointerBackedStruct = calloc<Struct8BytesNestedInt>().ref;
void reset() {
pointerBackedStruct.a0.a0 = 1;
@@ -130,5 +131,5 @@
Expect.equals(5, typedDataBackedStruct.a1.a0);
Expect.equals(6, typedDataBackedStruct.a1.a1);
- free(pointerBackedStruct.addressOf);
+ calloc.free(pointerBackedStruct.addressOf);
}
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
index d8ed635..e00f3fa 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -15,6 +15,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -1053,16 +1054,16 @@
/// Smallest struct with data.
/// 10 struct arguments will exhaust available registers.
void testPassStruct1ByteIntx10() {
- Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a1 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a2 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a3 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a4 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a5 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a6 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a7 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
- Struct1ByteInt a9 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a0 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a1 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a2 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a3 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a4 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a5 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a6 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a7 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a8 = calloc<Struct1ByteInt>().ref;
+ Struct1ByteInt a9 = calloc<Struct1ByteInt>().ref;
a0.a0 = -1;
a1.a0 = 2;
@@ -1081,16 +1082,16 @@
Expect.equals(5, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct3BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1120,26 +1121,16 @@
/// Not a multiple of word size, not a power of two.
/// 10 struct arguments will exhaust available registers.
void testPassStruct3BytesHomogeneousUint8x10() {
- Struct3BytesHomogeneousUint8 a0 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a1 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a2 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a3 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a4 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a5 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a6 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a7 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a8 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
- Struct3BytesHomogeneousUint8 a9 =
- allocate<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a0 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a1 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a2 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a3 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a4 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a5 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a6 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a7 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a8 = calloc<Struct3BytesHomogeneousUint8>().ref;
+ Struct3BytesHomogeneousUint8 a9 = calloc<Struct3BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1179,16 +1170,16 @@
Expect.equals(465, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct3BytesInt2ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -1219,16 +1210,16 @@
/// With alignment rules taken into account size is 4 bytes.
/// 10 struct arguments will exhaust available registers.
void testPassStruct3BytesInt2ByteAlignedx10() {
- Struct3BytesInt2ByteAligned a0 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a1 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a2 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a3 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a4 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a5 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a6 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a7 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a8 = allocate<Struct3BytesInt2ByteAligned>().ref;
- Struct3BytesInt2ByteAligned a9 = allocate<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a0 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a1 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a2 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a3 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a4 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a5 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a6 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a7 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a8 = calloc<Struct3BytesInt2ByteAligned>().ref;
+ Struct3BytesInt2ByteAligned a9 = calloc<Struct3BytesInt2ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1258,16 +1249,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct4BytesHomogeneousInt16x10 = ffiTestFunctions.lookupFunction<
@@ -1297,26 +1288,16 @@
/// Exactly word size on 32-bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct4BytesHomogeneousInt16x10() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a2 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a3 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a4 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a5 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a6 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a7 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a8 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a9 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a2 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a3 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a4 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a5 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a6 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a7 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a8 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a9 = calloc<Struct4BytesHomogeneousInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1346,16 +1327,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct7BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1385,26 +1366,16 @@
/// Sub word size on 64 bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct7BytesHomogeneousUint8x10() {
- Struct7BytesHomogeneousUint8 a0 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a1 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a2 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a3 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a4 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a5 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a6 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a7 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a8 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
- Struct7BytesHomogeneousUint8 a9 =
- allocate<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a0 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a1 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a2 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a3 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a4 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a5 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a6 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a7 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a8 = calloc<Struct7BytesHomogeneousUint8>().ref;
+ Struct7BytesHomogeneousUint8 a9 = calloc<Struct7BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1484,16 +1455,16 @@
Expect.equals(2485, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct7BytesInt4ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -1524,16 +1495,16 @@
/// With alignment rules taken into account size is 8 bytes.
/// 10 struct arguments will exhaust available registers.
void testPassStruct7BytesInt4ByteAlignedx10() {
- Struct7BytesInt4ByteAligned a0 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a1 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a2 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a3 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a4 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a5 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a6 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a7 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a8 = allocate<Struct7BytesInt4ByteAligned>().ref;
- Struct7BytesInt4ByteAligned a9 = allocate<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a0 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a1 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a2 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a3 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a4 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a5 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a6 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a7 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a8 = calloc<Struct7BytesInt4ByteAligned>().ref;
+ Struct7BytesInt4ByteAligned a9 = calloc<Struct7BytesInt4ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1573,16 +1544,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesIntx10 = ffiTestFunctions.lookupFunction<
@@ -1612,16 +1583,16 @@
/// Exactly word size struct on 64bit architectures.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesIntx10() {
- Struct8BytesInt a0 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a1 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a2 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a3 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a4 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a5 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a6 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a7 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a8 = allocate<Struct8BytesInt>().ref;
- Struct8BytesInt a9 = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt a0 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a1 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a2 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a3 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a4 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a5 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a6 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a7 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a8 = calloc<Struct8BytesInt>().ref;
+ Struct8BytesInt a9 = calloc<Struct8BytesInt>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -1660,16 +1631,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesHomogeneousFloatx10 = ffiTestFunctions.lookupFunction<
@@ -1699,26 +1670,16 @@
/// Arguments passed in FP registers as long as they fit.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesHomogeneousFloatx10() {
- Struct8BytesHomogeneousFloat a0 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a1 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a2 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a3 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a4 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a5 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a6 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a7 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a8 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
- Struct8BytesHomogeneousFloat a9 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a0 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a1 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a2 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a3 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a4 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a5 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a6 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a7 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a8 = calloc<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a9 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -1748,16 +1709,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesMixedx10 = ffiTestFunctions.lookupFunction<
@@ -1787,16 +1748,16 @@
/// On x64, arguments go in int registers because it is not only float.
/// 10 struct arguments will exhaust available registers.
void testPassStruct8BytesMixedx10() {
- Struct8BytesMixed a0 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a1 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a2 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a3 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a4 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a5 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a6 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a7 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a8 = allocate<Struct8BytesMixed>().ref;
- Struct8BytesMixed a9 = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a0 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a1 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a2 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a3 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a4 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a5 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a6 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a7 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a8 = calloc<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a9 = calloc<Struct8BytesMixed>().ref;
a0.a0 = -1.0;
a0.a1 = 2;
@@ -1836,16 +1797,16 @@
Expect.approxEquals(15.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct9BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -1878,26 +1839,16 @@
/// Tests upper bytes in the integer registers that are partly filled.
/// Tests stack alignment of non word size stack arguments.
void testPassStruct9BytesHomogeneousUint8x10() {
- Struct9BytesHomogeneousUint8 a0 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a1 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a2 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a3 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a4 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a5 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a6 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a7 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a8 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
- Struct9BytesHomogeneousUint8 a9 =
- allocate<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a0 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a1 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a2 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a3 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a4 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a5 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a6 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a7 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a8 = calloc<Struct9BytesHomogeneousUint8>().ref;
+ Struct9BytesHomogeneousUint8 a9 = calloc<Struct9BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -1997,16 +1948,16 @@
Expect.equals(4095, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct9BytesInt4Or8ByteAlignedx10 = ffiTestFunctions.lookupFunction<
@@ -2040,25 +1991,25 @@
///
void testPassStruct9BytesInt4Or8ByteAlignedx10() {
Struct9BytesInt4Or8ByteAligned a0 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a1 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a2 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a3 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a4 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a5 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a6 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a7 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a8 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
Struct9BytesInt4Or8ByteAligned a9 =
- allocate<Struct9BytesInt4Or8ByteAligned>().ref;
+ calloc<Struct9BytesInt4Or8ByteAligned>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2088,16 +2039,16 @@
Expect.equals(10, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
@@ -2121,17 +2072,17 @@
/// The last argument is to test whether arguments are backfilled.
void testPassStruct12BytesHomogeneousFloatx6() {
Struct12BytesHomogeneousFloat a0 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a1 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a2 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a3 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a4 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
Struct12BytesHomogeneousFloat a5 =
- allocate<Struct12BytesHomogeneousFloat>().ref;
+ calloc<Struct12BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2158,12 +2109,12 @@
Expect.approxEquals(9.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
}
final passStruct16BytesHomogeneousFloatx5 = ffiTestFunctions.lookupFunction<
@@ -2185,15 +2136,15 @@
/// 5 struct arguments will exhaust available registers.
void testPassStruct16BytesHomogeneousFloatx5() {
Struct16BytesHomogeneousFloat a0 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a1 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a2 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a3 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
Struct16BytesHomogeneousFloat a4 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2222,11 +2173,11 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
}
final passStruct16BytesMixedx10 = ffiTestFunctions.lookupFunction<
@@ -2258,16 +2209,16 @@
/// The rest goes on the stack.
/// On arm, arguments are 8 byte aligned.
void testPassStruct16BytesMixedx10() {
- Struct16BytesMixed a0 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a2 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a0 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a1 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a2 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a3 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a4 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a8 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a9 = calloc<Struct16BytesMixed>().ref;
a0.a0 = -1.0;
a0.a1 = 2;
@@ -2297,16 +2248,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct16BytesMixed2x10 = ffiTestFunctions.lookupFunction<
@@ -2338,16 +2289,16 @@
/// The rest goes on the stack.
/// On arm, arguments are 4 byte aligned.
void testPassStruct16BytesMixed2x10() {
- Struct16BytesMixed2 a0 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a1 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a2 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a3 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a4 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a5 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a6 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a7 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a8 = allocate<Struct16BytesMixed2>().ref;
- Struct16BytesMixed2 a9 = allocate<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a0 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a1 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a2 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a3 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a4 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a5 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a6 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a7 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a8 = calloc<Struct16BytesMixed2>().ref;
+ Struct16BytesMixed2 a9 = calloc<Struct16BytesMixed2>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2397,16 +2348,16 @@
Expect.approxEquals(20.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct17BytesIntx10 = ffiTestFunctions.lookupFunction<
@@ -2436,16 +2387,16 @@
/// Arguments are passed as pointer to copy on arm64.
/// Tests that the memory allocated for copies are rounded up to word size.
void testPassStruct17BytesIntx10() {
- Struct17BytesInt a0 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a1 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a2 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a3 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a4 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a5 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a6 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a7 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a8 = allocate<Struct17BytesInt>().ref;
- Struct17BytesInt a9 = allocate<Struct17BytesInt>().ref;
+ Struct17BytesInt a0 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a1 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a2 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a3 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a4 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a5 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a6 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a7 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a8 = calloc<Struct17BytesInt>().ref;
+ Struct17BytesInt a9 = calloc<Struct17BytesInt>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2485,16 +2436,16 @@
Expect.equals(15, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct19BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
@@ -2526,25 +2477,25 @@
///
void testPassStruct19BytesHomogeneousUint8x10() {
Struct19BytesHomogeneousUint8 a0 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a1 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a2 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a3 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a4 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a5 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a6 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a7 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a8 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
Struct19BytesHomogeneousUint8 a9 =
- allocate<Struct19BytesHomogeneousUint8>().ref;
+ calloc<Struct19BytesHomogeneousUint8>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -2744,16 +2695,16 @@
Expect.equals(18145, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct20BytesHomogeneousInt32x10 = ffiTestFunctions.lookupFunction<
@@ -2786,25 +2737,25 @@
/// pointers to copies are also passed on the stack.
void testPassStruct20BytesHomogeneousInt32x10() {
Struct20BytesHomogeneousInt32 a0 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a1 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a2 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a3 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a4 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a5 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a6 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a7 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a8 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
Struct20BytesHomogeneousInt32 a9 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -2864,16 +2815,16 @@
Expect.equals(25, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
@@ -2884,7 +2835,7 @@
/// Argument too big to go into FPU registers in hardfp and arm64.
void testPassStruct20BytesHomogeneousFloat() {
Struct20BytesHomogeneousFloat a0 =
- allocate<Struct20BytesHomogeneousFloat>().ref;
+ calloc<Struct20BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2898,7 +2849,7 @@
Expect.approxEquals(-3.0, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct32BytesHomogeneousDoublex5 = ffiTestFunctions.lookupFunction<
@@ -2920,15 +2871,15 @@
/// 5 struct arguments will exhaust available registers.
void testPassStruct32BytesHomogeneousDoublex5() {
Struct32BytesHomogeneousDouble a0 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a1 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a2 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a3 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
Struct32BytesHomogeneousDouble a4 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2957,11 +2908,11 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
}
final passStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
@@ -2972,7 +2923,7 @@
/// Argument too big to go into FPU registers in arm64.
void testPassStruct40BytesHomogeneousDouble() {
Struct40BytesHomogeneousDouble a0 =
- allocate<Struct40BytesHomogeneousDouble>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -2986,7 +2937,7 @@
Expect.approxEquals(-3.0, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
@@ -2997,7 +2948,7 @@
/// Test 1kb struct.
void testPassStruct1024BytesHomogeneousUint64() {
Struct1024BytesHomogeneousUint64 a0 =
- allocate<Struct1024BytesHomogeneousUint64>().ref;
+ calloc<Struct1024BytesHomogeneousUint64>().ref;
a0.a0 = 1;
a0.a1 = 2;
@@ -3134,7 +3085,7 @@
Expect.equals(8256, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passFloatStruct16BytesHomogeneousFloatFloatStruct1 =
@@ -3164,16 +3115,16 @@
void testPassFloatStruct16BytesHomogeneousFloatFloatStruct1() {
double a0;
Struct16BytesHomogeneousFloat a1 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a2;
Struct16BytesHomogeneousFloat a3 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a4;
Struct16BytesHomogeneousFloat a5 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a6;
Struct16BytesHomogeneousFloat a7 =
- allocate<Struct16BytesHomogeneousFloat>().ref;
+ calloc<Struct16BytesHomogeneousFloat>().ref;
double a8;
a0 = -1.0;
@@ -3205,10 +3156,10 @@
Expect.approxEquals(-11.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passFloatStruct32BytesHomogeneousDoubleFloatStruct =
@@ -3238,16 +3189,16 @@
void testPassFloatStruct32BytesHomogeneousDoubleFloatStruct() {
double a0;
Struct32BytesHomogeneousDouble a1 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a2;
Struct32BytesHomogeneousDouble a3 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a4;
Struct32BytesHomogeneousDouble a5 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a6;
Struct32BytesHomogeneousDouble a7 =
- allocate<Struct32BytesHomogeneousDouble>().ref;
+ calloc<Struct32BytesHomogeneousDouble>().ref;
double a8;
a0 = -1.0;
@@ -3279,10 +3230,10 @@
Expect.approxEquals(-11.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passInt8Struct16BytesMixedInt8Struct16BytesMixedIn =
@@ -3307,13 +3258,13 @@
/// Test backfilling of integer registers.
void testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn() {
int a0;
- Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a1 = calloc<Struct16BytesMixed>().ref;
int a2;
- Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a3 = calloc<Struct16BytesMixed>().ref;
int a4;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
int a6;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
int a8;
a0 = -1;
@@ -3337,10 +3288,10 @@
Expect.approxEquals(-7.0, result);
- free(a1.addressOf);
- free(a3.addressOf);
- free(a5.addressOf);
- free(a7.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a7.addressOf);
}
final passDoublex6Struct16BytesMixedx4Int32 = ffiTestFunctions.lookupFunction<
@@ -3379,10 +3330,10 @@
double a3;
double a4;
double a5;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a8 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a9 = calloc<Struct16BytesMixed>().ref;
int a10;
a0 = -1.0;
@@ -3408,10 +3359,10 @@
Expect.approxEquals(-8.0, result);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passInt32x4Struct16BytesMixedx4Double = ffiTestFunctions.lookupFunction<
@@ -3436,10 +3387,10 @@
int a1;
int a2;
int a3;
- Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
- Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a4 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a5 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a6 = calloc<Struct16BytesMixed>().ref;
+ Struct16BytesMixed a7 = calloc<Struct16BytesMixed>().ref;
double a8;
a0 = -1;
@@ -3463,10 +3414,10 @@
Expect.approxEquals(-7.0, result);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
}
final passStruct40BytesHomogeneousDoubleStruct4BytesHomo =
@@ -3481,11 +3432,9 @@
/// Check that the other two arguments are allocated on registers.
void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
Struct40BytesHomogeneousDouble a0 =
- allocate<Struct40BytesHomogeneousDouble>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct8BytesHomogeneousFloat a2 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ calloc<Struct40BytesHomogeneousDouble>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct8BytesHomogeneousFloat a2 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -3503,9 +3452,9 @@
Expect.approxEquals(-5.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
}
final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int =
@@ -3613,30 +3562,28 @@
double a15;
int a16;
int a17;
- Struct1ByteInt a18 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a18 = calloc<Struct1ByteInt>().ref;
int a19;
int a20;
- Struct4BytesHomogeneousInt16 a21 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a21 = calloc<Struct4BytesHomogeneousInt16>().ref;
int a22;
int a23;
- Struct8BytesInt a24 = allocate<Struct8BytesInt>().ref;
+ Struct8BytesInt a24 = calloc<Struct8BytesInt>().ref;
int a25;
int a26;
- Struct8BytesHomogeneousFloat a27 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a27 = calloc<Struct8BytesHomogeneousFloat>().ref;
int a28;
int a29;
- Struct8BytesMixed a30 = allocate<Struct8BytesMixed>().ref;
+ Struct8BytesMixed a30 = calloc<Struct8BytesMixed>().ref;
int a31;
int a32;
- StructAlignmentInt16 a33 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a33 = calloc<StructAlignmentInt16>().ref;
int a34;
int a35;
- StructAlignmentInt32 a36 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a36 = calloc<StructAlignmentInt32>().ref;
int a37;
int a38;
- StructAlignmentInt64 a39 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a39 = calloc<StructAlignmentInt64>().ref;
a0 = -1;
a1 = 2;
@@ -3737,14 +3684,14 @@
Expect.approxEquals(26.0, result);
- free(a18.addressOf);
- free(a21.addressOf);
- free(a24.addressOf);
- free(a27.addressOf);
- free(a30.addressOf);
- free(a33.addressOf);
- free(a36.addressOf);
- free(a39.addressOf);
+ calloc.free(a18.addressOf);
+ calloc.free(a21.addressOf);
+ calloc.free(a24.addressOf);
+ calloc.free(a27.addressOf);
+ calloc.free(a30.addressOf);
+ calloc.free(a33.addressOf);
+ calloc.free(a36.addressOf);
+ calloc.free(a39.addressOf);
}
final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -3753,7 +3700,7 @@
/// Test alignment and padding of 16 byte int within struct.
void testPassStructAlignmentInt16() {
- StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a0 = calloc<StructAlignmentInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3765,7 +3712,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
@@ -3774,7 +3721,7 @@
/// Test alignment and padding of 32 byte int within struct.
void testPassStructAlignmentInt32() {
- StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a0 = calloc<StructAlignmentInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3786,7 +3733,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
@@ -3795,7 +3742,7 @@
/// Test alignment and padding of 64 byte int within struct.
void testPassStructAlignmentInt64() {
- StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a0 = calloc<StructAlignmentInt64>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -3807,7 +3754,7 @@
Expect.equals(-2, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStruct8BytesNestedIntx10 = ffiTestFunctions.lookupFunction<
@@ -3837,16 +3784,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust registers on all platforms.
void testPassStruct8BytesNestedIntx10() {
- Struct8BytesNestedInt a0 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a1 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a2 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a3 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a4 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a5 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a6 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a7 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a8 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a9 = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a0 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a1 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a2 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a3 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a4 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a5 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a6 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a7 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a8 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a9 = calloc<Struct8BytesNestedInt>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -3896,16 +3843,16 @@
Expect.equals(20, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedFloatx10 = ffiTestFunctions.lookupFunction<
@@ -3935,16 +3882,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust fpu registers on all platforms.
void testPassStruct8BytesNestedFloatx10() {
- Struct8BytesNestedFloat a0 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a1 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a2 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a3 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a4 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a5 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a6 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a7 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a8 = allocate<Struct8BytesNestedFloat>().ref;
- Struct8BytesNestedFloat a9 = allocate<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a0 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a1 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a2 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a3 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a4 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a5 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a6 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a7 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a8 = calloc<Struct8BytesNestedFloat>().ref;
+ Struct8BytesNestedFloat a9 = calloc<Struct8BytesNestedFloat>().ref;
a0.a0.a0 = -1.0;
a0.a1.a0 = 2.0;
@@ -3974,16 +3921,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedFloat2x10 = ffiTestFunctions.lookupFunction<
@@ -4015,16 +3962,16 @@
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
/// and the fpu register usage on x64.
void testPassStruct8BytesNestedFloat2x10() {
- Struct8BytesNestedFloat2 a0 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a1 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a2 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a3 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a4 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a5 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a6 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a7 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a8 = allocate<Struct8BytesNestedFloat2>().ref;
- Struct8BytesNestedFloat2 a9 = allocate<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a0 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a1 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a2 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a3 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a4 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a5 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a6 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a7 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a8 = calloc<Struct8BytesNestedFloat2>().ref;
+ Struct8BytesNestedFloat2 a9 = calloc<Struct8BytesNestedFloat2>().ref;
a0.a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -4054,16 +4001,16 @@
Expect.approxEquals(10.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct8BytesNestedMixedx10 = ffiTestFunctions.lookupFunction<
@@ -4093,16 +4040,16 @@
/// Simple nested struct. No alignment gaps on any architectures.
/// 10 arguments exhaust all registers on all platforms.
void testPassStruct8BytesNestedMixedx10() {
- Struct8BytesNestedMixed a0 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a1 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a2 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a3 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a4 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a5 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a6 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a7 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a8 = allocate<Struct8BytesNestedMixed>().ref;
- Struct8BytesNestedMixed a9 = allocate<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a0 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a1 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a2 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a3 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a4 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a5 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a6 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a7 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a8 = calloc<Struct8BytesNestedMixed>().ref;
+ Struct8BytesNestedMixed a9 = calloc<Struct8BytesNestedMixed>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4142,16 +4089,16 @@
Expect.approxEquals(15.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
- free(a4.addressOf);
- free(a5.addressOf);
- free(a6.addressOf);
- free(a7.addressOf);
- free(a8.addressOf);
- free(a9.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
+ calloc.free(a4.addressOf);
+ calloc.free(a5.addressOf);
+ calloc.free(a6.addressOf);
+ calloc.free(a7.addressOf);
+ calloc.free(a8.addressOf);
+ calloc.free(a9.addressOf);
}
final passStruct16BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
@@ -4161,8 +4108,8 @@
/// Deeper nested struct to test recursive member access.
void testPassStruct16BytesNestedIntx2() {
- Struct16BytesNestedInt a0 = allocate<Struct16BytesNestedInt>().ref;
- Struct16BytesNestedInt a1 = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a0 = calloc<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a1 = calloc<Struct16BytesNestedInt>().ref;
a0.a0.a0.a0 = -1;
a0.a0.a0.a1 = 2;
@@ -4187,8 +4134,8 @@
Expect.equals(8, result);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final passStruct32BytesNestedIntx2 = ffiTestFunctions.lookupFunction<
@@ -4198,8 +4145,8 @@
/// Even deeper nested struct to test recursive member access.
void testPassStruct32BytesNestedIntx2() {
- Struct32BytesNestedInt a0 = allocate<Struct32BytesNestedInt>().ref;
- Struct32BytesNestedInt a1 = allocate<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt a0 = calloc<Struct32BytesNestedInt>().ref;
+ Struct32BytesNestedInt a1 = calloc<Struct32BytesNestedInt>().ref;
a0.a0.a0.a0.a0 = -1;
a0.a0.a0.a0.a1 = 2;
@@ -4240,8 +4187,8 @@
Expect.equals(16, result);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final passStructNestedIntStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -4252,7 +4199,7 @@
/// Test alignment and padding of nested struct with 16 byte int.
void testPassStructNestedIntStructAlignmentInt16() {
StructNestedIntStructAlignmentInt16 a0 =
- allocate<StructNestedIntStructAlignmentInt16>().ref;
+ calloc<StructNestedIntStructAlignmentInt16>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4267,7 +4214,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIntStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
@@ -4278,7 +4225,7 @@
/// Test alignment and padding of nested struct with 32 byte int.
void testPassStructNestedIntStructAlignmentInt32() {
StructNestedIntStructAlignmentInt32 a0 =
- allocate<StructNestedIntStructAlignmentInt32>().ref;
+ calloc<StructNestedIntStructAlignmentInt32>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4293,7 +4240,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIntStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
@@ -4304,7 +4251,7 @@
/// Test alignment and padding of nested struct with 64 byte int.
void testPassStructNestedIntStructAlignmentInt64() {
StructNestedIntStructAlignmentInt64 a0 =
- allocate<StructNestedIntStructAlignmentInt64>().ref;
+ calloc<StructNestedIntStructAlignmentInt64>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -4319,7 +4266,7 @@
Expect.equals(3, result);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final passStructNestedIrregularEvenBiggerx4 = ffiTestFunctions.lookupFunction<
@@ -4338,13 +4285,13 @@
/// Return big irregular struct as smoke test.
void testPassStructNestedIrregularEvenBiggerx4() {
StructNestedIrregularEvenBigger a0 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a1 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a2 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
StructNestedIrregularEvenBigger a3 =
- allocate<StructNestedIrregularEvenBigger>().ref;
+ calloc<StructNestedIrregularEvenBigger>().ref;
a0.a0 = 1;
a0.a1.a0.a0 = 2;
@@ -4489,10 +4436,10 @@
Expect.approxEquals(1572.0, result);
- free(a0.addressOf);
- free(a1.addressOf);
- free(a2.addressOf);
- free(a3.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
+ calloc.free(a3.addressOf);
}
final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
@@ -5922,7 +5869,7 @@
/// Especially for ffi callbacks.
/// Struct is passed in int registers in most ABIs.
void testReturnStructArgumentStruct1ByteInt() {
- Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a0 = calloc<Struct1ByteInt>().ref;
a0.a0 = -1;
@@ -5932,7 +5879,7 @@
Expect.equals(a0.a0, result.a0);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentInt32x8Struct1ByteInt =
@@ -5954,7 +5901,7 @@
int a5;
int a6;
int a7;
- Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+ Struct1ByteInt a8 = calloc<Struct1ByteInt>().ref;
a0 = -1;
a1 = 2;
@@ -5973,7 +5920,7 @@
Expect.equals(a8.a0, result.a0);
- free(a8.addressOf);
+ calloc.free(a8.addressOf);
}
final returnStructArgumentStruct8BytesHomogeneousFloat =
@@ -5987,8 +5934,7 @@
/// Especially for ffi callbacks.
/// Struct is passed in float registers in most ABIs.
void testReturnStructArgumentStruct8BytesHomogeneousFloat() {
- Struct8BytesHomogeneousFloat a0 =
- allocate<Struct8BytesHomogeneousFloat>().ref;
+ Struct8BytesHomogeneousFloat a0 = calloc<Struct8BytesHomogeneousFloat>().ref;
a0.a0 = -1.0;
a0.a1 = 2.0;
@@ -6000,7 +5946,7 @@
Expect.approxEquals(a0.a0, result.a0);
Expect.approxEquals(a0.a1, result.a1);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentStruct20BytesHomogeneousInt32 =
@@ -6015,7 +5961,7 @@
/// On arm64, both argument and return value are passed in by pointer.
void testReturnStructArgumentStruct20BytesHomogeneousInt32() {
Struct20BytesHomogeneousInt32 a0 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6033,7 +5979,7 @@
Expect.equals(a0.a3, result.a3);
Expect.equals(a0.a4, result.a4);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStructArgumentInt32x8Struct20BytesHomogeneou =
@@ -6056,7 +6002,7 @@
int a6;
int a7;
Struct20BytesHomogeneousInt32 a8 =
- allocate<Struct20BytesHomogeneousInt32>().ref;
+ calloc<Struct20BytesHomogeneousInt32>().ref;
a0 = -1;
a1 = 2;
@@ -6083,7 +6029,7 @@
Expect.equals(a8.a3, result.a3);
Expect.equals(a8.a4, result.a4);
- free(a8.addressOf);
+ calloc.free(a8.addressOf);
}
final returnStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
@@ -6163,10 +6109,8 @@
/// Simple nested struct.
void testReturnStruct8BytesNestedInt() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesHomogeneousInt16 a1 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesHomogeneousInt16 a1 = calloc<Struct4BytesHomogeneousInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6182,8 +6126,8 @@
Expect.equals(a1.a0, result.a1.a0);
Expect.equals(a1.a1, result.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct8BytesNestedFloat = ffiTestFunctions.lookupFunction<
@@ -6193,8 +6137,8 @@
/// Simple nested struct with floats.
void testReturnStruct8BytesNestedFloat() {
- Struct4BytesFloat a0 = allocate<Struct4BytesFloat>().ref;
- Struct4BytesFloat a1 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a0 = calloc<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a1 = calloc<Struct4BytesFloat>().ref;
a0.a0 = -1.0;
a1.a0 = 2.0;
@@ -6206,8 +6150,8 @@
Expect.approxEquals(a0.a0, result.a0.a0);
Expect.approxEquals(a1.a0, result.a1.a0);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct8BytesNestedFloat2 = ffiTestFunctions.lookupFunction<
@@ -6218,7 +6162,7 @@
/// The nesting is irregular, testing homogenous float rules on arm and arm64,
/// and the fpu register usage on x64.
void testReturnStruct8BytesNestedFloat2() {
- Struct4BytesFloat a0 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesFloat a0 = calloc<Struct4BytesFloat>().ref;
double a1;
a0.a0 = -1.0;
@@ -6231,7 +6175,7 @@
Expect.approxEquals(a0.a0, result.a0.a0);
Expect.approxEquals(a1, result.a1);
- free(a0.addressOf);
+ calloc.free(a0.addressOf);
}
final returnStruct8BytesNestedMixed = ffiTestFunctions.lookupFunction<
@@ -6242,9 +6186,8 @@
/// Simple nested struct with mixed members.
void testReturnStruct8BytesNestedMixed() {
- Struct4BytesHomogeneousInt16 a0 =
- allocate<Struct4BytesHomogeneousInt16>().ref;
- Struct4BytesFloat a1 = allocate<Struct4BytesFloat>().ref;
+ Struct4BytesHomogeneousInt16 a0 = calloc<Struct4BytesHomogeneousInt16>().ref;
+ Struct4BytesFloat a1 = calloc<Struct4BytesFloat>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6258,8 +6201,8 @@
Expect.equals(a0.a1, result.a0.a1);
Expect.approxEquals(a1.a0, result.a1.a0);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct16BytesNestedInt = ffiTestFunctions.lookupFunction<
@@ -6270,8 +6213,8 @@
/// Deeper nested struct to test recursive member access.
void testReturnStruct16BytesNestedInt() {
- Struct8BytesNestedInt a0 = allocate<Struct8BytesNestedInt>().ref;
- Struct8BytesNestedInt a1 = allocate<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a0 = calloc<Struct8BytesNestedInt>().ref;
+ Struct8BytesNestedInt a1 = calloc<Struct8BytesNestedInt>().ref;
a0.a0.a0 = -1;
a0.a0.a1 = 2;
@@ -6295,8 +6238,8 @@
Expect.equals(a1.a1.a0, result.a1.a1.a0);
Expect.equals(a1.a1.a1, result.a1.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStruct32BytesNestedInt = ffiTestFunctions.lookupFunction<
@@ -6307,8 +6250,8 @@
/// Even deeper nested struct to test recursive member access.
void testReturnStruct32BytesNestedInt() {
- Struct16BytesNestedInt a0 = allocate<Struct16BytesNestedInt>().ref;
- Struct16BytesNestedInt a1 = allocate<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a0 = calloc<Struct16BytesNestedInt>().ref;
+ Struct16BytesNestedInt a1 = calloc<Struct16BytesNestedInt>().ref;
a0.a0.a0.a0 = -1;
a0.a0.a0.a1 = 2;
@@ -6348,8 +6291,8 @@
Expect.equals(a1.a1.a1.a0, result.a1.a1.a1.a0);
Expect.equals(a1.a1.a1.a1, result.a1.a1.a1.a1);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt16 =
@@ -6361,8 +6304,8 @@
/// Test alignment and padding of nested struct with 16 byte int.
void testReturnStructNestedIntStructAlignmentInt16() {
- StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
- StructAlignmentInt16 a1 = allocate<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a0 = calloc<StructAlignmentInt16>().ref;
+ StructAlignmentInt16 a1 = calloc<StructAlignmentInt16>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6382,8 +6325,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt32 =
@@ -6395,8 +6338,8 @@
/// Test alignment and padding of nested struct with 32 byte int.
void testReturnStructNestedIntStructAlignmentInt32() {
- StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
- StructAlignmentInt32 a1 = allocate<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a0 = calloc<StructAlignmentInt32>().ref;
+ StructAlignmentInt32 a1 = calloc<StructAlignmentInt32>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6416,8 +6359,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIntStructAlignmentInt64 =
@@ -6429,8 +6372,8 @@
/// Test alignment and padding of nested struct with 64 byte int.
void testReturnStructNestedIntStructAlignmentInt64() {
- StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
- StructAlignmentInt64 a1 = allocate<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a0 = calloc<StructAlignmentInt64>().ref;
+ StructAlignmentInt64 a1 = calloc<StructAlignmentInt64>().ref;
a0.a0 = -1;
a0.a1 = 2;
@@ -6450,8 +6393,8 @@
Expect.equals(a1.a1, result.a1.a1);
Expect.equals(a1.a2, result.a1.a2);
- free(a0.addressOf);
- free(a1.addressOf);
+ calloc.free(a0.addressOf);
+ calloc.free(a1.addressOf);
}
final returnStructNestedIrregularEvenBigger = ffiTestFunctions.lookupFunction<
@@ -6466,8 +6409,8 @@
/// Return big irregular struct as smoke test.
void testReturnStructNestedIrregularEvenBigger() {
int a0;
- StructNestedIrregularBigger a1 = allocate<StructNestedIrregularBigger>().ref;
- StructNestedIrregularBigger a2 = allocate<StructNestedIrregularBigger>().ref;
+ StructNestedIrregularBigger a1 = calloc<StructNestedIrregularBigger>().ref;
+ StructNestedIrregularBigger a2 = calloc<StructNestedIrregularBigger>().ref;
double a3;
a0 = 1;
@@ -6544,6 +6487,6 @@
Expect.approxEquals(a2.a3, result.a2.a3);
Expect.approxEquals(a3, result.a3);
- free(a1.addressOf);
- free(a2.addressOf);
+ calloc.free(a1.addressOf);
+ calloc.free(a2.addressOf);
}
diff --git a/tests/ffi_2/function_structs_test.dart b/tests/ffi_2/function_structs_test.dart
index bf9ea5f..6bb3e56 100644
--- a/tests/ffi_2/function_structs_test.dart
+++ b/tests/ffi_2/function_structs_test.dart
@@ -9,12 +9,12 @@
import 'dart:ffi';
-import 'dylib_utils.dart';
-
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'coordinate.dart';
+import 'dylib_utils.dart';
import 'very_large_struct.dart';
typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
@@ -33,8 +33,10 @@
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
- Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 20.0, nullptr).addressOf;
- Pointer<Coordinate> c2 = Coordinate.allocate(42.0, 84.0, c1).addressOf;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(calloc, 10.0, 20.0, nullptr).addressOf;
+ Pointer<Coordinate> c2 =
+ Coordinate.allocate(calloc, 42.0, 84.0, c1).addressOf;
c1.ref.next = c2;
Coordinate result = f1(c1).ref;
@@ -45,8 +47,8 @@
Expect.approxEquals(42.0, result.x);
Expect.approxEquals(84.0, result.y);
- free(c1);
- free(c2);
+ calloc.free(c1);
+ calloc.free(c2);
}
/// pass an array of structs to a c funtion
@@ -55,7 +57,7 @@
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = allocate<Coordinate>(count: 3).ref;
+ Coordinate c1 = calloc<Coordinate>(3).ref;
Coordinate c2 = c1.addressOf[1];
Coordinate c3 = c1.addressOf[2];
c1.x = 10.0;
@@ -72,7 +74,7 @@
Expect.approxEquals(20.0, result.x);
Expect.approxEquals(20.0, result.y);
- free(c1.addressOf);
+ calloc.free(c1.addressOf);
}
typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
@@ -83,7 +85,7 @@
ffiTestFunctions.lookup("SumVeryLargeStruct");
VeryLargeStructSum f = p1.asFunction();
- VeryLargeStruct vls1 = allocate<VeryLargeStruct>(count: 2).ref;
+ VeryLargeStruct vls1 = calloc<VeryLargeStruct>(2).ref;
VeryLargeStruct vls2 = vls1.addressOf[1];
List<VeryLargeStruct> structs = [vls1, vls2];
for (VeryLargeStruct struct in structs) {
@@ -114,5 +116,5 @@
result = f(vls2.addressOf);
Expect.equals(2048, result);
- free(vls1.addressOf);
+ calloc.free(vls1.addressOf);
}
diff --git a/tests/ffi_2/function_test.dart b/tests/ffi_2/function_test.dart
index bff456e..b547ffe 100644
--- a/tests/ffi_2/function_test.dart
+++ b/tests/ffi_2/function_test.dart
@@ -15,11 +15,12 @@
import 'dart:ffi';
-import 'dylib_utils.dart';
-
import "package:ffi/ffi.dart";
import "package:expect/expect.dart";
+import 'dylib_utils.dart';
+import 'calloc.dart';
+
void main() {
for (int i = 0; i < 100; ++i) {
testNativeFunctionFromCast();
@@ -50,11 +51,11 @@
typedef GenericBinaryOp<T> = int Function(int, T);
void testNativeFunctionFromCast() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<NativeFunction<NativeBinaryOp>> p2 = p1.cast();
p2.asFunction<BinaryOp>();
p2.asFunction<GenericBinaryOp<int>>();
- free(p1);
+ calloc.free(p1);
}
typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
@@ -394,14 +395,14 @@
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
void testNativeFunctionPointer() {
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
p2.value = 42;
p2[1] = 1000;
Pointer<Int64> result = assign1337Index1(p2);
Expect.equals(1337, result.value);
Expect.equals(1337, p2[1]);
Expect.equals(p2.elementAt(1).address, result.address);
- free(p2);
+ calloc.free(p2);
}
Int64PointerUnOp nullableInt64ElemAt1 = ffiTestFunctions
@@ -411,10 +412,10 @@
Pointer<Int64> result = nullableInt64ElemAt1(nullptr);
Expect.equals(result, nullptr);
- Pointer<Int64> p2 = allocate(count: 2);
+ Pointer<Int64> p2 = calloc(2);
result = nullableInt64ElemAt1(p2);
Expect.notEquals(result, nullptr);
- free(p2);
+ calloc.free(p2);
}
typedef NativeFloatPointerToBool = Uint8 Function(Pointer<Float>);
@@ -424,13 +425,13 @@
NativeFloatPointerToBool, FloatPointerToBool>("IsRoughly1337");
void testFloatRounding() {
- Pointer<Float> p2 = allocate();
+ Pointer<Float> p2 = calloc();
p2.value = 1337.0;
int result = isRoughly1337(p2);
Expect.equals(1, result);
- free(p2);
+ calloc.free(p2);
}
typedef NativeFloatToVoid = Void Function(Float);
diff --git a/tests/ffi_2/generator/structs_by_value_tests_generator.dart b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
index f3f9f02..7bd7c83 100644
--- a/tests/ffi_2/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
@@ -197,7 +197,7 @@
return "${dartType} ${variableName};\n";
case StructType:
- return "${dartType} ${variableName} = allocate<$dartType>().ref;\n";
+ return "${dartType} ${variableName} = calloc<$dartType>().ref;\n";
}
throw Exception("Not implemented for ${this.runtimeType}");
@@ -243,7 +243,7 @@
return "";
case StructType:
- return "free($variableName.addressOf);\n";
+ return "calloc.free($variableName.addressOf);\n";
}
throw Exception("Not implemented for ${this.runtimeType}");
@@ -485,7 +485,7 @@
case TestType.structReturn:
// Allocate a struct.
buildReturnValue = """
- ${returnValue.dartType} result = allocate<${returnValue.dartType}>().ref;
+ ${returnValue.dartType} result = calloc<${returnValue.dartType}>().ref;
${arguments.copyValueStatements("${dartName}_", "result.")}
""";
@@ -749,6 +749,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -801,6 +802,7 @@
import "package:ffi/ffi.dart";
import 'callback_tests_utils.dart';
+import 'calloc.dart';
// Reuse the struct classes.
import 'function_structs_by_value_generated_test.dart';
diff --git a/tests/ffi_2/null_test.dart b/tests/ffi_2/null_test.dart
index 303499c..fb51f94 100644
--- a/tests/ffi_2/null_test.dart
+++ b/tests/ffi_2/null_test.dart
@@ -20,6 +20,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
import 'ffi_test_helpers.dart';
@@ -40,17 +41,17 @@
void testPointerStoreNull() {
int i = null;
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Expect.throws(() => p.value = i);
- free(p);
+ calloc.free(p);
double d = null;
- Pointer<Float> p2 = allocate();
+ Pointer<Float> p2 = calloc();
Expect.throws(() => p2.value = d);
- free(p2);
+ calloc.free(p2);
Pointer<Void> x = null;
- Pointer<Pointer<Void>> p3 = allocate();
+ Pointer<Pointer<Void>> p3 = calloc();
Expect.throws(() => p3.value = x);
- free(p3);
+ calloc.free(p3);
}
void testEquality() {
@@ -61,7 +62,7 @@
/// With extension methods, the receiver position can be null.
testNullReceivers() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Pointer<Int8> p4 = null;
Expect.throws(() => Expect.equals(10, p4.value));
@@ -74,11 +75,11 @@
Pointer<Foo> p6 = null;
Expect.throws(() => Expect.equals(10, p6.ref));
- free(p);
+ calloc.free(p);
}
testNullIndices() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Expect.throws(() => Expect.equals(10, p[null]));
Expect.throws(() => p[null] = 10);
@@ -90,13 +91,13 @@
Pointer<Foo> p6 = p.cast();
Expect.throws(() => Expect.equals(10, p6[null]));
- free(p);
+ calloc.free(p);
}
testNullArguments() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
Expect.throws(() => p.value = null);
- free(p);
+ calloc.free(p);
}
class Foo extends Struct {
diff --git a/tests/ffi_2/regress_37254_test.dart b/tests/ffi_2/regress_37254_test.dart
index 6ba796f..e73562d 100644
--- a/tests/ffi_2/regress_37254_test.dart
+++ b/tests/ffi_2/regress_37254_test.dart
@@ -65,34 +65,36 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+
// ===== a.value = b ======
// The tests follow table cells left to right, top to bottom.
void store1() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store2() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
final Pointer<NativeType> b =
- allocate<Int8>(); // Reified Pointer<Int8> at runtime.
+ calloc<Int8>(); // Reified Pointer<Int8> at runtime.
// Successful implicit downcast of argument at runtime.
// Should succeed now, should statically be rejected when NNBD lands.
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store3() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
// Failing implicit downcast of argument at runtime.
// Should fail now at runtime, should statically be rejected when NNBD lands.
@@ -100,124 +102,124 @@
a.value = b;
});
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store4() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store5() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
final Pointer<NativeType> b =
- allocate<Int8>(); // Reified as Pointer<Int8> at runtime.
+ calloc<Int8>(); // Reified as Pointer<Int8> at runtime.
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store6() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
// Fails on type check of argument.
Expect.throws(() {
a.value = b;
});
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store7() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
- final Pointer<Int8> b = allocate<Int8>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
+ final Pointer<Int8> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store8() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
// Reified as Pointer<Int8> at runtime.
- final Pointer<NativeType> b = allocate<Int8>();
+ final Pointer<NativeType> b = calloc<Int8>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
void store9() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
- final Pointer<NativeType> b = allocate<Int8>().cast<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
+ final Pointer<NativeType> b = calloc<Int8>().cast<Pointer<NativeType>>();
a.value = b;
- free(a);
- free(b);
+ calloc.free(a);
+ calloc.free(b);
}
// ====== b = a.value ======
// The tests follow table cells left to right, top to bottom.
void load1() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
Pointer<Int8> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load2() {
- final Pointer<Pointer<Int8>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<Int8>> a = calloc<Pointer<Int8>>();
Pointer<NativeType> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load3() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
Pointer<Int8> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load4() {
// Reified as Pointer<Pointer<Int8>> at runtime.
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<Int8>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<Int8>>();
// Return value runtime type is Pointer<Int8>.
Pointer<NativeType> b = a.value;
Expect.type<Pointer<Int8>>(b);
- free(a);
+ calloc.free(a);
}
void load5() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
// Failing implicit downcast of return value at runtime.
// Should fail now at runtime, should statically be rejected when NNBD lands.
@@ -225,16 +227,16 @@
Pointer<Int8> b = a.value;
});
- free(a);
+ calloc.free(a);
}
void load6() {
- final Pointer<Pointer<NativeType>> a = allocate<Pointer<NativeType>>();
+ final Pointer<Pointer<NativeType>> a = calloc<Pointer<NativeType>>();
Pointer<NativeType> b = a.value;
Expect.type<Pointer<NativeType>>(b);
- free(a);
+ calloc.free(a);
}
void main() {
diff --git a/tests/ffi_2/regress_39885_test.dart b/tests/ffi_2/regress_39885_test.dart
index 7d960f2..ef73ca7 100644
--- a/tests/ffi_2/regress_39885_test.dart
+++ b/tests/ffi_2/regress_39885_test.dart
@@ -3,12 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:ffi';
-import "package:ffi/ffi.dart" show allocate, free;
+
+import "package:ffi/ffi.dart";
+
+import 'calloc.dart';
main() {
- final data = allocate<Uint8>(count: 3);
+ final data = calloc<Uint8>(3);
for (int i = 0; i < 3; ++i) {
data.elementAt(i).value = 1;
}
- free(data);
+ calloc.free(data);
}
diff --git a/tests/ffi_2/regress_43693_test.dart b/tests/ffi_2/regress_43693_test.dart
index a30a118..b589b0c 100644
--- a/tests/ffi_2/regress_43693_test.dart
+++ b/tests/ffi_2/regress_43693_test.dart
@@ -9,6 +9,7 @@
import 'package:ffi/ffi.dart';
import 'package:expect/expect.dart';
+import 'calloc.dart';
import 'dylib_utils.dart';
class Struct43693 extends Struct {
@@ -27,10 +28,10 @@
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
void main() {
- final myStructs = allocate<Struct43693>();
+ final myStructs = calloc<Struct43693>();
myStructs[0].somePtr = nullptr;
myStructs[0].someValue = 0xAAAAAAAABBBBBBBB;
final result = readMyStructSomeValue(myStructs);
Expect.equals(0xAAAAAAAABBBBBBBB, result);
- free(myStructs);
+ calloc.free(myStructs);
}
diff --git a/tests/ffi_2/structs_nested_test.dart b/tests/ffi_2/structs_nested_test.dart
index 7083044..3a69edb 100644
--- a/tests/ffi_2/structs_nested_test.dart
+++ b/tests/ffi_2/structs_nested_test.dart
@@ -11,6 +11,7 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
@@ -48,16 +49,16 @@
}
void testAllocate() {
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
Expect.type<Pointer<Struct8BytesNestedInt>>(p);
print(p);
- free(p);
+ calloc.free(p);
}
/// Test that reading does not segfault, even uninitialized.
void testRead() {
print("read");
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
print(p);
print(p.ref.runtimeType);
print(p.ref.addressOf);
@@ -65,13 +66,13 @@
print(p.ref.a0.runtimeType);
print(p.ref.a0.addressOf);
print(p.ref.a0.a0);
- free(p);
+ calloc.free(p);
print("read");
}
void testWrite() {
print("write");
- final p = allocate<Struct8BytesNestedInt>(count: 2);
+ final p = calloc<Struct8BytesNestedInt>(2);
p[0].a0.a0 = 12;
p[0].a0.a1 = 13;
p[0].a1.a0 = 14;
@@ -88,18 +89,18 @@
Expect.equals(17, p[1].a0.a1);
Expect.equals(18, p[1].a1.a0);
Expect.equals(19, p[1].a1.a1);
- free(p);
+ calloc.free(p);
print("written");
}
void testCopy() {
print("copy");
- final p = allocate<Struct8BytesNestedInt>();
+ final p = calloc<Struct8BytesNestedInt>();
p.ref.a0.a0 = 12;
p.ref.a0.a1 = 13;
p.ref.a1 = p.ref.a0;
Expect.equals(12, p.ref.a1.a0);
Expect.equals(13, p.ref.a1.a1);
- free(p);
+ calloc.free(p);
print("copied");
}
diff --git a/tests/ffi_2/structs_test.dart b/tests/ffi_2/structs_test.dart
index 263d562..2759056 100644
--- a/tests/ffi_2/structs_test.dart
+++ b/tests/ffi_2/structs_test.dart
@@ -11,9 +11,10 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-import 'ffi_test_helpers.dart';
+import 'calloc.dart';
import 'coordinate_bare.dart' as bare;
import 'coordinate.dart';
+import 'ffi_test_helpers.dart';
void main() {
for (int i = 0; i < 100; i++) {
@@ -28,9 +29,12 @@
/// allocates each coordinate separately in c memory
void testStructAllocate() {
- Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
- Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
- Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
+ Pointer<Coordinate> c2 =
+ Coordinate.allocate(calloc, 20.0, 20.0, c1).addressOf;
+ Pointer<Coordinate> c3 =
+ Coordinate.allocate(calloc, 30.0, 30.0, c2).addressOf;
c1.ref.next = c3;
Coordinate currentCoordinate = c1.ref;
@@ -42,14 +46,14 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
- free(c2);
- free(c3);
+ calloc.free(c1);
+ calloc.free(c2);
+ calloc.free(c3);
}
/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
- Pointer<Coordinate> c1 = allocate(count: 3);
+ Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref
@@ -74,24 +78,24 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1);
+ calloc.free(c1);
}
void testStructWithNulls() {
Pointer<Coordinate> coordinate =
- Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
+ Coordinate.allocate(calloc, 10.0, 10.0, nullptr).addressOf;
Expect.equals(coordinate.ref.next, nullptr);
coordinate.ref.next = coordinate;
Expect.notEquals(coordinate.ref.next, nullptr);
coordinate.ref.next = nullptr;
Expect.equals(coordinate.ref.next, nullptr);
- free(coordinate);
+ calloc.free(coordinate);
}
void testBareStruct() {
int structSize = sizeOf<Double>() * 2 + sizeOf<IntPtr>();
bare.Coordinate c1 =
- allocate<Uint8>(count: structSize * 3).cast<bare.Coordinate>().ref;
+ calloc<Uint8>(structSize * 3).cast<bare.Coordinate>().ref;
bare.Coordinate c2 =
c1.addressOf.offsetBy(structSize).cast<bare.Coordinate>().ref;
bare.Coordinate c3 =
@@ -115,19 +119,19 @@
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
- free(c1.addressOf);
+ calloc.free(c1.addressOf);
}
void testTypeTest() {
- Coordinate c = Coordinate.allocate(10, 10, nullptr);
+ Coordinate c = Coordinate.allocate(calloc, 10, 10, nullptr);
Expect.isTrue(c is Struct);
Expect.isTrue(c.addressOf is Pointer<Coordinate>);
- free(c.addressOf);
+ calloc.free(c.addressOf);
}
void testUtf8() {
final String test = 'Hasta Mañana';
final Pointer<Utf8> medium = Utf8.toUtf8(test);
Expect.equals(test, Utf8.fromUtf8(medium));
- free(medium);
+ calloc.free(medium);
}
diff --git a/tests/ffi_2/variance_function_test.dart b/tests/ffi_2/variance_function_test.dart
index d6e6378..f53cdfc 100644
--- a/tests/ffi_2/variance_function_test.dart
+++ b/tests/ffi_2/variance_function_test.dart
@@ -12,11 +12,12 @@
import 'dart:ffi';
-import 'dylib_utils.dart';
-
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
+import 'calloc.dart';
+import 'dylib_utils.dart';
+
typedef Int64PointerParamOpDart = void Function(Pointer<Int64>);
typedef Int64PointerParamOp = Void Function(Pointer<Int64>);
typedef NaTyPointerParamOpDart = void Function(Pointer<NativeType>);
@@ -38,19 +39,19 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<Int64PointerParamOp>>(paramOpName);
final f = fp.asFunction<Int64PointerParamOpDart>();
- final arg = allocate<Int64>();
+ final arg = calloc<Int64>();
f(arg);
- free(arg);
+ calloc.free(arg);
}
void paramInvariant2() {
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final arg = allocate<Int64>().cast<NativeType>();
+ final arg = calloc<Int64>().cast<NativeType>();
Expect.type<Pointer<NativeType>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
// Pass a statically and dynamically subtyped argument.
@@ -58,10 +59,10 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final arg = allocate<Int64>();
+ final arg = calloc<Int64>();
Expect.type<Pointer<Int64>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
// Pass a statically subtyped but dynamically invariant argument.
@@ -69,10 +70,10 @@
final fp =
ffiTestFunctions.lookup<NativeFunction<NaTyPointerParamOp>>(paramOpName);
final f = fp.asFunction<NaTyPointerParamOpDart>();
- final Pointer<NativeType> arg = allocate<Int64>();
+ final Pointer<NativeType> arg = calloc<Int64>();
Expect.type<Pointer<Int64>>(arg);
f(arg);
- free(arg);
+ calloc.free(arg);
}
void returnInvariant1() {
@@ -220,7 +221,7 @@
}
void fromFunctionTests() {
- data = allocate();
+ data = calloc();
for (int i = 0; i < 100; ++i) {
callbackParamInvariant1(); // Pointer<Int64> invariant
callbackParamInvariant2(); // Pointer<NativeType> invariant
@@ -229,7 +230,7 @@
callbackReturnInvariant1(); // Pointer<Int64> invariant
callbackReturnInvariant2(); // Pointer<NativeType> invariant
}
- free(data);
+ calloc.free(data);
}
void main() {
diff --git a/tests/ffi_2/vmspecific_enable_ffi_test.dart b/tests/ffi_2/vmspecific_enable_ffi_test.dart
index f44753d..ce90607 100644
--- a/tests/ffi_2/vmspecific_enable_ffi_test.dart
+++ b/tests/ffi_2/vmspecific_enable_ffi_test.dart
@@ -7,11 +7,14 @@
// VMOptions=--enable-ffi=false
import 'dart:ffi'; //# 01: compile-time error
+
import 'package:ffi/ffi.dart'; //# 01: compile-time error
+import 'calloc.dart'; //# 01: compile-time error
+
void main() {
Pointer<Int8> p = //# 01: compile-time error
- allocate(); //# 01: compile-time error
+ calloc(); //# 01: compile-time error
print(p.address); //# 01: compile-time error
- free(p); //# 01: compile-time error
+ calloc.free(p); //# 01: compile-time error
}
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index ebbe474..f1db86e 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -10,6 +10,7 @@
import "package:ffi/ffi.dart";
+import 'calloc.dart';
import 'dylib_utils.dart';
void main() {
@@ -53,6 +54,8 @@
testEmptyStructAsFunctionReturn();
testEmptyStructFromFunctionArgument();
testEmptyStructFromFunctionReturn();
+ testAllocateGeneric();
+ testAllocateNativeType();
}
typedef Int8UnOp = Int8 Function(Int8);
@@ -65,20 +68,20 @@
return result;
}
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
- free(p);
+ calloc.free(p);
}
void testGetGeneric2() {
T generic<T extends Object>() {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
T result;
result = p.value; //# 21: compile-time error
- free(p);
+ calloc.free(p);
return result;
}
@@ -86,12 +89,12 @@
}
void testGetVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value; //# 22: compile-time error
- free(p1);
+ calloc.free(p1);
}
void testGetNativeFunction() {
@@ -104,14 +107,14 @@
}
void testGetTypeMismatch() {
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
Pointer<Int16> typedNull = nullptr;
p.value = typedNull;
// this fails to compile due to type mismatch
Pointer<Int8> p2 = p.value; //# 25: compile-time error
- free(p);
+ calloc.free(p);
}
void testSetGeneric() {
@@ -119,30 +122,30 @@
p.value = 123; //# 26: compile-time error
}
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = 123;
Pointer loseType = p;
generic(loseType);
- free(p);
+ calloc.free(p);
}
void testSetGeneric2() {
void generic<T extends Object>(T arg) {
- Pointer<Int8> p = allocate();
+ Pointer<Int8> p = calloc();
p.value = arg; //# 27: compile-time error
- free(p);
+ calloc.free(p);
}
generic<int>(123);
}
void testSetVoid() {
- Pointer<IntPtr> p1 = allocate();
+ Pointer<IntPtr> p1 = calloc();
Pointer<Void> p2 = p1.cast();
p2.value = 1234; //# 28: compile-time error
- free(p1);
+ calloc.free(p1);
}
void testSetNativeFunction() {
@@ -157,16 +160,16 @@
void testSetTypeMismatch() {
// the pointer to pointer types must match up
- Pointer<Int8> pHelper = allocate();
+ Pointer<Int8> pHelper = calloc();
pHelper.value = 123;
- Pointer<Pointer<Int16>> p = allocate();
+ Pointer<Pointer<Int16>> p = calloc();
// this fails to compile due to type mismatch
p.value = pHelper; //# 40: compile-time error
- free(pHelper);
- free(p);
+ calloc.free(pHelper);
+ calloc.free(p);
}
void testAsFunctionGeneric() {
@@ -475,6 +478,8 @@
class IStruct implements Struct {} //# 815: compile-time error
+class IOpaque implements Opaque {} //# 816: compile-time error
+
class MyClass {
int x;
MyClass(this.x);
@@ -550,3 +555,17 @@
class HasNestedEmptyStruct extends Struct {
EmptyStruct nestedEmptyStruct; //# 1106: compile-time error
}
+
+void testAllocateGeneric() {
+ Pointer<T> generic<T extends NativeType>() {
+ Pointer<T> pointer = nullptr;
+ pointer = calloc(); //# 1320: compile-time error
+ return pointer;
+ }
+
+ Pointer p = generic<Int64>();
+}
+
+void testAllocateNativeType() {
+ calloc(); //# 1321: compile-time error
+}
diff --git a/tests/language/class/override_inference_error_test.dart b/tests/language/class/override_inference_error_test.dart
index 65bcae6..14e215f 100644
--- a/tests/language/class/override_inference_error_test.dart
+++ b/tests/language/class/override_inference_error_test.dart
@@ -200,8 +200,6 @@
// ^
// [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
// [cfe] unspecified
- // ^
- // [analyzer] STATIC_WARNING.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED
}
// Inherits type variables, even with different names.
diff --git a/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart b/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart
new file mode 100644
index 0000000..342ccca
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_this_not_promoted_error_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test verifies that attempts to promote the type of `this` inside an
+// extension method have no effect.
+
+void f(dynamic d) {}
+
+class C {
+ int? cProp;
+}
+
+extension on C? {
+ void testCQuestion() {
+ if (this != null) {
+ f(this.cProp);
+ //^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe] Property 'cProp' cannot be accessed on 'C?' because it is potentially null.
+ f(cProp);
+ //^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // [cfe] Property 'cProp' cannot be accessed on 'C?' because it is potentially null.
+ }
+ }
+}
+
+class D extends C {
+ int? dProp;
+}
+
+extension on C {
+ void testC() {
+ if (this is D) {
+ f(this.dProp);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
+ // [cfe] The getter 'dProp' isn't defined for the class 'C'.
+ f(dProp);
+ //^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+ // [cfe] The getter 'dProp' isn't defined for the class 'C'.
+ }
+ }
+}
+
+main() {
+ C().testCQuestion();
+ C().testC();
+ D().testCQuestion();
+ D().testC();
+ (null as C?).testCQuestion();
+}
diff --git a/tests/language/super/bound_closure_test.dart b/tests/language/super/bound_closure_test.dart
index 554b0e2..5061145 100644
--- a/tests/language/super/bound_closure_test.dart
+++ b/tests/language/super/bound_closure_test.dart
@@ -72,8 +72,7 @@
fooIntercept27() => confuse(super.lastWhere)(0);
fooIntercept28() => confuse(super.lastWhere)(3, orElse: 77);
- // Warning: overrides should not change default parameter values.
- bar([var optional]) => -1; // //# 01: static type warning
+ bar([var optional]) => -1; // //# 01: ok
bar2({namedOptional}) => -1; // //# 01: continued
bar3(x, [var optional]) => -1; // //# 01: continued
bar4(x, {namedOptional}) => -1; //# 01: continued
diff --git a/tools/VERSION b/tools/VERSION
index 82ddcdf..5fccaeb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 223
+PRERELEASE 224
PRERELEASE_PATCH 0
\ No newline at end of file