Skip to content

Commit

Permalink
[vm/ffi] Add Bool
Browse files Browse the repository at this point in the history
This CL adds the `Bool` `NativeType` with support for loading/storing
from `Pointer<Bool>`, `Array<Bool>`, and `Struct` and `Union` fields,
and support for passing booleans through FFI calls and callbacks.

The assumption is that `bool` is always treated as `uint8_t` in the
native ABIs. Including: (1) whether there can be garbage in the upper
bytes in CPU registers, (2) stack alignment, and (3) alignment in
compounds.

The conversion from `bool` to `uint8_t` is implemented as follows:
- bool to int: `value ? 1 : 0`
- int to bool: `value != 0`
The conversion is implemented in Dart in patch files for memory loads
and stores (pointer, array, and struct fields) and kernel_to_il for
FFI call and callback arguments and return value.

TEST=runtime/vm/compiler/ffi/native_type_vm_test.cc
TEST=tests/ffi/bool_test.dart
TEST=tests/ffi/function_callbacks_structs_by_value_generated_test.dart
TEST=tests/ffi/function_structs_by_value_generated_test.dart

Closes: #36855

Change-Id: I75d100340ba41771abfb41c598ca92066a89370b
Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-debug-x64-try,vm-ffi-android-debug-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-ffi-android-debug-arm64c-try,vm-kernel-mac-release-arm64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-precomp-android-release-arm64c-try,vm-kernel-precomp-android-release-arm_x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216900
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
  • Loading branch information
dcharkes authored and commit-bot@chromium.org committed Oct 18, 2021
1 parent 72cfca3 commit 757c2b8
Show file tree
Hide file tree
Showing 32 changed files with 2,263 additions and 29 deletions.
17 changes: 17 additions & 0 deletions pkg/analyzer/lib/src/generated/ffi_verifier.dart
Expand Up @@ -42,6 +42,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
'Double',
];

static const _primitiveBoolNativeType = 'Bool';

static const _structClassName = 'Struct';

