Skip to content

Commit 5f68b0b

Browse files
dcharkescommit-bot@chromium.org
authored andcommitted
[test/ffi] Test struct workaround for external fields
Make sure the individual getter/setter workaround for structs in NNBD works. That way structs can be migrated without having to opt in to the proposed --enable-experiment=external-abstract-variables for external fields. Note that this requires dart:ffi users to migrate twice for NNBD, once to the workaround, and later a cleanup to external fields. Change-Id: I2a9020ff7df3ebf08e04f71183f9297d87acb1b1 Cq-Include-Trybots:dart/try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,vm-precomp-ffi-qemu-linux-release-arm-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153777 Reviewed-by: Erik Ernst <[email protected]> Commit-Queue: Daco Harkes <[email protected]>
1 parent 01ac35b commit 5f68b0b

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
library FfiTest;
6+
7+
import 'dart:ffi';
8+
import "package:ffi/ffi.dart";
9+
10+
/// Sample struct for dart:ffi library.
11+
class Coordinate extends Struct {
12+
@Double()
13+
external double get x;
14+
external set x(double v);
15+
16+
@Double()
17+
external double get y;
18+
external set y(double v);
19+
20+
external Pointer<Coordinate> get next;
21+
external set next(Pointer<Coordinate> v);
22+
23+
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
24+
return allocate<Coordinate>().ref
25+
..x = x
26+
..y = y
27+
..next = next;
28+
}
29+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// Dart test program for testing dart:ffi struct pointers.
6+
//
7+
// VMOptions=--deterministic --optimization-counter-threshold=50
8+
9+
import 'dart:ffi';
10+
11+
import "package:expect/expect.dart";
12+
import "package:ffi/ffi.dart";
13+
14+
import 'coordinate_nnbd_workaround.dart';
15+
16+
void main() {
17+
for (int i = 0; i < 100; i++) {
18+
testStructAllocate();
19+
testStructFromAddress();
20+
testStructWithNulls();
21+
testTypeTest();
22+
testUtf8();
23+
}
24+
}
25+
26+
/// allocates each coordinate separately in c memory
27+
void testStructAllocate() {
28+
Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
29+
Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
30+
Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
31+
c1.ref.next = c3;
32+
33+
Coordinate currentCoordinate = c1.ref;
34+
Expect.equals(10.0, currentCoordinate.x);
35+
currentCoordinate = currentCoordinate.next.ref;
36+
Expect.equals(30.0, currentCoordinate.x);
37+
currentCoordinate = currentCoordinate.next.ref;
38+
Expect.equals(20.0, currentCoordinate.x);
39+
currentCoordinate = currentCoordinate.next.ref;
40+
Expect.equals(10.0, currentCoordinate.x);
41+
42+
free(c1);
43+
free(c2);
44+
free(c3);
45+
}
46+
47+
/// allocates coordinates consecutively in c memory
48+
void testStructFromAddress() {
49+
Pointer<Coordinate> c1 = allocate(count: 3);
50+
Pointer<Coordinate> c2 = c1.elementAt(1);
51+
Pointer<Coordinate> c3 = c1.elementAt(2);
52+
c1.ref
53+
..x = 10.0
54+
..y = 10.0
55+
..next = c3;
56+
c2.ref
57+
..x = 20.0
58+
..y = 20.0
59+
..next = c1;
60+
c3.ref
61+
..x = 30.0
62+
..y = 30.0
63+
..next = c2;
64+
65+
Coordinate currentCoordinate = c1.ref;
66+
Expect.equals(10.0, currentCoordinate.x);
67+
currentCoordinate = currentCoordinate.next.ref;
68+
Expect.equals(30.0, currentCoordinate.x);
69+
currentCoordinate = currentCoordinate.next.ref;
70+
Expect.equals(20.0, currentCoordinate.x);
71+
currentCoordinate = currentCoordinate.next.ref;
72+
Expect.equals(10.0, currentCoordinate.x);
73+
74+
free(c1);
75+
}
76+
77+
void testStructWithNulls() {
78+
Pointer<Coordinate> coordinate =
79+
Coordinate.allocate(10.0, 10.0, nullptr).addressOf;
80+
Expect.equals(coordinate.ref.next, nullptr);
81+
coordinate.ref.next = coordinate;
82+
Expect.notEquals(coordinate.ref.next, nullptr);
83+
coordinate.ref.next = nullptr;
84+
Expect.equals(coordinate.ref.next, nullptr);
85+
free(coordinate);
86+
}
87+
88+
void testTypeTest() {
89+
Coordinate c = Coordinate.allocate(10, 10, nullptr);
90+
Expect.isTrue(c is Struct);
91+
Expect.isTrue(c.addressOf is Pointer<Coordinate>);
92+
free(c.addressOf);
93+
}
94+
95+
void testUtf8() {
96+
final String test = 'Hasta Mañana';
97+
final Pointer<Utf8> medium = Utf8.toUtf8(test);
98+
Expect.equals(test, Utf8.fromUtf8(medium));
99+
free(medium);
100+
}

0 commit comments

Comments
 (0)