Skip to content

Commit ddfc00e

Browse files
dcharkesCommit Queue
authored and
Commit Queue
committed
[vm/ffi] Unify TypedDataBase wrappers
For getting the address of `Struct` fields and `Array` elements it would be useful to access the `_typedDataBase` field in these 'wrappers' in a unified way. This CL makes `Array` extend `_Compound`. Since `Array` is not a `SizedNativeType`, the implements clauses for `Struct` and `Union` are moved to these classes. Moreover, any references to 'compound' which only apply to struct or union are updated. TEST=test/ffi Bug: #44589 Bug: #54739 Bug: #41237 CoreLibraryReviewExempt: No API change, only refactoring. Change-Id: Ib9d8bccd4872df04bcc67731e4052f826ab70af4 Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350960 Reviewed-by: Martin Kustermann <[email protected]> Reviewed-by: Liam Appelbe <[email protected]>
1 parent fbee607 commit ddfc00e

23 files changed

+131
-132
lines changed

pkg/analyzer/lib/src/test_utilities/mock_sdk.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -821,13 +821,13 @@ extension NativeFunctionPointer<NF extends Function>
821821
external DF asFunction<DF extends Function>({bool isLeaf = false});
822822
}
823823
824-
final class _Compound implements SizedNativeType {}
824+
abstract final class _Compound implements NativeType {}
825825
826826
@Since('2.12')
827-
abstract base class Struct extends _Compound {}
827+
abstract base class Struct extends _Compound implements SizedNativeType {}
828828
829829
@Since('2.14')
830-
abstract base class Union extends _Compound {}
830+
abstract base class Union extends _Compound implements SizedNativeType {}
831831
832832
@Since('2.13')
833833
final class Packed {
@@ -854,7 +854,7 @@ final class DartRepresentationOf {
854854
}
855855
856856
@Since('2.13')
857-
final class Array<T extends NativeType> implements NativeType {
857+
final class Array<T extends NativeType> extends _Compound {
858858
const factory Array(int dimension1,
859859
[int dimension2,
860860
int dimension3,

pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.strong.transformed.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ final class StructInlineArray extends ffi::Struct {
2727
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List}, #C3, #C13);
2828
@#C9
2929
set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void
30-
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::Array::_typedDataBase}{core::Object}, #C10, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
30+
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #C10, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
3131
@#C15
3232
static get #sizeOf() → core::int*
3333
return #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*};

pkg/front_end/testcases/nnbd/ffi_struct_inline_array.dart.weak.transformed.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ final class StructInlineArray extends ffi::Struct {
2727
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List}, #C3, #C13);
2828
@#C9
2929
set a0(synthesized ffi::Array<ffi::Uint8> #externalFieldValue) → void
30-
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::Array::_typedDataBase}{core::Object}, #C10, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
30+
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C11.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #C10, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
3131
@#C15
3232
static get #sizeOf() → core::int*
3333
return #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*};

pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.strong.transformed.expect

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
2828
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List}, #C9, #C14);
2929
@#C10
3030
set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
31-
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::Array::_typedDataBase}{core::Object}, #C11, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
31+
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #C11, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
3232
@#C16
3333
static get #sizeOf() → core::int*
3434
return #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*};
@@ -45,7 +45,7 @@ static method main() → dynamic {
4545
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
4646
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
4747
} =>new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
48-
synthesized core::Object #typedDataBase = #array.{ffi::Array::_typedDataBase}{core::Object};
48+
synthesized core::Object #typedDataBase = #array.{ffi::_Compound::_typedDataBase}{core::Object};
4949
synthesized core::int #offset = #offset;
5050
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Uint8>>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #elementSize){([core::int, core::int?]) → typ::Uint8List}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>});
5151
block {
@@ -55,7 +55,7 @@ static method main() → dynamic {
5555
synthesized core::int #singleElementSize = #C18;
5656
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
5757
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
58-
} =>ffi::_memCopy(#array.{ffi::Array::_typedDataBase}{core::Object}, #offset, subArray.{ffi::Array::_typedDataBase}{core::Object}, #C11, #elementSize);
58+
} =>ffi::_memCopy(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #offset, subArray.{ffi::_Compound::_typedDataBase}{core::Object}, #C11, #elementSize);
5959
#C17.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
6060
}
6161

pkg/front_end/testcases/nnbd/ffi_struct_inline_array_multi_dimensional.dart.weak.transformed.expect

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class StructInlineArrayMultiDimensional extends ffi::Struct {
2828
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}){([core::int, core::int?]) → typ::Uint8List}, #C9, #C14);
2929
@#C10
3030
set a0(synthesized ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
31-
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::Array::_typedDataBase}{core::Object}, #C11, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
31+
return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}{core::Object}, #C12.{core::List::[]}(ffi::_abi()){(core::int) → core::int*}, #externalFieldValue.{ffi::_Compound::_typedDataBase}{core::Object}, #C11, #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*});
3232
@#C16
3333
static get #sizeOf() → core::int*
3434
return #C13.{core::List::[]}(ffi::_abi()){(core::int) → core::int*};
@@ -45,7 +45,7 @@ static method main() → dynamic {
4545
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
4646
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
4747
} =>new ffi::Array::_<ffi::Array<ffi::Uint8>>( block {
48-
synthesized core::Object #typedDataBase = #array.{ffi::Array::_typedDataBase}{core::Object};
48+
synthesized core::Object #typedDataBase = #array.{ffi::_Compound::_typedDataBase}{core::Object};
4949
synthesized core::int #offset = #offset;
5050
} =>#typedDataBase is{ForLegacy} ffi::Pointer<ffi::NativeType> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Uint8>>(#typedDataBase.{ffi::Pointer::address}{core::int}.{core::num::+}(#offset){(core::num) → core::num}) : let synthesized typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}{typ::ByteBuffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}{core::int}.{core::num::+}(#offset){(core::num) → core::num}, #elementSize){([core::int, core::int?]) → typ::Uint8List}, #array.{ffi::Array::_nestedDimensionsFirst}{core::int}, #array.{ffi::Array::_nestedDimensionsRest}{core::List<core::int>});
5151
block {
@@ -55,7 +55,7 @@ static method main() → dynamic {
5555
synthesized core::int #singleElementSize = #C18;
5656
synthesized core::int #elementSize = #singleElementSize.{core::num::*}(#array.{ffi::Array::_nestedDimensionsFlattened}{core::int}){(core::num) → core::num};
5757
synthesized core::int #offset = #elementSize.{core::num::*}(#index){(core::num) → core::num};
58-
} =>ffi::_memCopy(#array.{ffi::Array::_typedDataBase}{core::Object}, #offset, subArray.{ffi::Array::_typedDataBase}{core::Object}, #C11, #elementSize);
58+
} =>ffi::_memCopy(#array.{ffi::_Compound::_typedDataBase}{core::Object}, #offset, subArray.{ffi::_Compound::_typedDataBase}{core::Object}, #C11, #elementSize);
5959
#C17.{all::CallocAllocator::free}(pointer){(ffi::Pointer<ffi::NativeType>) → void};
6060
}
6161

pkg/vm/lib/transformations/ffi/common.dart

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ class FfiTransformer extends Transformer {
249249
final Procedure lookupFunctionMethod;
250250
final Procedure fromFunctionMethod;
251251
final Field compoundTypedDataBaseField;
252-
final Field arrayTypedDataBaseField;
253252
final Field arraySizeField;
254253
final Field arrayNestedDimensionsField;
255254
final Procedure arrayCheckIndex;
@@ -411,8 +410,6 @@ class FfiTransformer extends Transformer {
411410
index.getProcedure('dart:ffi', 'Pointer', 'get:address'),
412411
compoundTypedDataBaseField =
413412
index.getField('dart:ffi', '_Compound', '_typedDataBase'),
414-
arrayTypedDataBaseField =
415-
index.getField('dart:ffi', 'Array', '_typedDataBase'),
416413
arraySizeField = index.getField('dart:ffi', 'Array', '_size'),
417414
arrayNestedDimensionsField =
418415
index.getField('dart:ffi', 'Array', '_nestedDimensions'),
@@ -636,13 +633,14 @@ class FfiTransformer extends Transformer {
636633
/// [Bool] -> [bool]
637634
/// [Void] -> [void]
638635
/// [Pointer]<T> -> [Pointer]<T>
639-
/// T extends [Compound] -> T
636+
/// T extends [Struct] -> T
637+
/// T extends [Union] -> T
640638
/// [Handle] -> [Object]
641639
/// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
642640
/// where DartRepresentationOf(Tn) -> Sn
643641
DartType? convertNativeTypeToDartType(
644642
DartType nativeType, {
645-
bool allowCompounds = false,
643+
bool allowStructAndUnion = false,
646644
bool allowHandle = false,
647645
bool allowInlineArray = false,
648646
bool allowVoid = false,
@@ -661,7 +659,7 @@ class FfiTransformer extends Transformer {
661659
final nested = convertNativeTypeToDartType(
662660
nativeType.typeArguments.single,
663661
allowInlineArray: true,
664-
allowCompounds: true,
662+
allowStructAndUnion: true,
665663
);
666664
if (nested == null) {
667665
return null;
@@ -678,7 +676,7 @@ class FfiTransformer extends Transformer {
678676
if (nativeClass == structClass || nativeClass == unionClass) {
679677
return null;
680678
}
681-
return allowCompounds ? nativeType : null;
679+
return allowStructAndUnion ? nativeType : null;
682680
}
683681
if (nativeType_ == null) {
684682
return null;
@@ -718,7 +716,7 @@ class FfiTransformer extends Transformer {
718716

719717
final DartType? returnType = convertNativeTypeToDartType(
720718
fun.returnType,
721-
allowCompounds: true,
719+
allowStructAndUnion: true,
722720
allowHandle: true,
723721
allowVoid: true,
724722
);
@@ -728,7 +726,7 @@ class FfiTransformer extends Transformer {
728726
argumentTypes.add(
729727
convertNativeTypeToDartType(
730728
paramDartType,
731-
allowCompounds: true,
729+
allowStructAndUnion: true,
732730
allowHandle: true,
733731
) ??
734732
dummyDartType,
@@ -749,7 +747,7 @@ class FfiTransformer extends Transformer {
749747
/// [convertNativeTypeToDartType].
750748
DartType? convertDartTypeToNativeType(DartType dartType) {
751749
if (isPointerType(dartType) ||
752-
isCompoundSubtype(dartType) ||
750+
isStructOrUnionSubtype(dartType) ||
753751
isArrayType(dartType)) {
754752
return dartType;
755753
} else {
@@ -1150,15 +1148,17 @@ class FfiTransformer extends Transformer {
11501148
SubtypeCheckMode.ignoringNullabilities);
11511149
}
11521150

1153-
bool isCompoundSubtype(DartType type) {
1151+
bool isStructOrUnionSubtype(DartType type) {
11541152
if (type is InvalidType) {
11551153
return false;
11561154
}
11571155
if (type is NullType) {
11581156
return false;
11591157
}
11601158
if (type is InterfaceType) {
1161-
if (type.classNode == structClass || type.classNode == unionClass) {
1159+
if (type.classNode == structClass ||
1160+
type.classNode == unionClass ||
1161+
type.classNode == arrayClass) {
11621162
return false;
11631163
}
11641164
}
@@ -1177,15 +1177,6 @@ class FfiTransformer extends Transformer {
11771177
..fileOffset = fileOffset;
11781178
}
11791179

1180-
Expression getArrayTypedDataBaseField(Expression receiver,
1181-
[int fileOffset = TreeNode.noOffset]) {
1182-
return InstanceGet(
1183-
InstanceAccessKind.Instance, receiver, arrayTypedDataBaseField.name,
1184-
interfaceTarget: arrayTypedDataBaseField,
1185-
resultType: arrayTypedDataBaseField.type)
1186-
..fileOffset = fileOffset;
1187-
}
1188-
11891180
Expression add(Expression a, Expression b) {
11901181
return InstanceInvocation(
11911182
InstanceAccessKind.Instance, a, numAddition.name, Arguments([b]),
@@ -1415,7 +1406,7 @@ class FfiTransformer extends Transformer {
14151406
}) {
14161407
final DartType correspondingDartType = convertNativeTypeToDartType(
14171408
nativeType,
1418-
allowCompounds: true,
1409+
allowStructAndUnion: true,
14191410
allowHandle: allowHandle,
14201411
allowInlineArray: allowArray,
14211412
allowVoid: allowVoid,
@@ -1459,12 +1450,12 @@ class FfiTransformer extends Transformer {
14591450
DartType nativeType,
14601451
TreeNode reportErrorOn, {
14611452
bool allowHandle = false,
1462-
bool allowCompounds = false,
1453+
bool allowStructAndUnion = false,
14631454
bool allowInlineArray = false,
14641455
bool allowVoid = false,
14651456
}) {
14661457
if (!_nativeTypeValid(nativeType,
1467-
allowCompounds: allowCompounds,
1458+
allowStructAndUnion: allowStructAndUnion,
14681459
allowHandle: allowHandle,
14691460
allowInlineArray: allowInlineArray,
14701461
allowVoid: allowVoid)) {
@@ -1482,13 +1473,13 @@ class FfiTransformer extends Transformer {
14821473
/// parameter types are only NativeTypes, so we need to check this.
14831474
bool _nativeTypeValid(
14841475
DartType nativeType, {
1485-
bool allowCompounds = false,
1476+
bool allowStructAndUnion = false,
14861477
bool allowHandle = false,
14871478
bool allowInlineArray = false,
14881479
bool allowVoid = false,
14891480
}) {
14901481
return convertNativeTypeToDartType(nativeType,
1491-
allowCompounds: allowCompounds,
1482+
allowStructAndUnion: allowStructAndUnion,
14921483
allowHandle: allowHandle,
14931484
allowInlineArray: allowInlineArray,
14941485
allowVoid: allowVoid) !=

0 commit comments

Comments
 (0)