Version 2.16.0-111.0.dev
Merge commit '78b7fc5ac19d6c6550438aa5ecdbd19983c69c91' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index c60aa80..81a7644 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -1259,8 +1259,14 @@
@override
void handleCommentReference(
- Token? newKeyword, Token? prefix, Token? period, Token token) {
- listener?.handleCommentReference(newKeyword, prefix, period, token);
+ Token? newKeyword,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
+ Token thirdToken) {
+ listener?.handleCommentReference(newKeyword, firstToken, firstPeriod,
+ secondToken, secondPeriod, thirdToken);
}
@override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 332225f..be42436 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -1840,13 +1840,20 @@
/// A single comment reference has been parsed.
/// * [newKeyword] may be null.
- /// * [prefix] and [period] are either both tokens or both `null`.
- /// * [token] can be an identifier or an operator.
+ /// * [firstToken] and [firstPeriod] are either both tokens or both
+ /// `null`.
+ /// * [secondToken] and [secondPeriod] are either both tokens or both `null`.
+ /// * [thirdToken] can be an identifier or an operator.
///
/// This event is generated by the parser when the parser's
/// `parseOneCommentReference` method is called.
void handleCommentReference(
- Token? newKeyword, Token? prefix, Token? period, Token token) {}
+ Token? newKeyword,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
+ Token thirdToken) {}
/// This event is generated by the parser when the parser's
/// `parseOneCommentReference` method is called.
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index fac9391..6ffcaf0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -8355,26 +8355,33 @@
newKeyword = token;
token = token.next!;
}
- Token? prefix, period;
+ Token? firstToken, firstPeriod, secondToken, secondPeriod;
if (token.isIdentifier && optional('.', token.next!)) {
- prefix = token;
- period = token.next!;
- Token identifier = period.next!;
+ secondToken = token;
+ secondPeriod = token.next!;
+ if (secondPeriod.next!.isIdentifier &&
+ optional('.', secondPeriod.next!.next!)) {
+ firstToken = secondToken;
+ firstPeriod = secondPeriod;
+ secondToken = secondPeriod.next!;
+ secondPeriod = secondToken.next!;
+ }
+ Token identifier = secondPeriod.next!;
if (identifier.kind == KEYWORD_TOKEN && optional('new', identifier)) {
// Treat `new` after `.` is as an identifier so that it can represent an
// unnamed constructor. This support is separate from the
// constructor-tearoffs feature.
rewriter.replaceTokenFollowing(
- period,
+ secondPeriod,
new StringToken(TokenType.IDENTIFIER, identifier.lexeme,
identifier.charOffset));
}
- token = period.next!;
+ token = secondPeriod.next!;
}
if (token.isEof) {
// Recovery: Insert a synthetic identifier for code completion
token = rewriter.insertSyntheticIdentifier(
- period ?? newKeyword ?? syntheticPreviousToken(token));
+ secondPeriod ?? newKeyword ?? syntheticPreviousToken(token));
if (begin == token.next!) {
begin = token;
}
@@ -8386,21 +8393,21 @@
}
if (token.isUserDefinableOperator) {
if (token.next!.isEof) {
- parseOneCommentReferenceRest(
- begin, referenceOffset, newKeyword, prefix, period, token);
+ parseOneCommentReferenceRest(begin, referenceOffset, newKeyword,
+ firstToken, firstPeriod, secondToken, secondPeriod, token);
return true;
}
} else {
token = operatorKeyword ?? token;
if (token.next!.isEof) {
if (token.isIdentifier) {
- parseOneCommentReferenceRest(
- begin, referenceOffset, newKeyword, prefix, period, token);
+ parseOneCommentReferenceRest(begin, referenceOffset, newKeyword,
+ firstToken, firstPeriod, secondToken, secondPeriod, token);
return true;
}
Keyword? keyword = token.keyword;
if (newKeyword == null &&
- prefix == null &&
+ secondToken == null &&
(keyword == Keyword.THIS ||
keyword == Keyword.NULL ||
keyword == Keyword.TRUE ||
@@ -8421,8 +8428,10 @@
Token begin,
int referenceOffset,
Token? newKeyword,
- Token? prefix,
- Token? period,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
Token identifierOrOperator) {
// Adjust the token offsets to match the enclosing comment token.
Token token = begin;
@@ -8431,8 +8440,8 @@
token = token.next!;
} while (!token.isEof);
- listener.handleCommentReference(
- newKeyword, prefix, period, identifierOrOperator);
+ listener.handleCommentReference(newKeyword, firstToken, firstPeriod,
+ secondToken, secondPeriod, identifierOrOperator);
}
/// Given that we have just found bracketed text within the given [comment],
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index e3b952f..9ce7dda 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -596,6 +596,8 @@
return;
}
}
+ } else if (expression is PropertyAccess) {
+ // Nothing to do?
} else {
throw UnimplementedError('Unhandled CommentReference expression type: '
'${expression.runtimeType}');
diff --git a/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart
new file mode 100644
index 0000000..e511df4
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/comment_reference_resolver.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+
+class CommentReferenceResolver {
+ final TypeProviderImpl _typeProvider;
+
+ final ResolverVisitor _resolver;
+
+ /// Helper for resolving properties on types.
+ final TypePropertyResolver _typePropertyResolver;
+
+ CommentReferenceResolver(this._typeProvider, this._resolver)
+ : _typePropertyResolver = _resolver.typePropertyResolver;
+
+ /// Resolves [commentReference].
+ void resolve(CommentReference commentReference) {
+ var expression = commentReference.expression;
+ if (expression is SimpleIdentifierImpl) {
+ _resolveSimpleIdentifierReference(expression,
+ hasNewKeyword: commentReference.newKeyword != null);
+ } else if (expression is PrefixedIdentifierImpl) {
+ _resolvePrefixedIdentifierReference(expression,
+ hasNewKeyword: commentReference.newKeyword != null);
+ } else if (expression is PropertyAccessImpl) {
+ _resolvePropertyAccessReference(expression,
+ hasNewKeyword: commentReference.newKeyword != null);
+ }
+ }
+
+ void _resolvePrefixedIdentifierReference(
+ PrefixedIdentifierImpl expression, {
+ required bool hasNewKeyword,
+ }) {
+ var prefix = expression.prefix;
+ var prefixElement = _resolveSimpleIdentifier(prefix);
+ prefix.staticElement = prefixElement;
+
+ if (prefixElement == null) {
+ return;
+ }
+
+ var name = expression.identifier;
+
+ if (prefixElement is PrefixElement) {
+ var prefixScope = prefixElement.scope;
+ var lookupResult = prefixScope.lookup(name.name);
+ var element = lookupResult.getter ?? lookupResult.setter;
+ element = _resolver.toLegacyElement(element);
+ name.staticElement = element;
+ return;
+ }
+
+ if (!hasNewKeyword) {
+ if (prefixElement is ClassElement) {
+ name.staticElement = prefixElement.getMethod(name.name) ??
+ prefixElement.getGetter(name.name) ??
+ prefixElement.getSetter(name.name) ??
+ prefixElement.getNamedConstructor(name.name);
+ } else if (prefixElement is ExtensionElement) {
+ name.staticElement = prefixElement.getMethod(name.name) ??
+ prefixElement.getGetter(name.name) ??
+ prefixElement.getSetter(name.name);
+ } else {
+ // TODO(brianwilkerson) Report this error.
+ }
+ } else if (prefixElement is ClassElement) {
+ var constructor = prefixElement.getNamedConstructor(name.name);
+ if (constructor == null) {
+ // TODO(brianwilkerson) Report this error.
+ } else {
+ name.staticElement = constructor;
+ }
+ } else {
+ // TODO(brianwilkerson) Report this error.
+ }
+ }
+
+ void _resolvePropertyAccessReference(
+ PropertyAccessImpl expression, {
+ required bool hasNewKeyword,
+ }) {
+ var target = expression.target;
+ if (target is! PrefixedIdentifierImpl) {
+ // A PropertyAccess with a target more complex than a
+ // [PrefixedIdentifier] is not a valid comment reference.
+ return;
+ }
+
+ var prefix = target.prefix;
+ var prefixElement = _resolveSimpleIdentifier(prefix);
+ prefix.staticElement = prefixElement;
+
+ if (prefixElement is! PrefixElement) {
+ // The only valid prefixElement is a PrefixElement; otherwise, this is
+ // not a comment reference.
+ return;
+ }
+
+ var name = target.identifier;
+ var prefixScope = prefixElement.scope;
+ var lookupResult = prefixScope.lookup(name.name);
+ var element = lookupResult.getter ?? lookupResult.setter;
+ element = _resolver.toLegacyElement(element);
+ name.staticElement = element;
+
+ var propertyName = expression.propertyName;
+ if (element is ClassElement) {
+ propertyName.staticElement = element.getMethod(propertyName.name) ??
+ element.getGetter(propertyName.name) ??
+ element.getSetter(propertyName.name) ??
+ element.getNamedConstructor(propertyName.name);
+ } else if (element is ExtensionElement) {
+ propertyName.staticElement = element.getMethod(propertyName.name) ??
+ element.getGetter(propertyName.name) ??
+ element.getSetter(propertyName.name);
+ }
+ }
+
+ /// Resolves the given simple [identifier] if possible.
+ ///
+ /// Returns the resolved element, or `null` if the identifier could not be
+ /// resolved. This does not record the results of the resolution.
+ Element? _resolveSimpleIdentifier(SimpleIdentifierImpl identifier) {
+ var lookupResult = identifier.scopeLookupResult!;
+
+ var element = _resolver.toLegacyElement(lookupResult.getter) ??
+ _resolver.toLegacyElement(lookupResult.setter);
+
+ if (element == null) {
+ InterfaceType enclosingType;
+ var enclosingClass = _resolver.enclosingClass;
+ if (enclosingClass != null) {
+ enclosingType = enclosingClass.thisType;
+ } else {
+ var enclosingExtension = _resolver.enclosingExtension;
+ if (enclosingExtension == null) {
+ return null;
+ }
+ var extendedType = enclosingExtension.extendedType
+ .resolveToBound(_typeProvider.objectType);
+ if (extendedType is InterfaceType) {
+ enclosingType = extendedType;
+ } else if (extendedType is FunctionType) {
+ enclosingType = _typeProvider.functionType;
+ } else {
+ return null;
+ }
+ }
+ var result = _typePropertyResolver.resolve(
+ receiver: null,
+ receiverType: enclosingType,
+ name: identifier.name,
+ propertyErrorEntity: identifier,
+ nameErrorEntity: identifier,
+ );
+ if (identifier.parent is CommentReference) {
+ // TODO(srawlins): Why is the setter preferred? This seems very flawed
+ // as it will only use the setter for a [SimpleIdentifier] comment
+ // reference, and not a [PrefixedIdentifier] or a [PropertyAccess].
+ element = result.setter;
+ }
+ element ??= result.getter;
+ }
+ return element;
+ }
+
+ void _resolveSimpleIdentifierReference(
+ SimpleIdentifierImpl expression, {
+ required bool hasNewKeyword,
+ }) {
+ var element = _resolveSimpleIdentifier(expression);
+ if (element == null) {
+ return;
+ }
+ expression.staticElement = element;
+ if (hasNewKeyword) {
+ if (element is ClassElement) {
+ var constructor = element.unnamedConstructor;
+ if (constructor == null) {
+ // TODO(brianwilkerson) Report this error.
+ } else {
+ expression.staticElement = constructor;
+ }
+ } else {
+ // TODO(brianwilkerson) Report this error.
+ }
+ }
+ }
+}
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index dea89e7..17b6069 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2668,13 +2668,26 @@
@override
void handleCommentReference(
- Token? newKeyword, Token? prefix, Token? period, Token token) {
- Identifier identifier = ast.simpleIdentifier(token);
- if (prefix != null) {
- identifier = ast.prefixedIdentifier(ast.simpleIdentifier(prefix), period!,
- identifier as SimpleIdentifier);
+ Token? newKeyword,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
+ Token thirdToken,
+ ) {
+ var identifier = ast.simpleIdentifier(thirdToken);
+ if (firstToken != null) {
+ var target = ast.prefixedIdentifier(ast.simpleIdentifier(firstToken),
+ firstPeriod!, ast.simpleIdentifier(secondToken!));
+ var expression = ast.propertyAccess(target, secondPeriod!, identifier);
+ push(ast.commentReference(newKeyword, expression));
+ } else if (secondToken != null) {
+ var expression = ast.prefixedIdentifier(
+ ast.simpleIdentifier(secondToken), secondPeriod!, identifier);
+ push(ast.commentReference(newKeyword, expression));
+ } else {
+ push(ast.commentReference(newKeyword, identifier));
}
- push(ast.commentReference(newKeyword, identifier));
}
@override
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index e64547d..c430007 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -10,9 +10,9 @@
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/resolver/comment_reference_resolver.dart';
import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -81,18 +81,17 @@
/// The element for the library containing the compilation unit being visited.
final LibraryElement _definingLibrary;
- /// Helper for resolving properties on types.
- final TypePropertyResolver _typePropertyResolver;
-
final MethodInvocationResolver _methodInvocationResolver;
+ late final _commentReferenceResolver =
+ CommentReferenceResolver(_typeProvider, _resolver);
+
/// Initialize a newly created visitor to work for the given [_resolver] to
/// resolve the nodes in a compilation unit.
ElementResolver(this._resolver,
{MigratableAstInfoProvider migratableAstInfoProvider =
const MigratableAstInfoProvider()})
: _definingLibrary = _resolver.definingLibrary,
- _typePropertyResolver = _resolver.typePropertyResolver,
_methodInvocationResolver = MethodInvocationResolver(
_resolver,
migratableAstInfoProvider,
@@ -124,70 +123,8 @@
}
@override
- void visitCommentReference(covariant CommentReferenceImpl node) {
- var expression = node.expression;
- if (expression is SimpleIdentifierImpl) {
- var element = _resolveSimpleIdentifier(expression);
- if (element == null) {
- return;
- }
- expression.staticElement = element;
- if (node.newKeyword != null) {
- if (element is ClassElement) {
- var constructor = element.unnamedConstructor;
- if (constructor == null) {
- // TODO(brianwilkerson) Report this error.
- } else {
- expression.staticElement = constructor;
- }
- } else {
- // TODO(brianwilkerson) Report this error.
- }
- }
- } else if (expression is PrefixedIdentifierImpl) {
- var prefix = expression.prefix;
- var prefixElement = _resolveSimpleIdentifier(prefix);
- prefix.staticElement = prefixElement;
-
- var name = expression.identifier;
-
- if (prefixElement == null) {
- return;
- }
-
- if (prefixElement is PrefixElement) {
- var prefixScope = prefixElement.scope;
- var lookupResult = prefixScope.lookup(name.name);
- var element = lookupResult.getter ?? lookupResult.setter;
- element = _resolver.toLegacyElement(element);
- name.staticElement = element;
- return;
- }
-
- if (node.newKeyword == null) {
- if (prefixElement is ClassElement) {
- name.staticElement = prefixElement.getMethod(name.name) ??
- prefixElement.getGetter(name.name) ??
- prefixElement.getSetter(name.name) ??
- prefixElement.getNamedConstructor(name.name);
- } else if (prefixElement is ExtensionElement) {
- name.staticElement = prefixElement.getMethod(name.name) ??
- prefixElement.getGetter(name.name) ??
- prefixElement.getSetter(name.name);
- } else {
- // TODO(brianwilkerson) Report this error.
- }
- } else if (prefixElement is ClassElement) {
- var constructor = prefixElement.getNamedConstructor(name.name);
- if (constructor == null) {
- // TODO(brianwilkerson) Report this error.
- } else {
- name.staticElement = constructor;
- }
- } else {
- // TODO(brianwilkerson) Report this error.
- }
- }
+ void visitCommentReference(CommentReference node) {
+ _commentReferenceResolver.resolve(node);
}
@override
@@ -571,88 +508,6 @@
_resolveAnnotations(node.metadata);
}
- /// Resolve the given simple [identifier] if possible. Return the element to
- /// which it could be resolved, or `null` if it could not be resolved. This
- /// does not record the results of the resolution.
- Element? _resolveSimpleIdentifier(SimpleIdentifierImpl identifier) {
- var lookupResult = identifier.scopeLookupResult!;
-
- var element = lookupResult.getter;
- element = _resolver.toLegacyElement(element);
-
- if (element is PropertyAccessorElement && identifier.inSetterContext()) {
- var setter = lookupResult.setter;
- if (setter == null) {
- //
- // Check to see whether there might be a locally defined getter and
- // an inherited setter.
- //
- var enclosingClass = _resolver.enclosingClass;
- if (enclosingClass != null) {
- var result = _typePropertyResolver.resolve(
- receiver: null,
- receiverType: enclosingClass.thisType,
- name: identifier.name,
- propertyErrorEntity: identifier,
- nameErrorEntity: identifier,
- );
- setter = result.setter;
- }
- }
- if (setter != null) {
- setter = _resolver.toLegacyElement(setter);
- element = setter;
- }
- } else if (element == null &&
- (identifier.inSetterContext() ||
- identifier.parent is CommentReference)) {
- element = lookupResult.setter;
- element = _resolver.toLegacyElement(element);
- }
- if (element == null) {
- InterfaceType enclosingType;
- var enclosingClass = _resolver.enclosingClass;
- if (enclosingClass == null) {
- var enclosingExtension = _resolver.enclosingExtension;
- if (enclosingExtension == null) {
- return null;
- }
- DartType extendedType =
- _resolveTypeParameter(enclosingExtension.extendedType);
- if (extendedType is InterfaceType) {
- enclosingType = extendedType;
- } else if (extendedType is FunctionType) {
- enclosingType = _typeProvider.functionType;
- } else {
- return null;
- }
- } else {
- enclosingType = enclosingClass.thisType;
- }
- if (element == null) {
- var result = _typePropertyResolver.resolve(
- receiver: null,
- receiverType: enclosingType,
- name: identifier.name,
- propertyErrorEntity: identifier,
- nameErrorEntity: identifier,
- );
- if (identifier.inSetterContext() ||
- identifier.parent is CommentReference) {
- element = result.setter;
- }
- element ??= result.getter;
- }
- }
- return element;
- }
-
- /// If the given [type] is a type parameter, resolve it to the type that
- /// should be used when looking up members. Otherwise, return the original
- /// type.
- DartType _resolveTypeParameter(DartType type) =>
- type.resolveToBound(_typeProvider.objectType);
-
/// Checks whether the given [expression] is a reference to a class. If it is
/// then the element representing the class is returned, otherwise `null` is
/// returned.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 80eebe3..95f6e32 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1253,7 +1253,7 @@
@override
void visitCommentReference(CommentReference node) {
//
- // We do not visit the identifier because it needs to be visited in the
+ // We do not visit the expression because it needs to be visited in the
// context of the reference.
//
node.accept(elementResolver);
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 7735e22..86a9a44 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -10,10 +10,240 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(CommentDriverResolutionTest);
+ defineReflectiveTests(CommentDriverResolution_PropertyAccessTest);
});
}
@reflectiveTest
+class CommentDriverResolution_PropertyAccessTest
+ extends PubPackageResolutionTest {
+ test_class_constructor_named() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ A.named();
+}
+
+/// [self.A.named]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.named'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.named]'), findElement.class_('A'));
+ // TODO(srawlins): Set the type of named, and test it, here and below.
+ assertElement(findNode.simple('named]'), findElement.constructor('named'));
+ }
+
+ test_class_constructor_unnamedViaNew() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ A();
+}
+
+/// [self.A.new]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.new'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.new'), findElement.class_('A'));
+ assertElement(findNode.simple('new]'), findElement.unnamedConstructor('A'));
+ }
+
+ test_class_instanceGetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ int get foo => 0;
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+ }
+
+ test_class_instanceMethod() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ void foo() {}
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.method('foo'));
+ }
+
+ test_class_instanceSetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ set foo(int value) {}
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+ }
+
+ test_class_staticGetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ static int get foo => 0;
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+ }
+
+ test_class_staticMethod() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ static void foo() {}
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.method('foo'));
+ }
+
+ test_class_staticSetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+class A {
+ static set foo(int value) {}
+}
+
+/// [self.A.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.A.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+ assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+ }
+
+ test_extension_instanceGetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ int get foo => 0;
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+ }
+
+ test_extension_instanceMethod() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ void foo() {}
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.method('foo'));
+ }
+
+ test_extension_instanceSetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ set foo(int value) {}
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+ }
+
+ test_extension_staticGetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ static int get foo => 0;
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+ }
+
+ test_extension_staticMethod() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ static void foo() {}
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.method('foo'));
+ }
+
+ test_extension_staticSetter() async {
+ await assertNoErrorsInCode('''
+import '' as self;
+extension E on int {
+ static set foo(int value) {}
+}
+
+/// [self.E.foo]
+void f() {}
+''');
+
+ assertElement(findNode.simple('self.E.foo'), findElement.prefix('self'));
+ assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+ assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+ }
+}
+
+@reflectiveTest
class CommentDriverResolutionTest extends PubPackageResolutionTest {
test_newKeyword() async {
await assertErrorsInCode('''
@@ -43,6 +273,37 @@
);
}
+ test_prefixedIdentifier_class_constructor_named() async {
+ // TODO(srawlins): Move PrefixedIdentifier tests into their own class, and
+ // improve coverage regarding getter/setter pairs, constructors, operators,
+ // and the 'new' keyword.
+ await assertNoErrorsInCode('''
+class A {
+ A.named();
+}
+
+/// [A.named]
+void f() {}
+''');
+
+ assertElement(findNode.simple('A.named]'), findElement.class_('A'));
+ assertElement(findNode.simple('named]'), findElement.constructor('named'));
+ }
+
+ test_prefixedIdentifier_class_constructor_unnamedViaNew() async {
+ await assertNoErrorsInCode('''
+class A {
+ A();
+}
+
+/// [A.new]
+void f() {}
+''');
+
+ assertElement(findNode.simple('A.new'), findElement.class_('A'));
+ assertElement(findNode.simple('new]'), findElement.unnamedConstructor('A'));
+ }
+
test_prefixedIdentifier_class_instanceGetter() async {
await assertNoErrorsInCode(r'''
class A {
@@ -348,6 +609,21 @@
assertElement(findNode.simple('p5]'), findElement.parameter('p5'));
}
+ test_simpleIdentifier_extension_conflictingSetterAndGetter() async {
+ await assertNoErrorsInCode('''
+extension E1 on int {
+ int get foo => 0;
+}
+
+/// [foo]
+extension E2 on int {
+ set foo(int value) {}
+}
+''');
+
+ assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+ }
+
test_simpleIdentifier_parameter_functionTyped() async {
await assertNoErrorsInCode(r'''
/// [bar]
diff --git a/pkg/dartdev/test/analysis_server_test.dart b/pkg/dartdev/test/analysis_server_test.dart
index 9902dda..975eb86 100644
--- a/pkg/dartdev/test/analysis_server_test.dart
+++ b/pkg/dartdev/test/analysis_server_test.dart
@@ -21,7 +21,7 @@
p = project();
});
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('can start', () async {
AnalysisServer server = AnalysisServer(
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index 11613ef..60bbb1a 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -176,7 +176,7 @@
setUp(() => p = null);
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
@@ -201,7 +201,7 @@
group('multiple items', () {
TestProject secondProject;
- tearDown(() => secondProject?.dispose());
+ tearDown(() async => await secondProject?.dispose());
test('folder and file', () async {
p = project(mainSrc: "int get foo => 'str';\n");
diff --git a/pkg/dartdev/test/commands/create_integration_test.dart b/pkg/dartdev/test/commands/create_integration_test.dart
index e4363a4..4856b47 100644
--- a/pkg/dartdev/test/commands/create_integration_test.dart
+++ b/pkg/dartdev/test/commands/create_integration_test.dart
@@ -18,7 +18,7 @@
setUp(() => p = null);
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
// Create tests for each template.
for (String templateId in CreateCommand.legalTemplateIds) {
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 6978d98..899c7b0 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -21,7 +21,7 @@
setUp(() => p = null);
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/commands/devtools_test.dart b/pkg/dartdev/test/commands/devtools_test.dart
index 656b8c6..e14ba0ac 100644
--- a/pkg/dartdev/test/commands/devtools_test.dart
+++ b/pkg/dartdev/test/commands/devtools_test.dart
@@ -16,7 +16,7 @@
void devtools() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 1f0dd94..c6382f4 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -26,7 +26,7 @@
setUp(() => p = null);
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
void assertResult({int exitCode = 0}) {
String message;
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index b5aa76e..3feab2d 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -57,7 +57,7 @@
void help() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index 5331c6d..cf82970 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -16,7 +16,7 @@
void format() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index 2202b56..69f1f27 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -15,7 +15,7 @@
void help() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
/// Commands not tested by the following loop.
List<String> _commandsNotTested = <String>[
diff --git a/pkg/dartdev/test/commands/language_server_test.dart b/pkg/dartdev/test/commands/language_server_test.dart
index 1e7a46d..543aec9 100644
--- a/pkg/dartdev/test/commands/language_server_test.dart
+++ b/pkg/dartdev/test/commands/language_server_test.dart
@@ -24,10 +24,7 @@
utils.TestProject project;
Process process;
- tearDown(() {
- project?.dispose();
- process?.kill();
- });
+ tearDown(() async => await project?.dispose());
Future runWithLsp(List<String> args) async {
project = utils.project();
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 68475ee..0b394ad 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -17,7 +17,7 @@
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index 2eafe5e..f2486dd 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -15,7 +15,7 @@
void pub() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
void _assertPubHelpInvoked(ProcessResult result) {
expect(result, isNotNull);
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 1e9b3e0..f3174c7 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -23,7 +23,7 @@
void run() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
@@ -147,7 +147,7 @@
expect(result.stdout, contains('FOO BAR [--arg1, arg2]'));
expect(result.exitCode, 0);
} finally {
- bar.dispose();
+ await bar.dispose();
}
});
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index 634d2b9..7f758d3 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -19,7 +19,7 @@
void defineTest(List<Experiment> experiments) {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('--help', () async {
p = project();
diff --git a/pkg/dartdev/test/core_test.dart b/pkg/dartdev/test/core_test.dart
index 5f49133..f9c8e29 100644
--- a/pkg/dartdev/test/core_test.dart
+++ b/pkg/dartdev/test/core_test.dart
@@ -105,7 +105,7 @@
void _project() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('hasPubspecFile positive', () {
p = project();
diff --git a/pkg/dartdev/test/fix_driver_test.dart b/pkg/dartdev/test/fix_driver_test.dart
index 35ec72a..8b71804 100644
--- a/pkg/dartdev/test/fix_driver_test.dart
+++ b/pkg/dartdev/test/fix_driver_test.dart
@@ -19,7 +19,7 @@
void _driver() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('no fixes', () async {
p = project(mainSrc: 'int get foo => 1;\n');
diff --git a/pkg/dartdev/test/load_from_dill_test.dart b/pkg/dartdev/test/load_from_dill_test.dart
index 633e7af..0412854 100644
--- a/pkg/dartdev/test/load_from_dill_test.dart
+++ b/pkg/dartdev/test/load_from_dill_test.dart
@@ -11,7 +11,7 @@
void main() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test("Fallback to dartdev.dill from dartdev.dart.snapshot for 'Hello World'",
() async {
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
index 9b2edc4..bf4eaa3 100644
--- a/pkg/dartdev/test/no_such_file_test.dart
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -9,7 +9,7 @@
void main() {
TestProject p;
- tearDown(() => p?.dispose());
+ tearDown(() async => await p?.dispose());
test('Ensure parsing fails after encountering invalid file', () async {
// Regression test for https://github.com/dart-lang/sdk/issues/43991
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index fe656a5..8f8147a 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -93,8 +93,9 @@
file.deleteSync();
}
- void dispose() {
+ Future<void> dispose() async {
_process?.kill();
+ await _process?.exitCode;
_process = null;
if (dir.existsSync()) {
dir.deleteSync(recursive: true);
@@ -135,7 +136,8 @@
...arguments,
],
workingDirectory: workingDir ?? dir.path,
- environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
+ environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'})
+ ..then((p) => _process = p);
}
String _sdkRootPath;
diff --git a/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
index 13348fd..b38e4ed 100644
--- a/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
+++ b/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
@@ -2552,13 +2552,20 @@
@override
void handleCommentReference(
- Token? newKeyword, Token? prefix, Token? period, Token token) {
+ Token? newKeyword,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
+ Token thirdToken) {
CommentReferenceHandle data = new CommentReferenceHandle(
ParserAstType.HANDLE,
newKeyword: newKeyword,
- prefix: prefix,
- period: period,
- token: token);
+ firstToken: firstToken,
+ firstPeriod: firstPeriod,
+ secondToken: secondToken,
+ secondPeriod: secondPeriod,
+ thirdToken: thirdToken);
seen(data);
}
@@ -7116,20 +7123,29 @@
class CommentReferenceHandle extends ParserAstNode {
final Token? newKeyword;
- final Token? prefix;
- final Token? period;
- final Token token;
+ final Token? firstToken;
+ final Token? firstPeriod;
+ final Token? secondToken;
+ final Token? secondPeriod;
+ final Token thirdToken;
CommentReferenceHandle(ParserAstType type,
- {this.newKeyword, this.prefix, this.period, required this.token})
+ {this.newKeyword,
+ this.firstToken,
+ this.firstPeriod,
+ this.secondToken,
+ this.secondPeriod,
+ required this.thirdToken})
: super("CommentReference", type);
@override
Map<String, Object?> get deprecatedArguments => {
"newKeyword": newKeyword,
- "prefix": prefix,
- "period": period,
- "token": token,
+ "firstToken": firstToken,
+ "firstPeriod": firstPeriod,
+ "secondToken": secondToken,
+ "secondPeriod": secondPeriod,
+ "thirdToken": thirdToken,
};
}
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index f90c7fa..b72f70d 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -2660,16 +2660,25 @@
@override
void handleCommentReference(
- Token? newKeyword, Token? prefix, Token? period, Token token) {
+ Token? newKeyword,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
+ Token thirdToken) {
seen(newKeyword);
- seen(prefix);
- seen(period);
- seen(token);
+ seen(firstToken);
+ seen(firstPeriod);
+ seen(secondToken);
+ seen(secondPeriod);
+ seen(thirdToken);
doPrint('handleCommentReference('
'$newKeyword, '
- '$prefix, '
- '$period, '
- '$token)');
+ '$firstToken, '
+ '$firstPeriod, '
+ '$secondToken, '
+ '$secondPeriod, '
+ '$thirdToken)');
}
@override
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
index 139220a..38d64e8 100644
--- a/pkg/front_end/test/parser_test_parser.dart
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -2494,19 +2494,30 @@
Token begin,
int referenceOffset,
Token? newKeyword,
- Token? prefix,
- Token? period,
+ Token? firstToken,
+ Token? firstPeriod,
+ Token? secondToken,
+ Token? secondPeriod,
Token identifierOrOperator) {
doPrint('parseOneCommentReferenceRest('
'$begin, '
'$referenceOffset, '
'$newKeyword, '
- '$prefix, '
- '$period, '
+ '$firstToken, '
+ '$firstPeriod, '
+ '$secondToken, '
+ '$secondPeriod, '
'$identifierOrOperator)');
indent++;
- var result = super.parseOneCommentReferenceRest(begin, referenceOffset,
- newKeyword, prefix, period, identifierOrOperator);
+ var result = super.parseOneCommentReferenceRest(
+ begin,
+ referenceOffset,
+ newKeyword,
+ firstToken,
+ firstPeriod,
+ secondToken,
+ secondPeriod,
+ identifierOrOperator);
indent--;
return result;
}
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index 0f75c8e..4b9fe69 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -210,6 +210,7 @@
flags.use_field_guards = true;
flags.use_osr = true;
flags.is_system_isolate = true;
+ flags.branch_coverage = false;
char* error;
Dart_Isolate dartdev_isolate = runner->create_isolate_(
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index e79e6c4..f37de2b 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -606,6 +606,7 @@
bool null_safety;
bool is_system_isolate;
bool snapshot_is_dontneed_safe;
+ bool branch_coverage;
} Dart_IsolateFlags;
/**
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 412cfbc..ee4f627 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -212,6 +212,7 @@
rewind_optimized_out_test: SkipSlow # Timeout
[ $arch == ia32 && $compiler == dartk ]
+*: Slow # Issue 47920, service tests are slow on IA32
valid_source_locations_test: Skip # Issue 34736, too slow.
[ $compiler == app_jitk && $system == linux ]
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index ac51da2..914b102 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -212,6 +212,7 @@
rewind_optimized_out_test: SkipSlow # Timeout
[ $arch == ia32 && $compiler == dartk ]
+*: Slow # Issue 47920, service tests are slow on IA32
valid_source_locations_test: Skip # Issue 34736, too slow.
[ $compiler == app_jitk && $system == linux ]
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 30f1303..9abd6ee 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -56,7 +56,10 @@
if (!is_android) {
libs += [ "pthread" ]
}
- if (!is_mac && !is_ios) {
+
+ # Clang with libc++ does not require an explicit atomic library reference.
+ # (similar to https://github.com/flutter/buildroot/blob/master/build/config/compiler/BUILD.gn#L562)
+ if (!is_clang) {
libs += [ "atomic" ]
}
}
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index a013cb2..a8e2f04 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -646,10 +646,6 @@
case Token::kMUL:
FALL_THROUGH;
case Token::kDIV: {
- if (op_kind == Token::kDIV &&
- !FlowGraphCompiler::SupportsHardwareDivision()) {
- return false;
- }
left_value = PrepareStaticOpInput(left_value, kDoubleCid, instr);
right_value = PrepareStaticOpInput(right_value, kDoubleCid, instr);
replacement = new (Z) BinaryDoubleOpInstr(
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index e811039..3b8931c 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -765,32 +765,30 @@
static void CompareDoubles(Assembler* assembler,
Label* normal_ir_body,
Condition true_condition) {
- if (TargetCPUFeatures::vfp_supported()) {
- Label is_smi, double_op;
+ Label is_smi, double_op;
- TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
- // Both arguments are double, right operand is in R0.
+ TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+ // Both arguments are double, right operand is in R0.
- __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
- __ Bind(&double_op);
- __ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left argument.
- __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ Bind(&double_op);
+ __ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left argument.
+ __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ vcmpd(D0, D1);
- __ vmstat();
- __ LoadObject(R0, CastHandle<Object>(FalseObject()));
- // Return false if D0 or D1 was NaN before checking true condition.
- READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, VS));
- __ LoadObject(R0, CastHandle<Object>(TrueObject()), true_condition);
- __ Ret();
+ __ vcmpd(D0, D1);
+ __ vmstat();
+ __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+ // Return false if D0 or D1 was NaN before checking true condition.
+ READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, VS));
+ __ LoadObject(R0, CastHandle<Object>(TrueObject()), true_condition);
+ __ Ret();
- __ Bind(&is_smi); // Convert R0 to a double.
- __ SmiUntag(R0);
- __ vmovsr(S0, R0);
- __ vcvtdi(D1, S0);
- __ b(&double_op); // Then do the comparison.
- __ Bind(normal_ir_body);
- }
+ __ Bind(&is_smi); // Convert R0 to a double.
+ __ SmiUntag(R0);
+ __ vmovsr(S0, R0);
+ __ vcvtdi(D1, S0);
+ __ b(&double_op); // Then do the comparison.
+ __ Bind(normal_ir_body);
}
void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
@@ -823,43 +821,41 @@
static void DoubleArithmeticOperations(Assembler* assembler,
Label* normal_ir_body,
Token::Kind kind) {
- if (TargetCPUFeatures::vfp_supported()) {
- Label is_smi, double_op;
+ Label is_smi, double_op;
- TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
- // Both arguments are double, right operand is in R0.
- __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
- __ Bind(&double_op);
- __ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left argument.
- __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- switch (kind) {
- case Token::kADD:
- __ vaddd(D0, D0, D1);
- break;
- case Token::kSUB:
- __ vsubd(D0, D0, D1);
- break;
- case Token::kMUL:
- __ vmuld(D0, D0, D1);
- break;
- case Token::kDIV:
- __ vdivd(D0, D0, D1);
- break;
- default:
- UNREACHABLE();
- }
- const Class& double_class = DoubleClass();
- __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
- R1); // Result register.
- __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ Ret();
- __ Bind(&is_smi); // Convert R0 to a double.
- __ SmiUntag(R0);
- __ vmovsr(S0, R0);
- __ vcvtdi(D1, S0);
- __ b(&double_op);
- __ Bind(normal_ir_body);
+ TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+ // Both arguments are double, right operand is in R0.
+ __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ Bind(&double_op);
+ __ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left argument.
+ __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ switch (kind) {
+ case Token::kADD:
+ __ vaddd(D0, D0, D1);
+ break;
+ case Token::kSUB:
+ __ vsubd(D0, D0, D1);
+ break;
+ case Token::kMUL:
+ __ vmuld(D0, D0, D1);
+ break;
+ case Token::kDIV:
+ __ vdivd(D0, D0, D1);
+ break;
+ default:
+ UNREACHABLE();
}
+ const Class& double_class = DoubleClass();
+ __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
+ R1); // Result register.
+ __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ Ret();
+ __ Bind(&is_smi); // Convert R0 to a double.
+ __ SmiUntag(R0);
+ __ vmovsr(S0, R0);
+ __ vcvtdi(D1, S0);
+ __ b(&double_op);
+ __ Bind(normal_ir_body);
}
void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
@@ -881,123 +877,111 @@
// Left is double, right is integer (Mint or Smi)
void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
Label* normal_ir_body) {
- if (TargetCPUFeatures::vfp_supported()) {
- Label fall_through;
- // Only smis allowed.
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- __ tst(R0, Operand(kSmiTagMask));
- __ b(normal_ir_body, NE);
- // Is Smi.
- __ SmiUntag(R0);
- __ vmovsr(S0, R0);
- __ vcvtdi(D1, S0);
- __ ldr(R0, Address(SP, 1 * target::kWordSize));
- __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ vmuld(D0, D0, D1);
- const Class& double_class = DoubleClass();
- __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
- R1); // Result register.
- __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ Ret();
- __ Bind(normal_ir_body);
- }
+ Label fall_through;
+ // Only smis allowed.
+ __ ldr(R0, Address(SP, 0 * target::kWordSize));
+ __ tst(R0, Operand(kSmiTagMask));
+ __ b(normal_ir_body, NE);
+ // Is Smi.
+ __ SmiUntag(R0);
+ __ vmovsr(S0, R0);
+ __ vcvtdi(D1, S0);
+ __ ldr(R0, Address(SP, 1 * target::kWordSize));
+ __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ vmuld(D0, D0, D1);
+ const Class& double_class = DoubleClass();
+ __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
+ R1); // Result register.
+ __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ Ret();
+ __ Bind(normal_ir_body);
}
void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
Label* normal_ir_body) {
- if (TargetCPUFeatures::vfp_supported()) {
- Label fall_through;
+ Label fall_through;
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- __ tst(R0, Operand(kSmiTagMask));
- __ b(normal_ir_body, NE);
- // Is Smi.
- __ SmiUntag(R0);
- __ vmovsr(S0, R0);
- __ vcvtdi(D0, S0);
- const Class& double_class = DoubleClass();
- __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
- R1); // Result register.
- __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ Ret();
- __ Bind(normal_ir_body);
- }
+ __ ldr(R0, Address(SP, 0 * target::kWordSize));
+ __ tst(R0, Operand(kSmiTagMask));
+ __ b(normal_ir_body, NE);
+ // Is Smi.
+ __ SmiUntag(R0);
+ __ vmovsr(S0, R0);
+ __ vcvtdi(D0, S0);
+ const Class& double_class = DoubleClass();
+ __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump, R0,
+ R1); // Result register.
+ __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ Ret();
+ __ Bind(normal_ir_body);
}
void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
Label* normal_ir_body) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ vcmpd(D0, D0);
- __ vmstat();
- __ LoadObject(R0, CastHandle<Object>(FalseObject()), VC);
- __ LoadObject(R0, CastHandle<Object>(TrueObject()), VS);
- __ Ret();
- }
+ __ ldr(R0, Address(SP, 0 * target::kWordSize));
+ __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ vcmpd(D0, D0);
+ __ vmstat();
+ __ LoadObject(R0, CastHandle<Object>(FalseObject()), VC);
+ __ LoadObject(R0, CastHandle<Object>(TrueObject()), VS);
+ __ Ret();
}
void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
Label* normal_ir_body) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- // R1 <- value[0:31], R2 <- value[32:63]
- __ LoadFieldFromOffset(R1, R0, target::Double::value_offset());
- __ LoadFieldFromOffset(R2, R0,
- target::Double::value_offset() + target::kWordSize);
+ __ ldr(R0, Address(SP, 0 * target::kWordSize));
+ // R1 <- value[0:31], R2 <- value[32:63]
+ __ LoadFieldFromOffset(R1, R0, target::Double::value_offset());
+ __ LoadFieldFromOffset(R2, R0,
+ target::Double::value_offset() + target::kWordSize);
- // If the low word isn't 0, then it isn't infinity.
- __ cmp(R1, Operand(0));
- __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
- READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE)); // Return if NE.
+ // If the low word isn't 0, then it isn't infinity.
+ __ cmp(R1, Operand(0));
+ __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+ READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE)); // Return if NE.
- // Mask off the sign bit.
- __ AndImmediate(R2, R2, 0x7FFFFFFF);
- // Compare with +infinity.
- __ CompareImmediate(R2, 0x7FF00000);
- __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
- READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE));
- __ LoadObject(R0, CastHandle<Object>(TrueObject()));
- __ Ret();
- }
+ // Mask off the sign bit.
+ __ AndImmediate(R2, R2, 0x7FFFFFFF);
+ // Compare with +infinity.
+ __ CompareImmediate(R2, 0x7FF00000);
+ __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+ READS_RETURN_ADDRESS_FROM_LR(__ bx(LR, NE));
+ __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+ __ Ret();
}
void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
Label* normal_ir_body) {
- if (TargetCPUFeatures::vfp_supported()) {
- Label is_false, is_true, is_zero;
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
- __ vcmpdz(D0);
- __ vmstat();
- __ b(&is_false, VS); // NaN -> false.
- __ b(&is_zero, EQ); // Check for negative zero.
- __ b(&is_false, CS); // >= 0 -> false.
+ Label is_false, is_true, is_zero;
+ __ ldr(R0, Address(SP, 0 * target::kWordSize));
+ __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+ __ vcmpdz(D0);
+ __ vmstat();
+ __ b(&is_false, VS); // NaN -> false.
+ __ b(&is_zero, EQ); // Check for negative zero.
+ __ b(&is_false, CS); // >= 0 -> false.
- __ Bind(&is_true);
- __ LoadObject(R0, CastHandle<Object>(TrueObject()));
- __ Ret();
+ __ Bind(&is_true);
+ __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+ __ Ret();
- __ Bind(&is_false);
- __ LoadObject(R0, CastHandle<Object>(FalseObject()));
- __ Ret();
+ __ Bind(&is_false);
+ __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+ __ Ret();
- __ Bind(&is_zero);
- // Check for negative zero by looking at the sign bit.
- __ vmovrrd(R0, R1, D0); // R1:R0 <- D0, so sign bit is in bit 31 of R1.
- __ mov(R1, Operand(R1, LSR, 31));
- __ tst(R1, Operand(1));
- __ b(&is_true, NE); // Sign bit set.
- __ b(&is_false);
- }
+ __ Bind(&is_zero);
+ // Check for negative zero by looking at the sign bit.
+ __ vmovrrd(R0, R1, D0); // R1:R0 <- D0, so sign bit is in bit 31 of R1.
+ __ mov(R1, Operand(R1, LSR, 31));
+ __ tst(R1, Operand(1));
+ __ b(&is_true, NE); // Sign bit set.
+ __ b(&is_false);
}
void AsmIntrinsifier::Double_hashCode(Assembler* assembler,
Label* normal_ir_body) {
// TODO(dartbug.com/31174): Convert this to a graph intrinsic.
- if (!TargetCPUFeatures::vfp_supported()) return;
-
// Load double value and check that it isn't NaN, since ARM gives an
// FPU exception if you try to convert NaN to an int.
Label double_hash;
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index eee0fb3..a9a71ee 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -702,7 +702,6 @@
}
void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sn != kNoSRegister);
ASSERT(rt != kNoRegister);
ASSERT(rt != SP);
@@ -716,7 +715,6 @@
}
void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sn != kNoSRegister);
ASSERT(rt != kNoRegister);
ASSERT(rt != SP);
@@ -733,7 +731,6 @@
Register rt,
Register rt2,
Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sm != kNoSRegister);
ASSERT(sm != S31);
ASSERT(rt != kNoRegister);
@@ -755,7 +752,6 @@
Register rt2,
SRegister sm,
Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sm != kNoSRegister);
ASSERT(sm != S31);
ASSERT(rt != kNoRegister);
@@ -775,7 +771,6 @@
}
void Assembler::vmovdr(DRegister dn, int i, Register rt, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((i == 0) || (i == 1));
ASSERT(rt != kNoRegister);
ASSERT(rt != SP);
@@ -793,7 +788,6 @@
Register rt,
Register rt2,
Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dm != kNoDRegister);
ASSERT(rt != kNoRegister);
ASSERT(rt != SP);
@@ -814,7 +808,6 @@
Register rt2,
DRegister dm,
Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dm != kNoDRegister);
ASSERT(rt != kNoRegister);
ASSERT(rt != SP);
@@ -833,7 +826,6 @@
}
void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sd != kNoSRegister);
ASSERT(cond != kNoCondition);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
@@ -844,7 +836,6 @@
}
void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
ASSERT(sd != kNoSRegister);
ASSERT(cond != kNoCondition);
@@ -856,7 +847,6 @@
}
void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dd != kNoDRegister);
ASSERT(cond != kNoCondition);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
@@ -867,7 +857,6 @@
}
void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
ASSERT(dd != kNoDRegister);
ASSERT(cond != kNoCondition);
@@ -884,7 +873,6 @@
Register base,
SRegister start,
uint32_t count) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(base != kNoRegister);
ASSERT(cond != kNoCondition);
ASSERT(start != kNoSRegister);
@@ -904,7 +892,6 @@
Register base,
DRegister start,
int32_t count) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(base != kNoRegister);
ASSERT(cond != kNoCondition);
ASSERT(start != kNoDRegister);
@@ -966,7 +953,6 @@
SRegister sd,
SRegister sn,
SRegister sm) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sd != kNoSRegister);
ASSERT(sn != kNoSRegister);
ASSERT(sm != kNoSRegister);
@@ -986,7 +972,6 @@
DRegister dd,
DRegister dn,
DRegister dm) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dd != kNoDRegister);
ASSERT(dn != kNoDRegister);
ASSERT(dm != kNoDRegister);
@@ -1149,7 +1134,6 @@
int32_t opcode,
SRegister sd,
DRegister dm) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(sd != kNoSRegister);
ASSERT(dm != kNoDRegister);
ASSERT(cond != kNoCondition);
@@ -1165,7 +1149,6 @@
int32_t opcode,
DRegister dd,
SRegister sm) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(dd != kNoDRegister);
ASSERT(sm != kNoSRegister);
ASSERT(cond != kNoCondition);
@@ -1234,7 +1217,6 @@
}
void Assembler::vmrs(Register rd, Condition cond) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(cond != kNoCondition);
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
B26 | B25 | B23 | B22 | B21 | B20 | B16 |
@@ -2526,24 +2508,16 @@
PushList(kAbiPreservedCpuRegs);
const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
- if (TargetCPUFeatures::vfp_supported()) {
ASSERT(2 * kAbiPreservedFpuRegCount < 16);
// Save FPU registers. 2 D registers per Q register.
vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
- } else {
- sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize));
- }
}
void Assembler::PopNativeCalleeSavedRegisters() {
const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
// Restore C++ ABI callee-saved registers.
- if (TargetCPUFeatures::vfp_supported()) {
- // Restore FPU registers. 2 D registers per Q register.
- vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
- } else {
- AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
- }
+ // Restore FPU registers. 2 D registers per Q register.
+ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
// Restore CPU registers.
PopList(kAbiPreservedCpuRegs);
}
@@ -3000,17 +2974,8 @@
Register tmp1,
Register tmp2,
DRegister dtmp) {
- if (TargetCPUFeatures::vfp_supported()) {
LoadDFromOffset(dtmp, src, target::Double::value_offset() - kHeapObjectTag);
StoreDToOffset(dtmp, dst, target::Double::value_offset() - kHeapObjectTag);
- } else {
- LoadFieldFromOffset(tmp1, src, target::Double::value_offset());
- LoadFieldFromOffset(tmp2, src,
- target::Double::value_offset() + target::kWordSize);
- StoreFieldToOffset(tmp1, dst, target::Double::value_offset());
- StoreFieldToOffset(tmp2, dst,
- target::Double::value_offset() + target::kWordSize);
- }
}
void Assembler::CopyFloat32x4Field(Register dst,
@@ -3215,7 +3180,6 @@
if (TargetCPUFeatures::integer_division_supported()) {
sdiv(result, left, right);
} else {
- ASSERT(TargetCPUFeatures::vfp_supported());
SRegister stmpl = EvenSRegisterOf(tmpl);
SRegister stmpr = EvenSRegisterOf(tmpr);
vmovsr(stmpl, left);
@@ -3298,7 +3262,6 @@
COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
// Preserve all volatile FPU registers.
- if (TargetCPUFeatures::vfp_supported()) {
DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg);
DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg);
if ((lastv - firstv + 1) >= 16) {
@@ -3308,7 +3271,6 @@
} else {
vstmd(DB_W, SP, firstv, lastv - firstv + 1);
}
- }
ReserveAlignedFrameSpace(frame_space);
}
@@ -3318,9 +3280,7 @@
// and ensure proper alignment of the stack frame.
// We need to restore it before restoring registers.
const intptr_t kPushedFpuRegisterSize =
- TargetCPUFeatures::vfp_supported()
- ? kDartVolatileFpuRegCount * kFpuRegisterSize
- : 0;
+ kDartVolatileFpuRegCount * kFpuRegisterSize;
COMPILE_ASSERT(PP < FP);
COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0);
@@ -3331,7 +3291,6 @@
AddImmediate(SP, FP, -kPushedRegistersSize);
// Restore all volatile FPU registers.
- if (TargetCPUFeatures::vfp_supported()) {
DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg);
DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg);
if ((lastv - firstv + 1) >= 16) {
@@ -3341,7 +3300,6 @@
} else {
vldmd(IA_W, SP, firstv, lastv - firstv + 1);
}
- }
// Restore volatile CPU registers.
RESTORES_LR_FROM_FRAME(
diff --git a/runtime/vm/compiler/assembler/assembler_arm_test.cc b/runtime/vm/compiler/assembler/assembler_arm_test.cc
index f925d7c..64db0ae 100644
--- a/runtime/vm/compiler/assembler/assembler_arm_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm_test.cc
@@ -273,81 +273,68 @@
}
ASSEMBLER_TEST_GENERATE(Vmov, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ mov(R3, Operand(43));
- __ mov(R1, Operand(41));
- __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43
- __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41
- __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41
- __ vmovrs(R3, S5); // R3 = S5, R3 == 41
- __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41
- __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41
- __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43
- __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43
- __ sub(R0, R1, Operand(R0)); // 43-41
- }
+ __ mov(R3, Operand(43));
+ __ mov(R1, Operand(41));
+ __ vmovsrr(S1, R1, R3); // S1:S2 = 41:43
+ __ vmovs(S0, S2); // S0 = S2, S0:S1 == 43:41
+ __ vmovd(D2, D0); // D2 = D0, S4:S5 == 43:41
+ __ vmovrs(R3, S5); // R3 = S5, R3 == 41
+ __ vmovrrs(R1, R2, S4); // R1:R2 = S4:S5, R1:R2 == 43:41
+ __ vmovdrr(D3, R3, R2); // D3 = R3:R2, S6:S7 == 41:41
+ __ vmovdr(D3, 1, R1); // D3[1] == S7 = R1, S6:S7 == 41:43
+ __ vmovrrd(R0, R1, D3); // R0:R1 = D3, R0:R1 == 41:43
+ __ sub(R0, R1, Operand(R0)); // 43-41
__ Ret();
}
ASSEMBLER_TEST_RUN(Vmov, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Vmov)() DART_UNUSED;
- EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(Vmov, test->entry()));
- }
+ typedef int (*Vmov)() DART_UNUSED;
+ EXPECT_EQ(2, EXECUTE_TEST_CODE_INT32(Vmov, test->entry()));
}
ASSEMBLER_TEST_GENERATE(SingleVLoadStore, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
- __ mov(R2, Operand(SP));
- __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
- __ vldrs(S0, Address(R2, (-target::kWordSize * 30)));
- __ vadds(S0, S0, S0);
- __ vstrs(S0, Address(R2, (-target::kWordSize * 30)));
- __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
- }
+ __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
+ __ mov(R2, Operand(SP));
+ __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+ __ vldrs(S0, Address(R2, (-target::kWordSize * 30)));
+ __ vadds(S0, S0, S0);
+ __ vstrs(S0, Address(R2, (-target::kWordSize * 30)));
+ __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
__ Ret();
}
ASSEMBLER_TEST_RUN(SingleVLoadStore, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef float (*SingleVLoadStore)() DART_UNUSED;
- float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
- EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
- }
+ typedef float (*SingleVLoadStore)() DART_UNUSED;
+ float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
+ EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
}
ASSEMBLER_TEST_GENERATE(SingleVShiftLoadStore, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
- __ mov(R2, Operand(SP));
- // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex));
- // as:
- __ mov(R1, Operand(target::kWordSize));
- __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex));
- __ vldrs(S0, Address(R2, (-target::kWordSize * 32)));
- __ vadds(S0, S0, S0);
- __ vstrs(S0, Address(R2, (-target::kWordSize * 32)));
- // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex));
- // as:
- __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
- }
+ __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
+ __ mov(R2, Operand(SP));
+ // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex));
+ // as:
+ __ mov(R1, Operand(target::kWordSize));
+ __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex));
+ __ vldrs(S0, Address(R2, (-target::kWordSize * 32)));
+ __ vadds(S0, S0, S0);
+ __ vstrs(S0, Address(R2, (-target::kWordSize * 32)));
+ // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex));
+ // as:
+ __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
__ Ret();
}
ASSEMBLER_TEST_RUN(SingleVShiftLoadStore, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef float (*SingleVLoadStore)() DART_UNUSED;
- float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
- EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
- }
+ typedef float (*SingleVLoadStore)() DART_UNUSED;
+ float res = EXECUTE_TEST_CODE_FLOAT(SingleVLoadStore, test->entry());
+ EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
}
ASSEMBLER_TEST_GENERATE(DoubleVLoadStore, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
int64_t value = bit_cast<int64_t, double>(12.3);
__ LoadImmediate(R0, Utils::Low32Bits(value));
__ LoadImmediate(R1, Utils::High32Bits(value));
@@ -359,69 +346,57 @@
__ vstrd(D0, Address(R2, (-target::kWordSize * 30)));
__ ldr(R1, Address(R2, (-target::kWordSize * 29)));
__ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
- }
- __ Ret();
+ __ Ret();
}
ASSEMBLER_TEST_RUN(DoubleVLoadStore, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef double (*DoubleVLoadStore)() DART_UNUSED;
- float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry());
- EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
- }
+ typedef double (*DoubleVLoadStore)() DART_UNUSED;
+ float res = EXECUTE_TEST_CODE_DOUBLE(DoubleVLoadStore, test->entry());
+ EXPECT_FLOAT_EQ(2 * 12.3f, res, 0.001f);
}
ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadSImmediate(S0, 12.3f);
- __ LoadSImmediate(S1, 3.4f);
- __ vnegs(S0, S0); // -12.3f
- __ vabss(S0, S0); // 12.3f
- __ vadds(S0, S0, S1); // 15.7f
- __ vmuls(S0, S0, S1); // 53.38f
- __ vsubs(S0, S0, S1); // 49.98f
- __ vdivs(S0, S0, S1); // 14.7f
- __ vsqrts(S0, S0); // 3.8340579f
- }
+ __ LoadSImmediate(S0, 12.3f);
+ __ LoadSImmediate(S1, 3.4f);
+ __ vnegs(S0, S0); // -12.3f
+ __ vabss(S0, S0); // 12.3f
+ __ vadds(S0, S0, S1); // 15.7f
+ __ vmuls(S0, S0, S1); // 53.38f
+ __ vsubs(S0, S0, S1); // 49.98f
+ __ vdivs(S0, S0, S1); // 14.7f
+ __ vsqrts(S0, S0); // 3.8340579f
__ Ret();
}
ASSEMBLER_TEST_RUN(SingleFPOperations, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef float (*SingleFPOperations)() DART_UNUSED;
- float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry());
- EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f);
- }
+ typedef float (*SingleFPOperations)() DART_UNUSED;
+ float res = EXECUTE_TEST_CODE_FLOAT(SingleFPOperations, test->entry());
+ EXPECT_FLOAT_EQ(3.8340579f, res, 0.001f);
}
ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadDImmediate(D0, 12.3, R0);
- __ LoadDImmediate(D1, 3.4, R0);
- __ vnegd(D0, D0); // -12.3
- __ vabsd(D0, D0); // 12.3
- __ vaddd(D0, D0, D1); // 15.7
- __ vmuld(D0, D0, D1); // 53.38
- __ vsubd(D0, D0, D1); // 49.98
- __ vdivd(D0, D0, D1); // 14.7
- __ vsqrtd(D0, D0); // 3.8340579
- }
+ __ LoadDImmediate(D0, 12.3, R0);
+ __ LoadDImmediate(D1, 3.4, R0);
+ __ vnegd(D0, D0); // -12.3
+ __ vabsd(D0, D0); // 12.3
+ __ vaddd(D0, D0, D1); // 15.7
+ __ vmuld(D0, D0, D1); // 53.38
+ __ vsubd(D0, D0, D1); // 49.98
+ __ vdivd(D0, D0, D1); // 14.7
+ __ vsqrtd(D0, D0); // 3.8340579
__ Ret();
}
ASSEMBLER_TEST_RUN(DoubleFPOperations, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef double (*DoubleFPOperations)() DART_UNUSED;
- double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry());
- EXPECT_FLOAT_EQ(3.8340579, res, 0.001);
- }
+ typedef double (*DoubleFPOperations)() DART_UNUSED;
+ double res = EXECUTE_TEST_CODE_DOUBLE(DoubleFPOperations, test->entry());
+ EXPECT_FLOAT_EQ(3.8340579, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(DoubleSqrtNeg, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
// Check that sqrt of a negative double gives NaN.
__ LoadDImmediate(D1, -1.0, R0);
__ vsqrtd(D0, D1);
@@ -429,161 +404,128 @@
__ vmstat();
__ mov(R0, Operand(1), VS);
__ mov(R0, Operand(0), VC);
- }
- __ Ret();
+ __ Ret();
}
ASSEMBLER_TEST_RUN(DoubleSqrtNeg, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*DoubleSqrtNeg)() DART_UNUSED;
- EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(DoubleSqrtNeg, test->entry()));
- }
+ typedef int (*DoubleSqrtNeg)() DART_UNUSED;
+ EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(DoubleSqrtNeg, test->entry()));
}
ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ mov(R3, Operand(6));
- __ vmovsr(S3, R3);
- __ vcvtdi(D0, S3);
- }
+ __ mov(R3, Operand(6));
+ __ vmovsr(S3, R3);
+ __ vcvtdi(D0, S3);
__ Ret();
}
ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef double (*IntToDoubleConversionCode)() DART_UNUSED;
- double res =
- EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, test->entry());
- EXPECT_FLOAT_EQ(6.0, res, 0.001);
- }
+ typedef double (*IntToDoubleConversionCode)() DART_UNUSED;
+ double res =
+ EXECUTE_TEST_CODE_DOUBLE(IntToDoubleConversionCode, test->entry());
+ EXPECT_FLOAT_EQ(6.0, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(LongToDoubleConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- int64_t value = 60000000000LL;
- __ LoadImmediate(R0, Utils::Low32Bits(value));
- __ LoadImmediate(R1, Utils::High32Bits(value));
- __ vmovsr(S0, R0);
- __ vmovsr(S2, R1);
- __ vcvtdu(D0, S0);
- __ vcvtdi(D1, S2);
- __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0);
- __ vmlad(D0, D1, D2);
- }
+ int64_t value = 60000000000LL;
+ __ LoadImmediate(R0, Utils::Low32Bits(value));
+ __ LoadImmediate(R1, Utils::High32Bits(value));
+ __ vmovsr(S0, R0);
+ __ vmovsr(S2, R1);
+ __ vcvtdu(D0, S0);
+ __ vcvtdi(D1, S2);
+ __ LoadDImmediate(D2, 1.0 * (1LL << 32), R0);
+ __ vmlad(D0, D1, D2);
__ Ret();
}
ASSEMBLER_TEST_RUN(LongToDoubleConversion, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef double (*LongToDoubleConversionCode)() DART_UNUSED;
- double res =
- EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, test->entry());
- EXPECT_FLOAT_EQ(60000000000.0, res, 0.001);
- }
+ typedef double (*LongToDoubleConversionCode)() DART_UNUSED;
+ double res =
+ EXECUTE_TEST_CODE_DOUBLE(LongToDoubleConversionCode, test->entry());
+ EXPECT_FLOAT_EQ(60000000000.0, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(IntToFloatConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ mov(R3, Operand(6));
- __ vmovsr(S3, R3);
- __ vcvtsi(S0, S3);
- }
+ __ mov(R3, Operand(6));
+ __ vmovsr(S3, R3);
+ __ vcvtsi(S0, S3);
__ Ret();
}
ASSEMBLER_TEST_RUN(IntToFloatConversion, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef float (*IntToFloatConversionCode)() DART_UNUSED;
- float res =
- EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry());
- EXPECT_FLOAT_EQ(6.0, res, 0.001);
- }
+ typedef float (*IntToFloatConversionCode)() DART_UNUSED;
+ float res = EXECUTE_TEST_CODE_FLOAT(IntToFloatConversionCode, test->entry());
+ EXPECT_FLOAT_EQ(6.0, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(FloatToIntConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ vcvtis(S1, S0);
- __ vmovrs(R0, S1);
- }
+ __ vcvtis(S1, S0);
+ __ vmovrs(R0, S1);
__ Ret();
}
ASSEMBLER_TEST_RUN(FloatToIntConversion, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*FloatToIntConversion)(float arg) DART_UNUSED;
- EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
- 12.8f));
- EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
- test->entry(), -FLT_MAX));
- EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
- test->entry(), FLT_MAX));
- }
+ typedef int (*FloatToIntConversion)(float arg) DART_UNUSED;
+ EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion, test->entry(),
+ 12.8f));
+ EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
+ test->entry(), -FLT_MAX));
+ EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_F(FloatToIntConversion,
+ test->entry(), FLT_MAX));
}
ASSEMBLER_TEST_GENERATE(DoubleToIntConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ vcvtid(S0, D0);
- __ vmovrs(R0, S0);
- }
+ __ vcvtid(S0, D0);
+ __ vmovrs(R0, S0);
__ Ret();
}
ASSEMBLER_TEST_RUN(DoubleToIntConversion, test) {
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED;
- EXPECT(test != NULL);
- EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
- test->entry(), 12.8));
- EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
- test->entry(), -DBL_MAX));
- EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
- test->entry(), DBL_MAX));
- }
+ typedef int (*DoubleToIntConversion)(double arg) DART_UNUSED;
+ EXPECT(test != NULL);
+ EXPECT_EQ(12, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(),
+ 12.8));
+ EXPECT_EQ(INT32_MIN, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
+ test->entry(), -DBL_MAX));
+ EXPECT_EQ(INT32_MAX, EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion,
+ test->entry(), DBL_MAX));
}
ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadSImmediate(S2, 12.8f);
- __ vcvtds(D0, S2);
- }
+ __ LoadSImmediate(S2, 12.8f);
+ __ vcvtds(D0, S2);
__ Ret();
}
ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) {
- if (TargetCPUFeatures::vfp_supported()) {
- typedef double (*FloatToDoubleConversionCode)() DART_UNUSED;
- EXPECT(test != NULL);
- double res =
- EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, test->entry());
- EXPECT_FLOAT_EQ(12.8, res, 0.001);
- }
+ typedef double (*FloatToDoubleConversionCode)() DART_UNUSED;
+ EXPECT(test != NULL);
+ double res =
+ EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, test->entry());
+ EXPECT_FLOAT_EQ(12.8, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadDImmediate(D1, 12.8, R0);
- __ vcvtsd(S0, D1);
- }
+ __ LoadDImmediate(D1, 12.8, R0);
+ __ vcvtsd(S0, D1);
__ Ret();
}
ASSEMBLER_TEST_RUN(DoubleToFloatConversion, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef float (*DoubleToFloatConversionCode)() DART_UNUSED;
- float res =
- EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, test->entry());
- EXPECT_FLOAT_EQ(12.8, res, 0.001);
- }
+ typedef float (*DoubleToFloatConversionCode)() DART_UNUSED;
+ float res =
+ EXECUTE_TEST_CODE_FLOAT(DoubleToFloatConversionCode, test->entry());
+ EXPECT_FLOAT_EQ(12.8, res, 0.001);
}
ASSEMBLER_TEST_GENERATE(FloatCompare, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
// Test 12.3f vs 12.5f.
__ LoadSImmediate(S0, 12.3f);
__ LoadSImmediate(S1, 12.5f);
@@ -605,21 +547,17 @@
__ vmstat();
// Error if not unordered (not Nan).
__ add(R0, R0, Operand(16), VC);
- }
- // R0 is 0 if all tests passed.
- __ Ret();
+ // R0 is 0 if all tests passed.
+ __ Ret();
}
ASSEMBLER_TEST_RUN(FloatCompare, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*FloatCompare)() DART_UNUSED;
- EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(FloatCompare, test->entry()));
- }
+ typedef int (*FloatCompare)() DART_UNUSED;
+ EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(FloatCompare, test->entry()));
}
ASSEMBLER_TEST_GENERATE(DoubleCompare, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
// Test 12.3 vs 12.5.
__ LoadDImmediate(D0, 12.3, R1);
__ LoadDImmediate(D1, 12.5, R1);
@@ -641,17 +579,14 @@
__ vmstat();
// Error if not unordered (not Nan).
__ add(R0, R0, Operand(16), VC);
- }
- // R0 is 0 if all tests passed.
- __ Ret();
+ // R0 is 0 if all tests passed.
+ __ Ret();
}
ASSEMBLER_TEST_RUN(DoubleCompare, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*DoubleCompare)() DART_UNUSED;
- EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleCompare, test->entry()));
- }
+ typedef int (*DoubleCompare)() DART_UNUSED;
+ EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleCompare, test->entry()));
}
ASSEMBLER_TEST_GENERATE(Loop, assembler) {
@@ -976,28 +911,24 @@
}
ASSEMBLER_TEST_GENERATE(QuotientRemainder, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ vmovsr(S2, R0);
- __ vmovsr(S4, R2);
- __ vcvtdi(D1, S2);
- __ vcvtdi(D2, S4);
- __ vdivd(D0, D1, D2);
- __ vcvtid(S0, D0);
- __ vmovrs(R1, S0); // r1 = r0/r2
- __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2
- }
+ __ vmovsr(S2, R0);
+ __ vmovsr(S4, R2);
+ __ vcvtdi(D1, S2);
+ __ vcvtdi(D2, S4);
+ __ vdivd(D0, D1, D2);
+ __ vcvtid(S0, D0);
+ __ vmovrs(R1, S0); // r1 = r0/r2
+ __ mls(R0, R1, R2, R0); // r0 = r0 - r1*r2
__ Ret();
}
ASSEMBLER_TEST_RUN(QuotientRemainder, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor)
- DART_UNUSED;
- EXPECT_EQ(0x1000400000da8LL,
- EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(),
- 0x12345678, 0x1234));
- }
+ typedef int64_t (*QuotientRemainder)(int64_t dividend, int64_t divisor)
+ DART_UNUSED;
+ EXPECT_EQ(0x1000400000da8LL,
+ EXECUTE_TEST_CODE_INT64_LL(QuotientRemainder, test->entry(),
+ 0x12345678, 0x1234));
}
ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) {
@@ -1437,332 +1368,308 @@
// Make sure we can store and reload the D registers using vstmd and vldmd
ASSEMBLER_TEST_GENERATE(VstmdVldmd, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadDImmediate(D0, 0.0, R0);
- __ LoadDImmediate(D1, 1.0, R0);
- __ LoadDImmediate(D2, 2.0, R0);
- __ LoadDImmediate(D3, 3.0, R0);
- __ LoadDImmediate(D4, 4.0, R0);
- __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
- __ LoadDImmediate(D0, 0.0, R0);
- __ LoadDImmediate(D1, 0.0, R0);
- __ LoadDImmediate(D2, 0.0, R0);
- __ LoadDImmediate(D3, 0.0, R0);
- __ LoadDImmediate(D4, 0.0, R0);
- __ vldmd(IA_W, SP, D0, 5); // Pop stack into D0 - D4, inc SP
+ __ LoadDImmediate(D0, 0.0, R0);
+ __ LoadDImmediate(D1, 1.0, R0);
+ __ LoadDImmediate(D2, 2.0, R0);
+ __ LoadDImmediate(D3, 3.0, R0);
+ __ LoadDImmediate(D4, 4.0, R0);
+ __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
+ __ LoadDImmediate(D0, 0.0, R0);
+ __ LoadDImmediate(D1, 0.0, R0);
+ __ LoadDImmediate(D2, 0.0, R0);
+ __ LoadDImmediate(D3, 0.0, R0);
+ __ LoadDImmediate(D4, 0.0, R0);
+ __ vldmd(IA_W, SP, D0, 5); // Pop stack into D0 - D4, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is back in D4
- __ LoadDImmediate(D5, 4.0, R1);
- __ vcmpd(D4, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 4.0 is back in D4
+ __ LoadDImmediate(D5, 4.0, R1);
+ __ vcmpd(D4, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 3.0 is back in D3
- __ LoadDImmediate(D5, 3.0, R1);
- __ vcmpd(D3, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 3.0 is back in D3
+ __ LoadDImmediate(D5, 3.0, R1);
+ __ vcmpd(D3, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 2.0 is back in D2
- __ LoadDImmediate(D5, 2.0, R1);
- __ vcmpd(D2, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 2.0 is back in D2
+ __ LoadDImmediate(D5, 2.0, R1);
+ __ vcmpd(D2, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 1.0 is back in D1
- __ LoadDImmediate(D5, 1.0, R1);
- __ vcmpd(D1, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- }
+ // Check that 1.0 is back in D1
+ __ LoadDImmediate(D5, 1.0, R1);
+ __ vcmpd(D1, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmdVldmd, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// Make sure we can store and reload the S registers using vstms and vldms
ASSEMBLER_TEST_GENERATE(VstmsVldms, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadSImmediate(S0, 0.0);
- __ LoadSImmediate(S1, 1.0);
- __ LoadSImmediate(S2, 2.0);
- __ LoadSImmediate(S3, 3.0);
- __ LoadSImmediate(S4, 4.0);
- __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
- __ LoadSImmediate(S0, 0.0);
- __ LoadSImmediate(S1, 0.0);
- __ LoadSImmediate(S2, 0.0);
- __ LoadSImmediate(S3, 0.0);
- __ LoadSImmediate(S4, 0.0);
- __ vldms(IA_W, SP, S0, S4); // Pop stack into S0 - S4, inc SP
+ __ LoadSImmediate(S0, 0.0);
+ __ LoadSImmediate(S1, 1.0);
+ __ LoadSImmediate(S2, 2.0);
+ __ LoadSImmediate(S3, 3.0);
+ __ LoadSImmediate(S4, 4.0);
+ __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
+ __ LoadSImmediate(S0, 0.0);
+ __ LoadSImmediate(S1, 0.0);
+ __ LoadSImmediate(S2, 0.0);
+ __ LoadSImmediate(S3, 0.0);
+ __ LoadSImmediate(S4, 0.0);
+ __ vldms(IA_W, SP, S0, S4); // Pop stack into S0 - S4, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is back in S4
- __ LoadSImmediate(S5, 4.0);
- __ vcmps(S4, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 4.0 is back in S4
+ __ LoadSImmediate(S5, 4.0);
+ __ vcmps(S4, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 3.0 is back in S3
- __ LoadSImmediate(S5, 3.0);
- __ vcmps(S3, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 3.0 is back in S3
+ __ LoadSImmediate(S5, 3.0);
+ __ vcmps(S3, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 2.0 is back in S2
- __ LoadSImmediate(S5, 2.0);
- __ vcmps(S2, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 2.0 is back in S2
+ __ LoadSImmediate(S5, 2.0);
+ __ vcmps(S2, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 1.0 is back in S1
- __ LoadSImmediate(S5, 1.0);
- __ vcmps(S1, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- }
+ // Check that 1.0 is back in S1
+ __ LoadSImmediate(S5, 1.0);
+ __ vcmps(S1, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmsVldms, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// Make sure we can start somewhere other than D0
ASSEMBLER_TEST_GENERATE(VstmdVldmd1, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadDImmediate(D1, 1.0, R0);
- __ LoadDImmediate(D2, 2.0, R0);
- __ LoadDImmediate(D3, 3.0, R0);
- __ LoadDImmediate(D4, 4.0, R0);
- __ vstmd(DB_W, SP, D1, 4); // Push D1 - D4 onto the stack, dec SP
- __ LoadDImmediate(D1, 0.0, R0);
- __ LoadDImmediate(D2, 0.0, R0);
- __ LoadDImmediate(D3, 0.0, R0);
- __ LoadDImmediate(D4, 0.0, R0);
- __ vldmd(IA_W, SP, D1, 4); // Pop stack into D1 - D4, inc SP
+ __ LoadDImmediate(D1, 1.0, R0);
+ __ LoadDImmediate(D2, 2.0, R0);
+ __ LoadDImmediate(D3, 3.0, R0);
+ __ LoadDImmediate(D4, 4.0, R0);
+ __ vstmd(DB_W, SP, D1, 4); // Push D1 - D4 onto the stack, dec SP
+ __ LoadDImmediate(D1, 0.0, R0);
+ __ LoadDImmediate(D2, 0.0, R0);
+ __ LoadDImmediate(D3, 0.0, R0);
+ __ LoadDImmediate(D4, 0.0, R0);
+ __ vldmd(IA_W, SP, D1, 4); // Pop stack into D1 - D4, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is back in D4
- __ LoadDImmediate(D5, 4.0, R1);
- __ vcmpd(D4, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 4.0 is back in D4
+ __ LoadDImmediate(D5, 4.0, R1);
+ __ vcmpd(D4, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 3.0 is back in D3
- __ LoadDImmediate(D5, 3.0, R1);
- __ vcmpd(D3, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 3.0 is back in D3
+ __ LoadDImmediate(D5, 3.0, R1);
+ __ vcmpd(D3, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 2.0 is back in D2
- __ LoadDImmediate(D5, 2.0, R1);
- __ vcmpd(D2, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 2.0 is back in D2
+ __ LoadDImmediate(D5, 2.0, R1);
+ __ vcmpd(D2, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 1.0 is back in D1
- __ LoadDImmediate(D5, 1.0, R1);
- __ vcmpd(D1, D5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- }
+ // Check that 1.0 is back in D1
+ __ LoadDImmediate(D5, 1.0, R1);
+ __ vcmpd(D1, D5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmdVldmd1, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// Make sure we can start somewhere other than S0
ASSEMBLER_TEST_GENERATE(VstmsVldms1, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadSImmediate(S1, 1.0);
- __ LoadSImmediate(S2, 2.0);
- __ LoadSImmediate(S3, 3.0);
- __ LoadSImmediate(S4, 4.0);
- __ vstms(DB_W, SP, S1, S4); // Push S0 - S4 onto the stack, dec SP
- __ LoadSImmediate(S1, 0.0);
- __ LoadSImmediate(S2, 0.0);
- __ LoadSImmediate(S3, 0.0);
- __ LoadSImmediate(S4, 0.0);
- __ vldms(IA_W, SP, S1, S4); // Pop stack into S0 - S4, inc SP
+ __ LoadSImmediate(S1, 1.0);
+ __ LoadSImmediate(S2, 2.0);
+ __ LoadSImmediate(S3, 3.0);
+ __ LoadSImmediate(S4, 4.0);
+ __ vstms(DB_W, SP, S1, S4); // Push S0 - S4 onto the stack, dec SP
+ __ LoadSImmediate(S1, 0.0);
+ __ LoadSImmediate(S2, 0.0);
+ __ LoadSImmediate(S3, 0.0);
+ __ LoadSImmediate(S4, 0.0);
+ __ vldms(IA_W, SP, S1, S4); // Pop stack into S0 - S4, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is back in S4
- __ LoadSImmediate(S5, 4.0);
- __ vcmps(S4, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 4.0 is back in S4
+ __ LoadSImmediate(S5, 4.0);
+ __ vcmps(S4, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 3.0 is back in S3
- __ LoadSImmediate(S5, 3.0);
- __ vcmps(S3, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 3.0 is back in S3
+ __ LoadSImmediate(S5, 3.0);
+ __ vcmps(S3, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 2.0 is back in S2
- __ LoadSImmediate(S5, 2.0);
- __ vcmps(S2, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 2.0 is back in S2
+ __ LoadSImmediate(S5, 2.0);
+ __ vcmps(S2, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 1.0 is back in S1
- __ LoadSImmediate(S5, 1.0);
- __ vcmps(S1, S5);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- }
+ // Check that 1.0 is back in S1
+ __ LoadSImmediate(S5, 1.0);
+ __ vcmps(S1, S5);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmsVldms1, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// Make sure we can store the D registers using vstmd and
// load them into a different set using vldmd
ASSEMBLER_TEST_GENERATE(VstmdVldmd_off, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- // Save used callee-saved FPU registers.
- __ vstmd(DB_W, SP, D8, 3);
- __ LoadDImmediate(D0, 0.0, R0);
- __ LoadDImmediate(D1, 1.0, R0);
- __ LoadDImmediate(D2, 2.0, R0);
- __ LoadDImmediate(D3, 3.0, R0);
- __ LoadDImmediate(D4, 4.0, R0);
- __ LoadDImmediate(D5, 5.0, R0);
- __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
- __ vldmd(IA_W, SP, D5, 5); // Pop stack into D5 - D9, inc SP
+ // Save used callee-saved FPU registers.
+ __ vstmd(DB_W, SP, D8, 3);
+ __ LoadDImmediate(D0, 0.0, R0);
+ __ LoadDImmediate(D1, 1.0, R0);
+ __ LoadDImmediate(D2, 2.0, R0);
+ __ LoadDImmediate(D3, 3.0, R0);
+ __ LoadDImmediate(D4, 4.0, R0);
+ __ LoadDImmediate(D5, 5.0, R0);
+ __ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
+ __ vldmd(IA_W, SP, D5, 5); // Pop stack into D5 - D9, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is in D9
- __ LoadDImmediate(D10, 4.0, R1);
- __ vcmpd(D9, D10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 4.0 is in D9
+ __ LoadDImmediate(D10, 4.0, R1);
+ __ vcmpd(D9, D10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 3.0 is in D8
- __ LoadDImmediate(D10, 3.0, R1);
- __ vcmpd(D8, D10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 3.0 is in D8
+ __ LoadDImmediate(D10, 3.0, R1);
+ __ vcmpd(D8, D10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 2.0 is in D7
- __ LoadDImmediate(D10, 2.0, R1);
- __ vcmpd(D7, D10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 2.0 is in D7
+ __ LoadDImmediate(D10, 2.0, R1);
+ __ vcmpd(D7, D10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 1.0 is in D6
- __ LoadDImmediate(D10, 1.0, R1);
- __ vcmpd(D6, D10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 1.0 is in D6
+ __ LoadDImmediate(D10, 1.0, R1);
+ __ vcmpd(D6, D10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Check that 0.0 is in D5
- __ LoadDImmediate(D10, 0.0, R1);
- __ vcmpd(D5, D10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
+ // Check that 0.0 is in D5
+ __ LoadDImmediate(D10, 0.0, R1);
+ __ vcmpd(D5, D10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure into R0 if NE
- // Restore used callee-saved FPU registers.
- __ vldmd(IA_W, SP, D8, 3);
- }
+ // Restore used callee-saved FPU registers.
+ __ vldmd(IA_W, SP, D8, 3);
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmdVldmd_off, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// Make sure we can start somewhere other than S0
ASSEMBLER_TEST_GENERATE(VstmsVldms_off, assembler) {
- if (TargetCPUFeatures::vfp_supported()) {
- __ LoadSImmediate(S0, 0.0);
- __ LoadSImmediate(S1, 1.0);
- __ LoadSImmediate(S2, 2.0);
- __ LoadSImmediate(S3, 3.0);
- __ LoadSImmediate(S4, 4.0);
- __ LoadSImmediate(S5, 5.0);
- __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
- __ vldms(IA_W, SP, S5, S9); // Pop stack into S5 - S9, inc SP
+ __ LoadSImmediate(S0, 0.0);
+ __ LoadSImmediate(S1, 1.0);
+ __ LoadSImmediate(S2, 2.0);
+ __ LoadSImmediate(S3, 3.0);
+ __ LoadSImmediate(S4, 4.0);
+ __ LoadSImmediate(S5, 5.0);
+ __ vstms(DB_W, SP, S0, S4); // Push S0 - S4 onto the stack, dec SP
+ __ vldms(IA_W, SP, S5, S9); // Pop stack into S5 - S9, inc SP
- // Load success value into R0
- __ mov(R0, Operand(42));
+ // Load success value into R0
+ __ mov(R0, Operand(42));
- // Check that 4.0 is in S9
- __ LoadSImmediate(S10, 4.0);
- __ vcmps(S9, S10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 4.0 is in S9
+ __ LoadSImmediate(S10, 4.0);
+ __ vcmps(S9, S10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 3.0 is in S8
- __ LoadSImmediate(S10, 3.0);
- __ vcmps(S8, S10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 3.0 is in S8
+ __ LoadSImmediate(S10, 3.0);
+ __ vcmps(S8, S10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 2.0 is in S7
- __ LoadSImmediate(S10, 2.0);
- __ vcmps(S7, S10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 2.0 is in S7
+ __ LoadSImmediate(S10, 2.0);
+ __ vcmps(S7, S10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 1.0 is back in S6
- __ LoadSImmediate(S10, 1.0);
- __ vcmps(S6, S10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
+ // Check that 1.0 is back in S6
+ __ LoadSImmediate(S10, 1.0);
+ __ vcmps(S6, S10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- // Check that 0.0 is back in S5
- __ LoadSImmediate(S10, 0.0);
- __ vcmps(S5, S10);
- __ vmstat();
- __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
- }
+ // Check that 0.0 is back in S5
+ __ LoadSImmediate(S10, 0.0);
+ __ vcmps(S5, S10);
+ __ vmstat();
+ __ mov(R0, Operand(0), NE); // Put failure value into R0 if NE
__ Ret();
}
ASSEMBLER_TEST_RUN(VstmsVldms_off, test) {
EXPECT(test != NULL);
- if (TargetCPUFeatures::vfp_supported()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
}
// 3 2 1 0
@@ -1942,11 +1849,9 @@
HostCPUFeatures::set_integer_division_supported(orig);
__ Ret();
#else
- if (TargetCPUFeatures::can_divide()) {
- __ mov(R0, Operand(27));
- __ mov(R1, Operand(9));
- __ IntegerDivide(R0, R0, R1, D0, D1);
- }
+ __ mov(R0, Operand(27));
+ __ mov(R1, Operand(9));
+ __ IntegerDivide(R0, R0, R1, D0, D1);
__ Ret();
#endif
}
@@ -1956,36 +1861,28 @@
#if defined(USING_SIMULATOR)
bool orig = TargetCPUFeatures::integer_division_supported();
HostCPUFeatures::set_integer_division_supported(true);
- if (TargetCPUFeatures::can_divide()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
HostCPUFeatures::set_integer_division_supported(orig);
#else
- if (TargetCPUFeatures::can_divide()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
#endif
}
ASSEMBLER_TEST_GENERATE(IntDiv_unsupported, assembler) {
#if defined(USING_SIMULATOR)
- if (TargetCPUFeatures::can_divide()) {
bool orig = TargetCPUFeatures::integer_division_supported();
HostCPUFeatures::set_integer_division_supported(false);
__ mov(R0, Operand(27));
__ mov(R1, Operand(9));
__ IntegerDivide(R0, R0, R1, D0, D1);
HostCPUFeatures::set_integer_division_supported(orig);
- }
__ Ret();
#else
- if (TargetCPUFeatures::can_divide()) {
- __ mov(R0, Operand(27));
- __ mov(R1, Operand(9));
- __ IntegerDivide(R0, R0, R1, D0, D1);
- }
+ __ mov(R0, Operand(27));
+ __ mov(R1, Operand(9));
+ __ IntegerDivide(R0, R0, R1, D0, D1);
__ Ret();
#endif
}
@@ -1995,16 +1892,12 @@
#if defined(USING_SIMULATOR)
bool orig = TargetCPUFeatures::integer_division_supported();
HostCPUFeatures::set_integer_division_supported(false);
- if (TargetCPUFeatures::can_divide()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
HostCPUFeatures::set_integer_division_supported(orig);
#else
- if (TargetCPUFeatures::can_divide()) {
- typedef int (*Tst)() DART_UNUSED;
- EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
- }
+ typedef int (*Tst)() DART_UNUSED;
+ EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
#endif
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 7bf8100..975e431 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -471,7 +471,6 @@
static bool SupportsUnboxedDoubles();
static bool SupportsUnboxedSimd128();
- static bool SupportsHardwareDivision();
static bool CanConvertInt64ToDouble();
// Accessors.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 3402cb2..d95dd98 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -66,17 +66,13 @@
}
bool FlowGraphCompiler::SupportsUnboxedDoubles() {
- return TargetCPUFeatures::vfp_supported() && FLAG_unbox_doubles;
+ return FLAG_unbox_doubles;
}
bool FlowGraphCompiler::SupportsUnboxedSimd128() {
return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline;
}
-bool FlowGraphCompiler::SupportsHardwareDivision() {
- return TargetCPUFeatures::can_divide();
-}
-
bool FlowGraphCompiler::CanConvertInt64ToDouble() {
// ARM does not have a short instruction sequence for converting int64 to
// double.
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index d7e4d14..abad72a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -73,10 +73,6 @@
return true;
}
-bool FlowGraphCompiler::SupportsHardwareDivision() {
- return true;
-}
-
void FlowGraphCompiler::EnterIntrinsicMode() {
ASSERT(!intrinsic_mode());
intrinsic_mode_ = true;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index d613572..1daf4c0 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -48,10 +48,6 @@
return FLAG_enable_simd_inline;
}
-bool FlowGraphCompiler::SupportsHardwareDivision() {
- return true;
-}
-
bool FlowGraphCompiler::CanConvertInt64ToDouble() {
return true;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 03922aa..91cc786 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -70,10 +70,6 @@
return FLAG_enable_simd_inline;
}
-bool FlowGraphCompiler::SupportsHardwareDivision() {
- return true;
-}
-
bool FlowGraphCompiler::CanConvertInt64ToDouble() {
return true;
}
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 3e956fe..d15b079 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -4139,7 +4139,6 @@
break;
}
case Token::kTRUNCDIV: {
- ASSERT(TargetCPUFeatures::can_divide());
if (RangeUtils::CanBeZero(right_range())) {
// Handle divide by zero in runtime.
__ cmp(right, compiler::Operand(0));
@@ -4161,7 +4160,6 @@
break;
}
case Token::kMOD: {
- ASSERT(TargetCPUFeatures::can_divide());
if (RangeUtils::CanBeZero(right_range())) {
// Handle divide by zero in runtime.
__ cmp(right, compiler::Operand(0));
@@ -6229,7 +6227,6 @@
compiler::Label* deopt =
compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
- ASSERT(TargetCPUFeatures::can_divide());
const Register left = locs()->in(0).reg();
const Register right = locs()->in(1).reg();
ASSERT(locs()->out(0).IsPairLocation());
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index dd01b09..56c5604 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -597,15 +597,9 @@
Add(Location::RegisterLocation(reg));
}
-#if defined(TARGET_ARCH_ARM)
- if (TargetCPUFeatures::vfp_supported()) {
-#endif
for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
Add(Location::FpuRegisterLocation(static_cast<FpuRegister>(i)));
}
-#if defined(TARGET_ARCH_ARM)
- }
-#endif
}
void AddAllArgumentRegisters() {
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 90d1657..c6325a5 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -539,7 +539,6 @@
}
break;
case Token::kDIV:
- if (!FlowGraphCompiler::SupportsHardwareDivision()) return false;
if (ShouldSpecializeForDouble(binary_feedback) ||
binary_feedback.OperandsAre(kSmiCid)) {
operands_type = kDoubleCid;
@@ -593,7 +592,6 @@
break;
case Token::kMOD:
case Token::kTRUNCDIV:
- if (!FlowGraphCompiler::SupportsHardwareDivision()) return false;
if (binary_feedback.OperandsAre(kSmiCid)) {
if (call->ic_data()->HasDeoptReason(ICData::kDeoptBinarySmiOp)) {
return false;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ccdc992..314505e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -364,7 +364,7 @@
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
- /* positional_parameter_count = */ NULL); // read arguments.
+ /* positional_parameter_count = */ nullptr); // read arguments.
argument_count += 1;
Class& parent_klass = GetSuperOrDie();
@@ -390,7 +390,7 @@
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
- /* positional_parameter_count = */ NULL); // read arguments.
+ /* positional_parameter_count = */ nullptr); // read arguments.
argument_count += 1;
const Function& target = Function::ZoneHandle(
@@ -487,7 +487,7 @@
ASSERT(yield_continuations().is_empty() || !dart_function.IsGeneric());
LocalVariable* fn_type_args = parsed_function()->function_type_arguments();
- ASSERT(fn_type_args != NULL && closure != NULL);
+ ASSERT(fn_type_args != nullptr && closure != nullptr);
if (dart_function.IsGeneric()) {
prologue += LoadLocal(fn_type_args);
@@ -527,7 +527,8 @@
// Prepend an entry corresponding to normal entry to the function.
yield_continuations().InsertAt(
- 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), kInvalidTryIndex));
+ 0,
+ YieldContinuation(new (Z) DropTempsInstr(0, nullptr), kInvalidTryIndex));
yield_continuations()[0].entry->LinkTo(body.entry);
// Load :await_jump_var into a temporary.
@@ -648,7 +649,7 @@
ASSERT((function.HasOptionalParameters() &&
raw_parameter.owner() == scope) ||
(!function.HasOptionalParameters() &&
- raw_parameter.owner() == NULL));
+ raw_parameter.owner() == nullptr));
ASSERT(!raw_parameter.is_captured());
// Copy the parameter from the stack to the context.
@@ -1017,7 +1018,7 @@
break;
}
UNREACHABLE();
- return NULL;
+ return nullptr;
}
void StreamingFlowGraphBuilder::ParseKernelASTFunction() {
@@ -1239,52 +1240,52 @@
return Fragment();
}
-Fragment StreamingFlowGraphBuilder::BuildStatement() {
+Fragment StreamingFlowGraphBuilder::BuildStatement(TokenPosition* position) {
intptr_t offset = ReaderOffset();
Tag tag = ReadTag(); // read tag.
switch (tag) {
case kExpressionStatement:
- return BuildExpressionStatement();
+ return BuildExpressionStatement(position);
case kBlock:
- return BuildBlock();
+ return BuildBlock(position);
case kEmptyStatement:
return BuildEmptyStatement();
case kAssertBlock:
- return BuildAssertBlock();
+ return BuildAssertBlock(position);
case kAssertStatement:
- return BuildAssertStatement();
+ return BuildAssertStatement(position);
case kLabeledStatement:
- return BuildLabeledStatement();
+ return BuildLabeledStatement(position);
case kBreakStatement:
- return BuildBreakStatement();
+ return BuildBreakStatement(position);
case kWhileStatement:
- return BuildWhileStatement();
+ return BuildWhileStatement(position);
case kDoStatement:
- return BuildDoStatement();
+ return BuildDoStatement(position);
case kForStatement:
- return BuildForStatement();
+ return BuildForStatement(position);
case kForInStatement:
- return BuildForInStatement(false);
+ return BuildForInStatement(false, position);
case kAsyncForInStatement:
- return BuildForInStatement(true);
+ return BuildForInStatement(true, position);
case kSwitchStatement:
- return BuildSwitchStatement();
+ return BuildSwitchStatement(position);
case kContinueSwitchStatement:
- return BuildContinueSwitchStatement();
+ return BuildContinueSwitchStatement(position);
case kIfStatement:
- return BuildIfStatement();
+ return BuildIfStatement(position);
case kReturnStatement:
- return BuildReturnStatement();
+ return BuildReturnStatement(position);
case kTryCatch:
- return BuildTryCatch();
+ return BuildTryCatch(position);
case kTryFinally:
- return BuildTryFinally();
+ return BuildTryFinally(position);
case kYieldStatement:
- return BuildYieldStatement();
+ return BuildYieldStatement(position);
case kVariableDeclaration:
- return BuildVariableDeclaration();
+ return BuildVariableDeclaration(position);
case kFunctionDeclaration:
- return BuildFunctionDeclaration(offset);
+ return BuildFunctionDeclaration(offset, position);
default:
ReportUnexpectedTag("statement", tag);
UNREACHABLE();
@@ -1294,7 +1295,7 @@
void StreamingFlowGraphBuilder::ReportUnexpectedTag(const char* variant,
Tag tag) {
- if ((flow_graph_builder_ == NULL) || (parsed_function() == NULL)) {
+ if ((flow_graph_builder_ == nullptr) || (parsed_function() == nullptr)) {
KernelReaderHelper::ReportUnexpectedTag(variant, tag);
} else {
H.ReportError(script_, TokenPosition::kNoSource,
@@ -1974,7 +1975,7 @@
intptr_t* argument_count,
intptr_t* positional_count) {
intptr_t dummy;
- if (argument_count == NULL) argument_count = &dummy;
+ if (argument_count == nullptr) argument_count = &dummy;
*argument_count = ReadUInt(); // read arguments count.
// List of types.
@@ -1982,7 +1983,7 @@
{
AlternativeReadingScope _(&reader_);
- if (positional_count == NULL) positional_count = &dummy;
+ if (positional_count == nullptr) positional_count = &dummy;
*positional_count = ReadListLength(); // read length of expression list
}
return BuildArgumentsFromActualArguments(argument_names);
@@ -2000,14 +2001,14 @@
// List of named.
list_length = ReadListLength(); // read list length.
- if (argument_names != NULL && list_length > 0) {
+ if (argument_names != nullptr && list_length > 0) {
*argument_names = Array::New(list_length, Heap::kOld);
}
for (intptr_t i = 0; i < list_length; ++i) {
String& name =
H.DartSymbolObfuscate(ReadStringReference()); // read ith name index.
instructions += BuildExpression(); // read ith expression.
- if (argument_names != NULL) {
+ if (argument_names != nullptr) {
argument_names->SetAt(i, name);
}
}
@@ -2021,7 +2022,7 @@
// [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special
// situations (e.g. an invalid annotation).
TokenPosition pos = ReadPosition();
- if (position != NULL) *position = pos;
+ if (position != nullptr) *position = pos;
const String& message = H.DartString(ReadStringReference());
Tag tag = ReadTag(); // read (first part of) expression.
if (tag == kSomething) {
@@ -2129,7 +2130,7 @@
Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
ReadUInt(); // read relative variable index.
@@ -2139,7 +2140,7 @@
Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
return BuildVariableSetImpl(position, variable_kernel_position);
@@ -2629,7 +2630,7 @@
Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@@ -2705,7 +2706,7 @@
Fragment StreamingFlowGraphBuilder::BuildSuperPropertySet(TokenPosition* p) {
const TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
Class& klass = GetSuperOrDie();
@@ -2772,7 +2773,7 @@
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@@ -2836,7 +2837,7 @@
Fragment StreamingFlowGraphBuilder::BuildStaticSet(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
NameIndex target = ReadCanonicalNameReference(); // read target_reference.
ASSERT(H.IsSetter(target));
@@ -2885,7 +2886,7 @@
const bool is_invariant = (flags & kInstanceInvocationFlagInvariant) != 0;
const TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const DirectCallMetadata direct_call =
direct_call_metadata_helper_.GetDirectTargetForMethodInvocation(offset);
@@ -2908,7 +2909,7 @@
Fragment instructions;
intptr_t type_args_len = 0;
- LocalVariable* type_arguments_temp = NULL;
+ LocalVariable* type_arguments_temp = nullptr;
{
AlternativeReadingScope alt(&reader_);
SkipExpression(); // skip receiver
@@ -2950,8 +2951,8 @@
ASSERT(type_args_len == 0);
// "==" or "!=" with null on either side.
instructions +=
- BuildArguments(NULL /* named */, NULL /* arg count */,
- NULL /* positional arg count */); // read arguments.
+ BuildArguments(nullptr /* named */, nullptr /* arg count */,
+ nullptr /* positional arg count */); // read arguments.
SkipInterfaceMemberNameReference(); // read interface_target_reference.
Token::Kind strict_cmp_kind =
token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
@@ -2959,11 +2960,11 @@
StrictCompare(position, strict_cmp_kind, /*number_check = */ true);
}
- LocalVariable* receiver_temp = NULL;
+ LocalVariable* receiver_temp = nullptr;
if (direct_call.check_receiver_for_null_) {
// Duplicate receiver for CheckNull before it is consumed by PushArgument.
receiver_temp = MakeTemporary();
- if (type_arguments_temp != NULL) {
+ if (type_arguments_temp != nullptr) {
// If call has type arguments then push them before pushing the receiver.
// The stack will contain:
//
@@ -3049,10 +3050,10 @@
}
// Drop temporaries preserving result on the top of the stack.
- ASSERT((receiver_temp != NULL) || (type_arguments_temp == NULL));
- if (receiver_temp != NULL) {
- const intptr_t num_temps =
- (receiver_temp != NULL ? 1 : 0) + (type_arguments_temp != NULL ? 1 : 0);
+ ASSERT((receiver_temp != nullptr) || (type_arguments_temp == nullptr));
+ if (receiver_temp != nullptr) {
+ const intptr_t num_temps = (receiver_temp != nullptr ? 1 : 0) +
+ (type_arguments_temp != nullptr ? 1 : 0);
instructions += DropTempsPreserveTop(num_temps);
}
@@ -3259,7 +3260,7 @@
TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@@ -3383,7 +3384,7 @@
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
- /* positional_argument_count = */ NULL); // read arguments.
+ /* positional_argument_count = */ nullptr); // read arguments.
++argument_count; // include receiver
SkipInterfaceMemberNameReference(); // interfaceTargetReference
return instructions +
@@ -3397,7 +3398,7 @@
Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
@@ -3425,7 +3426,7 @@
}
Fragment instructions;
- LocalVariable* instance_variable = NULL;
+ LocalVariable* instance_variable = nullptr;
const bool special_case_unchecked_cast =
klass.IsTopLevel() && (klass.library() == Library::InternalLibrary()) &&
@@ -3483,11 +3484,11 @@
Array& argument_names = Array::ZoneHandle(Z);
instructions +=
- BuildArguments(&argument_names, NULL /* arg count */,
- NULL /* positional arg count */); // read arguments.
+ BuildArguments(&argument_names, nullptr /* arg count */,
+ nullptr /* positional arg count */); // read arguments.
ASSERT(!special_case ||
target.AreValidArguments(type_args_len, argument_count, argument_names,
- NULL));
+ nullptr));
// Special case identical(x, y) call.
// TODO(27590) consider moving this into the inliner and force inline it
@@ -3514,7 +3515,7 @@
Fragment StreamingFlowGraphBuilder::BuildConstructorInvocation(
TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
NameIndex kernel_name =
ReadCanonicalNameReference(); // read target_reference.
@@ -3555,18 +3556,18 @@
intptr_t argument_count;
instructions += BuildArguments(
&argument_names, &argument_count,
- /* positional_argument_count = */ NULL); // read arguments.
+ /* positional_argument_count = */ nullptr); // read arguments.
const Function& target = Function::ZoneHandle(
Z, H.LookupConstructorByKernelConstructor(klass, kernel_name));
++argument_count;
instructions += StaticCall(position, target, argument_count, argument_names,
- ICData::kStatic, /* result_type = */ NULL);
+ ICData::kStatic, /* result_type = */ nullptr);
return instructions + Drop();
}
Fragment StreamingFlowGraphBuilder::BuildNot(TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
TokenPosition operand_position = TokenPosition::kNoSource;
Fragment instructions =
@@ -3664,7 +3665,7 @@
Fragment StreamingFlowGraphBuilder::BuildLogicalExpression(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
TestFragment exits;
exits.true_successor_addresses = new TestFragment::SuccessorAddressArray(2);
@@ -3701,7 +3702,7 @@
Fragment StreamingFlowGraphBuilder::BuildConditionalExpression(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
TestFragment condition = TranslateConditionForControl(); // read condition.
@@ -3817,7 +3818,7 @@
Fragment StreamingFlowGraphBuilder::BuildIsExpression(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
if (translation_helper_.info().kernel_binary_version() >= 38) {
// We do not use the library mode for the type test, which is indicated by
@@ -3870,7 +3871,7 @@
Fragment StreamingFlowGraphBuilder::BuildAsExpression(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const uint8_t flags = ReadFlags(); // read flags.
const bool is_type_error = (flags & kAsExpressionFlagTypeError) != 0;
@@ -3894,7 +3895,7 @@
}
Fragment StreamingFlowGraphBuilder::BuildTypeLiteral(TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
const AbstractType& type = T.BuildType(); // read type.
Fragment instructions;
@@ -3918,14 +3919,14 @@
Fragment StreamingFlowGraphBuilder::BuildThisExpression(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
return LoadLocal(parsed_function()->receiver_var());
}
Fragment StreamingFlowGraphBuilder::BuildRethrow(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
Fragment instructions = DebugStepCheck(position);
instructions += LoadLocal(catch_block()->exception_var());
@@ -3937,7 +3938,7 @@
Fragment StreamingFlowGraphBuilder::BuildThrow(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
Fragment instructions;
@@ -3954,7 +3955,7 @@
Fragment StreamingFlowGraphBuilder::BuildListLiteral(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const TypeArguments& type_arguments = T.BuildTypeArguments(1); // read type.
intptr_t length = ReadListLength(); // read list length.
@@ -4000,7 +4001,7 @@
Fragment StreamingFlowGraphBuilder::BuildMapLiteral(TokenPosition* p) {
TokenPosition position = ReadPosition(); // read position.
- if (p != NULL) *p = position;
+ if (p != nullptr) *p = position;
const TypeArguments& type_arguments =
T.BuildTypeArguments(2); // read key_type and value_type.
@@ -4057,8 +4058,8 @@
Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* p) {
const TokenPosition position = ReadPosition(); // read position.
if (p != nullptr) *p = position;
- Fragment instructions = BuildVariableDeclaration(); // read variable.
- instructions += BuildExpression(); // read body.
+ Fragment instructions = BuildVariableDeclaration(nullptr); // read variable.
+ instructions += BuildExpression(); // read body.
return instructions;
}
@@ -4082,7 +4083,7 @@
Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
const String& value =
H.DartString(ReadStringReference()); // read index into string table.
@@ -4097,7 +4098,7 @@
Fragment StreamingFlowGraphBuilder::BuildStringLiteral(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(H.DartSymbolPlain(
ReadStringReference())); // read index into string table.
@@ -4105,7 +4106,7 @@
Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload,
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
return IntConstant(value);
@@ -4113,7 +4114,7 @@
Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative,
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt())
: ReadUInt(); // read value.
@@ -4122,7 +4123,7 @@
Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
Double& constant = Double::ZoneHandle(
Z, Double::NewCanonical(ReadDouble())); // read double.
@@ -4131,20 +4132,20 @@
Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value,
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(Bool::Get(value));
}
Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
return Constant(Instance::ZoneHandle(Z, Instance::null()));
}
Fragment StreamingFlowGraphBuilder::BuildFutureNullValue(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
const Class& future = Class::Handle(Z, IG->object_store()->future_class());
ASSERT(!future.IsNull());
const auto& error = future.EnsureIsFinalized(thread());
@@ -4177,7 +4178,7 @@
Fragment StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation(
TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ if (position != nullptr) *position = TokenPosition::kNoSource;
// Create a copy of the closure.
@@ -4264,20 +4265,24 @@
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
- Fragment instructions = BuildExpression(); // read expression.
+Fragment StreamingFlowGraphBuilder::BuildExpressionStatement(
+ TokenPosition* position) {
+ Fragment instructions = BuildExpression(position); // read expression.
instructions += Drop();
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildBlock() {
+Fragment StreamingFlowGraphBuilder::BuildBlock(TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
Fragment instructions;
instructions += EnterScope(offset);
- ReadPosition(); // read file offset.
+ const TokenPosition pos = ReadPosition(); // read file offset.
+ if (position != nullptr) *position = pos;
+
ReadPosition(); // read file end offset.
+
intptr_t list_length = ReadListLength(); // read number of statements.
for (intptr_t i = 0; i < list_length; ++i) {
if (instructions.is_open()) {
@@ -4295,7 +4300,7 @@
return Fragment();
}
-Fragment StreamingFlowGraphBuilder::BuildAssertBlock() {
+Fragment StreamingFlowGraphBuilder::BuildAssertBlock(TokenPosition* position) {
if (!IG->asserts()) {
SkipStatementList();
return Fragment();
@@ -4309,7 +4314,8 @@
intptr_t list_length = ReadListLength(); // read number of statements.
for (intptr_t i = 0; i < list_length; ++i) {
if (instructions.is_open()) {
- instructions += BuildStatement(); // read ith statement.
+ // read ith statement.
+ instructions += BuildStatement(i == 0 ? position : nullptr);
} else {
SkipStatement(); // read ith statement.
}
@@ -4319,7 +4325,8 @@
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
+Fragment StreamingFlowGraphBuilder::BuildAssertStatement(
+ TokenPosition* position) {
if (!IG->asserts()) {
SetOffset(ReaderOffset() - 1); // Include the tag.
SkipStatement(); // read this statement.
@@ -4337,7 +4344,7 @@
//
// The call to `_AssertionError._evaluateAssertion()` will take care of both
// and returns a boolean.
- instructions += BuildExpression(); // read condition.
+ instructions += BuildExpression(position); // read condition.
const TokenPosition condition_start_offset =
ReadPosition(); // read condition start offset.
@@ -4382,7 +4389,8 @@
return Fragment(instructions.entry, then);
}
-Fragment StreamingFlowGraphBuilder::BuildLabeledStatement() {
+Fragment StreamingFlowGraphBuilder::BuildLabeledStatement(
+ TokenPosition* position) {
// There can be serveral cases:
//
// * the body contains a break
@@ -4395,7 +4403,7 @@
// traversed.
BreakableBlock block(flow_graph_builder_);
- Fragment instructions = BuildStatement(); // read body.
+ Fragment instructions = BuildStatement(position); // read body.
if (block.HadJumper()) {
if (instructions.is_open()) {
instructions += Goto(block.destination());
@@ -4406,11 +4414,14 @@
}
}
-Fragment StreamingFlowGraphBuilder::BuildBreakStatement() {
- TokenPosition position = ReadPosition(); // read position.
+Fragment StreamingFlowGraphBuilder::BuildBreakStatement(
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
intptr_t target_index = ReadUInt(); // read target index.
- TryFinallyBlock* outer_finally = NULL;
+ TryFinallyBlock* outer_finally = nullptr;
intptr_t target_context_depth = -1;
JoinEntryInstr* destination = breakable_block()->BreakDestination(
target_index, &outer_finally, &target_context_depth);
@@ -4418,8 +4429,8 @@
Fragment instructions;
// Break statement should pause before manipulation of context, which
// will possibly cause debugger having incorrect context object.
- if (NeedsDebugStepCheck(parsed_function()->function(), position)) {
- instructions += DebugStepCheck(position);
+ if (NeedsDebugStepCheck(parsed_function()->function(), pos)) {
+ instructions += DebugStepCheck(pos);
}
instructions +=
TranslateFinallyFinalizers(outer_finally, target_context_depth);
@@ -4429,10 +4440,13 @@
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
+Fragment StreamingFlowGraphBuilder::BuildWhileStatement(
+ TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no while in block-expr
loop_depth_inc();
- const TokenPosition position = ReadPosition(); // read position.
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
TestFragment condition = TranslateConditionForControl(); // read condition.
const Fragment body = BuildStatement(); // read body
@@ -4446,7 +4460,7 @@
Fragment loop(join);
ASSERT(B->GetStackDepth() == 0);
- loop += CheckStackOverflow(position);
+ loop += CheckStackOverflow(pos);
loop.current->LinkTo(condition.entry);
entry = Goto(join).entry;
@@ -4458,11 +4472,13 @@
return Fragment(entry, condition.CreateFalseSuccessor(flow_graph_builder_));
}
-Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
+Fragment StreamingFlowGraphBuilder::BuildDoStatement(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no do-while in block-expr
loop_depth_inc();
- const TokenPosition position = ReadPosition(); // read position.
- Fragment body = BuildStatement(); // read body.
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
+ Fragment body = BuildStatement(); // read body.
if (body.is_closed()) {
SkipExpression(); // read condition.
@@ -4475,7 +4491,7 @@
JoinEntryInstr* join = BuildJoinEntry();
Fragment loop(join);
ASSERT(B->GetStackDepth() == 0);
- loop += CheckStackOverflow(position);
+ loop += CheckStackOverflow(pos);
loop += body;
loop <<= condition.entry;
@@ -4487,10 +4503,11 @@
condition.CreateFalseSuccessor(flow_graph_builder_));
}
-Fragment StreamingFlowGraphBuilder::BuildForStatement() {
+Fragment StreamingFlowGraphBuilder::BuildForStatement(TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
- const TokenPosition position = ReadPosition(); // read position.
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
Fragment declarations;
@@ -4501,7 +4518,7 @@
intptr_t list_length = ReadListLength(); // read number of variables.
for (intptr_t i = 0; i < list_length; ++i) {
- declarations += BuildVariableDeclaration(); // read ith variable.
+ declarations += BuildVariableDeclaration(nullptr); // read ith variable.
}
Tag tag = ReadTag(); // Read first part of condition.
@@ -4543,7 +4560,7 @@
body += Goto(join);
Fragment loop(join);
- loop += CheckStackOverflow(position); // may have non-empty stack
+ loop += CheckStackOverflow(pos); // may have non-empty stack
if (condition.entry != nullptr) {
loop <<= condition.entry;
} else {
@@ -4566,10 +4583,14 @@
return loop;
}
-Fragment StreamingFlowGraphBuilder::BuildForInStatement(bool async) {
+Fragment StreamingFlowGraphBuilder::BuildForInStatement(
+ bool async,
+ TokenPosition* position) {
intptr_t offset = ReaderOffset() - 1; // Include the tag.
- const TokenPosition position = ReadPosition(); // read position.
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
TokenPosition body_position = ReadPosition(); // read body position.
intptr_t variable_kernel_position = ReaderOffset() + data_program_offset_;
SkipVariableDeclaration(); // read variable.
@@ -4613,7 +4634,7 @@
body += Goto(join);
Fragment loop(join);
- loop += CheckStackOverflow(position); // may have non-empty stack
+ loop += CheckStackOverflow(pos); // may have non-empty stack
loop += condition;
} else {
instructions += condition;
@@ -4624,8 +4645,11 @@
return Fragment(instructions.entry, loop_exit);
}
-Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
- ReadPosition(); // read position.
+Fragment StreamingFlowGraphBuilder::BuildSwitchStatement(
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
// We need the number of cases. So start by getting that, then go back.
intptr_t offset = ReaderOffset();
SkipExpression(); // temporarily skip condition
@@ -4663,7 +4687,7 @@
Fragment& body_fragment = body_fragments[i] =
BuildStatement(); // read body.
- if (body_fragment.entry == NULL) {
+ if (body_fragment.entry == nullptr) {
// Make a NOP in order to ensure linking works properly.
body_fragment = NullConstant();
body_fragment += Drop();
@@ -4750,7 +4774,7 @@
current_instructions += body_fragments[i];
}
} else {
- JoinEntryInstr* body_join = NULL;
+ JoinEntryInstr* body_join = nullptr;
if (block.HadJumper(i)) {
body_join = block.DestinationDirect(i);
body_fragments[i] = Fragment(body_join) + body_fragments[i];
@@ -4760,19 +4784,19 @@
TargetEntryInstr* then;
TargetEntryInstr* otherwise;
- TokenPosition position = ReadPosition(); // read jth position.
+ const TokenPosition pos = ReadPosition(); // read jth position.
current_instructions += Constant(
Instance::ZoneHandle(Z, constant_reader_.ReadConstantExpression()));
current_instructions += LoadLocal(scopes()->switch_variable);
current_instructions +=
- InstanceCall(position, Symbols::EqualOperator(), Token::kEQ,
+ InstanceCall(pos, Symbols::EqualOperator(), Token::kEQ,
/*argument_count=*/2,
/*checked_argument_count=*/2);
current_instructions += BranchIfTrue(&then, &otherwise, false);
Fragment then_fragment(then);
- if (body_join != NULL) {
+ if (body_join != nullptr) {
// There are several branches to the body, so we will make a goto to
// the join block (the real body has already been prepended with a
// join instruction).
@@ -4816,11 +4840,14 @@
return Fragment(head_instructions.entry, current_instructions.current);
}
-Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement() {
- TokenPosition position = ReadPosition(); // read position.
+Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement(
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+
intptr_t target_index = ReadUInt(); // read target index.
- TryFinallyBlock* outer_finally = NULL;
+ TryFinallyBlock* outer_finally = nullptr;
intptr_t target_context_depth = -1;
JoinEntryInstr* entry = switch_block()->Destination(
target_index, &outer_finally, &target_context_depth);
@@ -4829,16 +4856,17 @@
instructions +=
TranslateFinallyFinalizers(outer_finally, target_context_depth);
if (instructions.is_open()) {
- if (NeedsDebugStepCheck(parsed_function()->function(), position)) {
- instructions += DebugStepCheck(position);
+ if (NeedsDebugStepCheck(parsed_function()->function(), pos)) {
+ instructions += DebugStepCheck(pos);
}
instructions += Goto(entry);
}
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildIfStatement() {
- ReadPosition(); // read position.
+Fragment StreamingFlowGraphBuilder::BuildIfStatement(TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
TestFragment condition = TranslateConditionForControl();
@@ -4865,11 +4893,14 @@
}
}
-Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
- TokenPosition position = ReadPosition(); // read position.
- Tag tag = ReadTag(); // read first part of expression.
+Fragment StreamingFlowGraphBuilder::BuildReturnStatement(
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
- bool inside_try_finally = try_finally_block() != NULL;
+ Tag tag = ReadTag(); // read first part of expression.
+
+ bool inside_try_finally = try_finally_block() != nullptr;
Fragment instructions = tag == kNothing
? NullConstant()
@@ -4881,10 +4912,10 @@
scopes()->finally_return_variable;
ASSERT(finally_return_variable != nullptr);
const Function& function = parsed_function()->function();
- if (NeedsDebugStepCheck(function, position)) {
- instructions += DebugStepCheck(position);
+ if (NeedsDebugStepCheck(function, pos)) {
+ instructions += DebugStepCheck(pos);
}
- instructions += StoreLocal(position, finally_return_variable);
+ instructions += StoreLocal(pos, finally_return_variable);
instructions += Drop();
const intptr_t target_context_depth =
finally_return_variable->is_captured()
@@ -4901,7 +4932,7 @@
B->context_depth_ = saved_context_depth;
}
} else {
- instructions += Return(position);
+ instructions += Return(pos);
}
} else {
Pop();
@@ -4910,7 +4941,7 @@
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
+Fragment StreamingFlowGraphBuilder::BuildTryCatch(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no try-catch in block-expr
InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
@@ -4922,7 +4953,7 @@
try_depth_inc();
{
TryCatchBlock block(flow_graph_builder_, try_handler_index);
- try_body += BuildStatement(); // read body.
+ try_body += BuildStatement(position); // read body.
try_body += Goto(after_try);
}
try_depth_dec();
@@ -4945,7 +4976,7 @@
// Fill in the body of the catch.
for (intptr_t i = 0; i < catch_count; ++i) {
intptr_t catch_offset = ReaderOffset(); // Catch has no tag.
- TokenPosition position = ReadPosition(); // read position.
+ TokenPosition pos = ReadPosition(); // read position.
const AbstractType& type_guard = T.BuildType(); // read guard.
handler_types.SetAt(i, type_guard);
@@ -5002,9 +5033,9 @@
catch_body += Constant(type_guard);
- catch_body += InstanceCall(
- position, Library::PrivateCoreLibName(Symbols::_instanceOf()),
- Token::kIS, 4);
+ catch_body +=
+ InstanceCall(pos, Library::PrivateCoreLibName(Symbols::_instanceOf()),
+ Token::kIS, 4);
TargetEntryInstr* catch_entry;
TargetEntryInstr* next_catch_entry;
@@ -5031,7 +5062,7 @@
return Fragment(try_body.entry, after_try);
}
-Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
+Fragment StreamingFlowGraphBuilder::BuildTryFinally(TokenPosition* position) {
ASSERT(block_expression_depth() == 0); // no try-finally in block-expr
// Note on streaming:
// We only stream this TryFinally if we can stream everything inside it,
@@ -5076,7 +5107,7 @@
{
TryFinallyBlock tfb(flow_graph_builder_, finalizer_offset);
TryCatchBlock tcb(flow_graph_builder_, try_handler_index);
- try_body += BuildStatement(); // read body.
+ try_body += BuildStatement(position); // read body.
}
try_depth_dec();
@@ -5115,10 +5146,12 @@
return Fragment(try_body.entry, after_try);
}
-Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
- TokenPosition position = ReadPosition(); // read position.
- uint8_t flags = ReadByte(); // read flags.
+Fragment StreamingFlowGraphBuilder::BuildYieldStatement(
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition(); // read position.
+ if (position != nullptr) *position = pos;
+ uint8_t flags = ReadByte(); // read flags.
ASSERT(flags == kNativeYieldFlags); // Must have been desugared.
// Setup yield/continue point:
@@ -5145,11 +5178,11 @@
StoreLocal(TokenPosition::kNoSource, scopes()->yield_context_variable);
instructions += Drop();
instructions += BuildExpression(); // read expression.
- instructions += Return(position, new_yield_pos);
+ instructions += Return(pos, new_yield_pos);
// Note: DropTempsInstr serves as an anchor instruction. It will not
// be linked into the resulting graph.
- DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL);
+ DropTempsInstr* anchor = new (Z) DropTempsInstr(0, nullptr);
yield_continuations().Add(YieldContinuation(anchor, CurrentTryIndex()));
Fragment continuation(instructions.entry, anchor);
@@ -5189,7 +5222,7 @@
rethrow += LoadLocal(exception_var);
rethrow += LoadLocal(stack_trace_var);
- rethrow += RethrowException(position, kInvalidTryIndex);
+ rethrow += RethrowException(pos, kInvalidTryIndex);
Drop();
// Set current to the end of the no_error branch.
@@ -5199,7 +5232,8 @@
return continuation;
}
-Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration() {
+Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration(
+ TokenPosition* position) {
intptr_t kernel_position_no_tag = ReaderOffset() + data_program_offset_;
LocalVariable* variable = LookupVariable(kernel_position_no_tag);
@@ -5233,6 +5267,7 @@
const TokenPosition debug_position = helper.equals_position_.IsReal()
? helper.equals_position_
: helper.position_;
+ if (position != nullptr) *position = helper.position_;
if (NeedsDebugStepCheck(stack(), debug_position)) {
instructions = DebugStepCheck(debug_position) + instructions;
}
@@ -5241,8 +5276,12 @@
return instructions;
}
-Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration(intptr_t offset) {
- TokenPosition position = ReadPosition();
+Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration(
+ intptr_t offset,
+ TokenPosition* position) {
+ const TokenPosition pos = ReadPosition();
+ if (position != nullptr) *position = pos;
+
const intptr_t variable_offset = ReaderOffset() + data_program_offset_;
// Read variable declaration.
@@ -5271,10 +5310,10 @@
helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
- Fragment instructions = DebugStepCheck(position);
- instructions += BuildFunctionNode(position, helper.name_index_,
+ Fragment instructions = DebugStepCheck(pos);
+ instructions += BuildFunctionNode(pos, helper.name_index_,
has_valid_annotation, has_pragma, offset);
- instructions += StoreLocal(position, LookupVariable(variable_offset));
+ instructions += StoreLocal(pos, LookupVariable(variable_offset));
instructions += Drop();
return instructions;
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 47ed58b..ddfabe2 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -68,8 +68,8 @@
Fragment BuildInitializers(const Class& parent_class);
FlowGraph* BuildGraphOfFunction(bool constructor);
- Fragment BuildExpression(TokenPosition* position = NULL);
- Fragment BuildStatement();
+ Fragment BuildExpression(TokenPosition* position = nullptr);
+ Fragment BuildStatement(TokenPosition* position = nullptr);
// Kernel offset:
// start of function expression -> end of function body statement
@@ -178,7 +178,7 @@
intptr_t argument_count,
const Array& argument_names,
ICData::RebindRule rebind_rule,
- const InferredTypeMetadata* result_type = NULL,
+ const InferredTypeMetadata* result_type = nullptr,
intptr_t type_args_len = 0,
bool use_unchecked_entry = false);
Fragment InstanceCall(TokenPosition position,
@@ -333,26 +333,26 @@
Fragment BuildLibraryPrefixAction(TokenPosition* position,
const String& selector);
- Fragment BuildExpressionStatement();
- Fragment BuildBlock();
+ Fragment BuildExpressionStatement(TokenPosition* position);
+ Fragment BuildBlock(TokenPosition* position);
Fragment BuildEmptyStatement();
- Fragment BuildAssertBlock();
- Fragment BuildAssertStatement();
- Fragment BuildLabeledStatement();
- Fragment BuildBreakStatement();
- Fragment BuildWhileStatement();
- Fragment BuildDoStatement();
- Fragment BuildForStatement();
- Fragment BuildForInStatement(bool async);
- Fragment BuildSwitchStatement();
- Fragment BuildContinueSwitchStatement();
- Fragment BuildIfStatement();
- Fragment BuildReturnStatement();
- Fragment BuildTryCatch();
- Fragment BuildTryFinally();
- Fragment BuildYieldStatement();
- Fragment BuildVariableDeclaration();
- Fragment BuildFunctionDeclaration(intptr_t offset);
+ Fragment BuildAssertBlock(TokenPosition* position);
+ Fragment BuildAssertStatement(TokenPosition* position);
+ Fragment BuildLabeledStatement(TokenPosition* position);
+ Fragment BuildBreakStatement(TokenPosition* position);
+ Fragment BuildWhileStatement(TokenPosition* position);
+ Fragment BuildDoStatement(TokenPosition* position);
+ Fragment BuildForStatement(TokenPosition* position);
+ Fragment BuildForInStatement(bool async, TokenPosition* position);
+ Fragment BuildSwitchStatement(TokenPosition* position);
+ Fragment BuildContinueSwitchStatement(TokenPosition* position);
+ Fragment BuildIfStatement(TokenPosition* position);
+ Fragment BuildReturnStatement(TokenPosition* position);
+ Fragment BuildTryCatch(TokenPosition* position);
+ Fragment BuildTryFinally(TokenPosition* position);
+ Fragment BuildYieldStatement(TokenPosition* position);
+ Fragment BuildVariableDeclaration(TokenPosition* position);
+ Fragment BuildFunctionDeclaration(intptr_t offset, TokenPosition* position);
Fragment BuildFunctionNode(TokenPosition parent_position,
StringIndex name_index,
bool has_valid_annotation,
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index a0da87b..18abb34 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -966,20 +966,10 @@
}
bool GraphIntrinsifier::Build_Integer_mod(FlowGraph* flow_graph) {
-#if defined(TARGET_ARCH_ARM)
- if (!TargetCPUFeatures::can_divide()) {
- return false;
- }
-#endif
return BuildBinarySmiOp(flow_graph, Token::kMOD);
}
bool GraphIntrinsifier::Build_Integer_truncDivide(FlowGraph* flow_graph) {
-#if defined(TARGET_ARCH_ARM)
- if (!TargetCPUFeatures::can_divide()) {
- return false;
- }
-#endif
return BuildBinarySmiOp(flow_graph, Token::kTRUNCDIV);
}
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index bec292f..c4d5c98 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -1072,12 +1072,6 @@
#undef EMIT_BOX_ALLOCATION
void StubCodeCompiler::GenerateBoxDoubleStub(Assembler* assembler) {
-#if defined(TARGET_ARCH_ARM)
- if (!TargetCPUFeatures::vfp_supported()) {
- __ Breakpoint();
- return;
- }
-#endif // defined(TARGET_ARCH_ARM)
Label call_runtime;
if (!FLAG_use_slow_path && FLAG_inline_alloc) {
__ TryAllocate(compiler::DoubleClass(), &call_runtime,
@@ -1100,12 +1094,6 @@
}
void StubCodeCompiler::GenerateDoubleToIntegerStub(Assembler* assembler) {
-#if defined(TARGET_ARCH_ARM)
- if (!TargetCPUFeatures::vfp_supported()) {
- __ Breakpoint();
- return;
- }
-#endif // defined(TARGET_ARCH_ARM)
__ EnterStubFrame();
__ StoreUnboxedDouble(DoubleToIntegerStubABI::kInputReg, THR,
target::Thread::unboxed_double_runtime_arg_offset());
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 859643a..e31e943 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -161,13 +161,6 @@
intptr_t self_code_stub_offset_from_thread,
bool allow_return,
std::function<void()> perform_runtime_call) {
- // If the target CPU does not support VFP the caller should always use the
- // non-FPU stub.
- if (save_fpu_registers && !TargetCPUFeatures::vfp_supported()) {
- __ Breakpoint();
- return;
- }
-
// We want the saved registers to appear like part of the caller's frame, so
// we push them before calling EnterStubFrame.
RegisterSet all_registers;
@@ -825,7 +818,6 @@
}
}
- if (TargetCPUFeatures::vfp_supported()) {
ASSERT(kFpuRegisterSize == 4 * target::kWordSize);
if (kNumberOfDRegisters > 16) {
__ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16);
@@ -833,9 +825,6 @@
} else {
__ vstmd(DB_W, SP, D0, kNumberOfDRegisters);
}
- } else {
- __ AddImmediate(SP, -kNumberOfFpuRegisters * kFpuRegisterSize);
- }
__ mov(R0, Operand(SP)); // Pass address of saved registers block.
bool is_lazy =
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 6d300fb..284b62d 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -49,7 +49,6 @@
namespace dart {
-DEFINE_FLAG(bool, use_vfp, true, "Use vfp instructions if supported");
DEFINE_FLAG(bool, use_neon, true, "Use neon instructions if supported");
DEFINE_FLAG(bool,
use_integer_division,
@@ -104,7 +103,6 @@
}
bool HostCPUFeatures::integer_division_supported_ = false;
-bool HostCPUFeatures::vfp_supported_ = false;
bool HostCPUFeatures::neon_supported_ = false;
bool HostCPUFeatures::hardfp_supported_ = false;
const char* HostCPUFeatures::hardware_ = NULL;
@@ -121,7 +119,6 @@
hardware_ = "";
// When the VM is targetted to ARMv7, pretend that the CPU is ARMv7 even if
// the CPU is actually AArch64.
- vfp_supported_ = FLAG_use_vfp;
integer_division_supported_ = FLAG_use_integer_division;
neon_supported_ = FLAG_use_neon;
hardfp_supported_ = false;
@@ -151,15 +148,6 @@
#endif
}
-#if defined(DART_RUN_IN_QEMU_ARMv7)
- vfp_supported_ = true;
-#else
- // Has floating point unit.
- vfp_supported_ =
- (CpuInfo::FieldContains(kCpuInfoFeatures, "vfp") || is_arm64) &&
- FLAG_use_vfp;
-#endif
-
// Has integer division.
// Special cases:
// - Qualcomm Krait CPUs (QCT APQ8064) in Nexus 4 and 7 incorrectly report
@@ -198,7 +186,7 @@
}
neon_supported_ =
(CpuInfo::FieldContains(kCpuInfoFeatures, "neon") || is_arm64) &&
- FLAG_use_vfp && FLAG_use_neon;
+ FLAG_use_neon;
// Use the cross-compiler's predefined macros to determine whether we should
// use the hard or soft float ABI.
@@ -232,8 +220,7 @@
hardware_ = CpuInfo::GetCpuModel();
integer_division_supported_ = FLAG_use_integer_division;
- vfp_supported_ = FLAG_use_vfp;
- neon_supported_ = FLAG_use_vfp && FLAG_use_neon;
+ neon_supported_ = FLAG_use_neon;
hardfp_supported_ = FLAG_sim_use_hardfp;
#if defined(DEBUG)
initialized_ = true;
diff --git a/runtime/vm/cpu_arm.h b/runtime/vm/cpu_arm.h
index 2eaf4aa..0729a02 100644
--- a/runtime/vm/cpu_arm.h
+++ b/runtime/vm/cpu_arm.h
@@ -34,10 +34,6 @@
DEBUG_ASSERT(initialized_);
return integer_division_supported_;
}
- static bool vfp_supported() {
- DEBUG_ASSERT(initialized_);
- return vfp_supported_;
- }
static bool neon_supported() {
DEBUG_ASSERT(initialized_);
return neon_supported_;
@@ -56,10 +52,6 @@
DEBUG_ASSERT(initialized_);
integer_division_supported_ = supported;
}
- static void set_vfp_supported(bool supported) {
- DEBUG_ASSERT(initialized_);
- vfp_supported_ = supported;
- }
static void set_neon_supported(bool supported) {
DEBUG_ASSERT(initialized_);
neon_supported_ = supported;
@@ -69,7 +61,6 @@
private:
static const char* hardware_;
static bool integer_division_supported_;
- static bool vfp_supported_;
static bool neon_supported_;
static bool hardfp_supported_;
static intptr_t store_pc_read_offset_;
@@ -86,10 +77,6 @@
static bool integer_division_supported() {
return HostCPUFeatures::integer_division_supported();
}
- static bool vfp_supported() { return HostCPUFeatures::vfp_supported(); }
- static bool can_divide() {
- return integer_division_supported() || vfp_supported();
- }
static bool neon_supported() { return HostCPUFeatures::neon_supported(); }
static bool hardfp_supported() { return HostCPUFeatures::hardfp_supported(); }
static const char* hardware() { return HostCPUFeatures::hardware(); }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index e18e2a3..1379bfa 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -1173,6 +1173,8 @@
ADD_ISOLATE_GROUP_FLAG(use_field_guards, use_field_guards,
FLAG_use_field_guards);
ADD_ISOLATE_GROUP_FLAG(use_osr, use_osr, FLAG_use_osr);
+ ADD_ISOLATE_GROUP_FLAG(branch_coverage, branch_coverage,
+ FLAG_branch_coverage);
}
// Generated code must match the host architecture and ABI.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 426bb94..02cbfa3 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -8121,6 +8121,64 @@
EXPECT(Dart_CloseNativePort(port_id2));
}
+static const intptr_t kSendLength = 16;
+
+static void NewNativePort_ExternalTypedData(Dart_Port dest_port_id,
+ Dart_CObject* message) {
+ // Gets a send port message.
+ EXPECT_NOTNULL(message);
+ EXPECT_EQ(Dart_CObject_kTypedData, message->type);
+ EXPECT_EQ(Dart_TypedData_kUint8, message->value.as_typed_data.type);
+ EXPECT_EQ(kSendLength, message->value.as_typed_data.length);
+ for (intptr_t i = 0; i < kSendLength; i++) {
+ EXPECT_EQ((0x41 + i), message->value.as_typed_data.values[i]);
+ }
+}
+
+static void FinalizeTypedData(void* isolate_callback_data, void* peer) {
+ delete[] reinterpret_cast<int8_t*>(peer);
+}
+
+TEST_CASE(DartAPI_NativePortPostExternalTypedData) {
+ int8_t* extTypedData = new int8_t[kSendLength];
+ for (int i = 0; i < kSendLength; i++) {
+ extTypedData[i] = 0x41 + i;
+ }
+ const char* kScriptChars =
+ "import 'dart:typed_data';\n"
+ "import 'dart:isolate';\n"
+ "void callPort(SendPort port, Uint8List data) {\n"
+ " port.send(data);\n"
+ "}\n";
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_EnterScope();
+
+ Dart_Port port_id =
+ Dart_NewNativePort("Port123", NewNativePort_ExternalTypedData, true);
+
+ Dart_Handle send_port = Dart_NewSendPort(port_id);
+ EXPECT_VALID(send_port);
+
+ Dart_Handle extdata = Dart_NewExternalTypedDataWithFinalizer(
+ Dart_TypedData_kUint8, extTypedData, kSendLength, extTypedData,
+ kSendLength, FinalizeTypedData);
+ EXPECT_VALID(extdata);
+
+ // Test first port.
+ Dart_Handle dart_args[2];
+ dart_args[0] = send_port;
+ dart_args[1] = extdata;
+ Dart_Handle result = Dart_Invoke(lib, NewString("callPort"), 2, dart_args);
+ EXPECT_VALID(result);
+ result = Dart_RunLoop();
+ EXPECT_VALID(result);
+
+ Dart_ExitScope();
+
+ // Delete the native ports.
+ EXPECT(Dart_CloseNativePort(port_id));
+}
+
static void NewNativePort_nativeReceiveNull(Dart_Port dest_port_id,
Dart_CObject* message) {
EXPECT_NOTNULL(message);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index edf42f7..8af317a 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -246,6 +246,7 @@
D(support_rr, bool, false, "Support running within RR.") \
P(verify_entry_points, bool, false, \
"Throw API error on invalid member access throuh native API. See " \
- "entry_point_pragma.md")
+ "entry_point_pragma.md") \
+ C(branch_coverage, false, false, bool, false, "Enable branch coverage")
#endif // RUNTIME_VM_FLAG_LIST_H_
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index d79de5c..1048e4e 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -163,7 +163,9 @@
load_vmservice_library, false) \
V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr) \
V(NONPRODUCT, snapshot_is_dontneed_safe, SnapshotIsDontNeedSafe, \
- snapshot_is_dontneed_safe, false)
+ snapshot_is_dontneed_safe, false) \
+ V(NONPRODUCT, branch_coverage, BranchCoverage, branch_coverage, \
+ FLAG_branch_coverage)
#define BOOL_ISOLATE_FLAG_LIST_DEFAULT_GETTER(V) \
V(PRODUCT, copy_parent_code, CopyParentCode, copy_parent_code, false) \
@@ -796,7 +798,8 @@
V(Obfuscate) \
V(UseFieldGuards) \
V(UseOsr) \
- V(SnapshotIsDontNeedSafe)
+ V(SnapshotIsDontNeedSafe) \
+ V(BranchCoverage)
// Isolate group specific flags.
enum FlagBits {
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 6b52eae..8dd8013 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -916,25 +916,21 @@
// Accessors for VFP register state.
DART_FORCE_INLINE void Simulator::set_sregister(SRegister reg, float value) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
sregisters_[reg] = bit_cast<int32_t, float>(value);
}
DART_FORCE_INLINE float Simulator::get_sregister(SRegister reg) const {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
return bit_cast<float, int32_t>(sregisters_[reg]);
}
DART_FORCE_INLINE void Simulator::set_dregister(DRegister reg, double value) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
dregisters_[reg] = bit_cast<int64_t, double>(value);
}
DART_FORCE_INLINE double Simulator::get_dregister(DRegister reg) const {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
return bit_cast<double, int64_t>(dregisters_[reg]);
}
@@ -958,25 +954,21 @@
}
void Simulator::set_sregister_bits(SRegister reg, int32_t value) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
sregisters_[reg] = value;
}
int32_t Simulator::get_sregister_bits(SRegister reg) const {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
return sregisters_[reg];
}
void Simulator::set_dregister_bits(DRegister reg, int64_t value) {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
dregisters_[reg] = value;
}
int64_t Simulator::get_dregister_bits(DRegister reg) const {
- ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
return dregisters_[reg];
}
@@ -1500,7 +1492,6 @@
set_register(R3, icount_);
set_register(IP, icount_);
set_register(LR, icount_);
- if (TargetCPUFeatures::vfp_supported()) {
double zap_dvalue = static_cast<double>(icount_);
// Do not zap D0, as it may contain a float result.
for (int i = D1; i <= D7; i++) {
@@ -1513,7 +1504,6 @@
set_dregister(static_cast<DRegister>(i), zap_dvalue);
}
#endif
- }
// Return.
set_pc(saved_lr);
@@ -3519,7 +3509,6 @@
// Setup parameters.
if (fp_args) {
- ASSERT(TargetCPUFeatures::vfp_supported());
set_sregister(S0, bit_cast<float, int32_t>(parameter0));
set_sregister(S1, bit_cast<float, int32_t>(parameter1));
set_sregister(S2, bit_cast<float, int32_t>(parameter2));
@@ -3569,7 +3558,6 @@
double d14_val = 0.0;
double d15_val = 0.0;
- if (TargetCPUFeatures::vfp_supported()) {
d8_val = get_dregister(D8);
d9_val = get_dregister(D9);
d10_val = get_dregister(D10);
@@ -3578,7 +3566,6 @@
d13_val = get_dregister(D13);
d14_val = get_dregister(D14);
d15_val = get_dregister(D15);
- }
// Setup the callee-saved registers with a known value. To be able to check
// that they are preserved properly across dart execution.
@@ -3595,7 +3582,6 @@
set_register(R11, callee_saved_value);
double callee_saved_dvalue = 0.0;
- if (TargetCPUFeatures::vfp_supported()) {
callee_saved_dvalue = static_cast<double>(icount_);
set_dregister(D8, callee_saved_dvalue);
set_dregister(D9, callee_saved_dvalue);
@@ -3605,7 +3591,6 @@
set_dregister(D13, callee_saved_dvalue);
set_dregister(D14, callee_saved_dvalue);
set_dregister(D15, callee_saved_dvalue);
- }
// Start the simulation
Execute();
@@ -3622,7 +3607,6 @@
ASSERT(callee_saved_value == get_register(R10));
ASSERT(callee_saved_value == get_register(R11));
- if (TargetCPUFeatures::vfp_supported()) {
ASSERT(callee_saved_dvalue == get_dregister(D8));
ASSERT(callee_saved_dvalue == get_dregister(D9));
ASSERT(callee_saved_dvalue == get_dregister(D10));
@@ -3631,7 +3615,6 @@
ASSERT(callee_saved_dvalue == get_dregister(D13));
ASSERT(callee_saved_dvalue == get_dregister(D14));
ASSERT(callee_saved_dvalue == get_dregister(D15));
- }
// Restore callee-saved registers with the original value.
set_register(R4, r4_val);
@@ -3645,7 +3628,6 @@
set_register(R10, r10_val);
set_register(R11, r11_val);
- if (TargetCPUFeatures::vfp_supported()) {
set_dregister(D8, d8_val);
set_dregister(D9, d9_val);
set_dregister(D10, d10_val);
@@ -3654,13 +3636,11 @@
set_dregister(D13, d13_val);
set_dregister(D14, d14_val);
set_dregister(D15, d15_val);
- }
// Restore the SP register and return R1:R0.
set_register(SP, sp_before_call);
int64_t return_value;
if (fp_return) {
- ASSERT(TargetCPUFeatures::vfp_supported());
return_value = bit_cast<int64_t, double>(get_dregister(D0));
} else {
return_value = Utils::LowHighTo64Bits(get_register(R0), get_register(R1));
diff --git a/tools/VERSION b/tools/VERSION
index 07ad55c..6049f42 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 110
+PRERELEASE 111
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/flutter/analyze_flutter_gallery.sh b/tools/bots/flutter/analyze_flutter_gallery.sh
new file mode 100755
index 0000000..38dd5f7
--- /dev/null
+++ b/tools/bots/flutter/analyze_flutter_gallery.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+# Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Analyze Dart code in the flutter/gallery repo.
+
+set -ex
+
+checkout=$(pwd)
+dart=$checkout/out/ReleaseX64/dart-sdk/bin/dart
+sdk=$checkout/out/ReleaseX64/dart-sdk
+tmpdir=$(mktemp -d)
+cleanup() {
+ rm -rf "$tmpdir"
+}
+trap cleanup EXIT HUP INT QUIT TERM PIPE
+cd "$tmpdir"
+
+# install flutter
+git clone --single-branch -vv https://github.com/flutter/flutter
+export PATH="$PATH":"$tmpdir/flutter/bin"
+flutter --version
+
+git clone --single-branch -vv \
+ https://dart.googlesource.com/external/github.com/flutter/gallery
+
+cd gallery
+
+# analyze
+echo Analyzing...
+
+flutter packages get
+$dart analyze --fatal-infos
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 7a644b3..a2b07417 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3753,6 +3753,10 @@
{
"name": "analyze flutter/plugins",
"script": "tools/bots/flutter/analyze_flutter_plugins.sh"
+ },
+ {
+ "name": "analyze flutter/gallery",
+ "script": "tools/bots/flutter/analyze_flutter_gallery.sh"
}
]
},