Version 2.14.0-0.0.dev
Merge commit '4658b9ee6b3bd83a89aa9af8546ee7b9477c9105' into 'dev'
diff --git a/DEPS b/DEPS
index c5f55af..9408e60 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "42fe3fd9d6eb66702604dc38f4deca66245ee974",
+ "co19_rev": "65d887eaa99f45e0bd5320ae7ef247eb8d4a264f",
"co19_2_rev": "f7f583366396cb1457e58c9bfb6d6e53dc21d741",
# The internal benchmarks to use. See go/dart-benchmarks-internal
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 74cac9d..cc7a05d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -8,7 +8,7 @@
/// The current version of the Dart language (or, for non-stable releases, the
/// version of the language currently in the process of being developed).
-const _currentVersion = '2.13.0';
+const _currentVersion = '2.14.0';
/// A map containing information about all known experimental flags.
final _knownFeatures = <String, ExperimentalFeature>{
diff --git a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
index 23043cf..af2ef54 100644
--- a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
+++ b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
@@ -2,7 +2,7 @@
// 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.13
+//@dart=2.14
/*member: main:ignore*/
void main() {
diff --git a/pkg/compiler/test/inference/data/shift_right_unsigned.dart b/pkg/compiler/test/inference/data/shift_right_unsigned.dart
index 3518692..a229111 100644
--- a/pkg/compiler/test/inference/data/shift_right_unsigned.dart
+++ b/pkg/compiler/test/inference/data/shift_right_unsigned.dart
@@ -2,7 +2,7 @@
// 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.13
+//@dart=2.14
/*member: main:[null]*/
main() {
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index f774c07..759b8fb 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -29,20 +29,20 @@
}
const Version enableAlternativeInvalidationStrategyVersion =
- const Version(2, 13);
-const Version enableConstFunctionsVersion = const Version(2, 13);
+ const Version(2, 14);
+const Version enableConstFunctionsVersion = const Version(2, 14);
const Version enableConstantUpdate2018Version = const Version(2, 0);
const Version enableControlFlowCollectionsVersion = const Version(2, 0);
const Version enableExtensionMethodsVersion = const Version(2, 6);
-const Version enableExtensionTypesVersion = const Version(2, 13);
-const Version enableGenericMetadataVersion = const Version(2, 13);
+const Version enableExtensionTypesVersion = const Version(2, 14);
+const Version enableGenericMetadataVersion = const Version(2, 14);
const Version enableNonNullableVersion = const Version(2, 12);
const Version enableNonfunctionTypeAliasesVersion = const Version(2, 13);
const Version enableSetLiteralsVersion = const Version(2, 0);
const Version enableSpreadCollectionsVersion = const Version(2, 0);
-const Version enableTripleShiftVersion = const Version(2, 13);
-const Version enableValueClassVersion = const Version(2, 13);
-const Version enableVarianceVersion = const Version(2, 13);
+const Version enableTripleShiftVersion = const Version(2, 14);
+const Version enableValueClassVersion = const Version(2, 14);
+const Version enableVarianceVersion = const Version(2, 14);
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
@@ -113,37 +113,37 @@
};
const Map<ExperimentalFlag, Version> experimentEnabledVersion = {
- ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 13),
- ExperimentalFlag.constFunctions: const Version(2, 13),
+ ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 14),
+ ExperimentalFlag.constFunctions: const Version(2, 14),
ExperimentalFlag.constantUpdate2018: const Version(2, 0),
ExperimentalFlag.controlFlowCollections: const Version(2, 0),
ExperimentalFlag.extensionMethods: const Version(2, 6),
- ExperimentalFlag.extensionTypes: const Version(2, 13),
- ExperimentalFlag.genericMetadata: const Version(2, 13),
+ ExperimentalFlag.extensionTypes: const Version(2, 14),
+ ExperimentalFlag.genericMetadata: const Version(2, 14),
ExperimentalFlag.nonNullable: const Version(2, 12),
ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
ExperimentalFlag.setLiterals: const Version(2, 0),
ExperimentalFlag.spreadCollections: const Version(2, 0),
- ExperimentalFlag.tripleShift: const Version(2, 13),
- ExperimentalFlag.valueClass: const Version(2, 13),
- ExperimentalFlag.variance: const Version(2, 13),
+ ExperimentalFlag.tripleShift: const Version(2, 14),
+ ExperimentalFlag.valueClass: const Version(2, 14),
+ ExperimentalFlag.variance: const Version(2, 14),
};
const Map<ExperimentalFlag, Version> experimentReleasedVersion = {
- ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 13),
- ExperimentalFlag.constFunctions: const Version(2, 13),
+ ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 14),
+ ExperimentalFlag.constFunctions: const Version(2, 14),
ExperimentalFlag.constantUpdate2018: const Version(2, 0),
ExperimentalFlag.controlFlowCollections: const Version(2, 0),
ExperimentalFlag.extensionMethods: const Version(2, 6),
- ExperimentalFlag.extensionTypes: const Version(2, 13),
- ExperimentalFlag.genericMetadata: const Version(2, 13),
+ ExperimentalFlag.extensionTypes: const Version(2, 14),
+ ExperimentalFlag.genericMetadata: const Version(2, 14),
ExperimentalFlag.nonNullable: const Version(2, 10),
ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
ExperimentalFlag.setLiterals: const Version(2, 0),
ExperimentalFlag.spreadCollections: const Version(2, 0),
- ExperimentalFlag.tripleShift: const Version(2, 13),
- ExperimentalFlag.valueClass: const Version(2, 13),
- ExperimentalFlag.variance: const Version(2, 13),
+ ExperimentalFlag.tripleShift: const Version(2, 14),
+ ExperimentalFlag.valueClass: const Version(2, 14),
+ ExperimentalFlag.variance: const Version(2, 14),
};
const AllowedExperimentalFlags defaultAllowedExperimentalFlags =
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index bc3f745..bdf54c8 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -364,51 +364,12 @@
DartType subtype, DartType supertype) {
if (subtype is UnknownType) return const IsSubtypeOf.always();
- // For now, extension types are only related to themselves, top types, and
- // bottom types.
- // TODO(dmitryas): Implement subtyping rules for extension types.
- if (subtype is ExtensionType) {
- if (coreTypes.isTop(supertype)) {
- return const IsSubtypeOf.always();
- } else if (supertype is ExtensionType &&
- subtype.extension == supertype.extension) {
- assert(subtype.typeArguments.length == supertype.typeArguments.length);
- IsSubtypeOf result = const IsSubtypeOf.always();
- for (int i = 0; i < subtype.typeArguments.length; ++i) {
- result.and(performNullabilityAwareMutualSubtypesCheck(
- subtype.typeArguments[i], supertype.typeArguments[i]));
- }
- return result;
- } else {
- return const IsSubtypeOf.never();
- }
- }
-
DartType unwrappedSupertype = supertype;
while (unwrappedSupertype is FutureOrType) {
unwrappedSupertype = (unwrappedSupertype as FutureOrType).typeArgument;
}
if (unwrappedSupertype is UnknownType) {
return const IsSubtypeOf.always();
- } else if (unwrappedSupertype is ExtensionType) {
- // For now, extension types are only related to themselves, top types, and
- // bottom types.
- // TODO(dmitryas): Implement subtyping rules for extension types.
- if (coreTypes.isBottom(subtype)) {
- return const IsSubtypeOf.always();
- } else if (subtype is ExtensionType &&
- subtype.extension == unwrappedSupertype.extension) {
- assert(subtype.typeArguments.length ==
- unwrappedSupertype.typeArguments.length);
- IsSubtypeOf result = const IsSubtypeOf.always();
- for (int i = 0; i < subtype.typeArguments.length; ++i) {
- result.and(performNullabilityAwareMutualSubtypesCheck(
- subtype.typeArguments[i], unwrappedSupertype.typeArguments[i]));
- }
- return result;
- } else {
- return const IsSubtypeOf.never();
- }
}
return super.performNullabilityAwareSubtypeCheck(subtype, supertype);
}
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 92bc643..1ab807f 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.expect
@@ -19,7 +19,7 @@
#t1.{self::Coordinate::next} = next;
} =>#t1;
}
- abstract member-signature get _typedDataBase() → core::Object*; -> ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → core::Object*; -> ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.weak.outline.expect b/pkg/front_end/testcases/general/ffi_sample.dart.weak.outline.expect
index 6390099..d01ceca 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.weak.outline.expect
@@ -14,7 +14,7 @@
field ffi::Pointer<self::Coordinate*>* next;
static factory allocate(ffi::Allocator* allocator, core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate*
;
- abstract member-signature get _typedDataBase() → core::Object*; -> ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → core::Object*; -> ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
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 fa07ce3..cad4e7a 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
@@ -19,7 +19,7 @@
#t1.{self::Coordinate::next} = next;
} =>#t1;
}
- abstract member-signature get _typedDataBase() → core::Object*; -> ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → core::Object*; -> ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
@@ -31,17 +31,17 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
get x() → core::double*
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()));
set x(core::double* #v) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #v);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #v);
get y() → core::double*
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C14).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C14).{core::List::[]}(ffi::_abi()));
set y(core::double* #v) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C14).{core::List::[]}(ffi::_abi()), #v);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C14).{core::List::[]}(ffi::_abi()), #v);
get next() → ffi::Pointer<self::Coordinate*>*
- return ffi::_fromAddress<self::Coordinate*>(ffi::_loadIntPtr(this.{ffi::Struct::_typedDataBase}, (#C16).{core::List::[]}(ffi::_abi())));
+ return ffi::_fromAddress<self::Coordinate*>(ffi::_loadIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C16).{core::List::[]}(ffi::_abi())));
set next(ffi::Pointer<self::Coordinate*>* #v) → void
- return ffi::_storeIntPtr(this.{ffi::Struct::_typedDataBase}, (#C16).{core::List::[]}(ffi::_abi()), #v.{ffi::Pointer::address});
+ return ffi::_storeIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C16).{core::List::[]}(ffi::_abi()), #v.{ffi::Pointer::address});
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
index 359b430..e983eec 100644
--- a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.1.expect
@@ -12,7 +12,7 @@
static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -24,17 +24,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
index 9e6554f..f61ae87 100644
--- a/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/ffi_01.yaml.world.2.expect
@@ -12,7 +12,7 @@
static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -24,17 +24,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect b/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
index aa03bd6d..1979d4a 100644
--- a/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/ffi_02.yaml.world.1.expect
@@ -12,7 +12,7 @@
static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -24,17 +24,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
index 359b430..e983eec 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.1.expect
@@ -12,7 +12,7 @@
static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -24,17 +24,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
index feb7dd1..aae1c15 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.2.expect
@@ -12,7 +12,7 @@
static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -24,17 +24,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
index 3b28c5c..dcd9515 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_35.yaml.world.3.expect
@@ -13,7 +13,7 @@
dart.core::print("hello");
return null;
}
- abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::Struct::_typedDataBase
+ abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
@@ -25,17 +25,17 @@
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
get x() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()));
set x(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C12).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get y() → dart.core::double*
- return dart.ffi::_loadDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
+ return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()));
set y(dart.core::double* #v) → void
- return dart.ffi::_storeDouble(this.{dart.ffi::Struct::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
+ return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C14).{dart.core::List::[]}(dart.ffi::_abi()), #v);
get next() → dart.ffi::Pointer<lib::Coordinate*>*
- return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
+ return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi())));
set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
- return dart.ffi::_storeIntPtr(this.{dart.ffi::Struct::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
+ return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C16).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
}
}
library from "org-dartlang-test:///main.dart" as main {
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 a7d1f8b..eee9d220 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
@@ -14,20 +14,20 @@
;
@#C11
get x() → core::double
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()));
@#C11
set x(core::double #externalFieldValue) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue);
@#C11
get y() → core::double
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()));
@#C11
set y(core::double #externalFieldValue) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue);
get next() → ffi::Pointer<self::Coordinate>
- return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::Struct::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi())));
+ return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi())));
set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void
- return ffi::_storeIntPtr(this.{ffi::Struct::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
+ return ffi::_storeIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
return let final self::Coordinate #t1 = new self::Coordinate::#fromTypedDataBase(allocator.{ffi::Allocator::allocate}<self::Coordinate>(self::Coordinate::#sizeOf)!) in block {
#t1.{self::Coordinate::x} = x;
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 a7d1f8b..eee9d220 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
@@ -14,20 +14,20 @@
;
@#C11
get x() → core::double
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()));
@#C11
set x(core::double #externalFieldValue) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue);
@#C11
get y() → core::double
- return ffi::_loadDouble(this.{ffi::Struct::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()));
+ return ffi::_loadDouble(this.{ffi::_Compound::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()));
@#C11
set y(core::double #externalFieldValue) → void
- return ffi::_storeDouble(this.{ffi::Struct::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue);
+ return ffi::_storeDouble(this.{ffi::_Compound::_typedDataBase}, (#C15).{core::List::[]}(ffi::_abi()), #externalFieldValue);
get next() → ffi::Pointer<self::Coordinate>
- return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::Struct::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi())));
+ return ffi::_fromAddress<self::Coordinate>(ffi::_loadIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi())));
set next(ffi::Pointer<self::Coordinate> #externalFieldValue) → void
- return ffi::_storeIntPtr(this.{ffi::Struct::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
+ return ffi::_storeIntPtr(this.{ffi::_Compound::_typedDataBase}, (#C17).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Pointer::address});
static factory allocate(ffi::Allocator allocator, core::double x, core::double y, ffi::Pointer<self::Coordinate> next) → self::Coordinate {
return let final self::Coordinate #t1 = new self::Coordinate::#fromTypedDataBase(allocator.{ffi::Allocator::allocate}<self::Coordinate>(self::Coordinate::#sizeOf)!) in block {
#t1.{self::Coordinate::x} = x;
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 e7423e9c..49368b2 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
@@ -20,12 +20,12 @@
@#C10
get a0() → ffi::Array<ffi::Uint8>
return new ffi::Array::_<ffi::Uint8>( block {
- core::Object #typedDataBase = this.{ffi::Struct::_typedDataBase};
+ core::Object #typedDataBase = this.{ffi::_Compound::_typedDataBase};
core::int #offset = (#C12).{core::List::[]}(ffi::_abi());
} =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C3, #C13);
@#C10
set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void
- return ffi::_memCopy(this.{ffi::Struct::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C11, (#C9).{core::List::[]}(ffi::_abi()));
+ return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C11, (#C9).{core::List::[]}(ffi::_abi()));
}
static method main() → dynamic {}
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 73f80ad..0164237 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
@@ -20,12 +20,12 @@
@#C10
get a0() → ffi::Array<ffi::Uint8>
return new ffi::Array::_<ffi::Uint8>( block {
- core::Object #typedDataBase = this.{ffi::Struct::_typedDataBase};
+ core::Object #typedDataBase = this.{ffi::_Compound::_typedDataBase};
core::int #offset = (#C12).{core::List::[]}(ffi::_abi());
} =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Uint8>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C3, #C13);
@#C10
set a0(ffi::Array<ffi::Uint8> #externalFieldValue) → void
- return ffi::_memCopy(this.{ffi::Struct::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C11, (#C9).{core::List::[]}(ffi::_abi()));
+ return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}, (#C12).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C11, (#C9).{core::List::[]}(ffi::_abi()));
}
static method main() → dynamic {}
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 e9e3431..6b9936f 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
@@ -20,12 +20,12 @@
@#C11
get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>( block {
- core::Object #typedDataBase = this.{ffi::Struct::_typedDataBase};
+ core::Object #typedDataBase = this.{ffi::_Compound::_typedDataBase};
core::int #offset = (#C13).{core::List::[]}(ffi::_abi());
} =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C10, #C14);
@#C11
set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
- return ffi::_memCopy(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C12, (#C9).{core::List::[]}(ffi::_abi()));
+ return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C12, (#C9).{core::List::[]}(ffi::_abi()));
}
static method main() → dynamic {
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = (#C15).{ffi::Allocator::allocate}<self::StructInlineArrayMultiDimensional>(self::StructInlineArrayMultiDimensional::#sizeOf);
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 f6b5c52..cff35ac 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
@@ -20,12 +20,12 @@
@#C11
get a0() → ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>>
return new ffi::Array::_<ffi::Array<ffi::Array<ffi::Uint8>>>( block {
- core::Object #typedDataBase = this.{ffi::Struct::_typedDataBase};
+ core::Object #typedDataBase = this.{ffi::_Compound::_typedDataBase};
core::int #offset = (#C13).{core::List::[]}(ffi::_abi());
} =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} ffi::_fromAddress<ffi::Array<ffi::Array<ffi::Uint8>>>(#typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}(#typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C9).{core::List::[]}(ffi::_abi())), #C10, #C14);
@#C11
set a0(ffi::Array<ffi::Array<ffi::Array<ffi::Uint8>>> #externalFieldValue) → void
- return ffi::_memCopy(this.{ffi::Struct::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C12, (#C9).{core::List::[]}(ffi::_abi()));
+ return ffi::_memCopy(this.{ffi::_Compound::_typedDataBase}, (#C13).{core::List::[]}(ffi::_abi()), #externalFieldValue.{ffi::Array::_typedDataBase}, #C12, (#C9).{core::List::[]}(ffi::_abi()));
}
static method main() → dynamic {
final ffi::Pointer<self::StructInlineArrayMultiDimensional> pointer = (#C15).{ffi::Allocator::allocate}<self::StructInlineArrayMultiDimensional>(self::StructInlineArrayMultiDimensional::#sizeOf);
diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart
index 6de3073..135db61 100644
--- a/pkg/kernel/lib/default_language_version.dart
+++ b/pkg/kernel/lib/default_language_version.dart
@@ -9,4 +9,4 @@
import "ast.dart";
-Version defaultLanguageVersion = const Version(2, 13);
+Version defaultLanguageVersion = const Version(2, 14);
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 357af4c..0c4abbc 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -2,25 +2,7 @@
// 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 '../ast.dart'
- show
- Class,
- DartType,
- DynamicType,
- FunctionType,
- FutureOrType,
- InterfaceType,
- InvalidType,
- Library,
- NamedType,
- NeverType,
- NullType,
- Nullability,
- TypeParameter,
- TypeParameterType,
- TypedefType,
- Variance,
- VoidType;
+import '../ast.dart';
import '../class_hierarchy.dart' show ClassHierarchyBase;
@@ -350,6 +332,8 @@
IsSubtypeOf isTypeParameterRelated(TypeParameterType s, T t, Types types);
IsSubtypeOf isTypedefRelated(TypedefType s, T t, Types types);
+
+ IsSubtypeOf isExtensionRelated(ExtensionType s, T t, Types types);
}
class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
@@ -421,6 +405,13 @@
IsSubtypeOf isVoidRelated(VoidType s, InterfaceType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, InterfaceType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
@@ -596,6 +587,12 @@
IsSubtypeOf isVoidRelated(VoidType s, FunctionType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, FunctionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
@@ -676,6 +673,13 @@
IsSubtypeOf isVoidRelated(VoidType s, TypeParameterType t, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, TypeParameterType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
@@ -722,6 +726,12 @@
IsSubtypeOf isVoidRelated(VoidType s, TypedefType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s, t.unalias);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, TypedefType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsFutureOrSubtypeOf extends TypeRelation<FutureOrType> {
@@ -849,6 +859,12 @@
IsSubtypeOf isTypedefRelated(TypedefType s, FutureOrType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, FutureOrType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
@@ -908,37 +924,51 @@
VoidType s, TypeParameterType intersection, Types types) {
return const IsSubtypeOf.never();
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, TypeParameterType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsNullTypeSubtypeOf implements TypeRelation<NullType> {
const IsNullTypeSubtypeOf();
+ @override
IsSubtypeOf isDynamicRelated(DynamicType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isVoidRelated(VoidType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isInterfaceRelated(InterfaceType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NullType t, Types types) {
return types.performNullabilityAwareMutualSubtypesCheck(
intersection.promotedBound!, t);
}
+ @override
IsSubtypeOf isFunctionRelated(FunctionType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isFutureOrRelated(FutureOrType s, NullType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, NullType t, Types types) {
// We don't need to combine the check of the bound against [t] with the
@@ -947,40 +977,54 @@
return types.performNullabilityAwareSubtypeCheck(s.bound, t);
}
+ @override
IsSubtypeOf isTypedefRelated(TypedefType s, NullType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, NullType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
}
class IsNeverTypeSubtypeOf implements TypeRelation<NeverType> {
const IsNeverTypeSubtypeOf();
+ @override
IsSubtypeOf isDynamicRelated(DynamicType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isVoidRelated(VoidType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isInterfaceRelated(InterfaceType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isIntersectionRelated(
TypeParameterType intersection, NeverType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(
intersection.promotedBound!, t);
}
+ @override
IsSubtypeOf isFunctionRelated(FunctionType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isFutureOrRelated(FutureOrType s, NeverType t, Types types) {
return const IsSubtypeOf.never();
}
+ @override
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, NeverType t, Types types) {
return types
@@ -988,7 +1032,82 @@
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
+ @override
IsSubtypeOf isTypedefRelated(TypedefType s, NeverType t, Types types) {
return types.performNullabilityAwareSubtypeCheck(s.unalias, t);
}
+
+ @override
+ IsSubtypeOf isExtensionRelated(ExtensionType s, NeverType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+}
+
+class IsExtensionTypeSubtypeOf implements TypeRelation<ExtensionType> {
+ const IsExtensionTypeSubtypeOf();
+
+ @override
+ IsSubtypeOf isDynamicRelated(DynamicType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isVoidRelated(VoidType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isInterfaceRelated(
+ InterfaceType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isIntersectionRelated(
+ TypeParameterType intersection, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isFunctionRelated(FunctionType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isFutureOrRelated(FutureOrType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isTypeParameterRelated(
+ TypeParameterType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isTypedefRelated(TypedefType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ return const IsSubtypeOf.never();
+ }
+
+ @override
+ IsSubtypeOf isExtensionRelated(
+ ExtensionType s, ExtensionType t, Types types) {
+ // TODO(dmitryas): Use with the actual subtyping rules for extension types.
+ if (s.extension != t.extension) {
+ return const IsSubtypeOf.never();
+ }
+ return types
+ .areTypeArgumentsOfSubtypeKernel(
+ s.typeArguments, t.typeArguments, t.extension.typeParameters)
+ .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
+ }
}
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 551ee3a..bd70fef 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -229,6 +229,7 @@
final Field arraySizeDimension5Field;
final Field arraySizeDimensionsField;
final Class pointerClass;
+ final Class compoundClass;
final Class structClass;
final Class ffiStructLayoutClass;
final Field ffiStructLayoutTypesField;
@@ -254,7 +255,7 @@
final Procedure sizeOfMethod;
final Procedure lookupFunctionMethod;
final Procedure fromFunctionMethod;
- final Field structTypedDataBaseField;
+ final Field compoundTypedDataBaseField;
final Field arrayTypedDataBaseField;
final Field arraySizeField;
final Field arrayNestedDimensionsField;
@@ -330,6 +331,7 @@
arraySizeDimensionsField =
index.getMember('dart:ffi', '_ArraySize', 'dimensions'),
pointerClass = index.getClass('dart:ffi', 'Pointer'),
+ compoundClass = index.getClass('dart:ffi', '_Compound'),
structClass = index.getClass('dart:ffi', 'Struct'),
ffiStructLayoutClass = index.getClass('dart:ffi', '_FfiStructLayout'),
ffiStructLayoutTypesField =
@@ -351,8 +353,8 @@
offsetByMethod = index.getMember('dart:ffi', 'Pointer', '_offsetBy'),
elementAtMethod = index.getMember('dart:ffi', 'Pointer', 'elementAt'),
addressGetter = index.getMember('dart:ffi', 'Pointer', 'get:address'),
- structTypedDataBaseField =
- index.getMember('dart:ffi', 'Struct', '_typedDataBase'),
+ compoundTypedDataBaseField =
+ index.getMember('dart:ffi', '_Compound', '_typedDataBase'),
arrayTypedDataBaseField =
index.getMember('dart:ffi', 'Array', '_typedDataBase'),
arraySizeField = index.getMember('dart:ffi', 'Array', '_size'),
@@ -459,8 +461,7 @@
/// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
/// where DartRepresentationOf(Tn) -> Sn
DartType convertNativeTypeToDartType(DartType nativeType,
- {bool allowStructs = false,
- bool allowStructItself = false,
+ {bool allowCompounds = false,
bool allowHandle = false,
bool allowInlineArray = false}) {
if (nativeType is! InterfaceType) {
@@ -476,11 +477,11 @@
}
return nativeType;
}
- if (hierarchy.isSubclassOf(nativeClass, structClass)) {
- if (structClass == nativeClass) {
- return allowStructItself ? nativeType : null;
+ if (hierarchy.isSubclassOf(nativeClass, compoundClass)) {
+ if (nativeClass == structClass) {
+ return null;
}
- return allowStructs ? nativeType : null;
+ return allowCompounds ? nativeType : null;
}
if (nativeType_ == null) {
return null;
@@ -514,11 +515,11 @@
if (fun.typeParameters.length != 0) return null;
final DartType returnType = convertNativeTypeToDartType(fun.returnType,
- allowStructs: allowStructs, allowHandle: true);
+ allowCompounds: true, allowHandle: true);
if (returnType == null) return null;
final List<DartType> argumentTypes = fun.positionalParameters
.map((t) => convertNativeTypeToDartType(t,
- allowStructs: allowStructs, allowHandle: true))
+ allowCompounds: true, allowHandle: true))
.toList();
if (argumentTypes.contains(null)) return null;
return FunctionType(argumentTypes, returnType, Nullability.legacy);
@@ -740,7 +741,7 @@
return dimensions;
}
- bool isStructSubtype(DartType type) {
+ bool isCompoundSubtype(DartType type) {
if (type is InvalidType) {
return false;
}
@@ -762,9 +763,9 @@
class FfiTransformerData {
final Map<Field, Procedure> replacedGetters;
final Map<Field, Procedure> replacedSetters;
- final Set<Class> emptyStructs;
+ final Set<Class> emptyCompounds;
FfiTransformerData(
- this.replacedGetters, this.replacedSetters, this.emptyStructs);
+ this.replacedGetters, this.replacedSetters, this.emptyCompounds);
}
/// Checks if any library depends on dart:ffi.
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index ccf8b9d..732a676 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -34,7 +34,7 @@
import 'ffi.dart';
-/// Checks and elaborates the dart:ffi structs and fields.
+/// Checks and elaborates the dart:ffi compounds and their fields.
///
/// Input:
/// class Coord extends Struct {
@@ -87,30 +87,30 @@
libraries.forEach(transformer.visitLibrary);
transformer.manualVisitInTopologicalOrder();
return FfiTransformerData(transformer.replacedGetters,
- transformer.replacedSetters, transformer.emptyStructs);
+ transformer.replacedSetters, transformer.emptyCompounds);
}
-class StructDependencyGraph<T> implements Graph<T> {
+class CompoundDependencyGraph<T> implements Graph<T> {
final Map<T, Iterable<T>> map;
- StructDependencyGraph(this.map);
+ CompoundDependencyGraph(this.map);
Iterable<T> get vertices => map.keys;
Iterable<T> neighborsOf(T vertex) => map[vertex];
}
-/// Checks and elaborates the dart:ffi structs and fields.
+/// Checks and elaborates the dart:ffi compounds and their fields.
class _FfiDefinitionTransformer extends FfiTransformer {
final LibraryIndex index;
// Data structures for topological navigation.
- Map<Class, IndexedClass> indexedStructClasses = {};
- Map<Class, Set<Class>> structClassDependencies = {};
+ Map<Class, IndexedClass> indexedCompoundClasses = {};
+ Map<Class, Set<Class>> compoundClassDependencies = {};
Map<Class, bool> fieldsValid = {};
- Map<Class, StructNativeTypeCfe> structCache = {};
+ Map<Class, CompoundNativeTypeCfe> compoundCache = {};
Map<Field, Procedure> replacedGetters = {};
Map<Field, Procedure> replacedSetters = {};
- Set<Class> emptyStructs = {};
+ Set<Class> emptyCompounds = {};
ChangedStructureNotifier changedStructureNotifier;
@@ -127,8 +127,8 @@
referenceFromIndex) {}
void manualVisitInTopologicalOrder() {
- final connectedComponents =
- computeStrongComponents(StructDependencyGraph(structClassDependencies));
+ final connectedComponents = computeStrongComponents(
+ CompoundDependencyGraph(compoundClassDependencies));
connectedComponents.forEach((List<Class> component) {
bool report = false;
@@ -137,7 +137,7 @@
report = true;
}
if (component.length == 1) {
- if (structClassDependencies[component.single]
+ if (compoundClassDependencies[component.single]
.contains(component.single)) {
// Direct cycle.
report = true;
@@ -173,15 +173,17 @@
@override
visitClass(Class node) {
- if (!hierarchy.isSubclassOf(node, structClass) || node == structClass) {
+ if (!hierarchy.isSubclassOf(node, compoundClass) ||
+ node == compoundClass ||
+ node == structClass) {
return node;
}
- final packing = _checkStructClass(node);
+ final packing = _checkCompoundClass(node);
final indexedClass = currentLibraryIndex?.lookupIndexedClass(node.name);
_checkConstructors(node, indexedClass);
- indexedStructClasses[node] = indexedClass;
+ indexedCompoundClasses[node] = indexedClass;
fieldsValid[node] = _checkFieldAnnotations(node, packing);
@@ -189,16 +191,16 @@
}
void visitClassInTopologicalOrder(Class node) {
- final indexedClass = indexedStructClasses[node];
+ final indexedClass = indexedCompoundClasses[node];
if (fieldsValid[node]) {
- final structSize = _replaceFields(node, indexedClass);
- _replaceSizeOfMethod(node, structSize, indexedClass);
+ final compoundSize = _replaceFields(node, indexedClass);
+ _replaceSizeOfMethod(node, compoundSize, indexedClass);
changedStructureNotifier?.registerClassMemberChange(node);
}
}
/// Returns packing if any.
- int _checkStructClass(Class node) {
+ int _checkCompoundClass(Class node) {
if (node.typeParameters.length > 0) {
diagnosticReporter.report(
templateFfiStructGeneric.withArguments(node.name),
@@ -207,7 +209,7 @@
node.location.file);
}
- if (node.supertype?.classNode != structClass) {
+ if (node.superclass != structClass) {
// Not a struct, but extends a struct. The error will be emitted by
// _FfiUseSiteTransformer.
return null;
@@ -233,17 +235,18 @@
}
return packing;
}
+
return null;
}
- /// Returns members of [node] that correspond to struct fields.
+ /// Returns members of [node] that correspond to compound fields.
///
/// Note that getters and setters that originate from an external field have
/// the same `fileOffset`, we always returns getters first.
- List<Member> _structFieldMembers(Class node) {
+ List<Member> _compoundFieldMembers(Class node) {
final externalGetterSetters = [...node.procedures]
..retainWhere((p) => p.isExternal && (p.isGetter || p.isSetter));
- final structMembers = [...node.fields, ...externalGetterSetters]
+ final compoundMembers = [...node.fields, ...externalGetterSetters]
..sort((m1, m2) {
if (m1.fileOffset == m2.fileOffset) {
// Getter and setter have same offset, getter comes first.
@@ -251,10 +254,10 @@
}
return m1.fileOffset - m2.fileOffset;
});
- return structMembers;
+ return compoundMembers;
}
- DartType _structFieldMemberType(Member member) {
+ DartType _compoundFieldMemberType(Member member) {
if (member is Field) {
return member.type;
}
@@ -267,8 +270,8 @@
bool _checkFieldAnnotations(Class node, int packing) {
bool success = true;
- structClassDependencies[node] = {};
- final membersWithAnnotations = _structFieldMembers(node)
+ compoundClassDependencies[node] = {};
+ final membersWithAnnotations = _compoundFieldMembers(node)
..retainWhere((m) => (m is Field) || (m is Procedure && m.isGetter));
for (final Member f in membersWithAnnotations) {
if (f is Field) {
@@ -283,7 +286,7 @@
}
}
final nativeTypeAnnos = _getNativeTypeAnnotations(f).toList();
- final type = _structFieldMemberType(f);
+ final type = _compoundFieldMemberType(f);
if (type is NullType) {
diagnosticReporter.report(
templateFfiFieldNull.withArguments(f.name.text),
@@ -293,7 +296,7 @@
// This class is invalid, but continue reporting other errors on it.
success = false;
} else if (isPointerType(type) ||
- isStructSubtype(type) ||
+ isCompoundSubtype(type) ||
isArrayType(type)) {
if (nativeTypeAnnos.length != 0) {
diagnosticReporter.report(
@@ -304,17 +307,17 @@
// This class is invalid, but continue reporting other errors on it.
success = false;
}
- if (isStructSubtype(type)) {
+ if (isCompoundSubtype(type)) {
final clazz = (type as InterfaceType).classNode;
- structClassDependencies[node].add(clazz);
+ compoundClassDependencies[node].add(clazz);
_checkPacking(node, packing, clazz, f);
} else if (isArrayType(type)) {
final sizeAnnotations = _getArraySizeAnnotations(f);
if (sizeAnnotations.length == 1) {
final singleElementType = arraySingleElementType(type);
- if (isStructSubtype(singleElementType)) {
+ if (isCompoundSubtype(singleElementType)) {
final clazz = (singleElementType as InterfaceType).classNode;
- structClassDependencies[node].add(clazz);
+ compoundClassDependencies[node].add(clazz);
_checkPacking(node, packing, clazz, f);
}
if (arrayDimensions(type) != sizeAnnotations.single.length) {
@@ -348,7 +351,7 @@
Nullability.legacy);
final DartType shouldBeDartType = convertNativeTypeToDartType(
nativeType,
- allowStructs: true,
+ allowCompounds: true,
allowHandle: false);
if (shouldBeDartType == null ||
!env.isSubtypeOf(type, shouldBeDartType,
@@ -450,10 +453,10 @@
node.addConstructor(ctor);
}
- /// Computes the field offsets (for all ABIs) in the struct and replaces the
- /// fields with getters and setters using these offsets.
+ /// Computes the field offsets (for all ABIs) in the compound and replaces
+ /// the fields with getters and setters using these offsets.
///
- /// Returns the total size of the struct (for all ABIs).
+ /// Returns the total size of the compound (for all ABIs).
Map<Abi, int> _replaceFields(Class node, IndexedClass indexedClass) {
final types = <NativeTypeCfe>[];
final fields = <int, Field>{};
@@ -461,8 +464,8 @@
final setters = <int, Procedure>{};
int i = 0;
- for (final Member m in _structFieldMembers(node)) {
- final dartType = _structFieldMemberType(m);
+ for (final Member m in _compoundFieldMembers(node)) {
+ final dartType = _compoundFieldMemberType(m);
NativeTypeCfe type;
if (isArrayType(dartType)) {
@@ -470,10 +473,10 @@
if (sizeAnnotations.length == 1) {
final arrayDimensions = sizeAnnotations.single;
type = NativeTypeCfe(this, dartType,
- structCache: structCache, arrayDimensions: arrayDimensions);
+ compoundCache: compoundCache, arrayDimensions: arrayDimensions);
}
- } else if (isPointerType(dartType) || isStructSubtype(dartType)) {
- type = NativeTypeCfe(this, dartType, structCache: structCache);
+ } else if (isPointerType(dartType) || isCompoundSubtype(dartType)) {
+ type = NativeTypeCfe(this, dartType, compoundCache: compoundCache);
} else {
// The C type is in the annotation, not the field type itself.
final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
@@ -506,21 +509,21 @@
final packing =
(!packingAnnotations.isEmpty) ? packingAnnotations.first : null;
- _annoteStructWithFields(node, types, packing);
+ _annoteCompoundWithFields(node, types, packing);
if (types.isEmpty) {
diagnosticReporter.report(templateFfiEmptyStruct.withArguments(node.name),
node.fileOffset, node.name.length, node.location.file);
- emptyStructs.add(node);
+ emptyCompounds.add(node);
}
- final structType = StructNativeTypeCfe(node, types, packing: packing);
- structCache[node] = structType;
- final structLayout = structType.layout;
+ final compoundType = StructNativeTypeCfe(node, types, packing: packing);
+ compoundCache[node] = compoundType;
+ final compoundLayout = compoundType.layout;
final unalignedAccess = packing != null;
for (final i in fields.keys) {
- final fieldOffsets = structLayout
- .map((Abi abi, StructLayout v) => MapEntry(abi, v.offsets[i]));
+ final fieldOffsets = compoundLayout
+ .map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
final methods = _generateMethodsForField(
fields[i], types[i], fieldOffsets, unalignedAccess, indexedClass);
methods.forEach((p) => node.addProcedure(p));
@@ -531,8 +534,8 @@
}
for (final i in getters.keys) {
- final fieldOffsets = structLayout
- .map((Abi abi, StructLayout v) => MapEntry(abi, v.offsets[i]));
+ final fieldOffsets = compoundLayout
+ .map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
Procedure getter = getters[i];
getter.function.body = types[i].generateGetterStatement(
getter.function.returnType,
@@ -544,8 +547,8 @@
}
for (final i in setters.keys) {
- final fieldOffsets = structLayout
- .map((Abi abi, StructLayout v) => MapEntry(abi, v.offsets[i]));
+ final fieldOffsets = compoundLayout
+ .map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
Procedure setter = setters[i];
setter.function.body = types[i].generateSetterStatement(
setter.function.positionalParameters.single.type,
@@ -557,11 +560,11 @@
setter.isExternal = false;
}
- return structLayout.map((k, v) => MapEntry(k, v.size));
+ return compoundLayout.map((k, v) => MapEntry(k, v.size));
}
// packing is `int?`.
- void _annoteStructWithFields(
+ void _annoteCompoundWithFields(
Class node, List<NativeTypeCfe> types, int packing) {
List<Constant> constants =
types.map((t) => t.generateConstant(this)).toList();
@@ -630,7 +633,7 @@
/// Sample output:
/// int #sizeOf => [24,24,16][_abi()];
void _replaceSizeOfMethod(
- Class struct, Map<Abi, int> sizes, IndexedClass indexedClass) {
+ Class compound, Map<Abi, int> sizes, IndexedClass indexedClass) {
var name = Name("#sizeOf");
var getterReference = indexedClass?.lookupGetterReference(name);
final Field sizeOf = Field.immutable(name,
@@ -638,10 +641,10 @@
isFinal: true,
initializer: runtimeBranchOnLayout(sizes),
type: InterfaceType(intClass, Nullability.legacy),
- fileUri: struct.fileUri,
+ fileUri: compound.fileUri,
getterReference: getterReference)
- ..fileOffset = struct.fileOffset;
- struct.addField(sizeOf);
+ ..fileOffset = compound.fileOffset;
+ compound.addField(sizeOf);
}
NativeType _getFieldType(Class c) {
@@ -712,18 +715,20 @@
}
}
-/// The layout of a `Struct` in one [Abi].
-class StructLayout {
- /// Size of the entire struct.
+/// The layout of a `Struct` or `Union` in one [Abi].
+class CompoundLayout {
+ /// Size of the entire struct or union.
final int size;
- /// Alignment of struct when nested in other struct.
+ /// Alignment of struct or union when nested in a struct.
final int alignment;
/// Offset in bytes for each field, indexed by field number.
+ ///
+ /// Always 0 for unions.
final List<int> offsets;
- StructLayout(this.size, this.alignment, this.offsets);
+ CompoundLayout(this.size, this.alignment, this.offsets);
}
/// AST node wrapper for native types.
@@ -733,7 +738,7 @@
abstract class NativeTypeCfe {
factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
{List<int> arrayDimensions,
- Map<Class, StructNativeTypeCfe> structCache = const {}}) {
+ Map<Class, CompoundNativeTypeCfe> compoundCache = const {}}) {
if (transformer.isPrimitiveType(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
final nativeType = transformer.getType(clazz);
@@ -742,12 +747,12 @@
if (transformer.isPointerType(dartType)) {
return PointerNativeTypeCfe();
}
- if (transformer.isStructSubtype(dartType)) {
+ if (transformer.isCompoundSubtype(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
- if (structCache.containsKey(clazz)) {
- return structCache[clazz];
+ if (compoundCache.containsKey(clazz)) {
+ return compoundCache[clazz];
} else {
- throw "$clazz not found in structCache";
+ throw "$clazz not found in compoundCache";
}
}
if (transformer.isArrayType(dartType)) {
@@ -756,7 +761,7 @@
}
final elementType = transformer.arraySingleElementType(dartType);
final elementCfeType =
- NativeTypeCfe(transformer, elementType, structCache: structCache);
+ NativeTypeCfe(transformer, elementType, compoundCache: compoundCache);
return ArrayNativeTypeCfe.multi(elementCfeType, arrayDimensions);
}
throw "Invalid type $dartType";
@@ -777,13 +782,13 @@
/// See runtime/vm/compiler/ffi/native_type.cc:NativeType::FromAbstractType.
Constant generateConstant(FfiTransformer transformer);
- /// Generates the return statement for a struct field getter with this type.
+ /// Generates the return statement for a compound field getter with this type.
///
/// Takes [transformer] to be able to lookup classes and methods.
ReturnStatement generateGetterStatement(DartType dartType, int fileOffset,
Map<Abi, int> offsets, bool unalignedAccess, FfiTransformer transformer);
- /// Generates the return statement for a struct field setter with this type.
+ /// Generates the return statement for a compound field setter with this type.
///
/// Takes [transformer] to be able to lookup classes and methods.
ReturnStatement generateSetterStatement(
@@ -853,8 +858,8 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets)
]))
@@ -880,8 +885,8 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
VariableGet(argument)
@@ -923,8 +928,8 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets)
]))
@@ -952,8 +957,8 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
PropertyGet(VariableGet(argument), transformer.addressGetter.name,
@@ -963,46 +968,14 @@
..fileOffset = fileOffset);
}
-class StructNativeTypeCfe implements NativeTypeCfe {
+abstract class CompoundNativeTypeCfe implements NativeTypeCfe {
final Class clazz;
final List<NativeTypeCfe> members;
- // Nullable int.
- final int packing;
+ final Map<Abi, CompoundLayout> layout;
- final Map<Abi, StructLayout> layout;
-
- factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
- {int packing}) {
- final layout = Map.fromEntries(Abi.values
- .map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
- return StructNativeTypeCfe._(clazz, members, packing, layout);
- }
-
- // Keep consistent with runtime/vm/compiler/ffi/native_type.cc
- // NativeCompoundType::FromNativeTypes.
- static StructLayout _calculateLayout(
- List<NativeTypeCfe> types, int packing, Abi abi) {
- int offset = 0;
- final offsets = <int>[];
- int structAlignment = 1;
- for (int i = 0; i < types.length; i++) {
- final int size = types[i].size[abi];
- int alignment = types[i].alignment[abi];
- if (packing != null && packing < alignment) {
- alignment = packing;
- }
- offset = _alignOffset(offset, alignment);
- offsets.add(offset);
- offset += size;
- structAlignment = math.max(structAlignment, alignment);
- }
- final int size = _alignOffset(offset, structAlignment);
- return StructLayout(size, structAlignment, offsets);
- }
-
- StructNativeTypeCfe._(this.clazz, this.members, this.packing, this.layout);
+ CompoundNativeTypeCfe._(this.clazz, this.members, this.layout);
@override
Map<Abi, int> get size =>
@@ -1035,8 +1008,8 @@
transformer.typedDataBaseOffset(
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
transformer.runtimeBranchOnLayout(size),
@@ -1064,14 +1037,14 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
PropertyGet(
VariableGet(argument),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
ConstantExpression(IntConstant(0)),
transformer.runtimeBranchOnLayout(size),
@@ -1079,6 +1052,44 @@
..fileOffset = fileOffset);
}
+class StructNativeTypeCfe extends CompoundNativeTypeCfe {
+ // Nullable int.
+ final int packing;
+
+ factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
+ {int packing}) {
+ final layout = Map.fromEntries(Abi.values
+ .map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
+ return StructNativeTypeCfe._(clazz, members, packing, layout);
+ }
+
+ StructNativeTypeCfe._(Class clazz, List<NativeTypeCfe> members, this.packing,
+ Map<Abi, CompoundLayout> layout)
+ : super._(clazz, members, layout);
+
+ // Keep consistent with runtime/vm/compiler/ffi/native_type.cc
+ // NativeStructType::FromNativeTypes.
+ static CompoundLayout _calculateLayout(
+ List<NativeTypeCfe> types, int packing, Abi abi) {
+ int offset = 0;
+ final offsets = <int>[];
+ int structAlignment = 1;
+ for (int i = 0; i < types.length; i++) {
+ final int size = types[i].size[abi];
+ int alignment = types[i].alignment[abi];
+ if (packing != null && packing < alignment) {
+ alignment = packing;
+ }
+ offset = _alignOffset(offset, alignment);
+ offsets.add(offset);
+ offset += size;
+ structAlignment = math.max(structAlignment, alignment);
+ }
+ final int size = _alignOffset(offset, structAlignment);
+ return CompoundLayout(size, structAlignment, offsets);
+ }
+}
+
class ArrayNativeTypeCfe implements NativeTypeCfe {
final NativeTypeCfe elementType;
final int length;
@@ -1151,8 +1162,8 @@
transformer.typedDataBaseOffset(
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
transformer.runtimeBranchOnLayout(size),
@@ -1184,8 +1195,8 @@
Arguments([
PropertyGet(
ThisExpression(),
- transformer.structTypedDataBaseField.name,
- transformer.structTypedDataBaseField)
+ transformer.compoundTypedDataBaseField.name,
+ transformer.compoundTypedDataBaseField)
..fileOffset = fileOffset,
transformer.runtimeBranchOnLayout(offsets),
PropertyGet(
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 20cfbe8..52075ce 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -35,7 +35,7 @@
UNKNOWN,
wordSize;
-/// Checks and replaces calls to dart:ffi struct fields and methods.
+/// Checks and replaces calls to dart:ffi compound fields and methods.
void transformLibraries(
Component component,
CoreTypes coreTypes,
@@ -64,15 +64,15 @@
referenceFromIndex,
ffiTransformerData.replacedGetters,
ffiTransformerData.replacedSetters,
- ffiTransformerData.emptyStructs);
+ ffiTransformerData.emptyCompounds);
libraries.forEach(transformer.visitLibrary);
}
-/// Checks and replaces calls to dart:ffi struct fields and methods.
+/// Checks and replaces calls to dart:ffi compound fields and methods.
class _FfiUseSiteTransformer extends FfiTransformer {
final Map<Field, Procedure> replacedGetters;
final Map<Field, Procedure> replacedSetters;
- final Set<Class> emptyStructs;
+ final Set<Class> emptyCompounds;
StaticTypeContext _staticTypeContext;
bool get isFfiLibrary => currentLibrary == ffiLibrary;
@@ -89,7 +89,7 @@
ReferenceFromIndex referenceFromIndex,
this.replacedGetters,
this.replacedSetters,
- this.emptyStructs)
+ this.emptyCompounds)
: super(index, coreTypes, hierarchy, diagnosticReporter,
referenceFromIndex) {}
@@ -179,33 +179,33 @@
if (target == structPointerRef || target == structPointerElemAt) {
final DartType nativeType = node.arguments.types[0];
- _ensureNativeTypeValid(nativeType, node, allowStructItself: false);
+ _ensureNativeTypeValid(nativeType, node, allowCompounds: true);
return _replaceRef(node);
} else if (target == structArrayElemAt) {
final DartType nativeType = node.arguments.types[0];
- _ensureNativeTypeValid(nativeType, node, allowStructItself: false);
+ _ensureNativeTypeValid(nativeType, node, allowCompounds: true);
return _replaceRefArray(node);
} else if (target == arrayArrayElemAt) {
final DartType nativeType = node.arguments.types[0];
_ensureNativeTypeValid(nativeType, node,
- allowStructItself: false, allowInlineArray: true);
+ allowInlineArray: true, allowCompounds: true);
return _replaceArrayArrayElemAt(node);
} else if (target == arrayArrayAssignAt) {
final DartType nativeType = node.arguments.types[0];
_ensureNativeTypeValid(nativeType, node,
- allowStructItself: false, allowInlineArray: true);
+ allowInlineArray: true, allowCompounds: true);
return _replaceArrayArrayElemAt(node, setter: true);
} else if (target == sizeOfMethod) {
final DartType nativeType = node.arguments.types[0];
- _ensureNativeTypeValid(nativeType, node);
+ _ensureNativeTypeValid(nativeType, node, allowCompounds: true);
if (nativeType is InterfaceType) {
Expression inlineSizeOf = _inlineSizeOf(nativeType);
@@ -220,7 +220,7 @@
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
- _ensureNoEmptyStructs(dartType, node);
+ _ensureNoEmptyCompounds(dartType, node);
final replacement = _replaceLookupFunction(node);
@@ -229,7 +229,7 @@
if (returnType is InterfaceType) {
final clazz = returnType.classNode;
if (clazz.superclass == structClass) {
- return _invokeStructConstructor(replacement, clazz);
+ return _invokeCompoundConstructor(replacement, clazz);
}
}
}
@@ -241,7 +241,7 @@
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
- _ensureNoEmptyStructs(dartType, node);
+ _ensureNoEmptyCompounds(dartType, node);
final DartType nativeSignature =
(nativeType as InterfaceType).typeArguments[0];
@@ -257,7 +257,7 @@
if (returnType is InterfaceType) {
final clazz = returnType.classNode;
if (clazz.superclass == structClass) {
- return _invokeStructConstructor(replacement, clazz);
+ return _invokeCompoundConstructor(replacement, clazz);
}
}
}
@@ -272,7 +272,7 @@
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
- _ensureNoEmptyStructs(dartType, node);
+ _ensureNoEmptyCompounds(dartType, node);
final funcType = dartType as FunctionType;
@@ -348,16 +348,16 @@
final replacement = _replaceFromFunction(node);
- final structClasses = funcType.positionalParameters
+ final compoundClasses = funcType.positionalParameters
.whereType<InterfaceType>()
.map((t) => t.classNode)
.where((c) => c.superclass == structClass)
.toList();
- return _invokeStructConstructors(replacement, structClasses);
+ return _invokeCompoundConstructors(replacement, compoundClasses);
} else if (target == allocateMethod) {
final DartType nativeType = node.arguments.types[0];
- _ensureNativeTypeValid(nativeType, node);
+ _ensureNativeTypeValid(nativeType, node, allowCompounds: true);
// Inline the body to get rid of a generic invocation of sizeOf.
// TODO(http://dartbug.com/39964): Add `allignmentOf<T>()` call.
@@ -388,9 +388,9 @@
/// Prevents the struct from being tree-shaken in TFA by invoking its
/// constructor in a `_nativeEffect` expression.
- Expression _invokeStructConstructor(
- Expression nestedExpression, Class compositeClass) {
- final constructor = compositeClass.constructors
+ Expression _invokeCompoundConstructor(
+ Expression nestedExpression, Class compoundClass) {
+ final constructor = compoundClass.constructors
.firstWhere((c) => c.name == Name("#fromTypedDataBase"));
return BlockExpression(
Block([
@@ -414,15 +414,17 @@
..fileOffset = nestedExpression.fileOffset;
}
- Expression _invokeStructConstructors(
- Expression nestedExpression, List<Class> structClasses) =>
- structClasses.distinct().fold(nestedExpression, _invokeStructConstructor);
+ Expression _invokeCompoundConstructors(
+ Expression nestedExpression, List<Class> compoundClasses) =>
+ compoundClasses
+ .distinct()
+ .fold(nestedExpression, _invokeCompoundConstructor);
Expression _inlineSizeOf(InterfaceType nativeType) {
final Class nativeClass = nativeType.classNode;
final NativeType nt = getType(nativeClass);
if (nt == null) {
- // User-defined structs.
+ // User-defined compounds.
Field sizeOfField = nativeClass.fields.single;
return StaticGet(sizeOfField);
}
@@ -699,7 +701,7 @@
node.receiver.getStaticType(_staticTypeContext);
final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
- _ensureNativeTypeValid(nativeType, node);
+ _ensureNativeTypeValid(nativeType, node, allowCompounds: true);
Expression inlineSizeOf = _inlineSizeOf(nativeType);
if (inlineSizeOf != null) {
@@ -735,7 +737,7 @@
{bool allowHandle: false}) {
final DartType correspondingDartType = convertNativeTypeToDartType(
nativeType,
- allowStructs: true,
+ allowCompounds: true,
allowHandle: allowHandle);
if (dartType == correspondingDartType) return;
if (env.isSubtypeOf(correspondingDartType, dartType,
@@ -753,11 +755,10 @@
void _ensureNativeTypeValid(DartType nativeType, Expression node,
{bool allowHandle: false,
- bool allowStructItself = true,
+ bool allowCompounds: false,
bool allowInlineArray = false}) {
if (!_nativeTypeValid(nativeType,
- allowStructs: true,
- allowStructItself: allowStructItself,
+ allowCompounds: allowCompounds,
allowHandle: allowHandle,
allowInlineArray: allowInlineArray)) {
diagnosticReporter.report(
@@ -770,12 +771,12 @@
}
}
- void _ensureNoEmptyStructs(DartType nativeType, Expression node) {
+ void _ensureNoEmptyCompounds(DartType nativeType, Expression node) {
// Error on structs with no fields.
if (nativeType is InterfaceType) {
final Class nativeClass = nativeType.classNode;
- if (hierarchy.isSubclassOf(nativeClass, structClass)) {
- if (emptyStructs.contains(nativeClass)) {
+ if (hierarchy.isSubclassOf(nativeClass, compoundClass)) {
+ if (emptyCompounds.contains(nativeClass)) {
diagnosticReporter.report(
templateFfiEmptyStruct.withArguments(nativeClass.name),
node.fileOffset,
@@ -788,21 +789,19 @@
// Recurse when seeing a function type.
if (nativeType is FunctionType) {
nativeType.positionalParameters
- .forEach((e) => _ensureNoEmptyStructs(e, node));
- _ensureNoEmptyStructs(nativeType.returnType, node);
+ .forEach((e) => _ensureNoEmptyCompounds(e, node));
+ _ensureNoEmptyCompounds(nativeType.returnType, node);
}
}
/// The Dart type system does not enforce that NativeFunction return and
/// parameter types are only NativeTypes, so we need to check this.
bool _nativeTypeValid(DartType nativeType,
- {bool allowStructs: false,
- bool allowStructItself = false,
+ {bool allowCompounds: false,
bool allowHandle = false,
bool allowInlineArray = false}) {
return convertNativeTypeToDartType(nativeType,
- allowStructs: allowStructs,
- allowStructItself: allowStructItself,
+ allowCompounds: allowCompounds,
allowHandle: allowHandle,
allowInlineArray: allowInlineArray) !=
null;
@@ -822,14 +821,14 @@
}
Class _extendsOrImplementsSealedClass(Class klass) {
- final Class superClass = klass.supertype?.classNode;
+ final Class superClass = klass.superclass;
// The Opaque and Struct classes can be extended, but subclasses
// cannot be (nor implemented).
if (klass != opaqueClass &&
klass != structClass &&
(hierarchy.isSubtypeOf(klass, opaqueClass) ||
- hierarchy.isSubtypeOf(klass, structClass))) {
+ hierarchy.isSubtypeOf(klass, compoundClass))) {
return superClass != opaqueClass && superClass != structClass
? superClass
: null;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
index 3469672..367f663 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
@@ -41,7 +41,7 @@
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get nested() → self::Struct12*
return new self::Struct12::#fromTypedDataBase( block {
- core::Object #typedDataBase = [@vm.direct-call.metadata=dart.ffi::Struct._typedDataBase] this.{ffi::Struct::_typedDataBase};
+ core::Object #typedDataBase = [@vm.direct-call.metadata=dart.ffi::_Compound._typedDataBase] this.{ffi::_Compound::_typedDataBase};
core::int #offset = (#C12).{core::List::[]}(ffi::_abi());
} =>#typedDataBase is ffi::Pointer<dynamic> ?{core::Object} [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::_fromAddress<self::Struct12*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.direct-call.metadata=dart.ffi::Pointer.address] [@vm.inferred-type.metadata=int?] #typedDataBase.{ffi::Pointer::address}.{core::num::+}(#offset)) : let typ::TypedData #typedData = _in::unsafeCast<typ::TypedData>(#typedDataBase) in [@vm.direct-call.metadata=dart.typed_data::_ByteBuffer.asUint8List] [@vm.inferred-type.metadata=dart.typed_data::_Uint8ArrayView (skip check)] [@vm.inferred-type.metadata=dart.typed_data::_ByteBuffer] #typedData.{typ::TypedData::buffer}.{typ::ByteBuffer::asUint8List}([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=dart.core::_Smi] #typedData.{typ::TypedData::offsetInBytes}.{core::num::+}(#offset), (#C15).{core::List::[]}(ffi::_abi())));
}
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
index 480f045..dbaff91 100644
--- a/runtime/vm/compiler/ffi/marshaller.cc
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -390,7 +390,7 @@
}
bool CallMarshaller::PassTypedData() const {
- return IsStruct(compiler::ffi::kResultIndex);
+ return IsCompound(compiler::ffi::kResultIndex);
}
intptr_t CallMarshaller::TypedDataSizeInBytes() const {
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
index 657817e..4fafbe1 100644
--- a/runtime/vm/compiler/ffi/marshaller.h
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -110,7 +110,7 @@
kFfiHandleCid;
}
- bool IsStruct(intptr_t arg_index) const {
+ bool IsCompound(intptr_t arg_index) const {
const auto& type = AbstractType::Handle(zone_, CType(arg_index));
const bool predefined = IsFfiTypeClassId(type.type_class_id());
return !predefined;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index ed3fba1..5d294d8 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -3776,44 +3776,45 @@
return Fragment(instr);
}
-Fragment FlowGraphBuilder::WrapTypedDataBaseInStruct(
- const AbstractType& struct_type) {
- const auto& struct_sub_class = Class::ZoneHandle(Z, struct_type.type_class());
- struct_sub_class.EnsureIsFinalized(thread_);
+Fragment FlowGraphBuilder::WrapTypedDataBaseInCompound(
+ const AbstractType& compound_type) {
+ const auto& compound_sub_class =
+ Class::ZoneHandle(Z, compound_type.type_class());
+ compound_sub_class.EnsureIsFinalized(thread_);
const auto& lib_ffi = Library::Handle(Z, Library::FfiLibrary());
- const auto& struct_class =
- Class::Handle(Z, lib_ffi.LookupClass(Symbols::Struct()));
- const auto& struct_addressof = Field::ZoneHandle(
- Z,
- struct_class.LookupInstanceFieldAllowPrivate(Symbols::_typedDataBase()));
- ASSERT(!struct_addressof.IsNull());
+ const auto& compound_class =
+ Class::Handle(Z, lib_ffi.LookupClassAllowPrivate(Symbols::Compound()));
+ const auto& compound_typed_data_base =
+ Field::ZoneHandle(Z, compound_class.LookupInstanceFieldAllowPrivate(
+ Symbols::_typedDataBase()));
+ ASSERT(!compound_typed_data_base.IsNull());
Fragment body;
LocalVariable* typed_data = MakeTemporary("typed_data_base");
- body += AllocateObject(TokenPosition::kNoSource, struct_sub_class, 0);
- body += LoadLocal(MakeTemporary("struct")); // Duplicate Struct.
+ body += AllocateObject(TokenPosition::kNoSource, compound_sub_class, 0);
+ body += LoadLocal(MakeTemporary("compound")); // Duplicate Struct or Union.
body += LoadLocal(typed_data);
- body += StoreInstanceField(struct_addressof,
+ body += StoreInstanceField(compound_typed_data_base,
StoreInstanceFieldInstr::Kind::kInitializing);
body += DropTempsPreserveTop(1); // Drop TypedData.
return body;
}
-Fragment FlowGraphBuilder::LoadTypedDataBaseFromStruct() {
- const Library& lib_ffi = Library::Handle(zone_, Library::FfiLibrary());
- const Class& struct_class =
- Class::Handle(zone_, lib_ffi.LookupClass(Symbols::Struct()));
- const Field& struct_addressof = Field::ZoneHandle(
- zone_,
- struct_class.LookupInstanceFieldAllowPrivate(Symbols::_typedDataBase()));
- ASSERT(!struct_addressof.IsNull());
+Fragment FlowGraphBuilder::LoadTypedDataBaseFromCompound() {
+ const auto& lib_ffi = Library::Handle(Z, Library::FfiLibrary());
+ const auto& compound_class =
+ Class::Handle(Z, lib_ffi.LookupClassAllowPrivate(Symbols::Compound()));
+ const auto& compound_typed_data_base =
+ Field::ZoneHandle(Z, compound_class.LookupInstanceFieldAllowPrivate(
+ Symbols::_typedDataBase()));
+ ASSERT(!compound_typed_data_base.IsNull());
Fragment body;
- body += LoadField(struct_addressof, /*calls_initializer=*/false);
+ body += LoadField(compound_typed_data_base, /*calls_initializer=*/false);
return body;
}
-Fragment FlowGraphBuilder::CopyFromStructToStack(
+Fragment FlowGraphBuilder::CopyFromCompoundToStack(
LocalVariable* variable,
const GrowableArray<Representation>& representations) {
Fragment body;
@@ -3821,7 +3822,7 @@
int offset_in_bytes = 0;
for (intptr_t i = 0; i < num_defs; i++) {
body += LoadLocal(variable);
- body += LoadTypedDataBaseFromStruct();
+ body += LoadTypedDataBaseFromCompound();
body += LoadUntagged(compiler::target::Pointer::data_field_offset());
body += IntConstant(offset_in_bytes);
const Representation representation = representations[i];
@@ -3959,7 +3960,7 @@
return body;
}
-Fragment FlowGraphBuilder::FfiCallConvertStructArgumentToNative(
+Fragment FlowGraphBuilder::FfiCallConvertCompoundArgumentToNative(
LocalVariable* variable,
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index) {
@@ -3970,29 +3971,29 @@
// separate definitions into the FFI call.
GrowableArray<Representation> representations;
marshaller.RepsInFfiCall(arg_index, &representations);
- body += CopyFromStructToStack(variable, representations);
+ body += CopyFromCompoundToStack(variable, representations);
} else {
ASSERT(native_loc.IsPointerToMemory());
// Only load the typed data, do copying in the FFI call machine code.
body += LoadLocal(variable); // User-defined struct.
- body += LoadTypedDataBaseFromStruct();
+ body += LoadTypedDataBaseFromCompound();
}
return body;
}
-Fragment FlowGraphBuilder::FfiCallConvertStructReturnToDart(
+Fragment FlowGraphBuilder::FfiCallConvertCompoundReturnToDart(
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index) {
Fragment body;
// The typed data is allocated before the FFI call, and is populated in
// machine code. So, here, it only has to be wrapped in the struct class.
- const auto& struct_type =
+ const auto& compound_type =
AbstractType::Handle(Z, marshaller.CType(arg_index));
- body += WrapTypedDataBaseInStruct(struct_type);
+ body += WrapTypedDataBaseInCompound(compound_type);
return body;
}
-Fragment FlowGraphBuilder::FfiCallbackConvertStructArgumentToDart(
+Fragment FlowGraphBuilder::FfiCallbackConvertCompoundArgumentToDart(
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index,
ZoneGrowableArray<LocalVariable*>* definitions) {
@@ -4012,24 +4013,24 @@
} else {
ASSERT(marshaller.Location(arg_index).IsPointerToMemory());
// Allocate a TypedData and copy contents pointed to by an address into it.
- LocalVariable* address_of_struct = MakeTemporary("address_of_struct");
+ LocalVariable* address_of_compound = MakeTemporary("address_of_compound");
body += IntConstant(length_in_bytes);
body +=
AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
LocalVariable* typed_data_base = MakeTemporary("typed_data_base");
- body += LoadLocal(address_of_struct);
+ body += LoadLocal(address_of_compound);
body += LoadLocal(typed_data_base);
body += CopyFromUnboxedAddressToTypedDataBase(length_in_bytes);
- body += DropTempsPreserveTop(1); // address_of_struct.
+ body += DropTempsPreserveTop(1); // address_of_compound.
}
- // Wrap typed data in struct class.
- const auto& struct_type =
+ // Wrap typed data in compound class.
+ const auto& compound_type =
AbstractType::Handle(Z, marshaller.CType(arg_index));
- body += WrapTypedDataBaseInStruct(struct_type);
+ body += WrapTypedDataBaseInCompound(compound_type);
return body;
}
-Fragment FlowGraphBuilder::FfiCallbackConvertStructReturnToNative(
+Fragment FlowGraphBuilder::FfiCallbackConvertCompoundReturnToNative(
const compiler::ffi::CallbackMarshaller& marshaller,
intptr_t arg_index) {
Fragment body;
@@ -4037,14 +4038,14 @@
if (native_loc.IsMultiple()) {
// We pass in typed data to native return instruction, and do the copying
// in machine code.
- body += LoadTypedDataBaseFromStruct();
+ body += LoadTypedDataBaseFromCompound();
} else {
ASSERT(native_loc.IsPointerToMemory());
// We copy the data into the right location in IL.
const intptr_t length_in_bytes =
marshaller.Location(arg_index).payload_type().SizeInBytes();
- body += LoadTypedDataBaseFromStruct();
+ body += LoadTypedDataBaseFromCompound();
LocalVariable* typed_data_base = MakeTemporary("typed_data_base");
auto* pointer_to_return =
@@ -4065,7 +4066,7 @@
Fragment FlowGraphBuilder::FfiConvertPrimitiveToDart(
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index) {
- ASSERT(!marshaller.IsStruct(arg_index));
+ ASSERT(!marshaller.IsCompound(arg_index));
Fragment body;
if (marshaller.IsPointer(arg_index)) {
@@ -4093,7 +4094,7 @@
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index,
LocalVariable* api_local_scope) {
- ASSERT(!marshaller.IsStruct(arg_index));
+ ASSERT(!marshaller.IsCompound(arg_index));
Fragment body;
if (marshaller.IsPointer(arg_index)) {
@@ -4195,8 +4196,8 @@
// Unbox and push the arguments.
for (intptr_t i = 0; i < marshaller.num_args(); i++) {
- if (marshaller.IsStruct(i)) {
- body += FfiCallConvertStructArgumentToNative(
+ if (marshaller.IsCompound(i)) {
+ body += FfiCallConvertCompoundArgumentToNative(
parsed_function_->ParameterVariable(kFirstArgumentParameterOffset +
i),
marshaller, i);
@@ -4246,9 +4247,9 @@
body += Drop();
}
- if (marshaller.IsStruct(compiler::ffi::kResultIndex)) {
- body += FfiCallConvertStructReturnToDart(marshaller,
- compiler::ffi::kResultIndex);
+ if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
+ body += FfiCallConvertCompoundReturnToDart(marshaller,
+ compiler::ffi::kResultIndex);
} else {
body += FfiConvertPrimitiveToDart(marshaller, compiler::ffi::kResultIndex);
}
@@ -4322,8 +4323,8 @@
defs->Add(def);
}
- if (marshaller.IsStruct(i)) {
- body += FfiCallbackConvertStructArgumentToDart(marshaller, i, defs);
+ if (marshaller.IsCompound(i)) {
+ body += FfiCallbackConvertCompoundArgumentToDart(marshaller, i, defs);
} else {
body += FfiConvertPrimitiveToDart(marshaller, i);
}
@@ -4346,9 +4347,9 @@
String::ZoneHandle(Z, marshaller.function_name()));
}
- if (marshaller.IsStruct(compiler::ffi::kResultIndex)) {
- body += FfiCallbackConvertStructReturnToNative(marshaller,
- compiler::ffi::kResultIndex);
+ if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
+ body += FfiCallbackConvertCompoundReturnToNative(
+ marshaller, compiler::ffi::kResultIndex);
} else {
body += FfiConvertPrimitiveToNative(marshaller, compiler::ffi::kResultIndex,
/*api_local_scope=*/nullptr);
@@ -4379,7 +4380,7 @@
FfiConvertPrimitiveToNative(marshaller, compiler::ffi::kResultIndex,
/*api_local_scope=*/nullptr);
- } else if (marshaller.IsStruct(compiler::ffi::kResultIndex)) {
+ } else if (marshaller.IsCompound(compiler::ffi::kResultIndex)) {
ASSERT(function.FfiCallbackExceptionalReturn() == Object::null());
// Manufacture empty result.
const intptr_t size =
@@ -4390,9 +4391,9 @@
catch_body += IntConstant(size);
catch_body +=
AllocateTypedData(TokenPosition::kNoSource, kTypedDataUint8ArrayCid);
- catch_body += WrapTypedDataBaseInStruct(
+ catch_body += WrapTypedDataBaseInCompound(
AbstractType::Handle(Z, marshaller.CType(compiler::ffi::kResultIndex)));
- catch_body += FfiCallbackConvertStructReturnToNative(
+ catch_body += FfiCallbackConvertCompoundReturnToNative(
marshaller, compiler::ffi::kResultIndex);
} else {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 7e93009..ced5185 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -293,44 +293,46 @@
intptr_t arg_index);
// We pass in `variable` instead of on top of the stack so that we can have
- // multiple consecutive calls that keep only struct parts on the stack with
- // no struct parts in between.
- Fragment FfiCallConvertStructArgumentToNative(
+ // multiple consecutive calls that keep only compound parts on the stack with
+ // no compound parts in between.
+ Fragment FfiCallConvertCompoundArgumentToNative(
LocalVariable* variable,
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index);
- Fragment FfiCallConvertStructReturnToDart(
+ Fragment FfiCallConvertCompoundReturnToDart(
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index);
// We pass in multiple `definitions`, which are also expected to be the top
- // of the stack. This eases storing each definition in the resulting struct.
- Fragment FfiCallbackConvertStructArgumentToDart(
+ // of the stack. This eases storing each definition in the resulting struct
+ // or union.
+ Fragment FfiCallbackConvertCompoundArgumentToDart(
const compiler::ffi::BaseMarshaller& marshaller,
intptr_t arg_index,
ZoneGrowableArray<LocalVariable*>* definitions);
- Fragment FfiCallbackConvertStructReturnToNative(
+ Fragment FfiCallbackConvertCompoundReturnToNative(
const compiler::ffi::CallbackMarshaller& marshaller,
intptr_t arg_index);
- // Wraps a TypedDataBase from the stack and wraps it in a subclass of Struct.
- Fragment WrapTypedDataBaseInStruct(const AbstractType& struct_type);
+ // Wraps a TypedDataBase from the stack and wraps it in a subclass of
+ // _Compound.
+ Fragment WrapTypedDataBaseInCompound(const AbstractType& compound_type);
- // Loads the _typedDataBase field from a subclass of Struct.
- Fragment LoadTypedDataBaseFromStruct();
+ // Loads the _typedDataBase field from a subclass of _Compound.
+ Fragment LoadTypedDataBaseFromCompound();
- // Breaks up a subclass of Struct in multiple definitions and puts them on
+ // Breaks up a subclass of _Compound in multiple definitions and puts them on
// the stack.
//
- // Takes in the Struct as a local `variable` so that can be anywhere on the
- // stack and this function can be called multiple times to leave only the
- // results of this function on the stack without any Structs in between.
+ // Takes in the _Compound as a local `variable` so that can be anywhere on
+ // the stack and this function can be called multiple times to leave only the
+ // results of this function on the stack without any _Compounds in between.
//
- // The struct contents are heterogeneous, so pass in `representations` to
- // know what representation to load.
- Fragment CopyFromStructToStack(
+ // The compound contents are heterogeneous, so pass in
+ // `representations` to know what representation to load.
+ Fragment CopyFromCompoundToStack(
LocalVariable* variable,
const GrowableArray<Representation>& representations);
@@ -340,7 +342,7 @@
//
// Leaves TypedData on stack.
//
- // The struct contents are heterogeneous, so pass in `representations` to
+ // The compound contents are heterogeneous, so pass in `representations` to
// know what representation to load.
Fragment PopFromStackToTypedDataBase(
ZoneGrowableArray<LocalVariable*>* definitions,
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index 57eb309..1c79061 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -6,7 +6,7 @@
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart tools/generate_experimental_flags.dart' to update.
//
-// Current version: 2.13.0
+// Current version: 2.14.0
#include "vm/experimental_features.h"
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index d6816b3..035af24 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -6,7 +6,7 @@
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart tools/generate_experimental_flags.dart' to update.
//
-// Current version: 2.13.0
+// Current version: 2.14.0
#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index fdff2a6..e5220d1 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1661,7 +1661,7 @@
// optimized. We immediately set the guarded_cid_ to kDynamicCid, which
// is effectively the same as calling this method first with Pointer and
// subsequently with TypedData with field guards.
- if (klass.Name() == Symbols::Struct().ptr() &&
+ if (klass.Name() == Symbols::Compound().ptr() &&
Library::Handle(Z, klass.library()).url() == Symbols::DartFfi().ptr()) {
ASSERT(fields_.length() == 1);
ASSERT(String::Handle(Z, fields_[0]->name())
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 4921334..fd790e9 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -55,6 +55,7 @@
V(CompleterFuture, "future") \
V(CompleterGetFuture, "get:future") \
V(CompleterSyncConstructor, "Completer.sync") \
+ V(Compound, "_Compound") \
V(CompressedStackMaps, "CompressedStackMaps") \
V(ConstructorStacktracePrefix, "new ") \
V(Context, "Context") \
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
index e4fce17..de45d6d 100644
--- a/sdk/lib/ffi/struct.dart
+++ b/sdk/lib/ffi/struct.dart
@@ -4,6 +4,19 @@
part of dart.ffi;
+/// The supertype of all FFI compound types.
+///
+/// FFI struct types should extend [Struct]. For more information see the
+/// documentation on this class.
+abstract class _Compound extends NativeType {
+ @pragma("vm:entry-point")
+ final Object _typedDataBase;
+
+ _Compound._() : _typedDataBase = nullptr;
+
+ _Compound._fromTypedDataBase(this._typedDataBase);
+}
+
/// The supertype of all FFI struct types.
///
/// FFI struct types should extend this class and declare fields corresponding
@@ -47,17 +60,15 @@
/// by native memory or typed data. They may allocated via allocation or loaded
/// from a [Pointer] or created by ffi calls or callbacks. They cannot be
/// created by a generative constructor.
-abstract class Struct extends NativeType {
- @pragma("vm:entry-point")
- final Object _typedDataBase;
-
+abstract class Struct extends _Compound {
/// Construct a reference to the [nullptr].
///
/// Use [StructPointer]'s `.ref` to gain references to native memory backed
/// structs.
- Struct() : _typedDataBase = nullptr;
+ Struct() : super._();
- Struct._fromTypedDataBase(this._typedDataBase);
+ Struct._fromTypedDataBase(Object typedDataBase)
+ : super._fromTypedDataBase(typedDataBase);
}
/// Annotation to specify on `Struct` subtypes to indicate that its members
diff --git a/tools/VERSION b/tools/VERSION
index 18aba60..b12f608 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
#
CHANNEL dev
MAJOR 2
-MINOR 13
+MINOR 14
PATCH 0
-PRERELEASE 236
+PRERELEASE 0
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 336213d..55dfb4d 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -103,7 +103,7 @@
# default 'language' "category" with code generated for both CFE and Analyzer,
# while other categories can be tailored more specifically.
-current-version: '2.13.0'
+current-version: '2.14.0'
features:
triple-shift: