[vm/ffi] Add common C types
We're adding these types to `dart:ffi` rather than `package:ffi` so that
they can be used with `FfiNative`s.
Adds `NativeType`s for the following C types:
* char
* unsigned char
* signed char
* short
* unsigned short
* int
* unsigned int
* long
* unsigned long
* long long
* unsigned long long
* uintptr_t
* size_t
* wchar_t
Because the C standard only defines minimum sizes for many of these
types, future platforms might diverge from the typical size even if all
platforms currently agree on a size. To avoid having to reification
later, we define all types as AbiSpecificIntegers rather than typedefs,
even if all current target platforms agree on the size.
Closes: https://github.com/dart-lang/sdk/issues/36140
TEST=tests/ffi/c_types_test.dart
Change-Id: Ie97d253856d787386529231e8060f879069be886
Cq-Include-Trybots: luci.dart.try:dart-sdk-linux-try,dart-sdk-mac-try,dart-sdk-win-try,vm-ffi-android-debug-arm64c-try,vm-ffi-android-debug-arm-try,vm-canary-linux-debug-try,vm-fuchsia-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-mac-debug-x64-try,vm-kernel-mac-release-arm64-try,vm-kernel-nnbd-win-release-ia32-try,vm-kernel-nnbd-win-release-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/228541
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/benchmarks/FfiMemory/dart/FfiMemory.dart b/benchmarks/FfiMemory/dart/FfiMemory.dart
index 881eff2..6178f24 100644
--- a/benchmarks/FfiMemory/dart/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart/FfiMemory.dart
@@ -15,36 +15,6 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
-/// Represents a native unsigned pointer-sized integer in C.
-///
-/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
- const UintPtr();
-}
-
//
// Pointer store.
//
diff --git a/benchmarks/FfiMemory/dart2/FfiMemory.dart b/benchmarks/FfiMemory/dart2/FfiMemory.dart
index 86f7e1f..b3a6cf9 100644
--- a/benchmarks/FfiMemory/dart2/FfiMemory.dart
+++ b/benchmarks/FfiMemory/dart2/FfiMemory.dart
@@ -17,36 +17,6 @@
import 'package:ffi/ffi.dart';
import 'package:benchmark_harness/benchmark_harness.dart';
-/// Represents a native unsigned pointer-sized integer in C.
-///
-/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
- const UintPtr();
-}
-
//
// Pointer store.
//
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
index 8c513a4..d92782a 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
@@ -40,7 +40,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
index 8c513a4..d92782a 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.modular.expect
@@ -40,7 +40,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
index ae497d5a..0765c4c 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.transformed.expect
@@ -74,7 +74,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
index 6c37a20d..7e198e7 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.1.expect
@@ -51,6 +51,7 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
+ ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -63,6 +64,7 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
+ ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -76,6 +78,8 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
+ ffi::Long,
+ ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -86,6 +90,9 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
+ ffi::Short,
+ ffi::SignedChar,
+ ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -101,11 +108,18 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
+ ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
+ ffi::UnsignedChar,
+ ffi::UnsignedInt,
+ ffi::UnsignedLong,
+ ffi::UnsignedLongLong,
+ ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void)
+ ffi::Void,
+ ffi::WChar)
export "org-dartlang-test:///lib3.dart";
@@ -127,6 +141,7 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
+ ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -139,6 +154,7 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
+ ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -152,6 +168,8 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
+ ffi::Long,
+ ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -162,6 +180,9 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
+ ffi::Short,
+ ffi::SignedChar,
+ ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -177,11 +198,18 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
+ ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
+ ffi::UnsignedChar,
+ ffi::UnsignedInt,
+ ffi::UnsignedLong,
+ ffi::UnsignedLongLong,
+ ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void)
+ ffi::Void,
+ ffi::WChar)
export "dart:ffi";
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
index e7c047a..934102e 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_50_ffi.yaml.world.2.expect
@@ -51,6 +51,7 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
+ ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -63,6 +64,7 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
+ ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -76,6 +78,8 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
+ ffi::Long,
+ ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -86,6 +90,9 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
+ ffi::Short,
+ ffi::SignedChar,
+ ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -101,11 +108,18 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
+ ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
+ ffi::UnsignedChar,
+ ffi::UnsignedInt,
+ ffi::UnsignedLong,
+ ffi::UnsignedLongLong,
+ ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void)
+ ffi::Void,
+ ffi::WChar)
export "org-dartlang-test:///lib3.dart";
@@ -127,6 +141,7 @@
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
+ ffi::Char,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
@@ -139,6 +154,7 @@
ffi::FloatArray,
ffi::FloatPointer,
ffi::Handle,
+ ffi::Int,
ffi::Int16,
ffi::Int16Array,
ffi::Int16Pointer,
@@ -152,6 +168,8 @@
ffi::Int8Array,
ffi::Int8Pointer,
ffi::IntPtr,
+ ffi::Long,
+ ffi::LongLong,
ffi::NativeApi,
ffi::NativeFunction,
ffi::NativeFunctionPointer,
@@ -162,6 +180,9 @@
ffi::Pointer,
ffi::PointerArray,
ffi::PointerPointer,
+ ffi::Short,
+ ffi::SignedChar,
+ ffi::Size,
ffi::Struct,
ffi::StructArray,
ffi::StructPointer,
@@ -177,11 +198,18 @@
ffi::Uint8,
ffi::Uint8Array,
ffi::Uint8Pointer,
+ ffi::UintPtr,
ffi::Union,
ffi::UnionArray,
ffi::UnionPointer,
+ ffi::UnsignedChar,
+ ffi::UnsignedInt,
+ ffi::UnsignedLong,
+ ffi::UnsignedLongLong,
+ ffi::UnsignedShort,
ffi::Unsized,
- ffi::Void)
+ ffi::Void,
+ ffi::WChar)
export "dart:ffi";
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 35dda10..b190b3a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.strong.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25: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 02dfd2a..fccf634 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
@@ -65,7 +65,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
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 35dda10..b190b3a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
index 35dda10..b190b3a 100644
--- a/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_sample.dart.weak.modular.expect
@@ -34,7 +34,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25: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 02dfd2a..fccf634 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
@@ -65,7 +65,7 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_sample.dart:
-- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:144:9)
+- Double. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:114:9)
- _NativeDouble. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:34:9)
- NativeType. (from org-dartlang-sdk:///sdk/lib/ffi/native_type.dart:12:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
index 0db513d..4d771b3 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
index 525cfd9..f3903c0 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect
@@ -52,5 +52,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
index e6c0f95..e179ab5 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
index e6c0f95..e179ab5 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.modular.expect
@@ -25,5 +25,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
index b38ad34..24cfa96 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect
@@ -52,5 +52,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
index 0e058b1..dd7fa30 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
index ecf21c0..a16945b 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect
@@ -84,5 +84,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
index 5e4b756..be09548 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
index 5e4b756..be09548 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.modular.expect
@@ -33,5 +33,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
index a9ba39c..a83a86b 100644
--- a/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect
@@ -84,5 +84,5 @@
Constructor coverage from constants:
org-dartlang-testcase:///ffi_struct_inline_array_multi_dimensional.dart:
-- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:138:9)
+- _ArraySize. (from org-dartlang-sdk:///sdk/lib/ffi/ffi.dart:139:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index dd5e41f..1545f8e 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -1138,27 +1138,36 @@
typedef intptr_t ssize_t;
#endif
-#define DEFINE_SIZE_OF(type_modifier, type) \
- DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type() { \
- return sizeof(type_modifier type); \
+#define DEFINE_SIZE_OF_AND_SIGN_OF(type_modifier, type, type2) \
+ DART_EXPORT uint64_t FfiSizeOf_##type_modifier##_##type##_##type2() { \
+ return sizeof(type_modifier type type2); \
+ } \
+ \
+ DART_EXPORT uint64_t FfiSignOf_##type_modifier##_##type##_##type2() { \
+ return std::numeric_limits<type_modifier type type2>::is_signed; \
}
-#define SIZES(F) \
- F(, intptr_t) \
- F(, uintptr_t) \
- F(, int) \
- F(unsigned, int) \
- F(, long) /* NOLINT */ \
- F(unsigned, long) /* NOLINT */ \
- F(, wchar_t) \
- F(, size_t) \
- F(, ssize_t) \
- F(, off_t)
+#define TYPES(F) \
+ F(, char, ) /* NOLINT */ \
+ F(signed, char, ) /* NOLINT */ \
+ F(unsigned, char, ) /* NOLINT */ \
+ F(, short, ) /* NOLINT */ \
+ F(unsigned, short, ) /* NOLINT */ \
+ F(, int, ) /* NOLINT */ \
+ F(unsigned, int, ) /* NOLINT */ \
+ F(, long, ) /* NOLINT */ \
+ F(unsigned, long, ) /* NOLINT */ \
+ F(, long, long) /* NOLINT */ \
+ F(unsigned, long, long) /* NOLINT */ \
+ F(, intptr_t, ) /* NOLINT */ \
+ F(, uintptr_t, ) /* NOLINT */ \
+ F(, size_t, ) /* NOLINT */ \
+ F(, wchar_t, ) /* NOLINT */
-SIZES(DEFINE_SIZE_OF)
+TYPES(DEFINE_SIZE_OF_AND_SIGN_OF)
-#undef DEFINE_SIZE_OF
-#undef SIZES
+#undef DEFINE_SIZE_OF_AND_SIGN_OF
+#undef TYPES
DART_EXPORT int64_t WCharMinValue() {
return WCHAR_MIN;
diff --git a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
index 92e23c1..ca47a83 100644
--- a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -55,11 +55,6 @@
@pragma("vm:entry-point")
class Uint64 extends _NativeInteger {}
-// TODO(http://dartbug.com/47938): Implement as AbiSpecificInteger.
-@patch
-@pragma("vm:entry-point")
-class IntPtr extends _NativeInteger {}
-
@patch
@pragma("vm:entry-point")
class Float extends _NativeDouble {}
diff --git a/sdk/lib/ffi/abi_specific.dart b/sdk/lib/ffi/abi_specific.dart
index d84f74e..a41308c 100644
--- a/sdk/lib/ffi/abi_specific.dart
+++ b/sdk/lib/ffi/abi_specific.dart
@@ -13,10 +13,12 @@
/// For example:
///
/// ```
-/// /// Represents a `uintptr_t` in C.
+/// /// The C `uintptr_t` type.
/// ///
-/// /// [UintPtr] is not constructible in the Dart code and serves purely as
-/// /// marker in type signatures.
+/// /// The [UintPtr] type is a native type, and should not be constructed in
+/// /// Dart code.
+/// /// It occurs only in native type signatures and as annotation on [Struct]
+/// /// and [Union] fields.
/// @AbiSpecificIntegerMapping({
/// Abi.androidArm: Uint32(),
/// Abi.androidArm64: Uint64(),
diff --git a/sdk/lib/ffi/c_type.dart b/sdk/lib/ffi/c_type.dart
new file mode 100644
index 0000000..9370fdc
--- /dev/null
+++ b/sdk/lib/ffi/c_type.dart
@@ -0,0 +1,541 @@
+// Copyright (c) 2022, 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 library defines [NativeType]s for common C types.
+///
+/// Many C types only define a minimal size in the C standard, but they are
+/// consistent per [Abi]. Therefore we use [AbiSpecificInteger]s to define
+/// these C types in this library.
+part of dart.ffi;
+
+/// The C `char` type.
+///
+/// Typically a signed or unsigned 8-bit integer.
+/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type
+/// or [Uint8] with the C `uint8_t` type.
+/// For a specifically `signed` or `unsigned` `char`, use [SignedChar] or
+/// [UnsignedChar].
+///
+/// The [Char] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint8(),
+ Abi.androidArm64: Uint8(),
+ Abi.androidIA32: Uint8(),
+ Abi.androidX64: Uint8(),
+ Abi.fuchsiaArm64: Int8(),
+ Abi.fuchsiaX64: Int8(),
+ Abi.iosArm: Uint8(),
+ Abi.iosArm64: Int8(),
+ Abi.iosX64: Int8(),
+ Abi.linuxArm: Uint8(),
+ Abi.linuxArm64: Int8(),
+ Abi.linuxIA32: Int8(),
+ Abi.linuxX64: Int8(),
+ Abi.linuxRiscv32: Int8(),
+ Abi.linuxRiscv64: Int8(),
+ Abi.macosArm64: Int8(),
+ Abi.macosX64: Int8(),
+ Abi.windowsArm64: Int8(),
+ Abi.windowsIA32: Int8(),
+ Abi.windowsX64: Int8(),
+})
+class Char extends AbiSpecificInteger {
+ const Char();
+}
+
+/// The C `signed char` type.
+///
+/// Typically a signed 8-bit integer.
+/// For a guaranteed 8-bit integer, use [Int8] with the C `int8_t` type.
+/// For an `unsigned char`, use [UnsignedChar].
+///
+/// The [SignedChar] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int8(),
+ Abi.androidArm64: Int8(),
+ Abi.androidIA32: Int8(),
+ Abi.androidX64: Int8(),
+ Abi.fuchsiaArm64: Int8(),
+ Abi.fuchsiaX64: Int8(),
+ Abi.iosArm: Int8(),
+ Abi.iosArm64: Int8(),
+ Abi.iosX64: Int8(),
+ Abi.linuxArm: Int8(),
+ Abi.linuxArm64: Int8(),
+ Abi.linuxIA32: Int8(),
+ Abi.linuxX64: Int8(),
+ Abi.linuxRiscv32: Int8(),
+ Abi.linuxRiscv64: Int8(),
+ Abi.macosArm64: Int8(),
+ Abi.macosX64: Int8(),
+ Abi.windowsArm64: Int8(),
+ Abi.windowsIA32: Int8(),
+ Abi.windowsX64: Int8(),
+})
+class SignedChar extends AbiSpecificInteger {
+ const SignedChar();
+}
+
+/// The C `unsigned char` type.
+///
+/// Typically an unsigned 8-bit integer.
+/// For a guaranteed 8-bit integer, use [Uint8] with the C `uint8_t` type.
+/// For a `signed char`, use [Char].
+///
+/// The [UnsignedChar] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint8(),
+ Abi.androidArm64: Uint8(),
+ Abi.androidIA32: Uint8(),
+ Abi.androidX64: Uint8(),
+ Abi.fuchsiaArm64: Uint8(),
+ Abi.fuchsiaX64: Uint8(),
+ Abi.iosArm: Uint8(),
+ Abi.iosArm64: Uint8(),
+ Abi.iosX64: Uint8(),
+ Abi.linuxArm: Uint8(),
+ Abi.linuxArm64: Uint8(),
+ Abi.linuxIA32: Uint8(),
+ Abi.linuxX64: Uint8(),
+ Abi.linuxRiscv32: Uint8(),
+ Abi.linuxRiscv64: Uint8(),
+ Abi.macosArm64: Uint8(),
+ Abi.macosX64: Uint8(),
+ Abi.windowsArm64: Uint8(),
+ Abi.windowsIA32: Uint8(),
+ Abi.windowsX64: Uint8(),
+})
+class UnsignedChar extends AbiSpecificInteger {
+ const UnsignedChar();
+}
+
+/// The C `short` type.
+///
+/// Typically a signed 16-bit integer.
+/// For a guaranteed 16-bit integer, use [Int16] with the C `int16_t` type.
+/// For an `unsigned short`, use [UnsignedShort].
+///
+/// The [Short] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int16(),
+ Abi.androidArm64: Int16(),
+ Abi.androidIA32: Int16(),
+ Abi.androidX64: Int16(),
+ Abi.fuchsiaArm64: Int16(),
+ Abi.fuchsiaX64: Int16(),
+ Abi.iosArm: Int16(),
+ Abi.iosArm64: Int16(),
+ Abi.iosX64: Int16(),
+ Abi.linuxArm: Int16(),
+ Abi.linuxArm64: Int16(),
+ Abi.linuxIA32: Int16(),
+ Abi.linuxX64: Int16(),
+ Abi.linuxRiscv32: Int16(),
+ Abi.linuxRiscv64: Int16(),
+ Abi.macosArm64: Int16(),
+ Abi.macosX64: Int16(),
+ Abi.windowsArm64: Int16(),
+ Abi.windowsIA32: Int16(),
+ Abi.windowsX64: Int16(),
+})
+class Short extends AbiSpecificInteger {
+ const Short();
+}
+
+/// The C `unsigned short` type.
+///
+/// Typically an unsigned 16-bit integer.
+/// For a guaranteed 16-bit integer, use [Uint16] with the C `uint16_t` type.
+/// For a signed `short`, use [Short].
+///
+/// The [UnsignedShort] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint16(),
+ Abi.androidArm64: Uint16(),
+ Abi.androidIA32: Uint16(),
+ Abi.androidX64: Uint16(),
+ Abi.fuchsiaArm64: Uint16(),
+ Abi.fuchsiaX64: Uint16(),
+ Abi.iosArm: Uint16(),
+ Abi.iosArm64: Uint16(),
+ Abi.iosX64: Uint16(),
+ Abi.linuxArm: Uint16(),
+ Abi.linuxArm64: Uint16(),
+ Abi.linuxIA32: Uint16(),
+ Abi.linuxX64: Uint16(),
+ Abi.linuxRiscv32: Uint16(),
+ Abi.linuxRiscv64: Uint16(),
+ Abi.macosArm64: Uint16(),
+ Abi.macosX64: Uint16(),
+ Abi.windowsArm64: Uint16(),
+ Abi.windowsIA32: Uint16(),
+ Abi.windowsX64: Uint16(),
+})
+class UnsignedShort extends AbiSpecificInteger {
+ const UnsignedShort();
+}
+
+/// The C `int` type.
+///
+/// Typically a signed 32-bit integer.
+/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
+/// For an `unsigned int`, use [UnsignedInt].
+///
+/// The [Int] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int32(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int32(),
+ Abi.fuchsiaArm64: Int32(),
+ Abi.fuchsiaX64: Int32(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int32(),
+ Abi.iosX64: Int32(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int32(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int32(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int32(),
+ Abi.macosArm64: Int32(),
+ Abi.macosX64: Int32(),
+ Abi.windowsArm64: Int32(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int32(),
+})
+class Int extends AbiSpecificInteger {
+ const Int();
+}
+
+/// The C `unsigned int` type.
+///
+/// Typically an unsigned 32-bit integer.
+/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
+/// For a signed `int`, use [Int].
+///
+/// The [UnsignedInt] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint32(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint32(),
+ Abi.fuchsiaArm64: Uint32(),
+ Abi.fuchsiaX64: Uint32(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint32(),
+ Abi.iosX64: Uint32(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint32(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint32(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint32(),
+ Abi.macosArm64: Uint32(),
+ Abi.macosX64: Uint32(),
+ Abi.windowsArm64: Uint32(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint32(),
+})
+class UnsignedInt extends AbiSpecificInteger {
+ const UnsignedInt();
+}
+
+/// The C `long int`, aka. `long`, type.
+///
+/// Typically a signed 32- or 64-bit integer.
+/// For a guaranteed 32-bit integer, use [Int32] with the C `int32_t` type.
+/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
+/// For an `unsigned long`, use [UnsignedLong].
+///
+/// The [Long] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int32(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int32(),
+})
+class Long extends AbiSpecificInteger {
+ const Long();
+}
+
+/// The C `unsigned long int`, aka. `unsigned long`, type.
+///
+/// Typically an unsigned 32- or 64-bit integer.
+/// For a guaranteed 32-bit integer, use [Uint32] with the C `uint32_t` type.
+/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
+/// For a signed `long`, use [Long].
+///
+/// The [UnsignedLong] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint32(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint32(),
+})
+class UnsignedLong extends AbiSpecificInteger {
+ const UnsignedLong();
+}
+
+/// The C `long long` type.
+///
+/// Typically a signed 64-bit integer.
+/// For a guaranteed 64-bit integer, use [Int64] with the C `int64_t` type.
+/// For an `unsigned long long`, use [UnsignedLongLong].
+///
+/// The [LongLong] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int64(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int64(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int64(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int64(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int64(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int64(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int64(),
+ Abi.windowsIA32: Int64(),
+ Abi.windowsX64: Int64(),
+})
+class LongLong extends AbiSpecificInteger {
+ const LongLong();
+}
+
+/// The C `unsigned long long` type.
+///
+/// Typically an unsigned 64-bit integer.
+/// For a guaranteed 64-bit integer, use [Uint64] with the C `uint64_t` type.
+/// For a signed `long long`, use [LongLong].
+///
+/// The [UnsignedLongLong] type is a native type, and should not be constructed
+/// in Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint64(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint64(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint64(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint64(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint64(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint64(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint64(),
+ Abi.windowsX64: Uint64(),
+})
+class UnsignedLongLong extends AbiSpecificInteger {
+ const UnsignedLongLong();
+}
+
+/// The C `intptr_t` type.
+///
+/// The [IntPtr] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Int32(),
+ Abi.androidArm64: Int64(),
+ Abi.androidIA32: Int32(),
+ Abi.androidX64: Int64(),
+ Abi.fuchsiaArm64: Int64(),
+ Abi.fuchsiaX64: Int64(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int64(),
+ Abi.iosX64: Int64(),
+ Abi.linuxArm: Int32(),
+ Abi.linuxArm64: Int64(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int64(),
+ Abi.linuxRiscv32: Int32(),
+ Abi.linuxRiscv64: Int64(),
+ Abi.macosArm64: Int64(),
+ Abi.macosX64: Int64(),
+ Abi.windowsArm64: Int64(),
+ Abi.windowsIA32: Int32(),
+ Abi.windowsX64: Int64(),
+})
+class IntPtr extends AbiSpecificInteger {
+ const IntPtr();
+}
+
+/// The C `uintptr_t` type.
+///
+/// The [UintPtr] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class UintPtr extends AbiSpecificInteger {
+ const UintPtr();
+}
+
+/// The C `size_t` type.
+///
+/// The [Size] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint64(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint64(),
+ Abi.fuchsiaArm64: Uint64(),
+ Abi.fuchsiaX64: Uint64(),
+ Abi.iosArm: Uint32(),
+ Abi.iosArm64: Uint64(),
+ Abi.iosX64: Uint64(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint64(),
+ Abi.linuxIA32: Uint32(),
+ Abi.linuxX64: Uint64(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint64(),
+ Abi.macosArm64: Uint64(),
+ Abi.macosX64: Uint64(),
+ Abi.windowsArm64: Uint64(),
+ Abi.windowsIA32: Uint32(),
+ Abi.windowsX64: Uint64(),
+})
+class Size extends AbiSpecificInteger {
+ const Size();
+}
+
+/// The C `wchar_t` type.
+///
+/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as the
+/// defaults on the tested [Abi]s.
+///
+/// The [WChar] type is a native type, and should not be constructed in
+/// Dart code.
+/// It occurs only in native type signatures and as annotation on [Struct] and
+/// [Union] fields.
+@AbiSpecificIntegerMapping({
+ Abi.androidArm: Uint32(),
+ Abi.androidArm64: Uint32(),
+ Abi.androidIA32: Uint32(),
+ Abi.androidX64: Uint32(),
+ Abi.fuchsiaArm64: Uint32(),
+ Abi.fuchsiaX64: Int32(),
+ Abi.iosArm: Int32(),
+ Abi.iosArm64: Int32(),
+ Abi.iosX64: Int32(),
+ Abi.linuxArm: Uint32(),
+ Abi.linuxArm64: Uint32(),
+ Abi.linuxIA32: Int32(),
+ Abi.linuxX64: Int32(),
+ Abi.linuxRiscv32: Uint32(),
+ Abi.linuxRiscv64: Uint32(),
+ Abi.macosArm64: Int32(),
+ Abi.macosX64: Int32(),
+ Abi.windowsArm64: Uint16(),
+ Abi.windowsIA32: Uint16(),
+ Abi.windowsX64: Uint16(),
+})
+class WChar extends AbiSpecificInteger {
+ const WChar();
+}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index b1d53a6..9a7afe2 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -20,6 +20,7 @@
part 'native_type.dart';
part 'allocation.dart';
part 'annotations.dart';
+part 'c_type.dart';
part 'dynamic_library.dart';
part 'struct.dart';
part 'union.dart';
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index dbbea7c..55a9f6d 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -98,36 +98,6 @@
const Uint64();
}
-/// Represents a native pointer-sized integer in C.
-///
-/// [IntPtr] is not constructible in the Dart code and serves purely as marker
-/// in type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int64(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int64(),
-})
-class IntPtr extends AbiSpecificInteger {
- const IntPtr();
-}
-
/// Represents a native 32 bit float in C.
///
/// [Float] is not constructible in the Dart code and serves purely as marker
diff --git a/tests/ffi/abi_specific_int_test.dart b/tests/ffi/abi_specific_int_test.dart
index 266655c..cea45b1 100644
--- a/tests/ffi/abi_specific_int_test.dart
+++ b/tests/ffi/abi_specific_int_test.dart
@@ -8,8 +8,6 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
-import 'abi_specific_ints.dart';
-
void main() {
testSizeOf();
testStoreLoad();
diff --git a/tests/ffi/abi_specific_ints.dart b/tests/ffi/abi_specific_ints.dart
deleted file mode 100644
index c0cd3f0..0000000
--- a/tests/ffi/abi_specific_ints.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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';
-
-// TODO(dacoharkes): These should move to `package:ffi`.
-
-// `int` in C.
-typedef Int = Int32;
-
-// `unsigned int` in C.
-typedef UnsignedInt = Uint32;
-
-// `size_t` in C.
-typedef Size = UintPtr;
-
-// `ssize_t` in C.
-typedef SSize = IntPtr;
-
-// `off_t` in C.
-typedef Off = Long;
-
-/// Represents a native unsigned pointer-sized integer in C.
-///
-/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
- const UintPtr();
-}
-
-/// `long` in C.
-///
-/// [Long] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int32(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int32(),
-})
-class Long extends AbiSpecificInteger {
- const Long();
-}
-
-/// `unsigned long` in C.
-///
-/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint32(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint32(),
-})
-class UnsignedLong extends AbiSpecificInteger {
- const UnsignedLong();
-}
-
-/// `wchar_t` in C.
-///
-/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
-/// unsigned integer.
-///
-/// [WChar] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint32(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint32(),
- Abi.fuchsiaArm64: Uint32(),
- Abi.fuchsiaX64: Uint32(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint32(),
- Abi.iosX64: Uint32(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint32(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint32(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint32(),
- Abi.macosArm64: Uint32(),
- Abi.macosX64: Uint32(),
- Abi.windowsArm64: Uint16(),
- Abi.windowsIA32: Uint16(),
- Abi.windowsX64: Uint16(),
-})
-class WChar extends AbiSpecificInteger {
- const WChar();
-}
diff --git a/tests/ffi/c_types_test.dart b/tests/ffi/c_types_test.dart
index d423c2c..3c2e815 100644
--- a/tests/ffi/c_types_test.dart
+++ b/tests/ffi/c_types_test.dart
@@ -7,11 +7,11 @@
// SharedObjects=ffi_test_functions
import 'dart:ffi';
-
-import "package:expect/expect.dart";
import 'dart:io' show Platform;
-import 'abi_specific_ints.dart';
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
import 'ffi_test_helpers.dart';
void main() {
@@ -20,62 +20,162 @@
testIntAssumptions();
testSizeTAssumptions();
testLongAssumptions();
- testOffTAssumptions();
testWCharTAssumptions();
}
class CType {
final int ffiSize;
+ final int Function(Pointer)? ffiLoad;
final String modifier;
final String type;
+ final String type2;
- CType(this.ffiSize, this.type, [this.modifier = ""]);
+ CType(this.ffiSize, this.type,
+ {this.type2 = '', this.modifier = '', this.ffiLoad});
- String get cRepresentation => "$modifier $type".trim();
+ String get cRepresentation => '$modifier $type $type2'.trim();
- String get _getSizeName => "FfiSizeOf_$modifier\_$type";
+ String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
+
+ String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
int Function() get sizeFunction => ffiTestFunctions
.lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
+ int Function() get signFunction => ffiTestFunctions
+ .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
+
int get size => sizeFunction();
+ bool get isSigned => signFunction() != 0;
+
+ bool? get ffiIsSigned {
+ final ffiLoad_ = ffiLoad;
+ if (ffiLoad_ == null) {
+ return null;
+ }
+ assert(size < 8);
+ return using((Arena arena) {
+ final p = arena<Int64>()..value = -1;
+ return ffiLoad_(p) < 0;
+ });
+ }
+
String toString() => cRepresentation;
}
-final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
-final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
-final int_ = CType(sizeOf<Int>(), "int");
-final uint = CType(sizeOf<UnsignedInt>(), "int", "unsigned");
-final long = CType(sizeOf<Long>(), "long");
-final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
-final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
-final size_t = CType(sizeOf<Size>(), "size_t");
-final ssize_t = CType(sizeOf<SSize>(), "ssize_t");
-final off_t = CType(sizeOf<Off>(), "off_t");
+final char = CType(
+ sizeOf<Char>(),
+ 'char',
+ ffiLoad: (Pointer p) => p.cast<Char>().value,
+);
+final uchar = CType(
+ sizeOf<UnsignedChar>(),
+ 'char',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
+);
+final schar = CType(
+ sizeOf<SignedChar>(),
+ 'char',
+ modifier: 'signed',
+ ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
+);
+final short = CType(
+ sizeOf<Short>(),
+ 'short',
+ ffiLoad: (Pointer p) => p.cast<Short>().value,
+);
+final ushort = CType(
+ sizeOf<UnsignedShort>(),
+ 'short',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
+);
+final int_ = CType(
+ sizeOf<Int>(),
+ 'int',
+ ffiLoad: (Pointer p) => p.cast<Int>().value,
+);
+final uint = CType(
+ sizeOf<UnsignedInt>(),
+ 'int',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
+);
+final long = CType(
+ sizeOf<Long>(),
+ 'long',
+);
+final ulong = CType(
+ sizeOf<UnsignedLong>(),
+ 'long',
+ modifier: 'unsigned',
+);
+final longlong = CType(
+ sizeOf<LongLong>(),
+ 'long',
+ type2: 'long',
+);
+final ulonglong = CType(
+ sizeOf<UnsignedLongLong>(),
+ 'long',
+ type2: 'long',
+ modifier: 'unsigned',
+);
+final intptr_t = CType(
+ sizeOf<IntPtr>(),
+ 'intptr_t',
+);
+final uintptr_t = CType(
+ sizeOf<UintPtr>(),
+ 'uintptr_t',
+);
+final size_t = CType(
+ sizeOf<Size>(),
+ 'size_t',
+);
+final wchar_t = CType(
+ sizeOf<WChar>(),
+ 'wchar_t',
+ ffiLoad: (Pointer p) => p.cast<WChar>().value,
+);
final cTypes = [
- intptr_t,
- uintptr_t,
+ char,
+ uchar,
+ schar,
+ short,
+ ushort,
int_,
uint,
long,
ulong,
- wchar_t,
+ longlong,
+ ulonglong,
+ intptr_t,
+ uintptr_t,
size_t,
- ssize_t,
- off_t
+ wchar_t,
];
void printSizes() {
cTypes.forEach((element) {
- print("${element.cRepresentation.padRight(20)}: ${element.size}");
+ final cName = element.cRepresentation.padRight(20);
+ final size = element.size;
+ final signed = element.isSigned ? 'signed' : 'unsigned';
+ print('$cName: $size $signed');
});
}
void testSizes() {
cTypes.forEach((element) {
+ print(element);
Expect.equals(element.size, element.ffiSize);
+ final ffiIsSigned = element.ffiIsSigned;
+ if (ffiIsSigned != null) {
+ Expect.equals(element.isSigned, ffiIsSigned);
+ }
});
}
@@ -86,7 +186,6 @@
void testSizeTAssumptions() {
Expect.equals(intptr_t.size, size_t.size);
- Expect.equals(intptr_t.size, ssize_t.size);
}
void testLongAssumptions() {
@@ -99,13 +198,9 @@
}
}
-void testOffTAssumptions() {
- Expect.equals(long.size, off_t.size);
-}
-
void testWCharTAssumptions() {
- final bool isSigned = wCharMinValue() != 0;
- print("wchar_t isSigned $isSigned");
+ final bool isSigned = wchar_t.isSigned;
+ print('wchar_t isSigned $isSigned');
if (Platform.isWindows) {
Expect.equals(2, wchar_t.size);
if (isSigned) {
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 2276d2f..2fbccd1 100644
--- a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -16,9 +16,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'callback_tests_utils.dart';
import 'dylib_utils.dart';
diff --git a/tests/ffi/function_structs_by_value_generated_compounds.dart b/tests/ffi/function_structs_by_value_generated_compounds.dart
index 439e9a34..666ef20 100644
--- a/tests/ffi/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi/function_structs_by_value_generated_compounds.dart
@@ -7,9 +7,6 @@
import 'dart:ffi';
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
class Struct1ByteBool extends Struct {
@Bool()
external bool a0;
diff --git a/tests/ffi/function_structs_by_value_generated_leaf_test.dart b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
index 283faad..7704417 100644
--- a/tests/ffi/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_leaf_test.dart
@@ -16,9 +16,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
index 1f4c5d3..897472c 100644
--- a/tests/ffi/function_structs_by_value_generated_test.dart
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -16,9 +16,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'dylib_utils.dart';
// Reuse the compound classes.
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
index 4c260b9..3a18095 100644
--- a/tests/ffi/generator/structs_by_value_tests_generator.dart
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -922,8 +922,6 @@
import 'dart:ffi';
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
""";
}
@@ -967,8 +965,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
import 'dylib_utils.dart';
@@ -1029,8 +1025,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
import 'callback_tests_utils.dart';
diff --git a/tests/ffi_2/abi_specific_int_test.dart b/tests/ffi_2/abi_specific_int_test.dart
index 152c159..57daa3f 100644
--- a/tests/ffi_2/abi_specific_int_test.dart
+++ b/tests/ffi_2/abi_specific_int_test.dart
@@ -10,8 +10,6 @@
import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
-import 'abi_specific_ints.dart';
-
void main() {
testSizeOf();
testStoreLoad();
diff --git a/tests/ffi_2/abi_specific_ints.dart b/tests/ffi_2/abi_specific_ints.dart
deleted file mode 100644
index c1d8302..0000000
--- a/tests/ffi_2/abi_specific_ints.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-// 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.
-
-// @dart = 2.9
-
-import 'dart:ffi';
-
-// TODO(dacoharkes): These should move to `package:ffi`.
-
-/// Represents a native unsigned pointer-sized integer in C.
-///
-/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint64(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint64(),
-})
-class UintPtr extends AbiSpecificInteger {
- const UintPtr();
-}
-
-/// `long` in C.
-///
-/// [Long] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Int32(),
- Abi.androidArm64: Int64(),
- Abi.androidIA32: Int32(),
- Abi.androidX64: Int64(),
- Abi.fuchsiaArm64: Int64(),
- Abi.fuchsiaX64: Int64(),
- Abi.iosArm: Int32(),
- Abi.iosArm64: Int64(),
- Abi.iosX64: Int64(),
- Abi.linuxArm: Int32(),
- Abi.linuxArm64: Int64(),
- Abi.linuxIA32: Int32(),
- Abi.linuxX64: Int64(),
- Abi.linuxRiscv32: Int32(),
- Abi.linuxRiscv64: Int64(),
- Abi.macosArm64: Int64(),
- Abi.macosX64: Int64(),
- Abi.windowsArm64: Int32(),
- Abi.windowsIA32: Int32(),
- Abi.windowsX64: Int32(),
-})
-class Long extends AbiSpecificInteger {
- const Long();
-}
-
-/// `unsigned long` in C.
-///
-/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint64(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint64(),
- Abi.fuchsiaArm64: Uint64(),
- Abi.fuchsiaX64: Uint64(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint64(),
- Abi.iosX64: Uint64(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint64(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint64(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint64(),
- Abi.macosArm64: Uint64(),
- Abi.macosX64: Uint64(),
- Abi.windowsArm64: Uint32(),
- Abi.windowsIA32: Uint32(),
- Abi.windowsX64: Uint32(),
-})
-class UnsignedLong extends AbiSpecificInteger {
- const UnsignedLong();
-}
-
-/// `wchar_t` in C.
-///
-/// The signedness of `wchar_t` is undefined in C. Here, it is exposed as an
-/// unsigned integer.
-///
-/// [WChar] is not constructible in the Dart code and serves purely as marker in
-/// type signatures.
-@AbiSpecificIntegerMapping({
- Abi.androidArm: Uint32(),
- Abi.androidArm64: Uint32(),
- Abi.androidIA32: Uint32(),
- Abi.androidX64: Uint32(),
- Abi.fuchsiaArm64: Uint32(),
- Abi.fuchsiaX64: Uint32(),
- Abi.iosArm: Uint32(),
- Abi.iosArm64: Uint32(),
- Abi.iosX64: Uint32(),
- Abi.linuxArm: Uint32(),
- Abi.linuxArm64: Uint32(),
- Abi.linuxIA32: Uint32(),
- Abi.linuxX64: Uint32(),
- Abi.linuxRiscv32: Uint32(),
- Abi.linuxRiscv64: Uint32(),
- Abi.macosArm64: Uint32(),
- Abi.macosX64: Uint32(),
- Abi.windowsArm64: Uint16(),
- Abi.windowsIA32: Uint16(),
- Abi.windowsX64: Uint16(),
-})
-class WChar extends AbiSpecificInteger {
- const WChar();
-}
diff --git a/tests/ffi_2/c_types_test.dart b/tests/ffi_2/c_types_test.dart
index fa762bd..7a651ce 100644
--- a/tests/ffi_2/c_types_test.dart
+++ b/tests/ffi_2/c_types_test.dart
@@ -9,65 +9,187 @@
// @dart = 2.9
import 'dart:ffi';
-
-import "package:expect/expect.dart";
import 'dart:io' show Platform;
-import 'abi_specific_ints.dart';
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
import 'ffi_test_helpers.dart';
void main() {
printSizes();
testSizes();
+ testIntAssumptions();
+ testSizeTAssumptions();
testLongAssumptions();
testWCharTAssumptions();
}
class CType {
final int ffiSize;
+ final int Function(Pointer) ffiLoad;
final String modifier;
final String type;
+ final String type2;
- CType(this.ffiSize, this.type, [this.modifier = ""]);
+ CType(this.ffiSize, this.type,
+ {this.type2 = '', this.modifier = '', this.ffiLoad});
- String get cRepresentation => "$modifier $type".trim();
+ String get cRepresentation => '$modifier $type $type2'.trim();
- String get _getSizeName => "FfiSizeOf_$modifier\_$type";
+ String get _getSizeName => 'FfiSizeOf_$modifier\_$type\_$type2';
+
+ String get _getSignName => 'FfiSignOf_$modifier\_$type\_$type2';
int Function() get sizeFunction => ffiTestFunctions
.lookupFunction<Uint64 Function(), int Function()>(_getSizeName);
+ int Function() get signFunction => ffiTestFunctions
+ .lookupFunction<Uint64 Function(), int Function()>(_getSignName);
+
int get size => sizeFunction();
+ bool get isSigned => signFunction() != 0;
+
+ bool get ffiIsSigned {
+ final ffiLoad_ = ffiLoad;
+ if (ffiLoad_ == null) {
+ return null;
+ }
+ assert(size < 8);
+ return using((Arena arena) {
+ final p = arena<Int64>()..value = -1;
+ return ffiLoad_(p) < 0;
+ });
+ }
+
String toString() => cRepresentation;
}
-final intptr_t = CType(sizeOf<IntPtr>(), "intptr_t");
-final uintptr_t = CType(sizeOf<UintPtr>(), "uintptr_t");
-final long = CType(sizeOf<Long>(), "long");
-final ulong = CType(sizeOf<UnsignedLong>(), "long", "unsigned");
-final wchar_t = CType(sizeOf<WChar>(), "wchar_t");
+final char = CType(
+ sizeOf<Char>(),
+ 'char',
+ ffiLoad: (Pointer p) => p.cast<Char>().value,
+);
+final uchar = CType(
+ sizeOf<UnsignedChar>(),
+ 'char',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedChar>().value,
+);
+final schar = CType(
+ sizeOf<SignedChar>(),
+ 'char',
+ modifier: 'signed',
+ ffiLoad: (Pointer p) => p.cast<SignedChar>().value,
+);
+final short = CType(
+ sizeOf<Short>(),
+ 'short',
+ ffiLoad: (Pointer p) => p.cast<Short>().value,
+);
+final ushort = CType(
+ sizeOf<UnsignedShort>(),
+ 'short',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedShort>().value,
+);
+final int_ = CType(
+ sizeOf<Int>(),
+ 'int',
+ ffiLoad: (Pointer p) => p.cast<Int>().value,
+);
+final uint = CType(
+ sizeOf<UnsignedInt>(),
+ 'int',
+ modifier: 'unsigned',
+ ffiLoad: (Pointer p) => p.cast<UnsignedInt>().value,
+);
+final long = CType(
+ sizeOf<Long>(),
+ 'long',
+);
+final ulong = CType(
+ sizeOf<UnsignedLong>(),
+ 'long',
+ modifier: 'unsigned',
+);
+final longlong = CType(
+ sizeOf<LongLong>(),
+ 'long',
+ type2: 'long',
+);
+final ulonglong = CType(
+ sizeOf<UnsignedLongLong>(),
+ 'long',
+ type2: 'long',
+ modifier: 'unsigned',
+);
+final intptr_t = CType(
+ sizeOf<IntPtr>(),
+ 'intptr_t',
+);
+final uintptr_t = CType(
+ sizeOf<UintPtr>(),
+ 'uintptr_t',
+);
+final size_t = CType(
+ sizeOf<Size>(),
+ 'size_t',
+);
+final wchar_t = CType(
+ sizeOf<WChar>(),
+ 'wchar_t',
+ ffiLoad: (Pointer p) => p.cast<WChar>().value,
+);
final cTypes = [
- intptr_t,
- uintptr_t,
+ char,
+ uchar,
+ schar,
+ short,
+ ushort,
+ int_,
+ uint,
long,
ulong,
+ longlong,
+ ulonglong,
+ intptr_t,
+ uintptr_t,
+ size_t,
wchar_t,
];
void printSizes() {
cTypes.forEach((element) {
- print("${element.cRepresentation.padRight(20)}: ${element.size}");
+ final cName = element.cRepresentation.padRight(20);
+ final size = element.size;
+ final signed = element.isSigned ? 'signed' : 'unsigned';
+ print('$cName: $size $signed');
});
}
void testSizes() {
cTypes.forEach((element) {
+ print(element);
Expect.equals(element.size, element.ffiSize);
+ final ffiIsSigned = element.ffiIsSigned;
+ if (ffiIsSigned != null) {
+ Expect.equals(element.isSigned, ffiIsSigned);
+ }
});
}
+void testIntAssumptions() {
+ Expect.equals(4, int_.size);
+ Expect.equals(4, uint.size);
+}
+
+void testSizeTAssumptions() {
+ Expect.equals(intptr_t.size, size_t.size);
+}
+
void testLongAssumptions() {
if (Platform.isWindows) {
Expect.equals(4, long.size);
@@ -79,8 +201,8 @@
}
void testWCharTAssumptions() {
- final bool isSigned = wCharMinValue() != 0;
- print("wchar_t isSigned $isSigned");
+ final bool isSigned = wchar_t.isSigned;
+ print('wchar_t isSigned $isSigned');
if (Platform.isWindows) {
Expect.equals(2, wchar_t.size);
if (isSigned) {
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 f4100fb..b890cbc 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
@@ -18,9 +18,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'callback_tests_utils.dart';
import 'dylib_utils.dart';
diff --git a/tests/ffi_2/function_structs_by_value_generated_compounds.dart b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
index 6908177..cd3fdf1 100644
--- a/tests/ffi_2/function_structs_by_value_generated_compounds.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_compounds.dart
@@ -9,9 +9,6 @@
import 'dart:ffi';
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
class Struct1ByteBool extends Struct {
@Bool()
bool a0;
diff --git a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
index 7c64296..8c01056 100644
--- a/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_leaf_test.dart
@@ -18,9 +18,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'dylib_utils.dart';
// Reuse the compound classes.
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 ef24ad2..6329287 100644
--- a/tests/ffi_2/function_structs_by_value_generated_test.dart
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -18,9 +18,6 @@
import "package:expect/expect.dart";
import "package:ffi/ffi.dart";
-// Reuse the AbiSpecificInts.
-import 'abi_specific_ints.dart';
-
import 'dylib_utils.dart';
// Reuse the compound classes.