[vm/ffi] Use Pointer<Null> as the type of nullptr.

Also clean up test/benchmark/sample code using nullptr and fix pubspec.yaml in the SQLite sample.

Fixes https://github.com/dart-lang/sdk/issues/37362

Change-Id: I6fa0522374af28020ef8f096ac22b23712aedb5a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121122
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Samir Jindel 2019-10-11 14:39:47 +00:00 committed by commit-bot@chromium.org
parent e6a856a3b3
commit 4ee5ef9f10
12 changed files with 37 additions and 23 deletions

View file

@ -49,7 +49,7 @@ String hash(Pointer<Data> data, int length, Pointer<EVP_MD> hashAlgorithm) {
EVP_DigestUpdate(context, data, length);
final int resultSize = EVP_MD_CTX_size(context);
final Pointer<Bytes> result = allocate<Uint8>(count: resultSize).cast();
EVP_DigestFinal(context, result, nullptr.cast());
EVP_DigestFinal(context, result, nullptr);
EVP_MD_CTX_free(context);
final String hash = base64Encode(toUint8List(result.ref, resultSize));
free(result);

View file

@ -106,7 +106,7 @@ Now we have all ingredients to call `sqlite3_prepare_v2`.
Pointer<StatementPointer> statementOut = allocate();
CString queryC = CString.allocate(query);
int resultCode = sqlite3_prepare_v2(
_database, queryC, -1, statementOut, fromAddress(0));
_database, queryC, -1, statementOut, nullptr);
```
With `dart:ffi` we are responsible for freeing C memory that we allocate.

View file

@ -30,7 +30,7 @@ class Database {
Pointer<Pointer<types.Database>> dbOut = allocate();
final pathC = Utf8.toUtf8(path);
final int resultCode =
bindings.sqlite3_open_v2(pathC, dbOut, flags, Pointer.fromAddress(0));
bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
_database = dbOut.value;
free(dbOut);
free(pathC);
@ -66,7 +66,7 @@ class Database {
Pointer<Pointer<Statement>> statementOut = allocate();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, Pointer.fromAddress(0));
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
free(statementOut);
free(queryC);
@ -85,7 +85,7 @@ class Database {
Pointer<Pointer<Statement>> statementOut = allocate();
Pointer<Utf8> queryC = Utf8.toUtf8(query);
int resultCode = bindings.sqlite3_prepare_v2(
_database, queryC, -1, statementOut, Pointer.fromAddress(0));
_database, queryC, -1, statementOut, nullptr);
Pointer<Statement> statement = statementOut.value;
free(statementOut);
free(queryC);

View file

@ -5,5 +5,8 @@ description: >-
author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
environment:
sdk: '>=2.1.0 <3.0.0'
dependencies:
ffi:
path: ../../../third_party/pkg/ffi
dev_dependencies:
test: ^1.5.3

View file

@ -26,8 +26,9 @@ part "struct.dart";
/// Includes padding and alignment of structs.
external int sizeOf<T extends NativeType>();
/// Represents a pointer into the native C memory.
final Pointer<Void> nullptr = Pointer.fromAddress(0);
/// Represents a pointer into the native C memory corresponding to "NULL", e.g.
/// a pointer with address 0.
final Pointer<Null> nullptr = Pointer.fromAddress(0);
/// Represents a pointer into the native C memory. Cannot be extended.
@pragma("vm:entry-point")

View file

@ -28,8 +28,9 @@ part "struct.dart";
/// Includes padding and alignment of structs.
external int sizeOf<T extends NativeType>();
/// Represents a pointer into the native C memory.
final Pointer<Void> nullptr = Pointer.fromAddress(0);
/// Represents a pointer into the native C memory corresponding to "NULL", e.g.
/// a pointer with address 0.
final Pointer<Null> nullptr = Pointer.fromAddress(0);
/// Represents a pointer into the native C memory. Cannot be extended.
@pragma("vm:entry-point")

View file

@ -55,6 +55,7 @@ void main() {
testSizeOfNativeType();
testDynamicInvocation();
testMemoryAddressTruncation();
testNullptrCast();
}
void testPointerBasic() {
@ -328,7 +329,7 @@ void testPointerPointer() {
void testPointerPointerNull() {
Pointer<Pointer<Int8>> pointerToPointer = allocate();
Pointer<Int8> value = nullptr.cast();
Pointer<Int8> value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
@ -337,7 +338,7 @@ void testPointerPointerNull() {
value = pointerToPointer.value;
Expect.isNotNull(value);
free(value);
value = nullptr.cast();
value = nullptr;
pointerToPointer.value = value;
value = pointerToPointer.value;
Expect.equals(value, nullptr);
@ -510,6 +511,16 @@ void testDynamicInvocation() {
free(p);
}
final nullableInt64ElementAt1 = ffiTestFunctions.lookupFunction<
Pointer<Int64> Function(Pointer<Int64>),
Pointer<Int64> Function(Pointer<Int64>)>("NullableInt64ElemAt1");
void testNullptrCast() {
Pointer<Int64> ptr = nullptr;
ptr = nullableInt64ElementAt1(ptr);
Expect.equals(ptr, nullptr);
}
void testMemoryAddressTruncation() {
const int kIgnoreBytesPositive = 0x1122334400000000;
const int kIgnoreBytesNegative = 0xffddccbb00000000;

View file

@ -282,7 +282,7 @@ void testArrayStore() {
}
void testNegativeArray() {
Pointer<Int32> ptr = nullptr.cast();
Pointer<Int32> ptr = nullptr;
Expect.throws<ArgumentError>(() => ptr.asExternalTypedData(count: -1));
}

View file

@ -35,8 +35,7 @@ void testFunctionWithStruct() {
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
Pointer<Coordinate> c1 =
Coordinate.allocate(10.0, 20.0, nullptr.cast<Coordinate>()).addressOf;
Pointer<Coordinate> c1 = Coordinate.allocate(10.0, 20.0, nullptr).addressOf;
Pointer<Coordinate> c2 = Coordinate.allocate(42.0, 84.0, c1).addressOf;
c1.ref.next = c2;
@ -107,9 +106,9 @@ void testFunctionWithVeryLargeStruct() {
vls1.numChildren = 2;
vls1.children = vls1.addressOf;
vls2.parent = vls2.addressOf;
vls2.parent = nullptr.cast();
vls2.parent = nullptr;
vls2.numChildren = 0;
vls2.children = nullptr.cast();
vls2.children = nullptr;
int result = f(vls1.addressOf);
Expect.equals(2051, result);

View file

@ -355,7 +355,7 @@ Int64PointerUnOp nullableInt64ElemAt1 = ffiTestFunctions
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("NullableInt64ElemAt1");
void testNullPointers() {
Pointer<Int64> result = nullableInt64ElemAt1(nullptr.cast());
Pointer<Int64> result = nullableInt64ElemAt1(nullptr);
Expect.equals(result, nullptr);
Pointer<Int64> p2 = allocate(count: 2);

View file

@ -98,7 +98,7 @@ void testGetNativeType() {
void testGetTypeMismatch() {
Pointer<Pointer<Int16>> p = allocate();
Pointer<Int16> typedNull = nullptr.cast();
Pointer<Int16> typedNull = nullptr;
p.value = typedNull;
// this fails to compile due to type mismatch

View file

@ -30,8 +30,7 @@ void main() {
/// allocates each coordinate separately in c memory
void testStructAllocate() {
Pointer<Coordinate> c1 =
Coordinate.allocate(10.0, 10.0, nullptr.cast()).addressOf;
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;
@ -82,11 +81,11 @@ void testStructFromAddress() {
void testStructWithNulls() {
Pointer<Coordinate> coordinate =
Coordinate.allocate(10.0, 10.0, nullptr.cast<Coordinate>()).addressOf;
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.cast();
coordinate.ref.next = nullptr;
Expect.equals(coordinate.ref.next, nullptr);
free(coordinate);
}
@ -122,7 +121,7 @@ void testBareStruct() {
}
void testTypeTest() {
Coordinate c = Coordinate.allocate(10, 10, nullptr.cast<Coordinate>());
Coordinate c = Coordinate.allocate(10, 10, nullptr);
Expect.isTrue(c is Struct);
Expect.isTrue(c is Struct<Coordinate>);
free(c.addressOf);