Version 2.13.0-45.0.dev
Merge commit '5bcb19125ce52308c565bbe320ae5db4235c182a' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index c8e1eff..bfcdff4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -2393,32 +2393,6 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name, Uri uri_, Uri uri2_)>
- templateDuplicatedImport =
- const Template<Message Function(String name, Uri uri_, Uri uri2_)>(
- messageTemplate:
- r"""'#name' is imported from both '#uri' and '#uri2'.""",
- withArguments: _withArgumentsDuplicatedImport);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, Uri uri_, Uri uri2_)>
- codeDuplicatedImport =
- const Code<Message Function(String name, Uri uri_, Uri uri2_)>(
- "DuplicatedImport",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsDuplicatedImport(String name, Uri uri_, Uri uri2_) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String? uri = relativizeUri(uri_);
- String? uri2 = relativizeUri(uri2_);
- return new Message(codeDuplicatedImport,
- message: """'${name}' is imported from both '${uri}' and '${uri2}'.""",
- arguments: {'name': name, 'uri': uri_, 'uri2': uri2_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, Uri uri_, Uri uri2_)>
templateDuplicatedImportInType =
const Template<Message Function(String name, Uri uri_, Uri uri2_)>(
messageTemplate:
@@ -3244,33 +3218,6 @@
tip: r"""Try moving the export directives before the part directives.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, Uri uri_, Uri uri2_)>
- templateExportHidesExport =
- const Template<Message Function(String name, Uri uri_, Uri uri2_)>(
- messageTemplate:
- r"""Export of '#name' (from '#uri') hides export from '#uri2'.""",
- withArguments: _withArgumentsExportHidesExport);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, Uri uri_, Uri uri2_)>
- codeExportHidesExport =
- const Code<Message Function(String name, Uri uri_, Uri uri2_)>(
- "ExportHidesExport",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsExportHidesExport(String name, Uri uri_, Uri uri2_) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String? uri = relativizeUri(uri_);
- String? uri2 = relativizeUri(uri2_);
- return new Message(codeExportHidesExport,
- message:
- """Export of '${name}' (from '${uri}') hides export from '${uri2}'.""",
- arguments: {'name': name, 'uri': uri_, 'uri2': uri2_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeExportOptOutFromOptIn = messageExportOptOutFromOptIn;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4626,33 +4573,6 @@
tip: r"""Try moving the import directives before the part directives.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, Uri uri_, Uri uri2_)>
- templateImportHidesImport =
- const Template<Message Function(String name, Uri uri_, Uri uri2_)>(
- messageTemplate:
- r"""Import of '#name' (from '#uri') hides import from '#uri2'.""",
- withArguments: _withArgumentsImportHidesImport);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, Uri uri_, Uri uri2_)>
- codeImportHidesImport =
- const Code<Message Function(String name, Uri uri_, Uri uri2_)>(
- "ImportHidesImport",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsImportHidesImport(String name, Uri uri_, Uri uri2_) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String? uri = relativizeUri(uri_);
- String? uri2 = relativizeUri(uri2_);
- return new Message(codeImportHidesImport,
- message:
- """Import of '${name}' (from '${uri}') hides import from '${uri2}'.""",
- arguments: {'name': name, 'uri': uri_, 'uri2': uri2_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeIncorrectTypeArgumentVariable =
messageIncorrectTypeArgumentVariable;
@@ -6255,30 +6175,6 @@
message: r"""List literal requires exactly one type argument.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
- Message Function(Uri uri_)> templateLoadLibraryHidesMember = const Template<
- Message Function(Uri uri_)>(
- messageTemplate:
- r"""The library '#uri' defines a top-level member named 'loadLibrary'. This member is hidden by the special member 'loadLibrary' that the language adds to support deferred loading.""",
- tipTemplate: r"""Try to rename or hide the member.""",
- withArguments: _withArgumentsLoadLibraryHidesMember);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(Uri uri_)> codeLoadLibraryHidesMember =
- const Code<Message Function(Uri uri_)>("LoadLibraryHidesMember",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsLoadLibraryHidesMember(Uri uri_) {
- String? uri = relativizeUri(uri_);
- return new Message(codeLoadLibraryHidesMember,
- message:
- """The library '${uri}' defines a top-level member named 'loadLibrary'. This member is hidden by the special member 'loadLibrary' that the language adds to support deferred loading.""",
- tip: """Try to rename or hide the member.""",
- arguments: {'uri': uri_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeLoadLibraryTakesNoArguments =
messageLoadLibraryTakesNoArguments;
@@ -6289,56 +6185,6 @@
message: r"""'loadLibrary' takes no arguments.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, Uri uri_)>
- templateLocalDefinitionHidesExport =
- const Template<Message Function(String name, Uri uri_)>(
- messageTemplate:
- r"""Local definition of '#name' hides export from '#uri'.""",
- withArguments: _withArgumentsLocalDefinitionHidesExport);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, Uri uri_)>
- codeLocalDefinitionHidesExport =
- const Code<Message Function(String name, Uri uri_)>(
- "LocalDefinitionHidesExport",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsLocalDefinitionHidesExport(String name, Uri uri_) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String? uri = relativizeUri(uri_);
- return new Message(codeLocalDefinitionHidesExport,
- message: """Local definition of '${name}' hides export from '${uri}'.""",
- arguments: {'name': name, 'uri': uri_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, Uri uri_)>
- templateLocalDefinitionHidesImport =
- const Template<Message Function(String name, Uri uri_)>(
- messageTemplate:
- r"""Local definition of '#name' hides import from '#uri'.""",
- withArguments: _withArgumentsLocalDefinitionHidesImport);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, Uri uri_)>
- codeLocalDefinitionHidesImport =
- const Code<Message Function(String name, Uri uri_)>(
- "LocalDefinitionHidesImport",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsLocalDefinitionHidesImport(String name, Uri uri_) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String? uri = relativizeUri(uri_);
- return new Message(codeLocalDefinitionHidesImport,
- message: """Local definition of '${name}' hides import from '${uri}'.""",
- arguments: {'name': name, 'uri': uri_});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMainNotFunctionDeclaration =
messageMainNotFunctionDeclaration;
@@ -6510,27 +6356,6 @@
tip: r"""Try inserting 'const'.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(int count)>
- templateMissingExplicitTypeArguments =
- const Template<Message Function(int count)>(
- messageTemplate: r"""No type arguments provided, #count possible.""",
- withArguments: _withArgumentsMissingExplicitTypeArguments);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(int count)> codeMissingExplicitTypeArguments =
- const Code<Message Function(int count)>("MissingExplicitTypeArguments",
- severity: Severity.ignored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsMissingExplicitTypeArguments(int count) {
- // ignore: unnecessary_null_comparison
- if (count == null) throw 'No count provided';
- return new Message(codeMissingExplicitTypeArguments,
- message: """No type arguments provided, ${count} possible.""",
- arguments: {'count': count});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMissingExponent = messageMissingExponent;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 54cd975..95ce3fd 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -474,7 +474,6 @@
FfiCode.MUST_BE_A_NATIVE_FUNCTION_TYPE,
FfiCode.MUST_BE_A_SUBTYPE,
FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
- FfiCode.NON_CONSTANT_TYPE_ARGUMENT_WARNING,
FfiCode.NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER,
FfiCode.NON_SIZED_TYPE_ARGUMENT,
FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS,
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index 1e71193..bfbb9bd 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -185,20 +185,6 @@
/**
* Parameters:
- * 0: the name of the function, method, or constructor having type arguments
- */
- static const FfiCode NON_CONSTANT_TYPE_ARGUMENT_WARNING = FfiCode(
- name: 'NON_CONSTANT_TYPE_ARGUMENT_WARNING',
- message:
- "Support for using non-constant type arguments '{0}' in this FFI API"
- " is deprecated and will be removed in the next stable version of "
- "Dart. Rewrite the code to ensure that type arguments are compile "
- "time constants referring to a valid native type.",
- correction: "Try changing the type argument to be a constant type.",
- type: ErrorType.HINT);
-
- /**
- * Parameters:
* 0: the type that should be a valid dart:ffi native type.
*/
static const FfiCode NON_NATIVE_FUNCTION_TYPE_ARGUMENT_TO_POINTER = FfiCode(
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index bf59990..5f6241e 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -525,9 +525,7 @@
if (!_isValidFfiNativeType(T, allowVoid: true, allowEmptyStruct: true)) {
final AstNode errorNode = node;
_errorReporter.reportErrorForNode(
- FfiCode.NON_CONSTANT_TYPE_ARGUMENT_WARNING,
- errorNode,
- ['elementAt']);
+ FfiCode.NON_CONSTANT_TYPE_ARGUMENT, errorNode, ['elementAt']);
}
}
}
@@ -703,7 +701,7 @@
if (!_isValidFfiNativeType(T, allowVoid: true, allowEmptyStruct: true)) {
final AstNode errorNode = node;
_errorReporter.reportErrorForNode(
- FfiCode.NON_CONSTANT_TYPE_ARGUMENT_WARNING, errorNode, ['sizeOf']);
+ FfiCode.NON_CONSTANT_TYPE_ARGUMENT, errorNode, ['sizeOf']);
}
}
diff --git a/pkg/build_integration/lib/file_system/multi_root.dart b/pkg/build_integration/lib/file_system/multi_root.dart
index b5edb1b..bfaead5 100644
--- a/pkg/build_integration/lib/file_system/multi_root.dart
+++ b/pkg/build_integration/lib/file_system/multi_root.dart
@@ -75,9 +75,17 @@
Future<bool> exists() async => (await delegate).exists();
@override
+ Future<bool> existsAsyncIfPossible() async =>
+ (await delegate).existsAsyncIfPossible();
+
+ @override
Future<List<int>> readAsBytes() async => (await delegate).readAsBytes();
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() async =>
+ (await delegate).readAsBytes();
+
+ @override
Future<String> readAsString() async => (await delegate).readAsString();
}
@@ -91,10 +99,16 @@
Future<bool> exists() => Future.value(false);
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
Future<List<int>> readAsBytes() =>
Future.error(FileSystemException(uri, 'File not found'));
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() =>
Future.error(FileSystemException(uri, 'File not found'));
}
diff --git a/pkg/build_integration/lib/file_system/single_root.dart b/pkg/build_integration/lib/file_system/single_root.dart
index 03c73df..30cbc66 100644
--- a/pkg/build_integration/lib/file_system/single_root.dart
+++ b/pkg/build_integration/lib/file_system/single_root.dart
@@ -62,9 +62,17 @@
Future<bool> exists() async => delegate.exists();
@override
+ Future<bool> existsAsyncIfPossible() async =>
+ delegate.existsAsyncIfPossible();
+
+ @override
Future<List<int>> readAsBytes() async => delegate.readAsBytes();
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() async =>
+ delegate.readAsBytesAsyncIfPossible();
+
+ @override
Future<String> readAsString() async => delegate.readAsString();
}
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 25796fa..5076088 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -69,6 +69,9 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<bool> exists() async {
try {
api.Input input = await fs.inputProvider
@@ -78,6 +81,9 @@
return false;
}
}
+
+ @override
+ Future<bool> existsAsyncIfPossible() => exists();
}
/// Report a [message] received from the front-end, using dart2js's
diff --git a/pkg/front_end/lib/src/api_prototype/file_system.dart b/pkg/front_end/lib/src/api_prototype/file_system.dart
index 82b511a..e4195c5 100644
--- a/pkg/front_end/lib/src/api_prototype/file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/file_system.dart
@@ -38,17 +38,50 @@
Uri get uri;
/// Whether this file system entity exists.
+ ///
+ /// This method cannot be assumed to do any async work, in fact, if possible
+ /// it should perform the check sync as that might be faster depending on the
+ /// caller. If wanting to check async - for instance if trying to physically
+ /// check for existence and read in parallel - use [existsAsyncIfPossible]
+ /// instead.
Future<bool> exists();
+ /// Whether this file system entity exists.
+ ///
+ /// This method cannot be assumed to do any async work, but should - if
+ /// possible - in fact do async work as that might be faster depending on the
+ /// caller - for instance if trying to physically check for existence (and
+ /// read) in parallel.
+ /// For sequential checks one should use [exists] instead.
+ Future<bool> existsAsyncIfPossible();
+
/// Attempts to access this file system entity as a file and read its contents
/// as raw bytes.
///
+ /// This method cannot be assumed to do any async work, in fact, if possible
+ /// it should the read sync as that might be faster depending on the caller.
+ /// If wanting to read async - for instance if trying to physically read in
+ /// parallel - use [readAsBytesAsyncIfPossible] instead.
+ ///
/// If an error occurs while attempting to read the file (e.g. because no such
/// file exists, or the entity is a directory), the future is completed with
/// [FileSystemException].
Future<List<int>> readAsBytes();
/// Attempts to access this file system entity as a file and read its contents
+ /// as raw bytes.
+ ///
+ /// This method cannot be assumed to do any async work, but should - if
+ /// possible - in fact do async work as that might be faster depending on the
+ /// caller - for instance if trying to physically read in parallel.
+ /// For sequential reads one should use [readAsBytes] instead.
+ ///
+ /// If an error occurs while attempting to read the file (e.g. because no such
+ /// file exists, or the entity is a directory), the future is completed with
+ /// [FileSystemException].
+ Future<List<int>> readAsBytesAsyncIfPossible();
+
+ /// Attempts to access this file system entity as a file and read its contents
/// as a string.
///
/// The file is assumed to be UTF-8 encoded.
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index 194393b..01aa2e6 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -86,6 +86,9 @@
}
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
Future<List<int>> readAsBytes() async {
Uint8List? contents = _fileSystem._files[uri];
if (contents == null) {
@@ -95,6 +98,9 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() async {
List<int> bytes = await readAsBytes();
try {
diff --git a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
index bc1a4bc..35d34d5 100644
--- a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
@@ -25,7 +25,9 @@
@override
FileSystemEntity entityForUri(Uri uri) {
- if (uri.scheme == 'file' || uri.scheme == '') {
+ if (uri.scheme == 'file') {
+ return new _IoFileSystemEntity(uri);
+ } else if (uri.scheme == '') {
// TODO(askesc): Empty schemes should have been handled elsewhere.
return new _IoFileSystemEntity(Uri.base.resolveUri(uri));
} else if (uri.scheme == 'data') {
@@ -53,11 +55,26 @@
@override
Future<bool> exists() async {
+ if (new io.File.fromUri(uri).existsSync()) {
+ return true;
+ }
+ if (io.FileSystemEntity.isDirectorySync(uri.toFilePath())) {
+ return true;
+ }
+ // TODO(CFE-team): What about [Link]s?
+ return false;
+ }
+
+ @override
+ Future<bool> existsAsyncIfPossible() async {
+ if (await new io.File.fromUri(uri).exists()) {
+ return true;
+ }
if (await io.FileSystemEntity.isDirectory(uri.toFilePath())) {
return true;
- } else {
- return new io.File.fromUri(uri).exists();
}
+ // TODO(CFE-team): What about [Link]s?
+ return false;
}
@override
@@ -71,6 +88,16 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() async {
+ try {
+ CompilerContext.recordDependency(uri);
+ return await new io.File.fromUri(uri).readAsBytes();
+ } on io.FileSystemException catch (exception) {
+ throw _toFileSystemException(exception);
+ }
+ }
+
+ @override
Future<String> readAsString() async {
try {
CompilerContext.recordDependency(uri);
@@ -118,6 +145,12 @@
}
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() async {
return uri.data.contentAsString();
}
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 78acbcf..33b9faa 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -62,7 +62,6 @@
templateFfiFieldCyclic,
templateFfiFieldInitializer,
templateFfiFieldNoAnnotation,
- templateFfiNonConstantTypeArgumentWarning,
templateFfiNotStatic,
templateFfiStructGeneric,
templateFfiTypeInvalid,
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 1618af1..0678910 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -21,7 +21,6 @@
messageTypedefCause,
noLength,
templateExtendingRestricted,
- templateMissingExplicitTypeArguments,
templateNotAType,
templateSupertypeIsIllegal,
templateSupertypeIsTypeVariable,
@@ -142,23 +141,6 @@
} else if (member is TypeDeclarationBuilder) {
declaration = member.origin;
if (!declaration.isExtension) {
- if (arguments == null && declaration.typeVariablesCount != 0) {
- String typeName;
- int typeNameOffset;
- if (name is Identifier) {
- typeName = name.name;
- typeNameOffset = name.charOffset;
- } else {
- typeName = name;
- typeNameOffset = charOffset;
- }
- library.addProblem(
- templateMissingExplicitTypeArguments
- .withArguments(declaration.typeVariablesCount),
- typeNameOffset,
- typeName.length,
- fileUri);
- }
return;
}
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
index 0d94cfb..a145ee7 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
@@ -916,35 +916,6 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
- templateFfiNonConstantTypeArgumentWarning = const Template<
- Message Function(DartType _type, bool isNonNullableByDefault)>(
- messageTemplate:
- r"""Support for using non-constant type arguments '#type' in this FFI API is deprecated and will be removed in the next stable version of Dart. Rewrite the code to ensure that type arguments are compile time constants referring to a valid native type.""",
- withArguments: _withArgumentsFfiNonConstantTypeArgumentWarning);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(DartType _type, bool isNonNullableByDefault)>
- codeFfiNonConstantTypeArgumentWarning =
- const Code<Message Function(DartType _type, bool isNonNullableByDefault)>(
- "FfiNonConstantTypeArgumentWarning",
- analyzerCodes: <String>["NON_CONSTANT_TYPE_ARGUMENT_WARNING"],
- severity: Severity.info);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFfiNonConstantTypeArgumentWarning(
- DartType _type, bool isNonNullableByDefault) {
- TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
- List<Object> typeParts = labeler.labelType(_type);
- String type = typeParts.join();
- return new Message(codeFfiNonConstantTypeArgumentWarning,
- message:
- """Support for using non-constant type arguments '${type}' in this FFI API is deprecated and will be removed in the next stable version of Dart. Rewrite the code to ensure that type arguments are compile time constants referring to a valid native type.""" +
- labeler.originMessages,
- arguments: {'type': _type});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
DartType _type,
diff --git a/pkg/front_end/lib/src/fasta/hybrid_file_system.dart b/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
index 9f1a08b..10b1a47 100644
--- a/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
+++ b/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
@@ -51,8 +51,16 @@
Future<bool> exists() async => (await delegate).exists();
@override
+ Future<bool> existsAsyncIfPossible() async =>
+ (await delegate).existsAsyncIfPossible();
+
+ @override
Future<List<int>> readAsBytes() async => (await delegate).readAsBytes();
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() async =>
+ (await delegate).readAsBytesAsyncIfPossible();
+
+ @override
Future<String> readAsString() async => (await delegate).readAsString();
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 353fd1db..c407429 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -2995,12 +2995,6 @@
// as a recovery node once the IR can represent it (Issue #29840).
arguments = null;
}
- } else if (declaration.typeVariablesCount != 0) {
- _helper.addProblem(
- templateMissingExplicitTypeArguments
- .withArguments(declaration.typeVariablesCount),
- fileOffset,
- lengthForToken(token));
}
List<TypeBuilder> argumentBuilders;
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index a68f32c..b973591 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -2707,54 +2707,25 @@
AccessErrorBuilder error = other;
other = error.builder;
}
- bool isLocal = false;
- bool isLoadLibrary = false;
Builder preferred;
Uri uri;
Uri otherUri;
- Uri preferredUri;
- Uri hiddenUri;
if (scope.lookupLocalMember(name, setter: false) == declaration) {
- isLocal = true;
preferred = declaration;
- hiddenUri = computeLibraryUri(other);
} else {
uri = computeLibraryUri(declaration);
otherUri = computeLibraryUri(other);
if (declaration is LoadLibraryBuilder) {
- isLoadLibrary = true;
preferred = declaration;
- preferredUri = otherUri;
} else if (other is LoadLibraryBuilder) {
- isLoadLibrary = true;
preferred = other;
- preferredUri = uri;
} else if (otherUri?.scheme == "dart" && uri?.scheme != "dart") {
preferred = declaration;
- preferredUri = uri;
- hiddenUri = otherUri;
} else if (uri?.scheme == "dart" && otherUri?.scheme != "dart") {
preferred = other;
- preferredUri = otherUri;
- hiddenUri = uri;
}
}
if (preferred != null) {
- if (isLocal) {
- Template<Message Function(String name, Uri uri)> template = isExport
- ? templateLocalDefinitionHidesExport
- : templateLocalDefinitionHidesImport;
- addProblem(template.withArguments(name, hiddenUri), charOffset,
- noLength, fileUri);
- } else if (isLoadLibrary) {
- addProblem(templateLoadLibraryHidesMember.withArguments(preferredUri),
- charOffset, noLength, fileUri);
- } else {
- Template<Message Function(String name, Uri uri, Uri uri2)> template =
- isExport ? templateExportHidesExport : templateImportHidesImport;
- addProblem(template.withArguments(name, preferredUri, hiddenUri),
- charOffset, noLength, fileUri);
- }
return preferred;
}
if (declaration.next == null && other.next == null) {
@@ -2770,15 +2741,17 @@
});
}
}
- Template<Message Function(String name, Uri uri, Uri uri2)> template =
- isExport ? templateDuplicatedExport : templateDuplicatedImport;
- Message message = template.withArguments(name, uri, otherUri);
- addProblem(message, charOffset, noLength, fileUri);
+ if (isExport) {
+ Template<Message Function(String name, Uri uri, Uri uri2)> template =
+ templateDuplicatedExport;
+ Message message = template.withArguments(name, uri, otherUri);
+ addProblem(message, charOffset, noLength, fileUri);
+ }
Template<Message Function(String name, Uri uri, Uri uri2)> builderTemplate =
isExport
? templateDuplicatedExportInType
: templateDuplicatedImportInType;
- message = builderTemplate.withArguments(
+ Message message = builderTemplate.withArguments(
name,
// TODO(ahe): We should probably use a context object here
// instead of including URIs in this message.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 2ec9981..5a98676 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1677,11 +1677,6 @@
template: "'loadLibrary' takes no arguments."
analyzerCode: LOAD_LIBRARY_TAKES_NO_ARGUMENTS
-LoadLibraryHidesMember:
- template: "The library '#uri' defines a top-level member named 'loadLibrary'. This member is hidden by the special member 'loadLibrary' that the language adds to support deferred loading."
- tip: "Try to rename or hide the member."
- severity: IGNORED
-
TypeArgumentMismatch:
template: "Expected #count type arguments."
analyzerCode: WRONG_NUMBER_OF_TYPE_ARGUMENTS
@@ -1925,26 +1920,10 @@
IncrementalCompilerIllegalTypeParameter:
template: "Illegal type parameter name '#string' found during expression compilation."
-LocalDefinitionHidesExport:
- template: "Local definition of '#name' hides export from '#uri'."
- severity: IGNORED
-
-LocalDefinitionHidesImport:
- template: "Local definition of '#name' hides import from '#uri'."
- severity: IGNORED
-
DebugTrace:
template: "Fatal '#name' at:\n#string"
severity: IGNORED
-ExportHidesExport:
- template: "Export of '#name' (from '#uri') hides export from '#uri2'."
- severity: IGNORED
-
-ImportHidesImport:
- template: "Import of '#name' (from '#uri') hides import from '#uri2'."
- severity: IGNORED
-
MissingPrefixInDeferredImport:
index: 30
template: "Deferred imports should have a prefix."
@@ -1991,10 +1970,6 @@
DuplicatedExportInType:
template: "'#name' is exported from both '#uri' and '#uri2'."
-DuplicatedImport:
- template: "'#name' is imported from both '#uri' and '#uri2'."
- severity: IGNORED
-
DuplicatedImportInType:
template: "'#name' is imported from both '#uri' and '#uri2'."
analyzerCode: AMBIGUOUS_IMPORT
@@ -3777,10 +3752,6 @@
frontendInternal: true
external: test/incremental_load_from_invalid_dill_test.dart
-MissingExplicitTypeArguments:
- template: "No type arguments provided, #count possible."
- severity: IGNORED
-
WebLiteralCannotBeRepresentedExactly:
template: "The integer literal #string can't be represented exactly in JavaScript."
tip: "Try changing the literal to something that can be represented in Javascript. In Javascript #string2 is the nearest value that can be represented exactly."
@@ -4271,13 +4242,6 @@
#names
external: test/ffi_test.dart
-FfiNonConstantTypeArgumentWarning:
- # Used by dart:ffi
- template: "Support for using non-constant type arguments '#type' in this FFI API is deprecated and will be removed in the next stable version of Dart. Rewrite the code to ensure that type arguments are compile time constants referring to a valid native type."
- analyzerCode: NON_CONSTANT_TYPE_ARGUMENT_WARNING
- severity: INFO
- external: test/ffi_test.dart
-
FfiNotStatic:
# Used by dart:ffi
template: "#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code."
diff --git a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
index be6565f..1d3264e 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
@@ -2159,6 +2159,9 @@
}
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
Future<List<int>> readAsBytes() {
_ensureCachedIfOk();
Uint8List data = fs.data[uri];
@@ -2167,6 +2170,9 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() {
_ensureCachedIfOk();
Uint8List data = fs.data[uri];
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 6743621..9a03fcc 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1611,6 +1611,9 @@
}
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
Future<List<int>> readAsBytes() async {
await _ensureCachedIfOk();
Uint8List data = fs.data[uri];
@@ -1619,6 +1622,9 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() async {
await _ensureCachedIfOk();
Uint8List data = fs.data[uri];
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index d977b3a..3858ee0 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -388,6 +388,7 @@
estimate
eval
exhausted
+existence
existentially
exp
expando
@@ -845,6 +846,7 @@
perf
permanently
permit
+physically
pi
picking
pkg
@@ -1033,6 +1035,7 @@
semver
separators
sequencing
+sequential
serializables
serializer
serializers
@@ -1340,6 +1343,7 @@
vtab
w
waiting
+wanting
waste
wasted
watch
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index 50c922c..cb00f51 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -249,9 +249,17 @@
Future<bool> exists() async => (await delegate).exists();
@override
+ Future<bool> existsAsyncIfPossible() async =>
+ (await delegate).existsAsyncIfPossible();
+
+ @override
Future<List<int>> readAsBytes() async => (await delegate).readAsBytes();
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() async =>
+ (await delegate).readAsBytesAsyncIfPossible();
+
+ @override
Future<String> readAsString() async => (await delegate).readAsString();
void writeAsStringSync(String contents) =>
diff --git a/pkg/vm/lib/http_filesystem.dart b/pkg/vm/lib/http_filesystem.dart
index bae57bf..6d249e3 100644
--- a/pkg/vm/lib/http_filesystem.dart
+++ b/pkg/vm/lib/http_filesystem.dart
@@ -34,6 +34,9 @@
}
@override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
Future<List<int>> readAsBytes() async {
return connectAndRun((io.HttpClient httpClient) async {
io.HttpClientRequest request = await httpClient.getUrl(uri);
@@ -47,6 +50,9 @@
}
@override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
Future<String> readAsString() async {
return String.fromCharCodes(await readAsBytes());
}
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index c03f4b4..154a575 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -13,7 +13,6 @@
templateFfiExpectedExceptionalReturn,
templateFfiExpectedNoExceptionalReturn,
templateFfiExtendsOrImplementsSealedClass,
- templateFfiNonConstantTypeArgumentWarning,
templateFfiNotStatic,
templateFfiTypeInvalid,
templateFfiTypeMismatch;
@@ -189,7 +188,7 @@
// TODO(http://dartbug.com/38721): Change this to an error after
// package:ffi is no longer using sizeOf generically.
if (!isFfiLibrary) {
- _warningNativeTypeValid(nativeType, node);
+ _ensureNativeTypeValid(nativeType, node);
}
if (nativeType is InterfaceType) {
@@ -467,13 +466,7 @@
node.receiver.getStaticType(_staticTypeContext);
final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
- _warningNativeTypeValid(nativeType, node);
-
- // TODO(http://dartbug.com/38721): Change this to an error.
- if (nativeType is TypeParameterType) {
- // Do not rewire generic invocations.
- return node;
- }
+ _ensureNativeTypeValid(nativeType, node);
Expression inlineSizeOf = _inlineSizeOf(nativeType);
if (inlineSizeOf != null) {
@@ -541,22 +534,6 @@
}
}
- void _warningNativeTypeValid(DartType nativeType, Expression node,
- {bool allowHandle: false, bool allowStructItself = true}) {
- if (!_nativeTypeValid(nativeType,
- allowStructs: true,
- allowStructItself: allowStructItself,
- allowHandle: allowHandle)) {
- diagnosticReporter.report(
- templateFfiNonConstantTypeArgumentWarning.withArguments(
- nativeType, currentLibrary.isNonNullableByDefault),
- node.fileOffset,
- 1,
- node.location.file);
- throw _FfiStaticTypeError();
- }
- }
-
void _ensureNoEmptyStructs(DartType nativeType, Expression node) {
// Error on structs with no fields.
if (nativeType is InterfaceType) {
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 0724681..7b1ad66 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -11,7 +11,6 @@
#include "vm/bootstrap_natives.h"
#include "vm/class_finalizer.h"
#include "vm/class_id.h"
-#include "vm/compiler/ffi/native_type.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/log.h"
@@ -30,45 +29,6 @@
namespace dart {
-// The following functions are runtime checks on type arguments.
-// Some checks are also performed in kernel transformation, these are asserts.
-// Some checks are only performed at runtime to allow for generic code, these
-// throw ArgumentExceptions.
-
-static void CheckSized(const AbstractType& type_arg) {
- const classid_t type_cid = type_arg.type_class_id();
- if (IsFfiNativeTypeTypeClassId(type_cid) || IsFfiTypeVoidClassId(type_cid) ||
- IsFfiTypeNativeFunctionClassId(type_cid)) {
- const String& error = String::Handle(String::NewFormatted(
- "%s does not have a predefined size (@unsized). "
- "Unsized NativeTypes do not support [sizeOf] because their size "
- "is unknown. "
- "Consequently, [allocate], [Pointer.load], [Pointer.store], and "
- "[Pointer.elementAt] are not available.",
- String::Handle(type_arg.UserVisibleName()).ToCString()));
- Exceptions::ThrowArgumentError(error);
- }
-}
-
-// Calculate the size of a native type.
-//
-// You must check [IsConcreteNativeType] and [CheckSized] first to verify that
-// this type has a defined size.
-static size_t SizeOf(Zone* zone, const AbstractType& type) {
- if (IsFfiTypeClassId(type.type_class_id())) {
- return compiler::ffi::NativeType::FromAbstractType(zone, type)
- .SizeInBytes();
- } else {
- Class& struct_class = Class::Handle(type.type_class());
- Object& result = Object::Handle(
- struct_class.InvokeGetter(Symbols::SizeOfStructField(),
- /*throw_nsm_if_absent=*/false,
- /*respect_reflectable=*/false));
- ASSERT(!result.IsNull() && result.IsInteger());
- return Integer::Cast(result).AsInt64Value();
- }
-}
-
// The remainder of this file implements the dart:ffi native methods.
DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
@@ -101,13 +61,6 @@
UNREACHABLE();
}
-DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) {
- GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- CheckSized(type_arg);
-
- return Integer::New(SizeOf(zone, type_arg));
-}
-
// Static invocations to this method are translated directly in streaming FGB.
DEFINE_NATIVE_ENTRY(Ffi_asFunctionInternal, 2, 1) {
UNREACHABLE();
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 000452a..db34630 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -405,7 +405,6 @@
V(Ffi_storePointer, 3) \
V(Ffi_address, 1) \
V(Ffi_fromAddress, 1) \
- V(Ffi_sizeOf, 0) \
V(Ffi_asFunctionInternal, 1) \
V(Ffi_nativeCallbackFunction, 2) \
V(Ffi_pointerFromFunction, 1) \
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index 1496c09..edfa863 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -107,6 +107,8 @@
"ffi/native_calling_convention.h",
"ffi/native_location.cc",
"ffi/native_location.h",
+ "ffi/native_type.cc",
+ "ffi/native_type.h",
"ffi/recognized_method.cc",
"ffi/recognized_method.h",
"frontend/base_flow_graph_builder.cc",
@@ -189,8 +191,6 @@
"api/print_filter.cc",
"api/print_filter.h",
"api/type_check_mode.h",
- "ffi/native_type.cc",
- "ffi/native_type.h",
"jit/compiler.cc",
"jit/compiler.h",
"runtime_api.cc",
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 734e76e..f730542 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -222,7 +222,7 @@
heap_(isolate_group()->heap()),
old_space_(heap_->old_space()),
writable_(writable) {
- isolate()->safepoint_handler()->SafepointThreads(thread);
+ isolate_group()->safepoint_handler()->SafepointThreads(thread);
{
// It's not safe to iterate over old space when concurrent marking or
@@ -273,7 +273,7 @@
ml.NotifyAll();
}
- isolate()->safepoint_handler()->ResumeThreads(thread());
+ isolate_group()->safepoint_handler()->ResumeThreads(thread());
}
void HeapIterationScope::IterateObjects(ObjectVisitor* visitor) const {
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d5603cc..97dab6c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2866,19 +2866,19 @@
/*at_safepoint=*/true);
}
-ClassPtr Isolate::GetClassForHeapWalkAt(intptr_t cid) {
+ClassPtr IsolateGroup::GetClassForHeapWalkAt(intptr_t cid) {
ClassPtr raw_class = nullptr;
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- if (group()->IsReloading()) {
- raw_class = group()->program_reload_context()->GetClassForHeapWalkAt(cid);
+ if (IsReloading()) {
+ raw_class = program_reload_context()->GetClassForHeapWalkAt(cid);
} else {
- raw_class = group()->class_table()->At(cid);
+ raw_class = class_table()->At(cid);
}
#else
- raw_class = group()->class_table()->At(cid);
+ raw_class = class_table()->At(cid);
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(raw_class != nullptr);
- ASSERT(group()->remapping_cids() || raw_class->untag()->id_ == cid);
+ ASSERT(remapping_cids() || raw_class->untag()->id_ == cid);
return raw_class;
}
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 65c9a17..aa8575f 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -713,6 +713,9 @@
bool CanReload() { return false; }
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ // Prefers old classes when we are in the middle of a reload.
+ ClassPtr GetClassForHeapWalkAt(intptr_t cid);
+
bool IsReloading() const {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
return group_reload_context_ != nullptr;
@@ -1026,9 +1029,6 @@
return isolate_object_store_.get();
}
- // Prefers old classes when we are in the middle of a reload.
- ClassPtr GetClassForHeapWalkAt(intptr_t cid);
-
static intptr_t ic_miss_code_offset() {
return OFFSET_OF(Isolate, ic_miss_code_);
}
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index c117abf..dcc42cc 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -59,7 +59,6 @@
DECLARE_FLAG(bool, trace_deoptimization);
-#define I (isolate())
#define IG (isolate_group())
#define Z zone_
@@ -485,26 +484,22 @@
}
void IsolateGroupReloadContext::ReportError(const Error& error) {
- // TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
- // call to accept an isolate group instead of an isolate.
- Isolate* isolate = Isolate::Current();
- if (Isolate::IsSystemIsolate(isolate)) {
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ if (IsolateGroup::IsSystemIsolateGroup(isolate_group)) {
return;
}
TIR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
- ServiceEvent service_event(isolate, ServiceEvent::kIsolateReload);
+ ServiceEvent service_event(isolate_group, ServiceEvent::kIsolateReload);
service_event.set_reload_error(&error);
Service::HandleEvent(&service_event);
}
void IsolateGroupReloadContext::ReportSuccess() {
- // TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
- // call to accept an isolate group instead of an isolate.
- Isolate* isolate = Isolate::Current();
- if (Isolate::IsSystemIsolate(isolate)) {
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ if (IsolateGroup::IsSystemIsolateGroup(isolate_group)) {
return;
}
- ServiceEvent service_event(isolate, ServiceEvent::kIsolateReload);
+ ServiceEvent service_event(isolate_group, ServiceEvent::kIsolateReload);
Service::HandleEvent(&service_event);
}
@@ -616,9 +611,11 @@
kernel_program = kernel::Program::ReadFromTypedData(typed_data);
}
+ NoActiveIsolateScope no_active_isolate_scope;
+
ExternalTypedData& external_typed_data =
ExternalTypedData::Handle(Z, kernel_program.get()->typed_data()->ptr());
- IsolateGroupSource* source = Isolate::Current()->source();
+ IsolateGroupSource* source = IsolateGroup::Current()->source();
source->add_loaded_blob(Z, external_typed_data);
modified_libs_ = new (Z) BitVector(Z, num_old_libs_);
@@ -2124,10 +2121,13 @@
if (field.needs_load_guard()) {
continue; // Already guarding.
}
- value_ = field.StaticValue();
- if (value_.ptr() != Object::sentinel().ptr()) {
- CheckValueType(null_safety, value_, field);
- }
+ const intptr_t field_id = field.field_id();
+ thread->isolate_group()->ForEachIsolate([&](Isolate* isolate) {
+ value_ = isolate->field_table()->At(field_id);
+ if (value_.ptr() != Object::sentinel().ptr()) {
+ CheckValueType(null_safety, value_, field);
+ }
+ });
}
}
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index cb04006..30e6ef8 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -86,4 +86,120 @@
}
}
+#if defined(DEBUG)
+bool SafepointRwLock::IsCurrentThreadReader() {
+ ThreadId id = OSThread::GetCurrentThreadId();
+ if (IsCurrentThreadWriter()) {
+ return true;
+ }
+ MonitorLocker ml(&monitor_);
+ for (intptr_t i = readers_ids_.length() - 1; i >= 0; i--) {
+ if (readers_ids_.At(i) == id) {
+ return true;
+ }
+ }
+ return false;
+}
+#endif // defined(DEBUG)
+
+bool SafepointRwLock::EnterRead() {
+ // No need to safepoint if the current thread is not attached.
+ auto thread = Thread::Current();
+ const bool can_block_without_safepoint = thread == nullptr;
+
+ bool acquired_read_lock = false;
+ if (!TryEnterRead(can_block_without_safepoint, &acquired_read_lock)) {
+ // Important: must never hold monitor_ when blocking for safepoint.
+ TransitionVMToBlocked transition(thread);
+ const bool ok = TryEnterRead(/*can_block=*/true, &acquired_read_lock);
+ RELEASE_ASSERT(ok);
+ RELEASE_ASSERT(acquired_read_lock);
+ }
+ return acquired_read_lock;
+}
+
+bool SafepointRwLock::TryEnterRead(bool can_block, bool* acquired_read_lock) {
+ MonitorLocker ml(&monitor_);
+ if (IsCurrentThreadWriter()) {
+ *acquired_read_lock = false;
+ return true;
+ }
+ if (can_block) {
+ while (state_ < 0) {
+ ml.Wait();
+ }
+ }
+ if (state_ >= 0) {
+ ++state_;
+ DEBUG_ONLY(readers_ids_.Add(OSThread::GetCurrentThreadId()));
+ *acquired_read_lock = true;
+ return true;
+ }
+ return false;
+}
+
+void SafepointRwLock::LeaveRead() {
+ MonitorLocker ml(&monitor_);
+ ASSERT(state_ > 0);
+#if defined(DEBUG)
+ {
+ intptr_t i = readers_ids_.length() - 1;
+ ThreadId id = OSThread::GetCurrentThreadId();
+ while (i >= 0) {
+ if (readers_ids_.At(i) == id) {
+ readers_ids_.RemoveAt(i);
+ break;
+ }
+ i--;
+ }
+ ASSERT(i >= 0);
+ }
+#endif
+ if (--state_ == 0) {
+ ml.NotifyAll();
+ }
+}
+
+void SafepointRwLock::EnterWrite() {
+ // No need to safepoint if the current thread is not attached.
+ auto thread = Thread::Current();
+ const bool can_block_without_safepoint = thread == nullptr;
+
+ if (!TryEnterWrite(can_block_without_safepoint)) {
+ // Important: must never hold monitor_ when blocking for safepoint.
+ TransitionVMToBlocked transition(thread);
+ const bool ok = TryEnterWrite(/*can_block=*/true);
+ RELEASE_ASSERT(ok);
+ }
+}
+
+bool SafepointRwLock::TryEnterWrite(bool can_block) {
+ MonitorLocker ml(&monitor_);
+ if (IsCurrentThreadWriter()) {
+ state_--;
+ return true;
+ }
+ if (can_block) {
+ while (state_ != 0) {
+ ml.Wait();
+ }
+ }
+ if (state_ == 0) {
+ writer_id_ = OSThread::GetCurrentThreadId();
+ state_ = -1;
+ return true;
+ }
+ return false;
+}
+
+void SafepointRwLock::LeaveWrite() {
+ MonitorLocker ml(&monitor_);
+ ASSERT(state_ < 0);
+ if (++state_ < 0) {
+ return;
+ }
+ writer_id_ = OSThread::kInvalidThreadId;
+ ml.NotifyAll();
+}
+
} // namespace dart
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index d5b2576..7213808 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -322,21 +322,7 @@
SafepointRwLock() {}
~SafepointRwLock() {}
-#if defined(DEBUG)
- bool IsCurrentThreadReader() {
- ThreadId id = OSThread::GetCurrentThreadId();
- if (IsCurrentThreadWriter()) {
- return true;
- }
- MutexLocker ml(&reader_ids_mutex_);
- for (intptr_t i = readers_ids_.length() - 1; i >= 0; i--) {
- if (readers_ids_.At(i) == id) {
- return true;
- }
- }
- return false;
- }
-#endif // defined(DEBUG)
+ DEBUG_ONLY(bool IsCurrentThreadReader());
bool IsCurrentThreadWriter() {
return writer_id_ == OSThread::GetCurrentThreadId();
@@ -346,82 +332,33 @@
friend class SafepointReadRwLocker;
friend class SafepointWriteRwLocker;
- // returns [true] if read lock was acuired,
+ // returns [true] if read lock was acquired,
// returns [false] if the thread didn't have to acquire read lock due
// to the thread already holding write lock
- bool EnterRead() {
- SafepointMonitorLocker ml(&monitor_);
- if (IsCurrentThreadWriter()) {
- return false;
- }
- while (state_ < 0) {
- ml.Wait();
- }
-#if defined(DEBUG)
- {
- MutexLocker ml(&reader_ids_mutex_);
- readers_ids_.Add(OSThread::GetCurrentThreadId());
- }
-#endif
- ++state_;
- return true;
- }
- void LeaveRead() {
- SafepointMonitorLocker ml(&monitor_);
- ASSERT(state_ > 0);
-#if defined(DEBUG)
- {
- MutexLocker ml(&reader_ids_mutex_);
- intptr_t i = readers_ids_.length() - 1;
- ThreadId id = OSThread::GetCurrentThreadId();
- while (i >= 0) {
- if (readers_ids_.At(i) == id) {
- readers_ids_.RemoveAt(i);
- break;
- }
- i--;
- }
- ASSERT(i >= 0);
- }
-#endif
- if (--state_ == 0) {
- ml.NotifyAll();
- }
- }
+ bool EnterRead();
+ bool TryEnterRead(bool can_block, bool* acquired_read_lock);
+ void LeaveRead();
- void EnterWrite() {
- SafepointMonitorLocker ml(&monitor_);
- if (IsCurrentThreadWriter()) {
- state_--;
- return;
- }
- while (state_ != 0) {
- ml.Wait();
- }
- writer_id_ = OSThread::GetCurrentThreadId();
- state_ = -1;
- }
- void LeaveWrite() {
- SafepointMonitorLocker ml(&monitor_);
- ASSERT(state_ < 0);
- state_++;
- if (state_ < 0) {
- return;
- }
- writer_id_ = OSThread::kInvalidThreadId;
- ml.NotifyAll();
- }
+ void EnterWrite();
+ bool TryEnterWrite(bool can_block);
+ void LeaveWrite();
+ // We maintain an invariant that this monitor is never locked for long periods
+ // of time: Any thread that acquired this monitor must always be able to do
+ // it's work and release it (or wait on the monitor which will also release
+ // it).
+ //
+ // In particular we must ensure the monitor is never held and then a potential
+ // safepoint operation is triggered, since another thread could try to acquire
+ // the lock and it would deadlock.
Monitor monitor_;
+
// [state_] > 0 : The lock is held by multiple readers.
// [state_] == 0 : The lock is free (no readers/writers).
// [state_] < 0 : The lock is held by a single writer (possibly nested).
intptr_t state_ = 0;
-#if defined(DEBUG)
- Mutex reader_ids_mutex_;
- MallocGrowableArray<ThreadId> readers_ids_;
-#endif
+ DEBUG_ONLY(MallocGrowableArray<ThreadId> readers_ids_);
ThreadId writer_id_ = OSThread::kInvalidThreadId;
};
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ef11697..1186974 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3254,7 +3254,6 @@
ClassPtr Class::SuperClass(bool original_classes) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
- auto isolate = thread->isolate();
auto isolate_group = thread->isolate_group();
if (super_type() == AbstractType::null()) {
if (id() == kTypeArgumentsCid) {
@@ -3266,7 +3265,7 @@
const AbstractType& sup_type = AbstractType::Handle(zone, super_type());
const intptr_t type_class_id = sup_type.type_class_id();
if (original_classes) {
- return isolate->GetClassForHeapWalkAt(type_class_id);
+ return isolate_group->GetClassForHeapWalkAt(type_class_id);
} else {
return isolate_group->class_table()->At(type_class_id);
}
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index aae4940..8fc322a 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -876,7 +876,7 @@
: ObjectVisitor(),
ObjectPointerVisitor(IsolateGroup::Current()),
HandleVisitor(Thread::Current()),
- isolate_(thread()->isolate()),
+ isolate_group_(thread()->isolate_group()),
writer_(writer) {}
virtual bool trace_values_through_fields() const { return true; }
@@ -989,9 +989,9 @@
}
DoCount();
- obj->untag()->VisitPointersPrecise(isolate_, this);
+ obj->untag()->VisitPointersPrecise(isolate_group_, this);
DoWrite();
- obj->untag()->VisitPointersPrecise(isolate_, this);
+ obj->untag()->VisitPointersPrecise(isolate_group_, this);
}
void ScrubAndWriteUtf8(StringPtr str) {
@@ -1069,10 +1069,7 @@
}
private:
- // TODO(dartbug.com/36097): Once the shared class table contains more
- // information than just the size (i.e. includes an immutable class
- // descriptor), we can remove this dependency on the current isolate.
- Isolate* isolate_;
+ IsolateGroup* isolate_group_;
HeapSnapshotWriter* const writer_;
bool writing_ = false;
intptr_t counted_ = 0;
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 675836c1..edd66f5 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -377,6 +377,7 @@
friend class MonitorLocker;
friend class SafepointMonitorLocker;
+ friend class SafepointRwLock;
friend void Dart_TestMonitor();
DISALLOW_COPY_AND_ASSIGN(Monitor);
};
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 6bd76cd..cfe671e 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -377,7 +377,7 @@
#endif
}
-void UntaggedObject::VisitPointersPrecise(Isolate* isolate,
+void UntaggedObject::VisitPointersPrecise(IsolateGroup* isolate_group,
ObjectPointerVisitor* visitor) {
intptr_t class_id = GetClassId();
if (class_id < kNumPredefinedCids) {
@@ -386,7 +386,7 @@
}
// N.B.: Not using the heap size!
- uword next_field_offset = isolate->GetClassForHeapWalkAt(class_id)
+ uword next_field_offset = isolate_group->GetClassForHeapWalkAt(class_id)
->untag()
->host_next_field_offset_in_words_
<< kWordSizeLog2;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 6b6cf9a..1ac32d0 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -498,7 +498,8 @@
// This variant ensures that we do not visit the extra slot created from
// rounding up instance sizes up to the allocation unit.
- void VisitPointersPrecise(Isolate* isolate, ObjectPointerVisitor* visitor);
+ void VisitPointersPrecise(IsolateGroup* isolate_group,
+ ObjectPointerVisitor* visitor);
static ObjectPtr FromAddr(uword addr) {
// We expect the untagged address here.
@@ -900,7 +901,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
friend class Instance;
- friend class Isolate;
+ friend class IsolateGroup;
friend class Object;
friend class UntaggedInstance;
friend class UntaggedInstructions;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 7d41f1a..b026035 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3757,7 +3757,7 @@
// Notify clients that the set of subscribed streams has been updated.
if (Service::timeline_stream.enabled()) {
- ServiceEvent event(NULL, ServiceEvent::kTimelineStreamSubscriptionsUpdate);
+ ServiceEvent event(ServiceEvent::kTimelineStreamSubscriptionsUpdate);
Service::HandleEvent(&event);
}
@@ -4885,7 +4885,7 @@
Profiler::UpdateRunningState();
}
if (Service::vm_stream.enabled()) {
- ServiceEvent event(NULL, ServiceEvent::kVMFlagUpdate);
+ ServiceEvent event(ServiceEvent::kVMFlagUpdate);
event.set_flag_name(flag_name);
event.set_flag_new_value(flag_value);
Service::HandleEvent(&event);
@@ -4951,7 +4951,7 @@
free(vm_name);
vm_name = Utils::StrDup(name_param);
if (Service::vm_stream.enabled()) {
- ServiceEvent event(NULL, ServiceEvent::kVMUpdate);
+ ServiceEvent event(ServiceEvent::kVMUpdate);
Service::HandleEvent(&event);
}
PrintSuccess(js);
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 7f86141..aed7093 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -13,8 +13,20 @@
#ifndef PRODUCT
+ServiceEvent::ServiceEvent(EventKind event_kind)
+ : ServiceEvent(nullptr, nullptr, event_kind) {}
+
+ServiceEvent::ServiceEvent(IsolateGroup* isolate_group, EventKind event_kind)
+ : ServiceEvent(isolate_group, nullptr, event_kind) {}
+
ServiceEvent::ServiceEvent(Isolate* isolate, EventKind event_kind)
+ : ServiceEvent(isolate->group(), isolate, event_kind) {}
+
+ServiceEvent::ServiceEvent(IsolateGroup* isolate_group,
+ Isolate* isolate,
+ EventKind event_kind)
: isolate_(isolate),
+ isolate_group_(isolate_group),
kind_(event_kind),
flag_name_(NULL),
flag_new_value_(NULL),
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index 735ab0f..08979ac 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -78,10 +78,12 @@
const String* event_data;
};
+ explicit ServiceEvent(EventKind event_kind);
+ ServiceEvent(IsolateGroup* isolate_group, EventKind event_kind);
ServiceEvent(Isolate* isolate, EventKind event_kind);
Isolate* isolate() const { return isolate_; }
- IsolateGroup* isolate_group() const { return isolate_->group(); }
+ IsolateGroup* isolate_group() const { return isolate_group_; }
// Used by the C embedding api.
Dart_Port isolate_id() const { return isolate_->main_port(); }
@@ -204,7 +206,12 @@
void PrintJSONHeader(JSONObject* jsobj) const;
private:
+ ServiceEvent(IsolateGroup* isolate_group,
+ Isolate* isolate,
+ EventKind event_kind);
+
Isolate* isolate_;
+ IsolateGroup* isolate_group_;
EventKind kind_;
const char* flag_name_;
const char* flag_new_value_;
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 5253189..609f66e 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1524,7 +1524,7 @@
in_use_ = false;
#ifndef PRODUCT
if (Service::timeline_stream.enabled()) {
- ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents);
+ ServiceEvent service_event(ServiceEvent::kTimelineEvents);
service_event.set_timeline_event_block(this);
Service::HandleEvent(&service_event);
}
diff --git a/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart b/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
index daa428e..0edd45c 100644
--- a/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
@@ -12,6 +12,7 @@
// TODO(http://dartbug.com/39964): Add `alignmentOf<T>()` call.
@patch
Pointer<T> call<T extends NativeType>([int count = 1]) {
- return this.allocate(sizeOf<T>() * count);
+ // This case should have been rewritten in pre-processing.
+ throw UnimplementedError("Pointer<$T>");
}
}
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index 4c69e41..7b55e4a 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -26,19 +26,10 @@
@patch
int sizeOf<T extends NativeType>() {
- // This is not super fast, but it is faster than a runtime entry.
- // Hot loops with elementAt().load() do not use this sizeOf, elementAt is
- // optimized per NativeType statically to prevent use of sizeOf at runtime.
- final int? knownSize = _knownSizes[T];
- if (knownSize != null) return knownSize;
- if (T == IntPtr) return _intPtrSize;
- if (T == Pointer) return _intPtrSize;
- // For structs we fall back to a runtime entry.
- return _sizeOf<T>();
+ // This case should have been rewritten in pre-processing.
+ throw UnimplementedError("$T");
}
-int _sizeOf<T extends NativeType>() native "Ffi_sizeOf";
-
@pragma("vm:recognized", "other")
Pointer<T> _fromAddress<T extends NativeType>(int ptr) native "Ffi_fromAddress";
@@ -98,11 +89,13 @@
@pragma("vm:recognized", "other")
int get address native "Ffi_address";
- // For statically known types, this is rewired.
- // (Method sizeOf is slow, see notes above.)
+ // For statically known types, this is rewritten.
@patch
- Pointer<T> elementAt(int index) =>
- Pointer.fromAddress(address + sizeOf<T>() * index);
+ Pointer<T> elementAt(int index) {
+ // This case should have been rewritten in pre-processing.
+ // Only dynamic invocations are not rewritten in pre-processing.
+ throw UnsupportedError("Pointer.elementAt cannot be called dynamically.");
+ }
@patch
Pointer<T> _offsetBy(int offsetInBytes) =>
diff --git a/sdk/lib/core/bigint.dart b/sdk/lib/core/bigint.dart
index 25c0476..e3f7090 100644
--- a/sdk/lib/core/bigint.dart
+++ b/sdk/lib/core/bigint.dart
@@ -141,7 +141,7 @@
/// of `this` and [other]
///
/// If both operands are non-negative, the result is non-negative,
- /// otherwise the result us negative.
+ /// otherwise the result is negative.
BigInt operator |(BigInt other);
/// Bit-wise exclusive-or operator.
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index f365d79..5f4d6d1 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.dart
@@ -36,6 +36,11 @@
/// ```dart
/// const isLoggingOn = (const String.fromEnvironment("logging") == "on");
/// ```
+ ///
+ /// The string value, or lack of a value, associated with a [name]
+ /// must be consistent across all calls to [String.fromEnvironment],
+ /// [int.fromEnvironment], `bool.fromEnvironment` and [bool.hasEnvironment]
+ /// in a single program.
// The .fromEnvironment() constructors are special in that we do not want
// users to call them using "new". We prohibit that by giving them bodies
// that throw, even though const constructors are not allowed to have bodies.
@@ -66,6 +71,11 @@
/// ? String.fromEnvironment("logging")
/// : null;
/// ```
+ ///
+ /// The string value, or lack of a value, associated with a [name]
+ /// must be consistent across all calls to [String.fromEnvironment],
+ /// [int.fromEnvironment], [bool.fromEnvironment] and `bool.hasEnvironment`
+ /// in a single program.
// The .hasEnvironment() constructor is special in that we do not want
// users to call them using "new". We prohibit that by giving them bodies
// that throw, even though const constructors are not allowed to have bodies.
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 5d8f5d3..1578770 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -32,6 +32,11 @@
/// ```
/// const int.fromEnvironment("defaultPort", defaultValue: 80)
/// ```
+ ///
+ /// The string value, or lack of a value, associated with a [name]
+ /// must be consistent across all calls to [String.fromEnvironment],
+ /// `int.fromEnvironment`, [bool.fromEnvironment] and [bool.hasEnvironment]
+ /// in a single program.
// The .fromEnvironment() constructors are special in that we do not want
// users to call them using "new". We prohibit that by giving them bodies
// that throw, even though const constructors are not allowed to have bodies.
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 27aba63..fbeae71 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -146,6 +146,11 @@
/// ? String.fromEnvironment("maybeDeclared")
/// : null;
/// ```
+ ///
+ /// The string value, or lack of a value, associated with a [name]
+ /// must be consistent across all calls to `String.fromEnvironment`,
+ /// [int.fromEnvironment], [bool.fromEnvironment] and [bool.hasEnvironment]
+ /// in a single program.
// The .fromEnvironment() constructors are special in that we do not want
// users to call them using "new". We prohibit that by giving them bodies
// that throw, even though const constructors are not allowed to have bodies.
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index aef06c1..6beed01 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -24,9 +24,7 @@
///
/// Includes padding and alignment of structs.
///
-/// Support for invoking this function with non-constant [T] will be removed in
-/// the next stable version of Dart and it will become mandatory to invoke it
-/// with a compile-time constant [T].
+/// This function must be invoked with a compile-time constant [T].
external int sizeOf<T extends NativeType>();
/// Represents a pointer into the native C memory corresponding to "NULL", e.g.
@@ -65,9 +63,10 @@
/// Pointer arithmetic (takes element size into account).
///
- /// Support for invoking this method with non-constant [T] will be removed in
- /// the next stable version of Dart and it will become mandatory to invoke it
- /// with a compile-time constant [T].
+ /// This method must be invoked with a compile-time constant [T].
+ ///
+ /// Does not accept dynamic invocations -- where the type of the receiver is
+ /// [dynamic].
external Pointer<T> elementAt(int index);
/// Cast Pointer<T> to a Pointer<V>.
diff --git a/tests/ffi/data_test.dart b/tests/ffi/data_test.dart
index 1a10124..4b619dd 100644
--- a/tests/ffi/data_test.dart
+++ b/tests/ffi/data_test.dart
@@ -449,7 +449,7 @@
final int i = p.value;
});
Expect.throws(() => p.value = 1);
- p.elementAt(5); // Works, but is slow.
+ Expect.throws(() => p.elementAt(5));
final int addr = p.address;
final Pointer<Int16> p2 = p.cast<Int16>();
calloc.free(p);
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index 832d1ad..b88ef03 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -625,7 +625,7 @@
void testSizeOfGeneric() {
int generic<T extends Pointer>() {
int size = sizeOf<IntPtr>();
- size = sizeOf<T>(); //# 1300: ok
+ size = sizeOf<T>(); //# 1300: compile-time error
return size;
}
@@ -634,7 +634,7 @@
void testSizeOfNativeType() {
try {
- sizeOf(); //# 1301: ok
+ sizeOf(); //# 1301: compile-time error
} catch (e) {
print(e);
}
@@ -643,7 +643,7 @@
void testElementAtGeneric() {
Pointer<T> generic<T extends NativeType>(Pointer<T> pointer) {
Pointer<T> returnValue = pointer;
- returnValue = returnValue.elementAt(1); //# 1310: ok
+ returnValue = returnValue.elementAt(1); //# 1310: compile-time error
return returnValue;
}
@@ -657,6 +657,6 @@
Pointer<Int8> p = calloc();
p.elementAt(1);
Pointer<NativeType> p2 = p;
- p2.elementAt(1); //# 1311: ok
+ p2.elementAt(1); //# 1311: compile-time error
calloc.free(p);
}
diff --git a/tests/ffi_2/data_test.dart b/tests/ffi_2/data_test.dart
index f8ac487e..448b465 100644
--- a/tests/ffi_2/data_test.dart
+++ b/tests/ffi_2/data_test.dart
@@ -449,7 +449,7 @@
final int i = p.value;
});
Expect.throws(() => p.value = 1);
- p.elementAt(5); // Works, but is slow.
+ Expect.throws(() => p.elementAt(5));
final int addr = p.address;
final Pointer<Int16> p2 = p.cast<Int16>();
calloc.free(p);
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index b6a0451..079da6f 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -623,7 +623,7 @@
void testSizeOfGeneric() {
int generic<T extends Pointer>() {
int size = sizeOf<IntPtr>();
- size = sizeOf<T>(); //# 1300: ok
+ size = sizeOf<T>(); //# 1300: compile-time error
return size;
}
@@ -632,7 +632,7 @@
void testSizeOfNativeType() {
try {
- sizeOf(); //# 1301: ok
+ sizeOf(); //# 1301: compile-time error
} catch (e) {
print(e);
}
@@ -641,7 +641,7 @@
void testElementAtGeneric() {
Pointer<T> generic<T extends NativeType>(Pointer<T> pointer) {
Pointer<T> returnValue = pointer;
- returnValue = returnValue.elementAt(1); //# 1310: ok
+ returnValue = returnValue.elementAt(1); //# 1310: compile-time error
return returnValue;
}
@@ -655,6 +655,6 @@
Pointer<Int8> p = calloc();
p.elementAt(1);
Pointer<NativeType> p2 = p;
- p2.elementAt(1); //# 1311: ok
+ p2.elementAt(1); //# 1311: compile-time error
calloc.free(p);
}
diff --git a/tools/VERSION b/tools/VERSION
index 4eba935..d35a7a6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 44
+PRERELEASE 45
PRERELEASE_PATCH 0
\ No newline at end of file