Revert "[ffi]: Remove pointer elementAt method."

This reverts commit f706ff4ee2.

Reason for revert: b/321667799 - package:win32 uses this method - a78ff108fb/lib/src/com/iapplicationactivationmanager.dart (L46)

Original change's description:
> [ffi]: Remove pointer elementAt method.
>
> Closes #54250
>
> TEST=test/ffi
>
> R=dacoharkes@google.com
> Change-Id: I0e88adfcfe3caef0ad3bb6814ad8f27dce5dc7f4
> CoreLibraryReviewExempt: FFI only
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346380
> Reviewed-by: Daco Harkes <dacoharkes@google.com>
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Auto-Submit: Shikhar <shikharish05@gmail.com>

Change-Id: I1b7a48d14e9b85676a27f76a926e21cac9c76c85
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/347600
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
Oleh Prypin 2024-01-22 12:20:48 +00:00 committed by Commit Queue
parent 3a314331a7
commit 5a1ef6089c
30 changed files with 356 additions and 151 deletions

4
DEPS
View file

@ -50,7 +50,7 @@ vars = {
# Checked-in SDK version. The checked-in SDK is a Dart SDK distribution
# in a cipd package used to run Dart scripts in the build and test
# infrastructure, which is automatically built on the release commits.
"sdk_tag": "version:3.3.0-279.1.beta",
"sdk_tag": "version:3.2.4",
# co19 is a cipd package automatically generated for each co19 commit.
# Use tests/co19/update.sh to update this hash.
@ -142,7 +142,7 @@ vars = {
"dart_style_rev": "8b1f24a8475a0116757172cd9acca4acbf87d973", # disable rev_sdk_deps.dart
"dartdoc_rev": "b04c9c127fea5f3fdf600aa205f50d81d1c779c5", # https://github.com/dart-lang/dartdoc/issues/3562
"ecosystem_rev": "1e2785d6900b4d709a31f4c669381dc340cad605",
"ffi_rev": "76c581a0ad0cfe585cc8d7084c6afaa95a9696f5",
"ffi_rev": "c926657618443ff4821411ede01684096b503f84",
"file_rev": "cd3a9324f6483f313ba1f0f3ff382ea4e6982ef2",
"fixnum_rev": "3e08c0d7ce1a0cd832a17391444898ec610b5f89",
"flute_rev": "f42b09f77132210499ec8ed819a60c260af03db6",

View file

@ -2135,7 +2135,7 @@ class PointerUint8x02 extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p2 = p1.elementAt(1);
}
@override
@ -2168,7 +2168,7 @@ class PointerUint8x02Native extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p2 = p1.elementAt(1);
}
@override
@ -2201,7 +2201,7 @@ class PointerUint8x02NativeLeaf extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p2 = p1.elementAt(1);
}
@override
@ -2238,9 +2238,9 @@ class PointerUint8x04 extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
}
@override
@ -2275,9 +2275,9 @@ class PointerUint8x04Native extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
}
@override
@ -2312,9 +2312,9 @@ class PointerUint8x04NativeLeaf extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
}
@override
@ -2358,15 +2358,15 @@ class PointerUint8x10 extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
}
@override
@ -2416,15 +2416,15 @@ class PointerUint8x10Native extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
}
@override
@ -2474,15 +2474,15 @@ class PointerUint8x10NativeLeaf extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
}
@override
@ -2536,25 +2536,25 @@ class PointerUint8x20 extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p11 = p1 + 10;
p12 = p1 + 11;
p13 = p1 + 12;
p14 = p1 + 13;
p15 = p1 + 14;
p16 = p1 + 15;
p17 = p1 + 16;
p18 = p1 + 17;
p19 = p1 + 18;
p20 = p1 + 19;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
p11 = p1.elementAt(10);
p12 = p1.elementAt(11);
p13 = p1.elementAt(12);
p14 = p1.elementAt(13);
p15 = p1.elementAt(14);
p16 = p1.elementAt(15);
p17 = p1.elementAt(16);
p18 = p1.elementAt(17);
p19 = p1.elementAt(18);
p20 = p1.elementAt(19);
}
@override
@ -2625,25 +2625,25 @@ class PointerUint8x20Native extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p11 = p1 + 10;
p12 = p1 + 11;
p13 = p1 + 12;
p14 = p1 + 13;
p15 = p1 + 14;
p16 = p1 + 15;
p17 = p1 + 16;
p18 = p1 + 17;
p19 = p1 + 18;
p20 = p1 + 19;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
p11 = p1.elementAt(10);
p12 = p1.elementAt(11);
p13 = p1.elementAt(12);
p14 = p1.elementAt(13);
p15 = p1.elementAt(14);
p16 = p1.elementAt(15);
p17 = p1.elementAt(16);
p18 = p1.elementAt(17);
p19 = p1.elementAt(18);
p20 = p1.elementAt(19);
}
@override
@ -2714,25 +2714,25 @@ class PointerUint8x20NativeLeaf extends FfiBenchmarkBase {
@override
void setup() {
p1 = calloc(N + 1);
p2 = p1 + 1;
p3 = p1 + 2;
p4 = p1 + 3;
p5 = p1 + 4;
p6 = p1 + 5;
p7 = p1 + 6;
p8 = p1 + 7;
p9 = p1 + 8;
p10 = p1 + 9;
p11 = p1 + 10;
p12 = p1 + 11;
p13 = p1 + 12;
p14 = p1 + 13;
p15 = p1 + 14;
p16 = p1 + 15;
p17 = p1 + 16;
p18 = p1 + 17;
p19 = p1 + 18;
p20 = p1 + 19;
p2 = p1.elementAt(1);
p3 = p1.elementAt(2);
p4 = p1.elementAt(3);
p5 = p1.elementAt(4);
p6 = p1.elementAt(5);
p7 = p1.elementAt(6);
p8 = p1.elementAt(7);
p9 = p1.elementAt(8);
p10 = p1.elementAt(9);
p11 = p1.elementAt(10);
p12 = p1.elementAt(11);
p13 = p1.elementAt(12);
p14 = p1.elementAt(13);
p15 = p1.elementAt(14);
p16 = p1.elementAt(15);
p17 = p1.elementAt(16);
p18 = p1.elementAt(17);
p19 = p1.elementAt(18);
p20 = p1.elementAt(19);
}
@override

View file

@ -230,8 +230,8 @@ void generateBenchmarkPointer(StringBuffer buffer, List<String> types) {
List.generate(number, (i) => 'p${i + 1}');
final String pointers =
pointerNames.map((n) => '$type $n = nullptr;').join('\n');
final String setup =
List.generate(number - 1, (i) => 'p${i + 2} = p1 + ${i + 1};').join();
final String setup = List.generate(
number - 1, (i) => 'p${i + 2} = p1.elementAt(${i + 1});').join();
final String functionType = 'Function$number$dartTypeName';
final String functionNativeType = 'NativeFunction$number$typeName';
final String functionNameC = 'Function$number$typeName';

View file

@ -140,7 +140,7 @@ final finalizerAddress = () {
throw 'Failed to write executable code to the memory.';
}
return (finalizerStub + offset).cast<Void>();
return finalizerStub.elementAt(offset).cast<Void>();
}();
base class PeerData extends Struct {

View file

@ -212,14 +212,18 @@ class FfiTransformer extends Transformer {
final Procedure structPointerSetRef;
final Procedure structPointerGetElemAt;
final Procedure structPointerSetElemAt;
final Procedure structPointerElementAt;
final Procedure structPointerPlusOperator;
final Procedure structPointerMinusOperator;
final Procedure structPointerElementAtTearoff;
final Procedure unionPointerGetRef;
final Procedure unionPointerSetRef;
final Procedure unionPointerGetElemAt;
final Procedure unionPointerSetElemAt;
final Procedure unionPointerElementAt;
final Procedure unionPointerPlusOperator;
final Procedure unionPointerMinusOperator;
final Procedure unionPointerElementAtTearoff;
final Procedure structArrayElemAt;
final Procedure unionArrayElemAt;
final Procedure arrayArrayElemAt;
@ -228,8 +232,10 @@ class FfiTransformer extends Transformer {
final Procedure abiSpecificIntegerPointerSetValue;
final Procedure abiSpecificIntegerPointerElemAt;
final Procedure abiSpecificIntegerPointerSetElemAt;
final Procedure abiSpecificIntegerPointerElementAt;
final Procedure abiSpecificIntegerPointerPlusOperator;
final Procedure abiSpecificIntegerPointerMinusOperator;
final Procedure abiSpecificIntegerPointerElementAtTearoff;
final Procedure abiSpecificIntegerArrayElemAt;
final Procedure abiSpecificIntegerArraySetElemAt;
final Procedure asFunctionMethod;
@ -427,10 +433,14 @@ class FfiTransformer extends Transformer {
index.getProcedure('dart:ffi', 'StructPointer', '[]'),
structPointerSetElemAt =
index.getProcedure('dart:ffi', 'StructPointer', '[]='),
structPointerElementAt =
index.getProcedure('dart:ffi', 'StructPointer', 'elementAt'),
structPointerPlusOperator =
index.getProcedure('dart:ffi', 'StructPointer', '+'),
structPointerMinusOperator =
index.getProcedure('dart:ffi', 'StructPointer', '-'),
structPointerElementAtTearoff = index.getProcedure('dart:ffi',
'StructPointer', LibraryIndex.tearoffPrefix + 'elementAt'),
unionPointerGetRef =
index.getProcedure('dart:ffi', 'UnionPointer', 'get:ref'),
unionPointerSetRef =
@ -439,10 +449,14 @@ class FfiTransformer extends Transformer {
index.getProcedure('dart:ffi', 'UnionPointer', '[]'),
unionPointerSetElemAt =
index.getProcedure('dart:ffi', 'UnionPointer', '[]='),
unionPointerElementAt =
index.getProcedure('dart:ffi', 'UnionPointer', 'elementAt'),
unionPointerPlusOperator =
index.getProcedure('dart:ffi', 'UnionPointer', '+'),
unionPointerMinusOperator =
index.getProcedure('dart:ffi', 'UnionPointer', '-'),
unionPointerElementAtTearoff = index.getProcedure('dart:ffi',
'UnionPointer', LibraryIndex.tearoffPrefix + 'elementAt'),
structArrayElemAt = index.getProcedure('dart:ffi', 'StructArray', '[]'),
unionArrayElemAt = index.getProcedure('dart:ffi', 'UnionArray', '[]'),
arrayArrayElemAt = index.getProcedure('dart:ffi', 'ArrayArray', '[]'),
@ -456,10 +470,16 @@ class FfiTransformer extends Transformer {
index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '[]'),
abiSpecificIntegerPointerSetElemAt =
index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '[]='),
abiSpecificIntegerPointerElementAt = index.getProcedure(
'dart:ffi', 'AbiSpecificIntegerPointer', 'elementAt'),
abiSpecificIntegerPointerPlusOperator =
index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '+'),
abiSpecificIntegerPointerMinusOperator =
index.getProcedure('dart:ffi', 'AbiSpecificIntegerPointer', '-'),
abiSpecificIntegerPointerElementAtTearoff = index.getProcedure(
'dart:ffi',
'AbiSpecificIntegerPointer',
LibraryIndex.tearoffPrefix + 'elementAt'),
abiSpecificIntegerArrayElemAt =
index.getProcedure('dart:ffi', 'AbiSpecificIntegerArray', '[]'),
abiSpecificIntegerArraySetElemAt =

View file

@ -151,7 +151,10 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
node.isExtensionMember &&
(node == allocationTearoff ||
node == asFunctionTearoff ||
node == lookupFunctionTearoff))) ||
node == lookupFunctionTearoff ||
node == abiSpecificIntegerPointerElementAtTearoff ||
node == structPointerElementAtTearoff ||
node == unionPointerElementAtTearoff))) ||
// Dart2wasm uses enabledConstructorTearOffLowerings but these are not
// users trying to call constructors.
isConstructorTearOffLowering(node);
@ -271,7 +274,10 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
ensureNativeTypeValid(nativeType, node, allowCompounds: true);
return _replaceSetRef(node);
} else if (target == abiSpecificIntegerPointerPlusOperator ||
} else if (target == abiSpecificIntegerPointerElementAt ||
target == structPointerElementAt ||
target == unionPointerElementAt ||
target == abiSpecificIntegerPointerPlusOperator ||
target == structPointerPlusOperator ||
target == unionPointerPlusOperator ||
target == abiSpecificIntegerPointerMinusOperator ||

View file

@ -224,6 +224,10 @@ $platform$truncate$alignment external $dartType operator [](int index);
/// The $property at `address + sizeOf<$nativeType>() * index`.
$platform$truncate$alignment external void operator []=(int index, $dartType value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<$nativeType> elementAt(int index) => Pointer.fromAddress(address + sizeOf<$nativeType>() * index);
/// A pointer to the [offset]th [$nativeType] after this one.
///
/// Returns a pointer to the [$nativeType] whose address is

View file

@ -25,7 +25,7 @@ main() async {
using((Arena arena) {
final p = arena<Int64>(2);
p[0] = 24;
MemMove((p + 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]);
});
@ -35,7 +35,7 @@ main() async {
using((Arena arena) {
final p = arena<Int64>(2);
p[0] = 25;
MemMove((p + 1).cast<Void>(), p.cast<Void>(), 8);
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
Expect.equals(25, p[1]);
throw Exception("Some random exception");

View file

@ -24,7 +24,7 @@ main() async {
withZoneArena(() {
final p = zoneArena<Int64>(2);
p[0] = 24;
MemMove((p + 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]);
});
@ -34,7 +34,7 @@ main() async {
withZoneArena(() {
final p = zoneArena<Int64>(2);
p[0] = 25;
MemMove((p + 1).cast<Void>(), p.cast<Void>(), 8);
MemMove(p.elementAt(1).cast<Void>(), p.cast<Void>(), 8);
print(p[1]);
Expect.equals(25, p[1]);
throw Exception("Some random exception");

View file

@ -25,7 +25,7 @@ main() {
// For automatic management use a Arena.
final p = calloc<Int64>(2);
p[0] = 24;
memMove((p + 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]);
calloc.free(p);

View file

@ -71,7 +71,7 @@ main() {
Pointer<Int32> p2 = p1.cast();
print('${p2.runtimeType} value: ${p2.value}'); // -1
Pointer<Int32> p3 = p2 + 1;
Pointer<Int32> p3 = p2.elementAt(1);
print('${p3.runtimeType} value: ${p3.value}'); // 2^31 - 1
calloc.free(p1);
@ -81,10 +81,10 @@ main() {
// Data can be tightly packed in memory.
Pointer<Int8> p = calloc(8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
(p + i).value = i * 3;
p.elementAt(i).value = i * 3;
}
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
print('(p + $i) value: ${(p + i).value}');
print('p.elementAt($i) value: ${p.elementAt(i).value}');
}
calloc.free(p);
}

View file

@ -197,7 +197,7 @@ main() {
Pointer<Int64> p2 = calloc(2);
p2.value = 42;
p2[1] = 1000;
print((p2 + 1).address.toRadixString(16));
print(p2.elementAt(1).address.toRadixString(16));
print(p2[1]);
Pointer<Int64> result = assign1337Index1(p2);
print(p2[1]);

View file

@ -50,8 +50,8 @@ main() {
NativeCoordinateOp f1 = p1.asFunction();
Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1 + 1;
Pointer<Coordinate> c3 = c1 + 2;
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
c1.ref.y = 10.0;
c1.ref.next = c3;

View file

@ -40,8 +40,8 @@ main() {
{
// Allocates coordinates consecutively in c memory.
Pointer<Coordinate> c1 = calloc<Coordinate>(3);
Pointer<Coordinate> c2 = c1 + 1;
Pointer<Coordinate> c3 = c1 + 2;
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref.x = 10.0;
c1.ref.y = 10.0;
c1.ref.next = c3;

View file

@ -1094,6 +1094,10 @@ extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
@patch
Pointer<T> operator [](int index) => _loadPointer(this, _intPtrSize * index);
@patch
Pointer<Pointer<T>> elementAt(int index) =>
Pointer.fromAddress(address + _intPtrSize * index);
@patch
Pointer<Pointer<T>> operator +(int offset) =>
Pointer.fromAddress(address + _intPtrSize * offset);
@ -1125,6 +1129,10 @@ extension StructPointer<T extends Struct> on Pointer<T> {
void operator []=(int index, T value) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> elementAt(int index) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> operator +(int offset) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@ -1152,6 +1160,10 @@ extension UnionPointer<T extends Union> on Pointer<T> {
void operator []=(int index, T value) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> elementAt(int index) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> operator +(int offset) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@ -1180,6 +1192,10 @@ extension AbiSpecificIntegerPointer<T extends AbiSpecificInteger>
void operator []=(int index, int value) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> elementAt(int index) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";
@patch
Pointer<T> operator +(int offset) =>
throw "UNREACHABLE: This case should have been rewritten in the CFE.";

View file

@ -321,6 +321,11 @@ extension Int8Pointer on Pointer<Int8> {
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Int8> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Int8>() * index);
/// A pointer to the [offset]th [Int8] after this one.
///
/// Returns a pointer to the [Int8] whose address is
@ -393,6 +398,11 @@ extension Int16Pointer on Pointer<Int16> {
/// The [address] must be 2-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Int16> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Int16>() * index);
/// A pointer to the [offset]th [Int16] after this one.
///
/// Returns a pointer to the [Int16] whose address is
@ -467,6 +477,11 @@ extension Int32Pointer on Pointer<Int32> {
/// The [address] must be 4-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Int32> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Int32>() * index);
/// A pointer to the [offset]th [Int32] after this one.
///
/// Returns a pointer to the [Int32] whose address is
@ -532,6 +547,11 @@ extension Int64Pointer on Pointer<Int64> {
/// The [address] must be 8-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Int64> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Int64>() * index);
/// A pointer to the [offset]th [Int64] after this one.
///
/// Returns a pointer to the [Int64] whose address is
@ -600,6 +620,11 @@ extension Uint8Pointer on Pointer<Uint8> {
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Uint8> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Uint8>() * index);
/// A pointer to the [offset]th [Uint8] after this one.
///
/// Returns a pointer to the [Uint8] whose address is
@ -672,6 +697,11 @@ extension Uint16Pointer on Pointer<Uint16> {
/// The [address] must be 2-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Uint16> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Uint16>() * index);
/// A pointer to the [offset]th [Uint16] after this one.
///
/// Returns a pointer to the [Uint16] whose address is
@ -746,6 +776,11 @@ extension Uint32Pointer on Pointer<Uint32> {
/// The [address] must be 4-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Uint32> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Uint32>() * index);
/// A pointer to the [offset]th [Uint32] after this one.
///
/// Returns a pointer to the [Uint32] whose address is
@ -811,6 +846,11 @@ extension Uint64Pointer on Pointer<Uint64> {
/// The [address] must be 8-byte aligned.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Uint64> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Uint64>() * index);
/// A pointer to the [offset]th [Uint64] after this one.
///
/// Returns a pointer to the [Uint64] whose address is
@ -885,6 +925,11 @@ extension FloatPointer on Pointer<Float> {
/// The [address] must be 4-byte aligned.
external void operator []=(int index, double value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Float> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Float>() * index);
/// A pointer to the [offset]th [Float] after this one.
///
/// Returns a pointer to the [Float] whose address is
@ -950,6 +995,11 @@ extension DoublePointer on Pointer<Double> {
/// The [address] must be 8-byte aligned.
external void operator []=(int index, double value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Double> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Double>() * index);
/// A pointer to the [offset]th [Double] after this one.
///
/// Returns a pointer to the [Double] whose address is
@ -1010,6 +1060,11 @@ extension BoolPointer on Pointer<Bool> {
/// The bool at `address + sizeOf<Bool>() * index`.
external void operator []=(int index, bool value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
Pointer<Bool> elementAt(int index) =>
Pointer.fromAddress(address + sizeOf<Bool>() * index);
/// A pointer to the [offset]th [Bool] after this one.
///
/// Returns a pointer to the [Bool] whose address is
@ -1160,6 +1215,10 @@ extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
/// platforms the [address] must be 8-byte aligned.
external void operator []=(int index, Pointer<T> value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
external Pointer<Pointer<T>> elementAt(int index);
/// A pointer to the [offset]th [Pointer<T>] after this one.
///
/// Returns a pointer to the [Pointer<T>] whose address is
@ -1218,6 +1277,10 @@ extension StructPointer<T extends Struct> on Pointer<T> {
/// where `T` is a compile-time constant type.
external void operator []=(int index, T value);
/// Pointer arithmetic (takes element size into account)
@Deprecated('Use operator + instead')
external Pointer<T> elementAt(int index);
/// A pointer to the [offset]th [T] after this one.
///
/// Returns a pointer to the [T] whose address is
@ -1276,6 +1339,10 @@ extension UnionPointer<T extends Union> on Pointer<T> {
/// where `T` is a compile-time constant type.
external void operator []=(int index, T value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
external Pointer<T> elementAt(int index);
/// A pointer to the [offset]th [T] after this one.
///
/// Returns a pointer to the [T] whose address is
@ -1315,6 +1382,10 @@ extension AbiSpecificIntegerPointer<T extends AbiSpecificInteger>
/// The integer at `address + sizeOf<T>() * index`.
external void operator []=(int index, int value);
/// Pointer arithmetic (takes element size into account).
@Deprecated('Use operator + instead')
external Pointer<T> elementAt(int index);
/// A pointer to the [offset]th [T] after this one.
///
/// Returns a pointer to the [T] whose address is

View file

@ -107,7 +107,7 @@ final class IncompleteArrayArrayStruct extends Struct {
void testInlineArray2() {
final p = calloc<Int64>(100).cast<IncompleteArrayArrayStruct>();
Expect.throws(() {
p + 3;
p.elementAt(3);
});
Expect.throws(() {
(p + 3);

View file

@ -90,7 +90,7 @@ void testInlineArray2() {
int someValue(int a, int b, int c) => a * 1337 + b * 42 + c;
final p = calloc<WCharArrayArrayStruct>(_dim0);
for (int i0 = 0; i0 < _dim0; i0++) {
final array = (p + i0).ref.a0;
final array = p.elementAt(i0).ref.a0;
for (int i1 = 0; i1 < _dim1; i1++) {
final array2 = array[i1];
for (int i2 = 0; i2 < _dim2; i2++) {
@ -99,7 +99,7 @@ void testInlineArray2() {
}
}
for (int i0 = 0; i0 < _dim0; i0++) {
final array = (p + i0).ref.a0;
final array = p.elementAt(i0).ref.a0;
for (int i1 = 0; i1 < _dim1; i1++) {
final array2 = array[i1];
for (int i2 = 0; i2 < _dim2; i2++) {

View file

@ -22,8 +22,8 @@ void main() {
testAliasCast2();
testAliasOffsetBy();
testAliasOffsetBy2();
testAliasOperator();
testAliasOperator2();
testAliasElementAt();
testAliasElementAt2();
testAliasFromAddress();
testAliasFromAddress2();
testAliasFromAddressViaMemory();
@ -90,9 +90,9 @@ void testAliasOffsetBy2() {
calloc.free(source);
}
void testAliasOperator() {
void testAliasElementAt() {
final source = calloc<Int64>(2);
final alias = source + 1 - 1;
final alias = source.elementAt(1).elementAt(-1);
source.value = 42;
final int a = source.value;
alias.value = 1984;
@ -101,10 +101,10 @@ void testAliasOperator() {
calloc.free(source);
}
void testAliasOperator2() {
void testAliasElementAt2() {
final source = calloc<Int64>(3);
final alias = source + 2 - 2;
final alias2 = source + 1 - 1;
final alias = source.elementAt(2).elementAt(-2);
final alias2 = source.elementAt(1).elementAt(-1);
alias.value = 42;
final int a = alias.value;
alias2.value = 1984;

View file

@ -67,7 +67,7 @@ void testPointerFromPointer() {
void testPointerPointerArithmetic() {
Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p + 1;
Pointer<Int64> p2 = p.elementAt(1);
p2.value = 100;
Pointer<Int64> p3 = p.offsetBy(8);
Expect.equals(100, p3.value);
@ -83,13 +83,13 @@ void testPointerPointerArithmetic() {
void testPointerPointerArithmeticSizes() {
Pointer<Int64> p = calloc(2);
Pointer<Int64> p2 = p + 1;
Pointer<Int64> p2 = p.elementAt(1);
int addr = p.address;
Expect.equals(addr + 8, p2.address);
calloc.free(p);
Pointer<Int32> p3 = calloc(2);
Pointer<Int32> p4 = p3 + 1;
Pointer<Int32> p4 = p3.elementAt(1);
addr = p3.address;
Expect.equals(addr + 4, p4.address);
calloc.free(p3);
@ -439,7 +439,7 @@ void testDynamicInvocation() {
final int i = p.value;
});
Expect.throws(() => p.value = 1);
Expect.throws(() => p + 5);
Expect.throws(() => p.elementAt(5));
Expect.throws(() => p += 5);
final int addr = p.address;
final Pointer<Int16> p2 = p.cast<Int16>();

View file

@ -23,12 +23,12 @@ testStoreLoad() {
Expect.equals(20, p[1]);
if (sizeOf<IntPtr>() == 4) {
// Test round tripping.
Expect.equals(20, (p + 0x100000001).value);
Expect.equals(20, p.elementAt(0x100000001).value);
Expect.equals(20, p[0x100000001]);
}
// Test negative index.
final pUseNegative = p + 1;
final pUseNegative = p.elementAt(1);
Expect.equals(10, pUseNegative[-1]);
// Test negative index using operators
@ -80,8 +80,8 @@ testCompoundLoadAndStore() {
foos[i] = reference;
Expect.isTrue(foos[i].a == 10);
(foos + i).ref = reference;
Expect.isTrue((foos + i).ref.a == 10);
foos.elementAt(i).ref = reference;
Expect.isTrue(foos.elementAt(i).ref.a == 10);
}
for (var i = 1; i < 9; i++) {
@ -97,7 +97,7 @@ testCompoundLoadAndStore() {
for (var i = 1; i < 9; i++) {
bars[i] = bars[0];
Expect.isTrue((bars + i).ref.foo.a == 10);
Expect.isTrue(bars.elementAt(i).ref.foo.a == 10);
Expect.isTrue((bars + i).ref.foo.a == 10);
}

View file

@ -137,10 +137,10 @@ double manyArgs(
}
typedef StoreType = Pointer<Int64> Function(Pointer<Int64>);
Pointer<Int64> store(Pointer<Int64> ptr) => (ptr + 1)..value = 1337;
Pointer<Int64> store(Pointer<Int64> ptr) => ptr.elementAt(1)..value = 1337;
typedef NullPointersType = Pointer<Int64> Function(Pointer<Int64>);
Pointer<Int64> nullPointers(Pointer<Int64> ptr) => (ptr + 1);
Pointer<Int64> nullPointers(Pointer<Int64> ptr) => ptr.elementAt(1);
typedef ReturnVoid = Void Function();
void returnVoid() {}

View file

@ -71,15 +71,15 @@ void testFunctionWithStructArray({bool isLeaf = false}) {
Coordinate c3 = coordinateArray[2];
c1.x = 10.0;
c1.y = 10.0;
c1.next = coordinateArray + 2;
c1.next = coordinateArray.elementAt(2);
c2.x = 20.0;
c2.y = 20.0;
c2.next = coordinateArray + 0;
c2.next = coordinateArray.elementAt(0);
c3.x = 30.0;
c3.y = 30.0;
c3.next = coordinateArray + 1;
c3.next = coordinateArray.elementAt(1);
Coordinate result = f1(coordinateArray).ref;
Coordinate result = f1(coordinateArray.elementAt(0)).ref;
Expect.approxEquals(20.0, result.x);
Expect.approxEquals(20.0, result.y);
@ -114,18 +114,18 @@ void testFunctionWithVeryLargeStruct({bool isLeaf = false}) {
struct.k = 1024;
struct.smallLastField = 1;
}
vls1.parent = vlsArray + 1;
vls1.parent = vlsArray.elementAt(1);
vls1.numChildren = 2;
vls1.children = vlsArray;
vls2.parent = vlsArray + 1;
vls1.children = vlsArray.elementAt(0);
vls2.parent = vlsArray.elementAt(1);
vls2.parent = nullptr;
vls2.numChildren = 0;
vls2.children = nullptr;
int result = f(vlsArray);
int result = f(vlsArray.elementAt(0));
Expect.equals(2051, result);
result = f(vlsArray + 1);
result = f(vlsArray.elementAt(1));
Expect.equals(2048, result);
calloc.free(vlsArray);

View file

@ -398,7 +398,7 @@ void testNativeFunctionPointer() {
Pointer<Int64> result = assign1337Index1(p2);
Expect.equals(1337, result.value);
Expect.equals(1337, p2[1]);
Expect.equals((p2 + 1).address, result.address);
Expect.equals(p2.elementAt(1).address, result.address);
calloc.free(p2);
}

View file

@ -9,7 +9,7 @@ import "package:ffi/ffi.dart";
main() {
final data = calloc<Uint8>(3);
for (int i = 0; i < 3; ++i) {
(data + i).value = 1;
data.elementAt(i).value = 1;
}
calloc.free(data);
}

View file

@ -56,8 +56,8 @@ void testStructAllocate() {
/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1 + 1;
Pointer<Coordinate> c3 = c1 + 2;
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref
..x = 10.0
..y = 10.0

View file

@ -17,7 +17,9 @@ void main() {
for (int i = 0; i < 100; i++) {
testStructAllocate();
testStructFromAddress();
testStructFromAddressWithOperator();
testStructIndexedAccess();
testStructIndexedAccessWithOperator();
testStructWithNulls();
testTypeTest();
testUtf8();
@ -56,6 +58,35 @@ void testStructAllocate() {
/// Allocates coordinates consecutively in c memory.
void testStructFromAddress() {
Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1.elementAt(1);
Pointer<Coordinate> c3 = c1.elementAt(2);
c1.ref
..x = 10.0
..y = 10.0
..next = c3;
c2.ref
..x = 20.0
..y = 20.0
..next = c1;
c3.ref
..x = 30.0
..y = 30.0
..next = c2;
Coordinate currentCoordinate = c1.ref;
Expect.equals(10.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(30.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(20.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
calloc.free(c1);
}
void testStructFromAddressWithOperator() {
Pointer<Coordinate> c1 = calloc(3);
Pointer<Coordinate> c2 = c1 + 1;
Pointer<Coordinate> c3 = c1 + 2;
@ -86,6 +117,33 @@ void testStructFromAddress() {
/// Allocates coordinates consecutively in c memory.
void testStructIndexedAccess() {
Pointer<Coordinate> cs = calloc(3);
cs[0]
..x = 10.0
..y = 10.0
..next = cs.elementAt(2);
cs[1]
..x = 20.0
..y = 20.0
..next = cs;
cs[2]
..x = 30.0
..y = 30.0
..next = cs.elementAt(1);
Coordinate currentCoordinate = cs.ref;
Expect.equals(10.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(30.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(20.0, currentCoordinate.x);
currentCoordinate = currentCoordinate.next.ref;
Expect.equals(10.0, currentCoordinate.x);
calloc.free(cs);
}
void testStructIndexedAccessWithOperator() {
Pointer<Coordinate> cs = calloc(3);
cs[0]
..x = 10.0

View file

@ -90,7 +90,7 @@ void _freeAll() {
Pointer<T> _allocateUnaligned<T extends NativeType>() {
final pointer = calloc<Int8>(16);
_pool.add(pointer);
final misaligned = (pointer + 1).cast<T>();
final misaligned = pointer.elementAt(1).cast<T>();
Expect.equals(1, misaligned.address % 2);
return misaligned;
}

View file

@ -32,6 +32,7 @@ final List<Function()> functionsToTest = [
() => highAddressPointer.cast<Double>(),
() => Pointer.fromAddress(highAddressPointer.address),
() => highAddressPointer.address,
() => highAddressPointer.elementAt(1),
() => highAddressPointer + 1,
() => highAddressPointer.offsetBy(1),
() => highAddressPointer.asTypedList(1),

View file

@ -68,6 +68,8 @@ void main() {
testRefStruct();
testSizeOfGeneric();
testSizeOfInvalidType();
testElementAtGeneric();
testElementAtNativeType();
testLookupFunctionIsLeafMustBeConst();
testAsFunctionIsLeafMustBeConst();
testLookupFunctionTakesHandle();
@ -1131,6 +1133,33 @@ void testSizeOfInvalidType() {
// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_TYPE_ARGUMENT
}
void testElementAtGeneric() {
Pointer<T> generic<T extends NativeType>(Pointer<T> pointer) {
Pointer<T> returnValue = pointer;
returnValue = returnValue.elementAt(1);
// ^^^^^^^^^
// [cfe] The method 'elementAt' isn't defined for the class 'Pointer<T>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
return returnValue;
}
Pointer<Int8> p = calloc();
p.elementAt(1);
generic(p);
calloc.free(p);
}
void testElementAtNativeType() {
Pointer<Int8> p = calloc();
p.elementAt(1);
Pointer<NativeType> p2 = p;
p2.elementAt(1);
// ^^^^^^^^^
// [cfe] The method 'elementAt' isn't defined for the class 'Pointer<NativeType>'.
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
calloc.free(p);
}
final class TestStruct1400 extends Struct {
@Array(8)
@Array(8)