mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:47:13 +00:00
90f118484f
The diff from https://dart-review.googlesource.com/c/sdk/+/229156/1..3 This was blocked by https://github.com/timsneath/win32/issues/349 earlier. Now that that has been resolved, we should be able to land this. We should land this to make package:ffigen be able to bind to `char` in Dart 2.17. https://github.com/dart-lang/ffigen/pull/287#discussion_r835734993 TEST=tests/ffi/c_types_test.dart Change-Id: Ia3bc3785a3d5c0c9f7475106eb77f944f2d0a838 Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-ia32-try,vm-kernel-nnbd-mac-debug-arm64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-precomp-ffi-qemu-linux-release-riscv64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239020 Auto-Submit: Daco Harkes <dacoharkes@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
230 lines
5 KiB
Dart
230 lines
5 KiB
Dart
// Copyright (c) 2019, 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.
|
|
//
|
|
// Tests the sizes of c types from https://dartbug.com/36140.
|
|
//
|
|
// SharedObjects=ffi_test_functions
|
|
|
|
import 'dart:ffi';
|
|
import 'dart:io' show Platform;
|
|
|
|
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.type2 = '', this.modifier = '', this.ffiLoad});
|
|
|
|
String get cRepresentation => '$modifier $type $type2'.trim();
|
|
|
|
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 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 = [
|
|
char,
|
|
uchar,
|
|
schar,
|
|
short,
|
|
ushort,
|
|
int_,
|
|
uint,
|
|
long,
|
|
ulong,
|
|
longlong,
|
|
ulonglong,
|
|
intptr_t,
|
|
uintptr_t,
|
|
size_t,
|
|
wchar_t,
|
|
];
|
|
|
|
void printSizes() {
|
|
cTypes.forEach((element) {
|
|
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);
|
|
Expect.equals(4, ulong.size);
|
|
} else {
|
|
Expect.equals(intptr_t.size, long.size);
|
|
Expect.equals(intptr_t.size, ulong.size);
|
|
}
|
|
}
|
|
|
|
void testWCharTAssumptions() {
|
|
final bool isSigned = wchar_t.isSigned;
|
|
print('wchar_t isSigned $isSigned');
|
|
if (Platform.isWindows) {
|
|
Expect.equals(2, wchar_t.size);
|
|
if (isSigned) {
|
|
Expect.equals(-0x8000, wCharMinValue());
|
|
Expect.equals(0x7fff, wCharMaxValue());
|
|
} else {
|
|
Expect.equals(0, wCharMinValue());
|
|
Expect.equals(0xffff, wCharMaxValue());
|
|
}
|
|
} else {
|
|
Expect.equals(4, wchar_t.size);
|
|
if (isSigned) {
|
|
Expect.equals(-0x80000000, wCharMinValue());
|
|
Expect.equals(0x7fffffff, wCharMaxValue());
|
|
} else {
|
|
Expect.equals(0, wCharMinValue());
|
|
Expect.equals(0xffffffff, wCharMaxValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
int Function() wCharMinValue = ffiTestFunctions
|
|
.lookupFunction<Uint64 Function(), int Function()>('WCharMinValue');
|
|
|
|
int Function() wCharMaxValue = ffiTestFunctions
|
|
.lookupFunction<Uint64 Function(), int Function()>('WCharMaxValue');
|