static const _unionClassName = 'Union';
Expand Down Expand Up @@ -432,6 +434,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
return true;
case _PrimitiveDartType.int:
return true;
case _PrimitiveDartType.bool:
return true;
case _PrimitiveDartType.void_:
return false;
case _PrimitiveDartType.handle:
Expand Down Expand Up @@ -490,6 +494,7 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
return allowHandle;
case _PrimitiveDartType.double:
case _PrimitiveDartType.int:
case _PrimitiveDartType.bool:
return true;
case _PrimitiveDartType.none:
// These are the cases below.
Expand Down Expand Up @@ -560,6 +565,9 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
if (_primitiveDoubleNativeTypes.contains(name)) {
return _PrimitiveDartType.double;
}
if (name == _primitiveBoolNativeType) {
return _PrimitiveDartType.bool;
}
if (name == 'Void') {
return _PrimitiveDartType.void_;
}
Expand All @@ -580,6 +588,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
return _PrimitiveDartType.int;
} else if (_primitiveDoubleNativeTypes.contains(name)) {
return _PrimitiveDartType.double;
} else if (_primitiveBoolNativeType == name) {
return _PrimitiveDartType.bool;
}
}
return _PrimitiveDartType.none;
Expand Down Expand Up @@ -738,6 +748,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
return dartType.isDartCoreInt;
} else if (nativeReturnType == _PrimitiveDartType.double) {
return dartType.isDartCoreDouble;
} else if (nativeReturnType == _PrimitiveDartType.bool) {
return dartType.isDartCoreBool;
} else if (nativeReturnType == _PrimitiveDartType.void_) {
return dartType.isVoid;
} else if (nativeReturnType == _PrimitiveDartType.handle) {
Expand Down Expand Up @@ -827,6 +839,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
_validateAnnotations(fieldType, annotations, _PrimitiveDartType.int);
} else if (declaredType.isDartCoreDouble) {
_validateAnnotations(fieldType, annotations, _PrimitiveDartType.double);
} else if (declaredType.isDartCoreBool) {
_validateAnnotations(fieldType, annotations, _PrimitiveDartType.bool);
} else if (declaredType.isPointer) {
_validateNoAnnotations(annotations);
} else if (declaredType.isArray) {
Expand Down Expand Up @@ -1162,6 +1176,7 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
enum _PrimitiveDartType {
double,
int,
bool,
void_,
handle,
none,
Expand Down Expand Up @@ -1337,6 +1352,8 @@ extension on ClassElement {
return false;
} else if (declaredType.isDartCoreDouble) {
return false;
} else if (declaredType.isDartCoreBool) {
return false;
} else if (declaredType.isPointer) {
return false;
} else if (declaredType.isCompoundSubtype) {
Expand Down
Expand Up @@ -43,6 +43,9 @@ additionalExports = (ffi::nullptr,
ffi::AllocatorAlloc,
ffi::Array,
ffi::ArrayArray,
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
Expand Down Expand Up @@ -113,6 +116,9 @@ additionalExports = (ffi::nullptr,
ffi::AllocatorAlloc,
ffi::Array,
ffi::ArrayArray,
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
Expand Down
Expand Up @@ -43,6 +43,9 @@ additionalExports = (ffi::nullptr,
ffi::AllocatorAlloc,
ffi::Array,
ffi::ArrayArray,
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
Expand Down Expand Up @@ -113,6 +116,9 @@ additionalExports = (ffi::nullptr,
ffi::AllocatorAlloc,
ffi::Array,
ffi::ArrayArray,
ffi::Bool,
ffi::BoolArray,
ffi::BoolPointer,
ffi::DartRepresentationOf,
ffi::Dart_CObject,
ffi::Double,
Expand Down
10 changes: 10 additions & 0 deletions pkg/vm/lib/transformations/ffi.dart
Expand Up @@ -39,6 +39,7 @@ enum NativeType {
kOpaque,
kStruct,
kHandle,
kBool,
}

const Set<NativeType> nativeIntTypes = <NativeType>{
Expand Down Expand Up @@ -75,6 +76,7 @@ const Map<NativeType, String> nativeTypeClassNames = <NativeType, String>{
NativeType.kOpaque: 'Opaque',
NativeType.kStruct: 'Struct',
NativeType.kHandle: 'Handle',
NativeType.kBool: 'Bool',
};

const int UNKNOWN = 0;
Expand Down Expand Up @@ -102,6 +104,7 @@ const Map<NativeType, int> nativeTypeSizes = <NativeType, int>{
NativeType.kOpaque: UNKNOWN,
NativeType.kStruct: UNKNOWN,
NativeType.kHandle: WORD_SIZE,
NativeType.kBool: 1,
};

/// The struct layout in various ABIs.
Expand Down Expand Up @@ -178,6 +181,7 @@ const nonSizeAlignment = <Abi, Map<NativeType, int>>{

/// Load, store, and elementAt are rewired to their static type for these types.
const List<NativeType> optimizedTypes = [
NativeType.kBool,
NativeType.kInt8,
NativeType.kInt16,
NativeType.kInt32,
Expand Down Expand Up @@ -210,6 +214,7 @@ class FfiTransformer extends Transformer {
final Class objectClass;
final Class intClass;
final Class doubleClass;
final Class boolClass;
final Class listClass;
final Class typeClass;
final Procedure unsafeCastMethod;
Expand Down Expand Up @@ -319,6 +324,7 @@ class FfiTransformer extends Transformer {
objectClass = coreTypes.objectClass,
intClass = coreTypes.intClass,
doubleClass = coreTypes.doubleClass,
boolClass = coreTypes.boolClass,
listClass = coreTypes.listClass,
typeClass = coreTypes.typeClass,
unsafeCastMethod =
Expand Down Expand Up @@ -514,6 +520,7 @@ class FfiTransformer extends Transformer {
/// [IntPtr] -> [int]
/// [Double] -> [double]
/// [Float] -> [double]
/// [Bool] -> [bool]
/// [Void] -> [void]
/// [Pointer]<T> -> [Pointer]<T>
/// T extends [Pointer] -> T
Expand Down Expand Up @@ -555,6 +562,9 @@ class FfiTransformer extends Transformer {
if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
return InterfaceType(doubleClass, Nullability.legacy);
}
if (nativeType_ == NativeType.kBool) {
return InterfaceType(boolClass, Nullability.legacy);
}
if (nativeType_ == NativeType.kVoid) {
return VoidType();
}
Expand Down

0 comments on commit 757c2b8

Please sign in to comment.