Skip to content

Commit

Permalink
[test/ffi] Test struct workaround for external fields
Browse files Browse the repository at this point in the history
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 <eernst@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
  • Loading branch information
dcharkes authored and commit-bot@chromium.org committed Jul 9, 2020
1 parent 01ac35b commit 5f68b0b
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
29 changes: 29 additions & 0 deletions tests/ffi/coordinate_nnbd_workaround.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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.

library FfiTest;

import 'dart:ffi';
import "package:ffi/ffi.dart";

/// Sample struct for dart:ffi library.
class Coordinate extends Struct {
@Double()
external double get x;
external set x(double v);

@Double()
external double get y;
external set y(double v);

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
..x = x
..y = y
..next = next;
}
}
100 changes: 100 additions & 0 deletions tests/ffi/structs_nnbd_workaround_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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.
//
// Dart test program for testing dart:ffi struct pointers.
//
// VMOptions=--deterministic --optimization-counter-threshold=50

import 'dart:ffi';

import "package:expect/expect.dart";
import "package:ffi/ffi.dart";

import 'coordinate_nnbd_workaround.dart';

void main() {
for (int i = 0; i < 100; i++) {
testStructAllocate();
testStructFromAddress();
testStructWithNulls();
testTypeTest();
testUtf8();
}
}

/// 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;
c1.ref.next = c3;

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);

free(c1);
free(c2);
free(c3);
}

/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
Pointer<Coordinate> c1 = allocate(count: 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);

free(c1);
}

void testStructWithNulls() {
Pointer<Coordinate> coordinate =
Coordinate.allocate(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);
}

void testTypeTest() {
Coordinate c = Coordinate.allocate(10, 10, nullptr);
Expect.isTrue(c is Struct);
Expect.isTrue(c.addressOf is Pointer<Coordinate>);
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);
}

0 comments on commit 5f68b0b

Please sign in to comment.