Version 2.0.0-dev.63.0
Merge '84f077842bb9736e398a71d2af6a0f65527b9878' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d84689d..beb9682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,29 @@
+## 2.0.0-dev.XX.0
+(Add new changes here, and they will be copied to the
+ change section for the next dev version)
+
+### Language
+
+#### Strong Mode
+
+### Dart VM
+
+### Tool Changes
+
+#### Pub
+
+#### Other Tools
+
+### Core library changes
+
+## 2.0.0-dev.63.0
+
+### Tool Changes
+
+#### Pub
+
+* Fix an error which prevented `pub publish` due to the package validation.
+
## 2.0.0-dev.62.0
### Language
diff --git a/DEPS b/DEPS
index a7da2e0..94230ce 100644
--- a/DEPS
+++ b/DEPS
@@ -94,7 +94,7 @@
"intl_tag": "0.15.2",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.6",
- "linter_tag": "0.1.52",
+ "linter_tag": "0.1.53",
"logging_tag": "0.11.3+1",
"markdown_tag": "2.0.0",
"matcher_tag": "0.12.1+4",
@@ -110,7 +110,7 @@
"ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
"pool_tag": "1.3.4",
"protobuf_tag": "0.7.1",
- "pub_rev": "881a0c3fbe63af07dd043b3f5e6cbe74eacb377c",
+ "pub_rev": "8b9526c915bf21627a20cd0104cb6c2be25a879f",
"pub_semver_tag": "1.4.1",
"quiver_tag": "5aaa3f58c48608af5b027444d561270b53f15dbf",
"resource_rev":"af5a5bf65511943398146cf146e466e5f0b95cb9",
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index f06888f..aa78dff 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -56,6 +56,8 @@
% - Introduce `subterm` and `immediate subterm`.
% - Introduce `top type`.
% - Specify configurable imports.
+% - Specify the dynamic type of the Iterable/Future/Stream returned from
+% invocations of functions marked sync*/async/async*.
%
% 1.15
% - Change how language specification describes control flow.
@@ -4907,7 +4909,13 @@
}
\LMHash{}
-If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementing the built-in class \code{Iterable} is associated with the invocation and immediately returned.
+If $f$ is marked \SYNC* (\ref{functions}),
+then a fresh instance (\ref{generativeConstructors}) $i$
+implementing \code{Iterable<$U$>} is immediately returned,
+where $U$ is determined as follows:
+Let $T$ be the actual return type of $f$ (\ref{actualTypeOfADeclaration}).
+If $T$ is \code{Iterable<$S$>} for some type $S$, then $U$ is $S$,
+otherwise $U$ is \code{Object}.
\commentary{
A Dart implementation will need to provide a specific implementation of \code{Iterable} that will be returned by \SYNC* methods.
@@ -4957,7 +4965,10 @@
% The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. The yielded value might differ from the expression in the yield. And it is a potential memory leak as the cache is kept alive by any iterator.
\LMHash{}
-If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $o$ implementing the built-in class \code{Future} is associated with the invocation.
+If $f$ is marked \ASYNC{} (\ref{functions}),
+then a fresh instance (\ref{generativeConstructors}) $o$ is associated with the invocation,
+where the dynamic type of $o$ implements \code{Future<$flatten(T)$>},
+and $T$ is the actual return type of $f$ (\ref{actualTypeOfADeclaration}).
Then the body of $f$ is executed until it either suspends or completes, at which point $o$ is returned.
\commentary{
The body of $f$ may suspend during the evaluation of an \AWAIT{} expression or execution of an asynchronous \FOR{} loop.
@@ -4976,7 +4987,13 @@
}
\LMHash{}
-If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementing the built-in class \code{Stream} is associated with the invocation and immediately returned.
+If $f$ is marked \ASYNC* (\ref{functions}),
+then a fresh instance (\ref{generativeConstructors}) $s$
+implementing \code{Stream<$U$>} is immediately returned,
+where $U$ is determined as follows:
+Let $T$ be the actual return type of $f$ (\ref{actualTypeOfADeclaration}).
+If $T$ is \code{Stream<$S$>} for some type $S$, then $U$ is $S$,
+otherwise $U$ is \code{Object}.
When $s$ is listened to, execution of the body of $f$ will begin.
When execution of the body of $f$ completes:
\begin{itemize}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 8fd931b..52473f1 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1404,8 +1404,6 @@
}
Future<Null> _addProposal_flutterConvertToStatefulWidget() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
ClassDeclaration widgetClass =
node.getAncestor((n) => n is ClassDeclaration);
TypeName superclass = widgetClass?.extendsClause?.superclass;
@@ -1447,27 +1445,93 @@
String widgetName = widgetClassElement.displayName;
String stateName = widgetName + 'State';
- var buildLinesRange = utils.getLinesRange(range.node(buildMethod));
- var buildText = utils.getRangeText(buildLinesRange);
+ // Find fields assigned in constructors.
+ var fieldsAssignedInConstructors = new Set<FieldElement>();
+ for (var member in widgetClass.members) {
+ if (member is ConstructorDeclaration) {
+ member.accept(new _SimpleIdentifierRecursiveAstVisitor((node) {
+ if (node.parent is FieldFormalParameter) {
+ Element element = node.staticElement;
+ if (element is FieldFormalParameterElement) {
+ fieldsAssignedInConstructors.add(element.field);
+ }
+ }
+ if (node.parent is ConstructorFieldInitializer) {
+ Element element = node.staticElement;
+ if (element is FieldElement) {
+ fieldsAssignedInConstructors.add(element);
+ }
+ }
+ if (node.inSetterContext()) {
+ Element element = node.staticElement;
+ if (element is PropertyAccessorElement) {
+ PropertyInducingElement field = element.variable;
+ if (field is FieldElement) {
+ fieldsAssignedInConstructors.add(field);
+ }
+ }
+ }
+ }));
+ }
+ }
- // Update the build() text to insert `widget.` before references to
- // the widget class members.
- final List<SourceEdit> buildTextEdits = [];
- buildMethod.body.accept(new _SimpleIdentifierRecursiveAstVisitor((node) {
- if (node.staticElement?.enclosingElement == widgetClassElement) {
- var offset = node.offset - buildLinesRange.offset;
- AstNode parent = node.parent;
- if (parent is InterpolationExpression &&
- parent.leftBracket.type ==
- TokenType.STRING_INTERPOLATION_IDENTIFIER) {
- buildTextEdits.add(new SourceEdit(offset, 0, '{widget.'));
- buildTextEdits.add(new SourceEdit(offset + node.length, 0, '}'));
- } else {
- buildTextEdits.add(new SourceEdit(offset, 0, 'widget.'));
+ // Prepare nodes to move.
+ var nodesToMove = new Set<ClassMember>();
+ var elementsToMove = new Set<Element>();
+ for (var member in widgetClass.members) {
+ if (member is FieldDeclaration && !member.isStatic) {
+ for (VariableDeclaration fieldNode in member.fields.variables) {
+ FieldElement fieldElement = fieldNode.element;
+ if (!fieldsAssignedInConstructors.contains(fieldElement)) {
+ nodesToMove.add(member);
+ elementsToMove.add(fieldElement);
+ elementsToMove.add(fieldElement.getter);
+ if (fieldElement.setter != null) {
+ elementsToMove.add(fieldElement.setter);
+ }
+ }
}
}
- }));
- buildText = SourceEdit.applySequence(buildText, buildTextEdits.reversed);
+ if (member is MethodDeclaration && !member.isStatic) {
+ nodesToMove.add(member);
+ elementsToMove.add(member.element);
+ }
+ }
+
+ /// Return the code for the [movedNode] which is suitable to be used
+ /// inside the `State` class, so that references to the widget fields and
+ /// methods, that are not moved, are qualified with the corresponding
+ /// instance `widget.`, or static `MyWidgetClass.` qualifier.
+ String rewriteWidgetMemberReferences(AstNode movedNode) {
+ var linesRange = utils.getLinesRange(range.node(movedNode));
+ var text = utils.getRangeText(linesRange);
+
+ // Insert `widget.` before references to the widget instance members.
+ final List<SourceEdit> edits = [];
+ movedNode.accept(new _SimpleIdentifierRecursiveAstVisitor((node) {
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ var element = node.staticElement;
+ if (element is ExecutableElement &&
+ element?.enclosingElement == widgetClassElement &&
+ !elementsToMove.contains(element)) {
+ var offset = node.offset - linesRange.offset;
+ var qualifier = element.isStatic ? widgetName : 'widget';
+
+ AstNode parent = node.parent;
+ if (parent is InterpolationExpression &&
+ parent.leftBracket.type ==
+ TokenType.STRING_INTERPOLATION_IDENTIFIER) {
+ edits.add(new SourceEdit(offset, 0, '{$qualifier.'));
+ edits.add(new SourceEdit(offset + node.length, 0, '}'));
+ } else {
+ edits.add(new SourceEdit(offset, 0, '$qualifier.'));
+ }
+ }
+ }));
+ return SourceEdit.applySequence(text, edits.reversed);
+ }
var statefulWidgetClass = await sessionHelper.getClass(
flutter.WIDGETS_LIBRARY_URI, 'StatefulWidget');
@@ -1480,23 +1544,94 @@
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
builder.addReplacement(range.node(superclass), (builder) {
builder.writeType(statefulWidgetClass.type);
});
- builder.addReplacement(buildLinesRange, (builder) {
- builder.writeln(' @override');
- builder.writeln(' $stateName createState() {');
- builder.writeln(' return new $stateName();');
- builder.writeln(' }');
- });
+
+ int replaceOffset = 0;
+ bool hasBuildMethod = false;
+
+ /// Replace code between [replaceOffset] and [replaceEnd] with
+ /// `createState()`, empty line, or nothing.
+ void replaceInterval(int replaceEnd,
+ {bool replaceWithEmptyLine: false,
+ bool hasEmptyLineBeforeCreateState: false,
+ bool hasEmptyLineAfterCreateState: true}) {
+ int replaceLength = replaceEnd - replaceOffset;
+ builder.addReplacement(
+ new SourceRange(replaceOffset, replaceLength),
+ (builder) {
+ if (hasBuildMethod) {
+ if (hasEmptyLineBeforeCreateState) {
+ builder.writeln();
+ }
+ builder.writeln(' @override');
+ builder.writeln(' $stateName createState() {');
+ builder.writeln(' return new $stateName();');
+ builder.writeln(' }');
+ if (hasEmptyLineAfterCreateState) {
+ builder.writeln();
+ }
+ hasBuildMethod = false;
+ } else if (replaceWithEmptyLine) {
+ builder.writeln();
+ }
+ },
+ );
+ replaceOffset = 0;
+ }
+
+ // Remove continuous ranges of lines of nodes being moved.
+ bool lastToRemoveIsField = false;
+ int endOfLastNodeToKeep = 0;
+ for (var node in widgetClass.members) {
+ if (nodesToMove.contains(node)) {
+ if (replaceOffset == 0) {
+ var linesRange = utils.getLinesRange(range.node(node));
+ replaceOffset = linesRange.offset;
+ }
+ if (node == buildMethod) {
+ hasBuildMethod = true;
+ }
+ lastToRemoveIsField = node is FieldDeclaration;
+ } else {
+ var linesRange = utils.getLinesRange(range.node(node));
+ endOfLastNodeToKeep = linesRange.end;
+ if (replaceOffset != 0) {
+ replaceInterval(linesRange.offset,
+ replaceWithEmptyLine:
+ lastToRemoveIsField && node is! FieldDeclaration);
+ }
+ }
+ }
+
+ // Remove nodes at the end of the widget class.
+ if (replaceOffset != 0) {
+ // Remove from the last node to keep, so remove empty lines.
+ if (endOfLastNodeToKeep != 0) {
+ replaceOffset = endOfLastNodeToKeep;
+ }
+ replaceInterval(widgetClass.rightBracket.offset,
+ hasEmptyLineBeforeCreateState: endOfLastNodeToKeep != 0,
+ hasEmptyLineAfterCreateState: false);
+ }
+
+ // Create the State subclass.
builder.addInsertion(widgetClass.end, (builder) {
builder.writeln();
builder.writeln();
builder.writeClassDeclaration(stateName, superclass: stateType,
membersWriter: () {
- builder.write(buildText);
+ bool writeEmptyLine = false;
+ for (var member in nodesToMove) {
+ if (writeEmptyLine) {
+ builder.writeln();
+ }
+ String text = rewriteWidgetMemberReferences(member);
+ builder.write(text);
+ // Write empty lines between members, but not before the first.
+ writeEmptyLine = true;
+ }
});
});
});
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 986c6ae..e165000 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -3058,6 +3058,314 @@
''');
}
+ test_flutterConvertToStatefulWidget_OK_empty() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(
+ DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ }
+
+ test_flutterConvertToStatefulWidget_OK_fields() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ static String staticField1;
+ final String instanceField1;
+ final String instanceField2;
+ String instanceField3;
+ static String staticField2;
+ String instanceField4;
+ String instanceField5;
+ static String staticField3;
+
+ MyWidget(this.instanceField1) : instanceField2 = '' {
+ instanceField3 = '';
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ instanceField4 = instanceField1;
+ return new Row(
+ children: [
+ new Text(instanceField1),
+ new Text(instanceField2),
+ new Text(instanceField3),
+ new Text(instanceField4),
+ new Text(instanceField5),
+ new Text(staticField1),
+ new Text(staticField2),
+ new Text(staticField3),
+ ],
+ );
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(
+ DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ static String staticField1;
+ final String instanceField1;
+ final String instanceField2;
+ String instanceField3;
+ static String staticField2;
+ static String staticField3;
+
+ MyWidget(this.instanceField1) : instanceField2 = '' {
+ instanceField3 = '';
+ }
+
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ String instanceField4;
+
+ String instanceField5;
+
+ @override
+ Widget build(BuildContext context) {
+ instanceField4 = widget.instanceField1;
+ return new Row(
+ children: [
+ new Text(widget.instanceField1),
+ new Text(widget.instanceField2),
+ new Text(widget.instanceField3),
+ new Text(instanceField4),
+ new Text(instanceField5),
+ new Text(MyWidget.staticField1),
+ new Text(MyWidget.staticField2),
+ new Text(MyWidget.staticField3),
+ ],
+ );
+ }
+}
+''');
+ }
+
+ test_flutterConvertToStatefulWidget_OK_getters() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(staticGetter1),
+ new Text(staticGetter2),
+ new Text(instanceGetter1),
+ new Text(instanceGetter2),
+ ],
+ );
+ }
+
+ static String get staticGetter1 => '';
+
+ String get instanceGetter1 => '';
+
+ static String get staticGetter2 => '';
+
+ String get instanceGetter2 => '';
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(
+ DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+
+ static String get staticGetter1 => '';
+
+ static String get staticGetter2 => '';
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(MyWidget.staticGetter1),
+ new Text(MyWidget.staticGetter2),
+ new Text(instanceGetter1),
+ new Text(instanceGetter2),
+ ],
+ );
+ }
+
+ String get instanceGetter1 => '';
+
+ String get instanceGetter2 => '';
+}
+''');
+ }
+
+ test_flutterConvertToStatefulWidget_OK_methods() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ static String staticField;
+ final String instanceField1;
+ String instanceField2;
+
+ MyWidget(this.instanceField1);
+
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(instanceField1),
+ new Text(instanceField2),
+ new Text(staticField),
+ ],
+ );
+ }
+
+ void instanceMethod1() {
+ instanceMethod1();
+ instanceMethod2();
+ staticMethod1();
+ }
+
+ static void staticMethod1() {
+ print('static 1');
+ }
+
+ void instanceMethod2() {
+ print('instance 2');
+ }
+
+ static void staticMethod2() {
+ print('static 2');
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(
+ DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ static String staticField;
+ final String instanceField1;
+
+ MyWidget(this.instanceField1);
+
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+
+ static void staticMethod1() {
+ print('static 1');
+ }
+
+ static void staticMethod2() {
+ print('static 2');
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ String instanceField2;
+
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(widget.instanceField1),
+ new Text(instanceField2),
+ new Text(MyWidget.staticField),
+ ],
+ );
+ }
+
+ void instanceMethod1() {
+ instanceMethod1();
+ instanceMethod2();
+ MyWidget.staticMethod1();
+ }
+
+ void instanceMethod2() {
+ print('instance 2');
+ }
+}
+''');
+ }
+
+ test_flutterConvertToStatefulWidget_OK_tail() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(
+ DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ }
+
test_flutterMoveWidgetDown_BAD_last() async {
addFlutterPackage();
await resolveTestUnit('''
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index ab46a8d..18a2e6c 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+@deprecated
import 'dart:io';
import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d308de5..59dcb83 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -145,15 +145,15 @@
await _driver.discoverAvailableFiles();
try {
- for (String path in _driver.knownFiles) {
- if (onlyForFile != null && path != onlyForFile) {
+ List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
+ for (FileState file in knownFiles) {
+ if (onlyForFile != null && file.path != onlyForFile) {
continue;
}
- if (files.contains(path)) {
+ if (files.contains(file.path)) {
continue;
}
- FileState file = _driver.fsState.getFileForPath(path);
int fileIndex;
void addDeclaration(String name, DeclarationKind kind, int offset,
@@ -380,10 +380,10 @@
await _driver.discoverAvailableFiles();
List<SubtypeResult> results = [];
- for (String path in _driver.knownFiles) {
- FileState file = _driver.fsState.getFileForPath(path);
+ List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
+ for (FileState file in knownFiles) {
if (file.subtypedNames.contains(name)) {
- AnalysisDriverUnitIndex index = await _driver.getIndex(path);
+ AnalysisDriverUnitIndex index = await _driver.getIndex(file.path);
if (index != null) {
for (AnalysisDriverSubtype subtype in index.subtypes) {
if (subtype.supertypes.contains(id)) {
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 410a1f0..b65aa46 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1409,14 +1409,11 @@
if (errorOccurred) {
return null;
}
- DartType elementType = _typeProvider.dynamicType;
- NodeList<TypeAnnotation> typeArgs = node.typeArguments?.arguments;
- if (typeArgs?.length == 1) {
- DartType type = visitTypeAnnotation(typeArgs[0])?.toTypeValue();
- if (type != null) {
- elementType = type;
- }
- }
+ var nodeType = node.staticType;
+ DartType elementType =
+ nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
+ ? nodeType.typeArguments[0]
+ : _typeProvider.dynamicType;
InterfaceType listType = _typeProvider.listType.instantiate([elementType]);
return new DartObjectImpl(listType, new ListState(elements));
}
@@ -1445,17 +1442,12 @@
}
DartType keyType = _typeProvider.dynamicType;
DartType valueType = _typeProvider.dynamicType;
- NodeList<TypeAnnotation> typeArgs = node.typeArguments?.arguments;
- if (typeArgs?.length == 2) {
- DartType keyTypeCandidate =
- visitTypeAnnotation(typeArgs[0])?.toTypeValue();
- if (keyTypeCandidate != null) {
- keyType = keyTypeCandidate;
- }
- DartType valueTypeCandidate =
- visitTypeAnnotation(typeArgs[1])?.toTypeValue();
- if (valueTypeCandidate != null) {
- valueType = valueTypeCandidate;
+ var nodeType = node.staticType;
+ if (nodeType is InterfaceType) {
+ var typeArguments = nodeType.typeArguments;
+ if (typeArguments.length >= 2) {
+ keyType = typeArguments[0];
+ valueType = typeArguments[1];
}
}
InterfaceType mapType =
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 7e47780..95c7f18 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -83,6 +83,7 @@
@override
ListLiteral visitListLiteral(ListLiteral node) {
ListLiteral literal = super.visitListLiteral(node);
+ literal.staticType = node.staticType;
if (previewDart2 && node.constKeyword == null && node.isConst) {
literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
}
@@ -92,6 +93,7 @@
@override
MapLiteral visitMapLiteral(MapLiteral node) {
MapLiteral literal = super.visitMapLiteral(node);
+ literal.staticType = node.staticType;
if (previewDart2 && node.constKeyword == null && node.isConst) {
literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
}
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 7e08aa0..2a7ab90 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -186,6 +186,28 @@
}
@override
+ Generator<Expression, Statement, Arguments> delayedAssignment(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ Expression value,
+ String assignmentOperator) {
+ // TODO(brianwilkerson) Implement this.
+ throw new UnimplementedError();
+ }
+
+ @override
+ Generator<Expression, Statement, Arguments> delayedPostfixIncrement(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ kernel.Name binaryOperator,
+ kernel.Procedure interfaceTarget) {
+ // TODO(brianwilkerson) Implement this.
+ throw new UnimplementedError();
+ }
+
+ @override
Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
ParenthesizedExpression condition, Token semicolon) =>
astFactory.doStatement(
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 746ca53..1d350f0 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -492,6 +492,18 @@
verify([source]);
}
+ test_listLiteral_inferredElementType() async {
+ resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+ Source source = addSource('''
+const Object x = [1];
+const List<String> y = x;
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+ verify([source]);
+ }
+
test_mapKeyTypeNotAssignable() async {
Source source = addSource("var v = const <String, int > {1 : 2};");
await computeAnalysisResult(source);
@@ -502,6 +514,30 @@
verify([source]);
}
+ test_mapLiteral_inferredKeyType() async {
+ resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+ Source source = addSource('''
+const Object x = {1: 1};
+const Map<String, dynamic> y = x;
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+ verify([source]);
+ }
+
+ test_mapLiteral_inferredValueType() async {
+ resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+ Source source = addSource('''
+const Object x = {1: 1};
+const Map<dynamic, String> y = x;
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+ verify([source]);
+ }
+
test_mapValueTypeNotAssignable() async {
Source source = addSource("var v = const <String, String> {'a' : 2};");
await computeAnalysisResult(source);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 0724a03..f425dce 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -4860,7 +4860,7 @@
@B.named8()
main() {}
''');
- final aSource = addNamedSource("/a.dart", r'''
+ addNamedSource("/a.dart", r'''
class Unbounded<T> {
const Unbounded();
const Unbounded.named();
@@ -4870,7 +4870,7 @@
const Bounded.named();
}
''');
- final bSource = addNamedSource("/b.dart", r'''
+ addNamedSource("/b.dart", r'''
import 'a.dart';
import 'a.dart' as p;
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index fabf804..8c02681 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -378,22 +378,6 @@
// Fasta no longer supports type comment based syntax
// super.test_method_invalidTypeParameterExtendsComment();
}
-
- @override
- @failingTest
- void test_missingFunctionParameters_topLevel_void_block() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
- super.test_missingFunctionParameters_topLevel_void_block();
- }
-
- @override
- @failingTest
- void test_missingFunctionParameters_topLevel_void_expression() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
- super.test_missingFunctionParameters_topLevel_void_expression();
- }
}
/**
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 2965261..891b523 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -183,7 +183,13 @@
@failingTest // See dartbug.com/32290
test_const_constructor_inferred_args() =>
- test_const_constructor_inferred_args();
+ super.test_const_constructor_inferred_args();
+
+ @failingTest // See dartbug.com/33441
+ test_const_list_inferredType() => super.test_const_list_inferredType();
+
+ @failingTest // See dartbug.com/33441
+ test_const_map_inferredType() => super.test_const_map_inferredType();
@override
@failingTest
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index dd8e30b..88a7e76 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -3297,6 +3297,35 @@
}
}
+ test_const_list_inferredType() async {
+ if (!isStrongMode) return;
+ // The summary needs to contain enough information so that when the constant
+ // is resynthesized, the constant value can get the type that was computed
+ // by type inference.
+ var library = await checkLibrary('''
+const Object x = const [1];
+''');
+ checkElementText(library, '''
+const Object x = const <
+ int/*location: dart:core;int*/>[1];
+''');
+ }
+
+ test_const_map_inferredType() async {
+ if (!isStrongMode) return;
+ // The summary needs to contain enough information so that when the constant
+ // is resynthesized, the constant value can get the type that was computed
+ // by type inference.
+ var library = await checkLibrary('''
+const Object x = const {1: 1.0};
+''');
+ checkElementText(library, '''
+const Object x = const <
+ int/*location: dart:core;int*/,
+ double/*location: dart:core;double*/>{1: 1.0};
+''');
+ }
+
test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
var library = await checkLibrary(r'''
class C {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
index 707aa7e..9a2a5e1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
@@ -147,7 +147,7 @@
@failingTest // See dartbug.com/32290
test_const_constructor_inferred_args() =>
- test_const_constructor_inferred_args();
+ super.test_const_constructor_inferred_args();
@failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/30258')
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 2228fa0..9aa47e4 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -349,6 +349,7 @@
''');
}
+ @failingTest // See dartbug.com/33440
test_constantGenericTypeArg_explicit() async {
// Regression test for https://github.com/dart-lang/sdk/issues/26141
await checkFile('''
@@ -375,6 +376,7 @@
''');
}
+ @failingTest // See dartbug.com/32918
test_constantGenericTypeArg_infer() async {
// Regression test for https://github.com/dart-lang/sdk/issues/26141
await checkFile('''
diff --git a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
index c64cfd8..e780e81 100644
--- a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
@@ -9,6 +9,8 @@
import 'file_system.dart';
+import '../fasta/compiler_context.dart' show CompilerContext;
+
/// Concrete implementation of [FileSystem] handling standard URI schemes.
///
/// file: URIs are handled using file I/O.
@@ -60,6 +62,7 @@
@override
Future<List<int>> readAsBytes() async {
try {
+ CompilerContext.recordDependency(uri);
return await new io.File.fromUri(uri).readAsBytes();
} on io.FileSystemException catch (exception) {
throw _toFileSystemException(exception);
@@ -69,6 +72,7 @@
@override
Future<String> readAsString() async {
try {
+ CompilerContext.recordDependency(uri);
return await new io.File.fromUri(uri).readAsString();
} on io.FileSystemException catch (exception) {
throw _toFileSystemException(exception);
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 2eda950..e979f14 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -47,7 +47,9 @@
/// programs.
final Map<Uri, Source> uriToSource = <Uri, Source>{};
- final List errors = <Object>[];
+ final List<Object> errors = <Object>[];
+
+ final List<Uri> dependencies = <Uri>[];
FileSystem get fileSystem => options.fileSystem;
@@ -87,8 +89,18 @@
errors.add(severity);
}
+ static void recordDependency(Uri uri) {
+ if (uri.scheme != "file") {
+ throw new ArgumentError("Expected a file-URI, but got: '$uri'.");
+ }
+ CompilerContext context = Zone.current[compilerContextKey];
+ if (context != null) {
+ context.dependencies.add(uri);
+ }
+ }
+
static CompilerContext get current {
- var context = Zone.current[compilerContextKey];
+ CompilerContext context = Zone.current[compilerContextKey];
if (context == null) {
// Note: we throw directly and don't use internalProblem, because
// internalProblem depends on having a compiler context available.
@@ -127,5 +139,6 @@
void clear() {
StringToken.canonicalizer.clear();
errors.clear();
+ dependencies.clear();
}
}
diff --git a/pkg/front_end/lib/src/fasta/get_dependencies.dart b/pkg/front_end/lib/src/fasta/get_dependencies.dart
index 4fa99af..c7b7ba3 100644
--- a/pkg/front_end/lib/src/fasta/get_dependencies.dart
+++ b/pkg/front_end/lib/src/fasta/get_dependencies.dart
@@ -24,7 +24,6 @@
import 'uri_translator.dart' show UriTranslator;
-// TODO(sigmund): reimplement this API using the directive listener intead.
Future<List<Uri>> getDependencies(Uri script,
{Uri sdk,
Uri packages,
@@ -57,6 +56,6 @@
kernelTarget.read(script);
await dillTarget.buildOutlines();
await kernelTarget.loader.buildOutlines();
- return await kernelTarget.loader.getDependencies();
+ return new List<Uri>.from(c.dependencies);
});
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index c69b304..a7228a9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -18,7 +18,20 @@
templateNotAType,
templateUnresolvedPrefixInTypeAnnotation;
-import '../names.dart' show lengthName;
+import '../names.dart'
+ show
+ ampersandName,
+ barName,
+ caretName,
+ divisionName,
+ leftShiftName,
+ lengthName,
+ minusName,
+ multiplyName,
+ mustacheName,
+ percentName,
+ plusName,
+ rightShiftName;
import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
@@ -35,9 +48,12 @@
TypeDeclarationBuilder,
UnlinkedDeclaration;
+import 'kernel_api.dart' show printQualifiedNameOn;
+
import 'kernel_ast_api.dart'
show
DartType,
+ DynamicType,
Initializer,
InvalidType,
Member,
@@ -61,8 +77,6 @@
export 'kernel_expression_generator.dart'
show
- DelayedAssignment,
- DelayedPostfixIncrement,
IncompleteErrorGenerator,
IncompletePropertyAccessGenerator,
IncompleteSendGenerator,
@@ -862,3 +876,197 @@
sink.write(declaration.name);
}
}
+
+abstract class ContextAwareGenerator<Expression, Statement, Arguments>
+ implements Generator<Expression, Statement, Arguments> {
+ Generator<Expression, Statement, Arguments> get generator;
+
+ @override
+ String get plainNameForRead {
+ return unsupported("plainNameForRead", token.charOffset, helper.uri);
+ }
+
+ @override
+ Expression doInvocation(int charOffset, Arguments arguments) {
+ return unhandled("${runtimeType}", "doInvocation", charOffset, uri);
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildNullAwareAssignment(
+ Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: -1,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false}) {
+ return makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildPrefixIncrement(Name binaryOperator,
+ {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
+ return makeInvalidWrite(null);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
+ return makeInvalidWrite(null);
+ }
+
+ @override
+ makeInvalidRead() {
+ return unsupported("makeInvalidRead", token.charOffset, helper.uri);
+ }
+
+ @override
+ Expression makeInvalidWrite(Expression value) {
+ return helper.deprecated_buildCompileTimeError(
+ "Can't be used as left-hand side of assignment.",
+ offsetForToken(token));
+ }
+}
+
+abstract class DelayedAssignment<Expression, Statement, Arguments>
+ implements ContextAwareGenerator<Expression, Statement, Arguments> {
+ factory DelayedAssignment(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ Expression value,
+ String assignmentOperator) {
+ return helper.forest
+ .delayedAssignment(helper, token, generator, value, assignmentOperator);
+ }
+
+ Expression get value;
+
+ String get assignmentOperator;
+
+ @override
+ String get debugName => "DelayedAssignment";
+
+ @override
+ Expression buildSimpleRead() {
+ return handleAssignment(false);
+ }
+
+ @override
+ Expression buildForEffect() {
+ return handleAssignment(true);
+ }
+
+ Expression handleAssignment(bool voidContext) {
+ if (helper.constantContext != ConstantContext.none) {
+ return helper.deprecated_buildCompileTimeError(
+ "Not a constant expression.", offsetForToken(token));
+ }
+ if (identical("=", assignmentOperator)) {
+ return generator.buildAssignment(value, voidContext: voidContext);
+ } else if (identical("+=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(plusName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("-=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(minusName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("*=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(multiplyName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("%=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(percentName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("&=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(ampersandName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("/=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(divisionName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("<<=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(leftShiftName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical(">>=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(rightShiftName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("??=", assignmentOperator)) {
+ return generator.buildNullAwareAssignment(
+ value, const DynamicType(), offsetForToken(token),
+ voidContext: voidContext);
+ } else if (identical("^=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(caretName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("|=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(barName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else if (identical("~/=", assignmentOperator)) {
+ return generator.buildCompoundAssignment(mustacheName, value,
+ offset: offsetForToken(token), voidContext: voidContext);
+ } else {
+ return unhandled(
+ assignmentOperator, "handleAssignment", token.charOffset, helper.uri);
+ }
+ }
+
+ @override
+ Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+ if (!identical("=", assignmentOperator) ||
+ !generator.isThisPropertyAccess) {
+ return generator.buildFieldInitializer(initializedFields);
+ }
+ return helper.buildFieldInitializer(
+ false, generator.plainNameForRead, offsetForToken(token), value);
+ }
+}
+
+abstract class DelayedPostfixIncrement<Expression, Statement, Arguments>
+ implements ContextAwareGenerator<Expression, Statement, Arguments> {
+ factory DelayedPostfixIncrement(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ Name binaryOperator,
+ Procedure interfaceTarget) {
+ return helper.forest.delayedPostfixIncrement(
+ helper, token, generator, binaryOperator, interfaceTarget);
+ }
+
+ Name get binaryOperator;
+
+ Procedure get interfaceTarget;
+
+ @override
+ String get debugName => "DelayedPostfixIncrement";
+
+ @override
+ Expression buildSimpleRead() {
+ return generator.buildPostfixIncrement(binaryOperator,
+ offset: offsetForToken(token),
+ voidContext: false,
+ interfaceTarget: interfaceTarget);
+ }
+
+ @override
+ Expression buildForEffect() {
+ return generator.buildPostfixIncrement(binaryOperator,
+ offset: offsetForToken(token),
+ voidContext: true,
+ interfaceTarget: interfaceTarget);
+ }
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", binaryOperator: ");
+ sink.write(binaryOperator.name);
+ sink.write(", interfaceTarget: ");
+ printQualifiedNameOn(interfaceTarget, sink);
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index a976f3b..1700191 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -46,6 +46,8 @@
import 'kernel_expression_generator.dart'
show
KernelDeferredAccessGenerator,
+ KernelDelayedAssignment,
+ KernelDelayedPostfixIncrement,
KernelIndexedAccessGenerator,
KernelLargeIntAccessGenerator,
KernelLoadLibraryGenerator,
@@ -775,6 +777,28 @@
UnlinkedDeclaration declaration) {
return new KernelUnlinkedGenerator(helper, token, declaration);
}
+
+ @override
+ KernelDelayedAssignment delayedAssignment(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ Expression value,
+ String assignmentOperator) {
+ return new KernelDelayedAssignment(
+ helper, token, generator, value, assignmentOperator);
+ }
+
+ @override
+ KernelDelayedPostfixIncrement delayedPostfixIncrement(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ Name binaryOperator,
+ Procedure interfaceTarget) {
+ return new KernelDelayedPostfixIncrement(
+ helper, token, generator, binaryOperator, interfaceTarget);
+ }
}
class _VariablesDeclaration extends Statement {
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index ac39797..4d80798 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -472,6 +472,20 @@
Location location,
UnlinkedDeclaration declaration);
+ Generator<Expression, Statement, Arguments> delayedAssignment(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Location location,
+ Generator<Expression, Statement, Arguments> generator,
+ Expression value,
+ String assignmentOperator);
+
+ Generator<Expression, Statement, Arguments> delayedPostfixIncrement(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Location location,
+ Generator<Expression, Statement, Arguments> generator,
+ kernel.Name binaryOperator,
+ kernel.Procedure interfaceTarget);
+
// TODO(ahe): Remove this method when all users are moved here.
kernel.Arguments castArguments(Arguments arguments) {
dynamic a = arguments;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index bc2d940..de2683d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -18,23 +18,7 @@
import '../messages.dart' show Message, noLength;
-import '../names.dart'
- show
- ampersandName,
- barName,
- callName,
- caretName,
- divisionName,
- equalsName,
- indexGetName,
- indexSetName,
- leftShiftName,
- minusName,
- multiplyName,
- mustacheName,
- percentName,
- plusName,
- rightShiftName;
+import '../names.dart' show callName, equalsName, indexGetName, indexSetName;
import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
@@ -46,7 +30,10 @@
import 'expression_generator.dart'
show
+ ContextAwareGenerator,
DeferredAccessGenerator,
+ DelayedAssignment,
+ DelayedPostfixIncrement,
ErroneousExpressionGenerator,
ExpressionGenerator,
Generator,
@@ -79,7 +66,6 @@
show
Constructor,
DartType,
- DynamicType,
Field,
Initializer,
InvalidType,
@@ -1512,6 +1498,71 @@
}
}
+abstract class KernelContextAwareGenerator extends KernelGenerator
+ with ContextAwareGenerator<Expression, Statement, Arguments> {
+ @override
+ final Generator<Expression, Statement, Arguments> generator;
+
+ KernelContextAwareGenerator(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ this.generator)
+ : super(helper, token);
+
+ @override
+ Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+ return unsupported("_makeRead", offsetForToken(token), uri);
+ }
+
+ @override
+ Expression _makeWrite(Expression value, bool voidContext,
+ ShadowComplexAssignment complexAssignment) {
+ return unsupported("_makeWrite", offsetForToken(token), uri);
+ }
+}
+
+class KernelDelayedAssignment extends KernelContextAwareGenerator
+ with DelayedAssignment<Expression, Statement, Arguments> {
+ @override
+ final Expression value;
+
+ @override
+ String assignmentOperator;
+
+ KernelDelayedAssignment(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ this.value,
+ this.assignmentOperator)
+ : super(helper, token, generator);
+
+ @override
+ void printOn(StringSink sink) {
+ sink.write(", value: ");
+ printNodeOn(value, sink);
+ sink.write(", assignmentOperator: ");
+ sink.write(assignmentOperator);
+ }
+}
+
+class KernelDelayedPostfixIncrement extends KernelContextAwareGenerator
+ with DelayedPostfixIncrement<Expression, Statement, Arguments> {
+ @override
+ final Name binaryOperator;
+
+ @override
+ final Procedure interfaceTarget;
+
+ KernelDelayedPostfixIncrement(
+ ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+ Token token,
+ Generator<Expression, Statement, Arguments> generator,
+ this.binaryOperator,
+ this.interfaceTarget)
+ : super(helper, token, generator);
+}
+
Expression makeLet(VariableDeclaration variable, Expression body) {
if (variable == null) return body;
return new Let(variable, body);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index 1f93a18..1acf3cd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -436,194 +436,3 @@
"Can't assign to a parenthesized expression.", offsetForToken(token));
}
}
-
-abstract class ContextAwareGenerator
- extends Generator<Expression, Statement, Arguments> {
- final Generator generator;
-
- ContextAwareGenerator(
- ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
- Token token,
- this.generator)
- : super(helper, token);
-
- String get plainNameForRead {
- return unsupported("plainNameForRead", token.charOffset, helper.uri);
- }
-
- Expression doInvocation(int charOffset, Arguments arguments) {
- return unhandled("${runtimeType}", "doInvocation", charOffset, uri);
- }
-
- Expression buildSimpleRead();
-
- Expression buildForEffect();
-
- Expression buildAssignment(Expression value, {bool voidContext: false}) {
- return makeInvalidWrite(value);
- }
-
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- return makeInvalidWrite(value);
- }
-
- Expression buildCompoundAssignment(Name binaryOperator, Expression value,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget,
- bool isPreIncDec: false}) {
- return makeInvalidWrite(value);
- }
-
- Expression buildPrefixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return makeInvalidWrite(null);
- }
-
- Expression buildPostfixIncrement(Name binaryOperator,
- {int offset: TreeNode.noOffset,
- bool voidContext: false,
- Procedure interfaceTarget}) {
- return makeInvalidWrite(null);
- }
-
- makeInvalidRead() {
- return unsupported("makeInvalidRead", token.charOffset, helper.uri);
- }
-
- Expression makeInvalidWrite(Expression value) {
- return helper.deprecated_buildCompileTimeError(
- "Can't be used as left-hand side of assignment.",
- offsetForToken(token));
- }
-}
-
-class DelayedAssignment extends ContextAwareGenerator {
- final Expression value;
-
- final String assignmentOperator;
-
- DelayedAssignment(ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
- Token token, Generator generator, this.value, this.assignmentOperator)
- : super(helper, token, generator);
-
- String get debugName => "DelayedAssignment";
-
- Expression buildSimpleRead() {
- return handleAssignment(false);
- }
-
- Expression buildForEffect() {
- return handleAssignment(true);
- }
-
- Expression handleAssignment(bool voidContext) {
- if (helper.constantContext != ConstantContext.none) {
- return helper.deprecated_buildCompileTimeError(
- "Not a constant expression.", offsetForToken(token));
- }
- if (identical("=", assignmentOperator)) {
- return generator.buildAssignment(value, voidContext: voidContext);
- } else if (identical("+=", assignmentOperator)) {
- return generator.buildCompoundAssignment(plusName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("-=", assignmentOperator)) {
- return generator.buildCompoundAssignment(minusName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("*=", assignmentOperator)) {
- return generator.buildCompoundAssignment(multiplyName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("%=", assignmentOperator)) {
- return generator.buildCompoundAssignment(percentName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("&=", assignmentOperator)) {
- return generator.buildCompoundAssignment(ampersandName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("/=", assignmentOperator)) {
- return generator.buildCompoundAssignment(divisionName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("<<=", assignmentOperator)) {
- return generator.buildCompoundAssignment(leftShiftName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical(">>=", assignmentOperator)) {
- return generator.buildCompoundAssignment(rightShiftName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("??=", assignmentOperator)) {
- return generator.buildNullAwareAssignment(
- value, const DynamicType(), offsetForToken(token),
- voidContext: voidContext);
- } else if (identical("^=", assignmentOperator)) {
- return generator.buildCompoundAssignment(caretName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("|=", assignmentOperator)) {
- return generator.buildCompoundAssignment(barName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else if (identical("~/=", assignmentOperator)) {
- return generator.buildCompoundAssignment(mustacheName, value,
- offset: offsetForToken(token), voidContext: voidContext);
- } else {
- return unhandled(
- assignmentOperator, "handleAssignment", token.charOffset, helper.uri);
- }
- }
-
- @override
- Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- if (!identical("=", assignmentOperator) ||
- !generator.isThisPropertyAccess) {
- return generator.buildFieldInitializer(initializedFields);
- }
- return helper.buildFieldInitializer(
- false, generator.plainNameForRead, offsetForToken(token), value);
- }
-
- @override
- void printOn(StringSink sink) {
- sink.write(", value: ");
- printNodeOn(value, sink);
- sink.write(", assignmentOperator: ");
- sink.write(assignmentOperator);
- }
-}
-
-class DelayedPostfixIncrement extends ContextAwareGenerator {
- final Name binaryOperator;
-
- final Procedure interfaceTarget;
-
- DelayedPostfixIncrement(
- ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
- Token token,
- Generator generator,
- this.binaryOperator,
- this.interfaceTarget)
- : super(helper, token, generator);
-
- String get debugName => "DelayedPostfixIncrement";
-
- Expression buildSimpleRead() {
- return generator.buildPostfixIncrement(binaryOperator,
- offset: offsetForToken(token),
- voidContext: false,
- interfaceTarget: interfaceTarget);
- }
-
- Expression buildForEffect() {
- return generator.buildPostfixIncrement(binaryOperator,
- offset: offsetForToken(token),
- voidContext: true,
- interfaceTarget: interfaceTarget);
- }
-
- @override
- void printOn(StringSink sink) {
- sink.write(", binaryOperator: ");
- sink.write(binaryOperator.name);
- sink.write(", interfaceTarget: ");
- printQualifiedNameOn(interfaceTarget, sink);
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
index 1830ea2..752a461 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_formal_parameter_builder.dart
@@ -46,10 +46,6 @@
isFieldFormal: hasThis,
isCovariant: isCovariant)
..fileOffset = charOffset;
- if (type == null && hasThis) {
- library.loader.typeInferenceEngine
- .recordInitializingFormal(declaration);
- }
}
return declaration;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index 935acb9..c78baa0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -444,6 +444,15 @@
return isRedirectingGenerativeConstructorImplementation(constructor);
}
+ bool get isEligibleForTopLevelInference {
+ if (formals != null) {
+ for (var formal in formals) {
+ if (formal.type == null && formal.hasThis) return true;
+ }
+ }
+ return false;
+ }
+
Constructor build(SourceLibraryBuilder library) {
if (constructor.name == null) {
constructor.function = buildFunction(library);
@@ -455,6 +464,14 @@
constructor.isExternal = isExternal;
constructor.name = new Name(name, library.target);
}
+ if (!library.disableTypeInference && isEligibleForTopLevelInference) {
+ for (KernelFormalParameterBuilder formal in formals) {
+ if (formal.type == null && formal.hasThis) {
+ formal.declaration.type = null;
+ }
+ }
+ library.loader.typeInferenceEngine.toBeInferred[constructor] = library;
+ }
return constructor;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index f72a8a2..36ec248 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -34,7 +34,10 @@
InstrumentationValueForTypeArgs;
import '../fasta_codes.dart'
- show noLength, templateCantUseSuperBoundedTypeForInstanceCreation;
+ show
+ noLength,
+ templateCantInferTypeDueToCircularity,
+ templateCantUseSuperBoundedTypeForInstanceCreation;
import '../problems.dart' show unhandled, unsupported;
@@ -607,6 +610,36 @@
@override
DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
+ var library = inferrer.engine.beingInferred[target];
+ if (library != null) {
+ // There is a cyclic dependency where inferring the types of the
+ // initializing formals of a constructor required us to infer the
+ // corresponding field type which required us to know the type of the
+ // constructor.
+ var name = target.enclosingClass.name;
+ if (target.name.name != '') name += '.${target.name.name}';
+ library.addProblem(
+ templateCantInferTypeDueToCircularity.withArguments(name),
+ target.fileOffset,
+ name.length,
+ target.fileUri);
+ for (var declaration in target.function.positionalParameters) {
+ declaration.type ??= const DynamicType();
+ }
+ for (var declaration in target.function.namedParameters) {
+ declaration.type ??= const DynamicType();
+ }
+ } else if ((library = inferrer.engine.toBeInferred[target]) != null) {
+ inferrer.engine.toBeInferred.remove(target);
+ inferrer.engine.beingInferred[target] = library;
+ for (var declaration in target.function.positionalParameters) {
+ inferrer.engine.inferInitializingFormal(declaration, target);
+ }
+ for (var declaration in target.function.namedParameters) {
+ inferrer.engine.inferInitializingFormal(declaration, target);
+ }
+ inferrer.engine.beingInferred.remove(target);
+ }
var inferredType = inferrer.inferInvocation(
typeContext,
fileOffset,
@@ -807,7 +840,7 @@
/// Concrete shadow object representing a field in kernel form.
class ShadowField extends Field implements ShadowMember {
@override
- InferenceNode _inferenceNode;
+ InferenceNode inferenceNode;
ShadowTypeInferrer _typeInferrer;
@@ -823,13 +856,13 @@
}
static bool hasTypeInferredFromInitializer(ShadowField field) =>
- field._inferenceNode is FieldInitializerInferenceNode;
+ field.inferenceNode is FieldInitializerInferenceNode;
static bool isImplicitlyTyped(ShadowField field) => field._isImplicitlyTyped;
static void setInferenceNode(ShadowField field, InferenceNode node) {
- assert(field._inferenceNode == null);
- field._inferenceNode = node;
+ assert(field.inferenceNode == null);
+ field.inferenceNode = node;
}
}
@@ -1428,18 +1461,18 @@
abstract class ShadowMember implements Member {
Uri get fileUri;
- InferenceNode get _inferenceNode;
+ InferenceNode get inferenceNode;
- void set _inferenceNode(InferenceNode value);
+ void set inferenceNode(InferenceNode value);
void setInferredType(
TypeInferenceEngine engine, Uri uri, DartType inferredType);
static void resolveInferenceNode(Member member) {
if (member is ShadowMember) {
- if (member._inferenceNode != null) {
- member._inferenceNode.resolve();
- member._inferenceNode = null;
+ if (member.inferenceNode != null) {
+ member.inferenceNode.resolve();
+ member.inferenceNode = null;
}
}
}
@@ -1568,7 +1601,7 @@
/// Concrete shadow object representing a procedure in kernel form.
class ShadowProcedure extends Procedure implements ShadowMember {
@override
- InferenceNode _inferenceNode;
+ InferenceNode inferenceNode;
final bool _hasImplicitReturnType;
@@ -1757,9 +1790,9 @@
if (write is StaticSet) {
writeContext = write.target.setterType;
writeMember = write.target;
- if (writeMember is ShadowField && writeMember._inferenceNode != null) {
- writeMember._inferenceNode.resolve();
- writeMember._inferenceNode = null;
+ if (writeMember is ShadowField && writeMember.inferenceNode != null) {
+ writeMember.inferenceNode.resolve();
+ writeMember.inferenceNode = null;
}
}
var inferredResult = _inferRhs(inferrer, readType, writeContext);
@@ -1776,9 +1809,9 @@
@override
DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
var target = this.target;
- if (target is ShadowField && target._inferenceNode != null) {
- target._inferenceNode.resolve();
- target._inferenceNode = null;
+ if (target is ShadowField && target.inferenceNode != null) {
+ target.inferenceNode.resolve();
+ target.inferenceNode = null;
}
var type = target.getterType;
if (target is Procedure && target.kind == ProcedureKind.Method) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 5a912e3..c436163 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -514,10 +514,12 @@
Constructor constructor, Map<TypeParameter, DartType> substitutionMap) {
VariableDeclaration copyFormal(VariableDeclaration formal) {
// TODO(ahe): Handle initializers.
- return new VariableDeclaration(formal.name,
- type: substitute(formal.type, substitutionMap),
- isFinal: formal.isFinal,
- isConst: formal.isConst);
+ var copy = new VariableDeclaration(formal.name,
+ isFinal: formal.isFinal, isConst: formal.isConst);
+ if (formal.type != null) {
+ copy.type = substitute(formal.type, substitutionMap);
+ }
+ return copy;
}
List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 0501d8b..8937d33 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -776,18 +776,7 @@
if (!optional('(', leftParen)) {
reportRecoverableError(
leftParen, fasta.templateExpectedButGot.withArguments('('));
-
- int offset = leftParen.charOffset;
- BeginToken openParen =
- new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
- Token next = openParen
- .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
- next = next.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
- openParen.endGroup = next;
-
- token.setNext(openParen);
- next.setNext(leftParen);
- leftParen = openParen;
+ leftParen = rewriter.insertParens(token, true);
}
token = parseDottedName(leftParen);
Token next = token.next;
@@ -1150,10 +1139,7 @@
Token next = token.next;
if (!optional('(', next)) {
reportRecoverableError(next, missingParameterMessage(kind));
- Token replacement = link(
- new SyntheticBeginToken(TokenType.OPEN_PAREN, next.charOffset),
- new SyntheticToken(TokenType.CLOSE_PAREN, next.charOffset));
- rewriter.insertTokenAfter(token, replacement);
+ rewriter.insertParens(token, false);
}
return parseFormalParameters(token, kind);
}
@@ -2469,7 +2455,7 @@
token = name;
listener.handleNoTypeVariables(token.next);
}
- checkFormals(name, isGetter, token.next, MemberKind.TopLevelMethod);
+ checkFormals(token, name, isGetter, MemberKind.TopLevelMethod);
token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod);
AsyncModifier savedAsyncModifier = asyncState;
Token asyncToken = token.next;
@@ -2499,10 +2485,11 @@
return token;
}
- void checkFormals(Token name, bool isGetter, Token token, MemberKind kind) {
- if (optional("(", token)) {
+ void checkFormals(Token token, Token name, bool isGetter, MemberKind kind) {
+ Token next = token.next;
+ if (optional("(", next)) {
if (isGetter) {
- reportRecoverableError(token, fasta.messageGetterWithFormals);
+ reportRecoverableError(next, fasta.messageGetterWithFormals);
}
} else if (!isGetter) {
if (optional('operator', name)) {
@@ -2513,7 +2500,9 @@
name = next.next;
}
}
+ // Recovery
reportRecoverableError(name, missingParameterMessage(kind));
+ rewriter.insertParens(token, false);
}
}
@@ -3157,7 +3146,7 @@
MemberKind kind = staticToken != null
? MemberKind.StaticMethod
: MemberKind.NonStaticMethod;
- checkFormals(name, isGetter, token.next, kind);
+ checkFormals(token, name, isGetter, kind);
Token beforeParam = token;
token = parseFormalParametersOpt(token, kind);
token = parseInitializersOpt(token);
@@ -4203,10 +4192,7 @@
// TODO(danrubel): Consider removing the 2nd error message.
reportRecoverableError(
next, fasta.templateExpectedToken.withArguments(')'));
- BeginToken replacement = link(
- new SyntheticBeginToken(TokenType.OPEN_PAREN, next.charOffset),
- new SyntheticToken(TokenType.CLOSE_PAREN, next.charOffset));
- rewriter.insertTokenAfter(token, replacement).next;
+ rewriter.insertParens(token, false);
}
Token begin = token.next;
token = parseExpressionInParenthesis(token);
@@ -4474,10 +4460,7 @@
if (!optional('(', next)) {
reportRecoverableError(
token, fasta.templateExpectedButGot.withArguments('('));
- BeginToken replacement = link(
- new SyntheticBeginToken(TokenType.OPEN_PAREN, next.offset),
- new SyntheticToken(TokenType.CLOSE_PAREN, next.offset));
- rewriter.insertTokenAfter(token, replacement);
+ rewriter.insertParens(token, false);
}
token = parseArguments(token);
return token;
@@ -5507,15 +5490,7 @@
Token openParens = catchKeyword.next;
if (!optional("(", openParens)) {
reportRecoverableError(openParens, fasta.messageCatchSyntax);
- BeginToken open = new SyntheticBeginToken(
- TokenType.OPEN_PAREN, openParens.charOffset);
- Token identifier = open.setNext(new SyntheticStringToken(
- TokenType.IDENTIFIER, '', openParens.charOffset));
- Token close = identifier.setNext(
- new SyntheticToken(TokenType.CLOSE_PAREN, openParens.charOffset));
- open.endGroup = close;
- rewriter.insertTokenAfter(catchKeyword, open);
- openParens = open;
+ openParens = rewriter.insertParens(catchKeyword, true);
}
Token exceptionName = openParens.next;
@@ -5774,18 +5749,7 @@
// Recovery
reportRecoverableError(
leftParenthesis, fasta.templateExpectedButGot.withArguments('('));
- int offset = leftParenthesis.offset;
-
- BeginToken openParen =
- token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
- Token identifier = openParen
- .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
- Token closeParen =
- identifier.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
- openParen.endGroup = closeParen;
- closeParen.setNext(leftParenthesis);
-
- leftParenthesis = openParen;
+ leftParenthesis = rewriter.insertParens(token, true);
}
token = leftParenthesis;
Token commaToken = null;
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index 529c38e..38b68b6 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -6,6 +6,7 @@
show
BeginToken,
SimpleToken,
+ SyntheticBeginToken,
SyntheticStringToken,
SyntheticToken,
Token,
@@ -39,6 +40,25 @@
/// Initialize a newly created re-writer.
TokenStreamRewriter();
+ /// Insert a synthetic open and close parenthesis and return the new synthetic
+ /// open parenthesis. If [insertIdentifier] is true, then a synthetic
+ /// identifier is included between the open and close parenthesis.
+ Token insertParens(Token token, bool includeIdentifier) {
+ Token next = token.next;
+ int offset = next.charOffset;
+ BeginToken leftParen =
+ next = new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
+ if (includeIdentifier) {
+ next = next.setNext(
+ new SyntheticStringToken(TokenType.IDENTIFIER, '', offset, 0));
+ }
+ next = next.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+ leftParen.endGroup = next;
+ next.setNext(token.next);
+ token.setNext(leftParen);
+ return leftParen;
+ }
+
/// Insert a synthetic identifier after [token] and return the new identifier.
Token insertSyntheticIdentifier(Token token) {
Token identifier = new SyntheticStringToken(
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index f3952c9..1a037f4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -815,8 +815,6 @@
ticker.logMs("Performed top level inference");
}
- List<Uri> getDependencies() => sourceBytes.keys.toList();
-
Expression instantiateInvocation(Expression receiver, String name,
Arguments arguments, int offset, bool isSuper) {
return target.backendTarget.instantiateInvocation(
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 5a52a48..9fe590f 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -4,16 +4,16 @@
import 'package:kernel/ast.dart'
show
- Class,
+ Constructor,
DartType,
DartTypeVisitor,
DynamicType,
FunctionType,
InterfaceType,
- Location,
TypeParameter,
TypeParameterType,
- TypedefType;
+ TypedefType,
+ VariableDeclaration;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
@@ -21,12 +21,9 @@
import '../builder/library_builder.dart';
-import '../deprecated_problems.dart' show Crash;
-
import '../kernel/kernel_shadow_ast.dart';
-import '../messages.dart'
- show getLocationFromNode, noLength, templateCantInferTypeDueToCircularity;
+import '../messages.dart' show noLength, templateCantInferTypeDueToCircularity;
import '../source/source_library_builder.dart';
@@ -211,7 +208,20 @@
final staticInferenceNodes = <FieldInitializerInferenceNode>[];
- final initializingFormals = <ShadowVariableDeclaration>[];
+ /// A map containing constructors with initializing formals whose types
+ /// need to be inferred.
+ ///
+ /// This is represented as a map from a constructor to its library
+ /// builder because the builder is used to report errors due to cyclic
+ /// inference dependencies.
+ final Map<Constructor, LibraryBuilder> toBeInferred = {};
+
+ /// A map containing constructors in the process of being inferred.
+ ///
+ /// This is used to detect cyclic inference dependencies. It is represented
+ /// as a map from a constructor to its library builder because the builder
+ /// is used to report errors.
+ final Map<Constructor, LibraryBuilder> beingInferred = {};
final Instrumentation instrumentation;
@@ -248,20 +258,37 @@
}
/// Performs the third phase of top level inference, which is to visit all
- /// initializing formals and infer their types (if necessary) from the
- /// corresponding fields.
+ /// constructors still needing inference and infer the types of their
+ /// initializing formals from the corresponding fields.
void finishTopLevelInitializingFormals() {
- for (ShadowVariableDeclaration formal in initializingFormals) {
- try {
- formal.type = _inferInitializingFormalType(formal);
- } catch (e, s) {
- Location location = getLocationFromNode(formal);
- if (location == null) {
- rethrow;
- } else {
- throw new Crash(location.file, formal.fileOffset, e, s);
+ // Field types have all been inferred so there cannot be a cyclic
+ // dependency.
+ for (Constructor constructor in toBeInferred.keys) {
+ for (var declaration in constructor.function.positionalParameters) {
+ inferInitializingFormal(declaration, constructor);
+ }
+ for (var declaration in constructor.function.namedParameters) {
+ inferInitializingFormal(declaration, constructor);
+ }
+ }
+ toBeInferred.clear();
+ }
+
+ void inferInitializingFormal(VariableDeclaration formal, Constructor parent) {
+ if (formal.type == null) {
+ for (ShadowField field in parent.enclosingClass.fields) {
+ if (field.name.name == formal.name) {
+ if (field.inferenceNode != null) {
+ field.inferenceNode.resolve();
+ }
+ formal.type = field.type;
+ return;
}
}
+ // We did not find the corresponding field, so the program is erroneous.
+ // The error should have been reported elsewhere and type inference
+ // should continue by inferring dynamic.
+ formal.type = const DynamicType();
}
}
@@ -274,12 +301,6 @@
new TypeSchemaEnvironment(coreTypes, hierarchy, strongMode);
}
- /// Records that the given initializing [formal] will need top level type
- /// inference.
- void recordInitializingFormal(ShadowVariableDeclaration formal) {
- initializingFormals.add(formal);
- }
-
/// Records that the given static [field] will need top level type inference.
void recordStaticFieldInferenceCandidate(
ShadowField field, LibraryBuilder library) {
@@ -287,20 +308,4 @@
ShadowField.setInferenceNode(field, node);
staticInferenceNodes.add(node);
}
-
- DartType _inferInitializingFormalType(ShadowVariableDeclaration formal) {
- assert(ShadowVariableDeclaration.isImplicitlyTyped(formal));
- var enclosingClass = formal.parent?.parent?.parent;
- if (enclosingClass is Class) {
- for (var field in enclosingClass.fields) {
- if (field.name.name == formal.name) {
- return field.type;
- }
- }
- }
- // No matching field, or something else has gone wrong (e.g. initializing
- // formal outside of a class declaration). The error should be reported
- // elsewhere, so just infer `dynamic`.
- return const DynamicType();
- }
}
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 8b78836..b699884 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -144,7 +144,7 @@
return new CompilerResult(
summary: summary,
component: component,
- deps: kernelTarget.loader.getDependencies());
+ deps: new List<Uri>.from(CompilerContext.current.dependencies));
} on deprecated_InputError catch (e) {
options.report(
deprecated_InputError.toMessage(e), Severity.internalProblem);
diff --git a/pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart b/pkg/front_end/lib/src/scheme_based_file_system.dart
similarity index 94%
rename from pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart
rename to pkg/front_end/lib/src/scheme_based_file_system.dart
index c992ea7..c2b3981 100644
--- a/pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart
+++ b/pkg/front_end/lib/src/scheme_based_file_system.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'file_system.dart';
+import 'api_prototype/file_system.dart';
/// A [FileSystem] that delegates to other file systems based on the URI scheme.
class SchemeBasedFileSystem implements FileSystem {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index d308900..8c56c40 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -116,7 +116,6 @@
DuplicatedExportInType/analyzerCode: Fail
DuplicatedExportInType/example: Fail
DuplicatedImportInType/analyzerCode: Fail
-DuplicatedImportInType/example: Fail
DuplicatedModifier/script1: Fail
DuplicatedName/analyzerCode: Fail
DuplicatedName/example: Fail
@@ -249,7 +248,6 @@
MissingMain/analyzerCode: Fail
MissingMain/example: Fail
MissingPartOf/analyzerCode: Fail
-MissingPartOf/example: Fail
MissingPrefixInDeferredImport/example: Fail
MixinInferenceNoMatchingClass/analyzerCode: Fail
MixinInferenceNoMatchingClass/example: Fail
@@ -299,15 +297,12 @@
PartOfLibraryNameMismatch/analyzerCode: Fail
PartOfLibraryNameMismatch/example: Fail
PartOfSelf/analyzerCode: Fail
-PartOfSelf/example: Fail
PartOfTwoLibraries/analyzerCode: Fail # Issue 33227
-PartOfTwoLibraries/example: Fail # Needs multiple files
PartOfUriMismatch/analyzerCode: Fail
PartOfUriMismatch/example: Fail
PartOfUseUri/analyzerCode: Fail
PartOfUseUri/example: Fail
PartTwice/analyzerCode: Fail
-PartTwice/example: Fail
PatchClassTypeVariablesMismatch/analyzerCode: Fail
PatchClassTypeVariablesMismatch/example: Fail
PatchDeclarationMismatch/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index af33dd73..534bfdf 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1410,6 +1410,10 @@
DuplicatedImportInType:
template: "'#name' is imported from both '#uri' and '#uri2'."
severity: ERROR_LEGACY_WARNING
+ script:
+ lib1.dart: "class A {}"
+ lib2.dart: "class A {}"
+ main.dart: "import 'lib1.dart'; import 'lib2.dart'; A a;"
CyclicClassHierarchy:
template: "'#name' is a supertype of itself via '#string'."
@@ -1579,6 +1583,8 @@
PartOfSelf:
template: "A file can't be a part of itself."
+ script:
+ main.dart: "part 'main.dart';"
TypeVariableDuplicatedName:
template: "A type variable can't have the same name as another."
@@ -1703,11 +1709,18 @@
PartTwice:
template: "Can't use '#uri' as a part more than once."
+ script:
+ part.dart: "part of 'main.dart';"
+ main.dart: "part 'part.dart'; part 'part.dart';"
PartOfTwoLibraries:
template: "A file can't be part of more than one library."
tip: "Try moving the shared declarations into the libraries, or into a new library."
severity: ERROR
+ script:
+ main.dart: "library lib; import 'lib.dart'; part 'part.dart';"
+ lib.dart: "library lib; part 'part.dart';"
+ part.dart: "part of lib;"
PartOfTwoLibrariesContext:
template: "Used as a part in this library."
@@ -1765,6 +1778,9 @@
MissingPartOf:
template: "Can't use '#uri' as a part, because it has no 'part of' declaration."
+ script:
+ part.dart: ""
+ main.dart: "part 'part.dart';"
SupertypeIsFunction:
template: "Can't use a function type as supertype."
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 4ba2dc2..86c698f 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -20,6 +20,7 @@
dev_dependencies:
analyzer: '>=0.31.0 <0.33.0'
args: '>=0.13.0 <2.0.0'
+ build_integration: ^0.0.1
dart_style: '^1.0.7'
json_rpc_2: ^2.0.4
mockito: ^2.0.2
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 8d1dad4..4901f63 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -54,11 +54,11 @@
import 'package:front_end/src/fasta/kernel/kernel_expression_generator.dart'
show
- DelayedAssignment,
- DelayedPostfixIncrement,
IncompleteErrorGenerator,
IncompletePropertyAccessGenerator,
KernelDeferredAccessGenerator,
+ KernelDelayedAssignment,
+ KernelDelayedPostfixIncrement,
KernelIndexedAccessGenerator,
KernelLargeIntAccessGenerator,
KernelLoadLibraryGenerator,
@@ -140,12 +140,12 @@
check(
"DelayedAssignment(offset: 4, value: expression,"
" assignmentOperator: +=)",
- new DelayedAssignment(
+ new KernelDelayedAssignment(
helper, token, generator, expression, assignmentOperator));
check(
"DelayedPostfixIncrement(offset: 4, binaryOperator: +,"
" interfaceTarget: $uri::#class1::myInterfaceTarget)",
- new DelayedPostfixIncrement(
+ new KernelDelayedPostfixIncrement(
helper, token, generator, binaryOperator, interfaceTarget));
check(
"VariableUseGenerator(offset: 4, variable: dynamic #t1;\n,"
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index e1a706c..d5d759d 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -157,10 +157,11 @@
if (node is YamlList) {
int i = 0;
for (YamlNode script in node.nodes) {
- examples.add(new ScriptExample("script${++i}", name, script));
+ examples
+ .add(new ScriptExample("script${++i}", name, script, this));
}
} else {
- examples.add(new ScriptExample("script", name, node));
+ examples.add(new ScriptExample("script", name, node, this));
}
break;
@@ -301,6 +302,10 @@
YamlNode get node;
Uint8List get bytes;
+
+ Map<String, Uint8List> get scripts {
+ return {"main.dart": bytes};
+ }
}
class BytesExample extends Example {
@@ -380,15 +385,33 @@
@override
final YamlNode node;
- final String script;
+ final Object script;
- ScriptExample(String name, String code, this.node)
+ ScriptExample(String name, String code, this.node, MessageTestSuite suite)
: script = node.value,
- super(name, code);
+ super(name, code) {
+ if (script is! String && script is! Map) {
+ throw suite.formatProblems(
+ "A script must be either a String or a Map in $code:",
+ this, <List>[]);
+ }
+ }
@override
- Uint8List get bytes {
- return new Uint8List.fromList(utf8.encode(script));
+ Uint8List get bytes => throw "Unsupported: ScriptExample.bytes";
+
+ @override
+ Map<String, Uint8List> get scripts {
+ Object script = this.script;
+ if (script is Map) {
+ var scriptFiles = <String, Uint8List>{};
+ script.forEach((fileName, value) {
+ scriptFiles[fileName] = new Uint8List.fromList(utf8.encode(value));
+ });
+ return scriptFiles;
+ } else {
+ return {"main.dart": new Uint8List.fromList(utf8.encode(script))};
+ }
}
}
@@ -414,12 +437,16 @@
Future<Result<Null>> run(Example example, MessageTestSuite suite) async {
if (example == null) return pass(null);
- String name = "${example.expectedCode}/${example.name}";
- Uri uri = suite.fileSystem.currentDirectory.resolve("${name}.dart");
- suite.fileSystem.entityForUri(uri).writeAsBytesSync(example.bytes);
- Uri output = uri.resolve("${uri.path}.dill");
+ String dir = "${example.expectedCode}/${example.name}";
+ example.scripts.forEach((String fileName, Uint8List bytes) {
+ Uri uri = suite.fileSystem.currentDirectory.resolve("$dir/$fileName");
+ suite.fileSystem.entityForUri(uri).writeAsBytesSync(bytes);
+ });
+ Uri main = suite.fileSystem.currentDirectory.resolve("$dir/main.dart");
+ Uri output =
+ suite.fileSystem.currentDirectory.resolve("$dir/main.dart.dill");
- print("Compiling $uri");
+ print("Compiling $main");
List<List> problems = <List>[];
await suite.compiler.batchCompile(
@@ -432,7 +459,7 @@
problems.add([problem, severity]);
}
..strongMode = true,
- uri,
+ main,
output);
List<List> unexpectedProblems = <List>[];
diff --git a/pkg/front_end/test/scheme_based_file_system_test.dart b/pkg/front_end/test/scheme_based_file_system_test.dart
index be40f65..e6b374b 100644
--- a/pkg/front_end/test/scheme_based_file_system_test.dart
+++ b/pkg/front_end/test/scheme_based_file_system_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:front_end/src/api_prototype/file_system.dart';
-import 'package:front_end/src/api_prototype/scheme_based_file_system.dart';
+import 'package:front_end/src/scheme_based_file_system.dart';
import 'package:test/test.dart';
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart b/pkg/front_end/testcases/circularity-via-initializing-formal.dart
new file mode 100644
index 0000000..939cb91
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// This test is intended to trigger a circular top-level type-inference
+// dependency involving an initializing formal where the circularity is detected
+// when inferring the type of the constructor.
+//
+// The compiler should generate an error message and it should be properly
+// formatted including offset and lenght of the constructor.
+var x = new C._circular(null);
+
+class C {
+ var f = new C._circular(null);
+ C._circular(this.f);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.expect
new file mode 100644
index 0000000..245a701
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field dynamic f = new self::C::_circular(null);
+ constructor _circular(dynamic f) → void
+ : self::C::f = f, super core::Object::•()
+ ;
+}
+static field dynamic x = new self::C::_circular(null);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.transformed.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.transformed.expect
new file mode 100644
index 0000000..245a701
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field dynamic f = new self::C::_circular(null);
+ constructor _circular(dynamic f) → void
+ : self::C::f = f, super core::Object::•()
+ ;
+}
+static field dynamic x = new self::C::_circular(null);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.outline.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.outline.expect
new file mode 100644
index 0000000..9bdea4e
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field dynamic f;
+ constructor _circular(dynamic f) → void
+ ;
+}
+static field dynamic x;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect
new file mode 100644
index 0000000..6fa3d2b
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field self::C f = new self::C::_circular(null);
+ constructor _circular(self::C f) → void
+ : self::C::f = f, super core::Object::•()
+ ;
+}
+static field self::C x = new self::C::_circular(null);
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
+Specify the type explicitly.
+ C._circular(this.f);
+ ^^^^^^^^^^^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fa3d2b
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ field self::C f = new self::C::_circular(null);
+ constructor _circular(self::C f) → void
+ : self::C::f = f, super core::Object::•()
+ ;
+}
+static field self::C x = new self::C::_circular(null);
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
+Specify the type explicitly.
+ C._circular(this.f);
+ ^^^^^^^^^^^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31155.dart.direct.expect
index 4776f6a..cf914a5 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.direct.expect
@@ -32,5 +32,12 @@
var f = Map<A, B> {};
^", "pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
var f = Map<A, B> {};
- ^"]/* from null */;
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A function expression can't have a name.
+ var f = Map<A, B> {};
+ ^^^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: A function declaration needs an explicit list of parameters.
+Try adding a parameter list to the function declaration.
+ var f = Map<A, B> {};
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: Expected a function body, but got '<'.
+ var f = Map<A, B> {};
+ ^"]/* from null */;
static method main() → void {}
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.direct.transformed.expect
index 4776f6a..cf914a5 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.direct.transformed.expect
@@ -32,5 +32,12 @@
var f = Map<A, B> {};
^", "pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
var f = Map<A, B> {};
- ^"]/* from null */;
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A function expression can't have a name.
+ var f = Map<A, B> {};
+ ^^^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: A function declaration needs an explicit list of parameters.
+Try adding a parameter list to the function declaration.
+ var f = Map<A, B> {};
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: Expected a function body, but got '<'.
+ var f = Map<A, B> {};
+ ^"]/* from null */;
static method main() → void {}
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
index e088ade..da8a488 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
@@ -35,5 +35,12 @@
var f = Map<A, B> {};
^", "pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
var f = Map<A, B> {};
- ^"]/* from null */;
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A function expression can't have a name.
+ var f = Map<A, B> {};
+ ^^^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: A function declaration needs an explicit list of parameters.
+Try adding a parameter list to the function declaration.
+ var f = Map<A, B> {};
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: Expected a function body, but got '<'.
+ var f = Map<A, B> {};
+ ^"]/* from null */;
static method main() → void {}
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
index 3e6b682..f332e29 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
@@ -35,5 +35,12 @@
var f = Map<A, B> {};
^", "pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
var f = Map<A, B> {};
- ^"]/* from null */;
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:11: Error: A function expression can't have a name.
+ var f = Map<A, B> {};
+ ^^^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: A function declaration needs an explicit list of parameters.
+Try adding a parameter list to the function declaration.
+ var f = Map<A, B> {};
+ ^", "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: Expected a function body, but got '<'.
+ var f = Map<A, B> {};
+ ^"]/* from null */;
static method main() → void {}
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index daceb3cd..8408682 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -6,9 +6,17 @@
import 'dart:io' show exit;
+import 'package:build_integration/file_system/single_root.dart'
+ show SingleRootFileSystem;
+
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
+import 'package:front_end/src/api_prototype/file_system.dart' show FileSystem;
+
+import 'package:front_end/src/api_prototype/standard_file_system.dart'
+ show StandardFileSystem;
+
import 'package:front_end/src/base/processed_options.dart'
show ProcessedOptions;
@@ -29,10 +37,13 @@
import 'package:front_end/src/fasta/severity.dart' show Severity;
+import 'package:front_end/src/scheme_based_file_system.dart'
+ show SchemeBasedFileSystem;
+
import 'package:kernel/target/targets.dart'
show Target, getTarget, TargetFlags, targets;
-Uri resolveFile(String path) => Uri.base.resolveUri(new Uri.file(path));
+import 'resolve_input_uri.dart' show resolveInputUri;
class CommandLineProblem {
final Message message;
@@ -159,7 +170,9 @@
"but expected one of: 'true', 'false', 'yes', or 'no'.");
}
} else if (valueSpecification == Uri) {
- parsedValue = resolveFile(value);
+ // TODO(ahe): resolve Uris lazily, so that schemes provided by
+ // other flags can be used for parsed command-line arguments too.
+ parsedValue = resolveInputUri(value);
} else if (valueSpecification == String) {
parsedValue = value;
} else if (valueSpecification is String) {
@@ -210,6 +223,8 @@
"--packages": Uri,
"--platform": Uri,
"--sdk": Uri,
+ "--single-root-scheme": String,
+ "--single-root-base": Uri,
"--strong": "--strong-mode",
"--strong-mode": false,
"--sync-async": true,
@@ -279,6 +294,24 @@
final bool compileSdk = options.containsKey("--compile-sdk");
+ final String singleRootScheme = options["--single-root-scheme"];
+ final Uri singleRootBase = options["--single-root-base"];
+
+ FileSystem fileSystem = StandardFileSystem.instance;
+ List<String> extraSchemes = const [];
+ if (singleRootScheme != null) {
+ extraSchemes = [singleRootScheme];
+ fileSystem = new SchemeBasedFileSystem({
+ 'file': fileSystem,
+ 'data': fileSystem,
+ // TODO(askesc): remove also when fixing StandardFileSystem (empty schemes
+ // should have been handled elsewhere).
+ '': fileSystem,
+ singleRootScheme: new SingleRootFileSystem(
+ singleRootScheme, singleRootBase, fileSystem),
+ });
+ }
+
if (programName == "compile_platform") {
if (arguments.length != 4) {
return throw new CommandLineProblem.deprecated(
@@ -296,8 +329,10 @@
return new ProcessedOptions(
new CompilerOptions()
..sdkSummary = options["--platform"]
- ..librariesSpecificationUri = resolveFile(arguments[1])
+ ..librariesSpecificationUri =
+ resolveInputUri(arguments[1], extraSchemes: extraSchemes)
..setExitCodeOnProblem = true
+ ..fileSystem = fileSystem
..packagesFileUri = packages
..strongMode = strongMode
..target = target
@@ -308,12 +343,13 @@
..verbose = verbose
..verify = verify,
<Uri>[Uri.parse(arguments[0])],
- resolveFile(arguments[2]));
+ resolveInputUri(arguments[2], extraSchemes: extraSchemes));
} else if (arguments.isEmpty) {
return throw new CommandLineProblem.deprecated("No Dart file specified.");
}
- final Uri defaultOutput = resolveFile("${arguments.first}.dill");
+ final Uri defaultOutput =
+ resolveInputUri("${arguments.first}.dill", extraSchemes: extraSchemes);
final Uri output = options["-o"] ?? options["--output"] ?? defaultOutput;
@@ -326,6 +362,7 @@
CompilerOptions compilerOptions = new CompilerOptions()
..compileSdk = compileSdk
+ ..fileSystem = fileSystem
..sdkRoot = sdk
..sdkSummary = platform
..packagesFileUri = packages
@@ -343,7 +380,7 @@
List<Uri> inputs = <Uri>[];
if (areRestArgumentsInputs) {
for (String argument in arguments) {
- inputs.add(resolveFile(argument));
+ inputs.add(resolveInputUri(argument, extraSchemes: extraSchemes));
}
}
return new ProcessedOptions(compilerOptions, inputs, output);
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index fd26f5f..4f02bd0 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -8,6 +8,8 @@
import 'dart:io' show File, Platform, exitCode;
+import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
+
import 'package:vm/bytecode/gen_bytecode.dart'
show generateBytecode, isKernelBytecodeEnabledForPlatform;
@@ -16,17 +18,17 @@
import 'package:front_end/src/fasta/deprecated_problems.dart'
show deprecated_InputError;
+import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
+
import 'package:front_end/src/fasta/kernel/utils.dart'
show writeComponentToFile;
import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:front_end/src/kernel_generator_impl.dart'
- show generateKernelInternal;
-
import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
-import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
+import 'package:front_end/src/kernel_generator_impl.dart'
+ show generateKernelInternal;
import 'additional_targets.dart' show installAdditionalTargets;
@@ -87,14 +89,33 @@
c.options.ticker.logMs("Wrote component to ${fullOutput.toFilePath()}");
List<Uri> deps = result.deps.toList();
- deps.addAll(await getDependencies(Platform.script,
- platform: outlineOutput, target: c.options.target));
+ for (Uri dependency
+ in await computeHostDependencies(outlineOutput.resolve("./"))) {
+ // Add the dependencies of the compiler's own sources.
+ if (dependency != outlineOutput) {
+ // We're computing the dependencies for [outlineOutput], so we shouldn't
+ // include it in the deps file.
+ deps.add(dependency);
+ }
+ }
await writeDepsFile(
fullOutput, new File(new File.fromUri(fullOutput).path + ".d").uri, deps);
}
+Future<List<Uri>> computeHostDependencies(Uri platformLocation) async {
+ // Returns a list of source files that make up the Fasta compiler (the files
+ // the Dart VM reads to run Fasta). Until Fasta is self-hosting (in strong
+ // mode), this is only an approximation, albeit accurate. Once Fasta is
+ // self-hosting, this isn't an approximation. Regardless, strong mode
+ // shouldn't affect which files are read.
+ Uri hostPlatform = platformLocation.resolve("vm_outline_strong.dill");
+ Target hostTarget = getTarget("vm", new TargetFlags(strongMode: true));
+ return getDependencies(Platform.script,
+ platform: hostPlatform, target: hostTarget);
+}
+
Future writeDepsFile(
- Uri output, Uri depsFile, Iterable<Uri> allDependencies) async {
+ Uri output, Uri depsFile, List<Uri> allDependencies) async {
if (allDependencies.isEmpty) return;
String toRelativeFilePath(Uri uri) {
// Ninja expects to find file names relative to the current working
@@ -122,9 +143,20 @@
StringBuffer sb = new StringBuffer();
sb.write(toRelativeFilePath(output));
sb.write(":");
- for (Uri uri in allDependencies) {
- sb.write(" \\\n ");
- sb.write(toRelativeFilePath(uri));
+ List<String> paths = new List<String>(allDependencies.length);
+ for (int i = 0; i < allDependencies.length; i++) {
+ paths[i] = toRelativeFilePath(allDependencies[i]);
+ }
+ // Sort the relative paths to ease analyzing future changes to this code.
+ paths.sort();
+ String previous;
+ for (String path in paths) {
+ // Check for and omit duplicates.
+ if (path != previous) {
+ previous = path;
+ sb.write(" \\\n ");
+ sb.write(path);
+ }
}
sb.writeln();
await new File.fromUri(depsFile).writeAsString("$sb");
diff --git a/pkg/front_end/tool/_fasta/compile_platform_legacy_test.dart b/pkg/front_end/tool/_fasta/compile_platform_legacy_test.dart
index 76ffc18..47a5f9c 100644
--- a/pkg/front_end/tool/_fasta/compile_platform_legacy_test.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform_legacy_test.dart
@@ -20,7 +20,7 @@
asyncTest(() async {
await withTemporaryDirectory("compile_platform_test_", (Uri tmp) async {
Uri platformDill = tmp.resolve("vm_platform.dill");
- Uri outlineDill = tmp.resolve("vm_outline.dill");
+ Uri outlineDill = tmp.resolve("vm_outline_strong.dill");
ProcessResult result = await Process.run(dartVm.toFilePath(), <String>[
compilePlatform.toFilePath(),
"-v",
diff --git a/pkg/front_end/tool/_fasta/compile_platform_test.dart b/pkg/front_end/tool/_fasta/compile_platform_test.dart
index 84ef2df..b09d1c6 100644
--- a/pkg/front_end/tool/_fasta/compile_platform_test.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform_test.dart
@@ -20,7 +20,7 @@
asyncTest(() async {
await withTemporaryDirectory("compile_platform_test_", (Uri tmp) async {
Uri platformDill = tmp.resolve("vm_platform.dill");
- Uri outlineDill = tmp.resolve("vm_outline.dill");
+ Uri outlineDill = tmp.resolve("vm_outline_strong.dill");
ProcessResult result = await Process.run(dartVm.toFilePath(), <String>[
compilePlatform.toFilePath(),
"-v",
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index b2a1d8f..3af6703 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -100,7 +100,8 @@
run() async {
await for (String line in lines) {
try {
- if (await batchCompileArguments(jsonDecode(line))) {
+ if (await batchCompileArguments(
+ new List<String>.from(jsonDecode(line)))) {
stdout.writeln(">>> TEST OK");
} else {
stdout.writeln(">>> TEST FAIL");
diff --git a/pkg/front_end/tool/_fasta/resolve_input_uri.dart b/pkg/front_end/tool/_fasta/resolve_input_uri.dart
new file mode 100644
index 0000000..f0b49d5
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/resolve_input_uri.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, 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.
+
+/// Resolve [string] as a [Uri]. If the input [string] starts with a supported
+/// scheme, it is resolved as a Uri of that scheme, otherwise the [string]
+/// is treated as a file system (possibly relative) path.
+///
+/// Three schemes are always supported by default: `dart`, `package`, and
+/// `data`. Additional supported schemes can be specified via [extraSchemes].
+Uri resolveInputUri(String string, {List<String> extraSchemes: const []}) {
+ if (string.startsWith('dart:')) return Uri.parse(string);
+ if (string.startsWith('data:')) return Uri.parse(string);
+ if (string.startsWith('package:')) return Uri.parse(string);
+ for (var scheme in extraSchemes) {
+ if (string.startsWith('$scheme:')) return Uri.parse(string);
+ }
+ return Uri.base.resolveUri(new Uri.file(string));
+}
diff --git a/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart b/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart
new file mode 100644
index 0000000..7020ffc
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2018, 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:test/test.dart';
+
+import 'resolve_input_uri.dart';
+
+main() {
+ test('data URI scheme is supported by default', () {
+ expect(resolveInputUri('data:,foo').scheme, 'data');
+ });
+
+ test('internal dart schemes are recognized by default', () {
+ expect(resolveInputUri('dart:foo').scheme, 'dart');
+ expect(resolveInputUri('package:foo').scheme, 'package');
+ });
+
+ test('unknown schemes are not recognized by default', () {
+ expect(resolveInputUri('test:foo').scheme, 'file');
+ expect(resolveInputUri('org-dartlang-foo:bar').scheme, 'file');
+ });
+
+ test('more schemes can be supported', () {
+ expect(resolveInputUri('test:foo', extraSchemes: ['test']).scheme, 'test');
+ expect(
+ resolveInputUri('org-dartlang-foo:bar',
+ extraSchemes: ['org-dartlang-foo']).scheme,
+ 'org-dartlang-foo');
+ });
+}
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index b8a3aa8..cf18494 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -287,6 +287,10 @@
// Handle use-sites of constants (and "inline" constant expressions):
+ visitSymbolLiteral(SymbolLiteral node) {
+ return new ConstantExpression(constantEvaluator.evaluate(node));
+ }
+
visitStaticGet(StaticGet node) {
final Member target = node.target;
if (target is Field && target.isConst) {
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 1ff41ca..0c49070 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -49,6 +49,7 @@
front_end/tool/incremental_perf_test: Slow, Pass
kernel/test/closures_test: Slow, Pass
kernel/testcases/*: Skip # These are not tests but input for tests.
+vm/test/frontend_server_test: Slow, Pass
vm/test/transformations/type_flow/transformer_test: Slow, Pass
vm/testcases/*: SkipByDesign # These are not tests but input for tests.
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 797bc67..4e218c8 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -152,6 +152,11 @@
if (locals.hasTypeArgsVar) {
asm.emitPush(locals.typeArgsVarIndexInFrame);
+ } else if (enclosingMember is Procedure &&
+ (enclosingMember as Procedure).isFactory) {
+ // Null type arguments are passed to factory constructors even if class
+ // is not generic. TODO(alexmarkov): Clean this up.
+ _genPushNull();
}
if (locals.hasReceiver) {
asm.emitPush(locals.getVarIndexInFrame(locals.receiverVar));
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index e484146..9d5797b 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -373,39 +373,40 @@
// be invalidated by the normal approach anyway.
if (_generator.initialized) return null;
+ final File f = new File(_initializeFromDill);
+ if (!f.existsSync()) return null;
+
+ Component component;
try {
- final File f = new File(_initializeFromDill);
- if (!f.existsSync()) return null;
+ component = loadComponentSourceFromBytes(f.readAsBytesSync());
+ } catch (e) {
+ // If we cannot load the dill file we shouldn't initialize from it.
+ _generator = _createGenerator(null);
+ return null;
+ }
- final Component component =
- loadComponentSourceFromBytes(f.readAsBytesSync());
- for (Uri uri in component.uriToSource.keys) {
- if ('$uri' == '') continue;
+ nextUri:
+ for (Uri uri in component.uriToSource.keys) {
+ if (uri == null || '$uri' == '') continue nextUri;
- final List<int> oldBytes = component.uriToSource[uri].source;
- final FileSystemEntity entity =
- _compilerOptions.fileSystem.entityForUri(uri);
- if (!await entity.exists()) {
+ final List<int> oldBytes = component.uriToSource[uri].source;
+ final FileSystemEntity entity =
+ _compilerOptions.fileSystem.entityForUri(uri);
+ if (!await entity.exists()) {
+ _generator.invalidate(uri);
+ continue nextUri;
+ }
+ final List<int> newBytes = await entity.readAsBytes();
+ if (oldBytes.length != newBytes.length) {
+ _generator.invalidate(uri);
+ continue nextUri;
+ }
+ for (int i = 0; i < oldBytes.length; ++i) {
+ if (oldBytes[i] != newBytes[i]) {
_generator.invalidate(uri);
- continue;
- }
- final List<int> newBytes = await entity.readAsBytes();
- if (oldBytes.length != newBytes.length) {
- _generator.invalidate(uri);
- continue;
- }
- for (int i = 0; i < oldBytes.length; ++i) {
- if (oldBytes[i] != newBytes[i]) {
- _generator.invalidate(uri);
- continue;
- }
+ continue nextUri;
}
}
- } catch (e) {
- // If there's a failure in the above block we might not have invalidated
- // correctly. Create a new generator that doesn't initialize from dill to
- // avoid missing any changes.
- _generator = _createGenerator(null);
}
}
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 997bdf9..7efa188 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -6,6 +6,8 @@
import 'package:args/src/arg_results.dart';
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/kernel.dart' show loadComponentFromBinary;
+import 'package:kernel/verifier.dart' show verifyComponent;
import 'package:mockito/mockito.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -786,6 +788,168 @@
expect(path.basename(depContentsParsed[0]), path.basename(dillFile.path));
expect(depContentsParsed[1], isNotEmpty);
});
+
+ test('mimic flutter benchmark', () async {
+ // This is based on what flutters "hot_mode_dev_cycle__benchmark" does.
+ var dillFile = new File('${tempDir.path}/full.dill');
+ var incrementalDillFile = new File('${tempDir.path}/incremental.dill');
+ expect(dillFile.existsSync(), equals(false));
+ final List<String> args = <String>[
+ '--sdk-root=${sdkRoot.toFilePath()}',
+ '--strong',
+ '--incremental',
+ '--platform=${platformKernel.path}',
+ '--output-dill=${dillFile.path}',
+ '--output-incremental-dill=${incrementalDillFile.path}'
+ ];
+ File dart2js = new File.fromUri(
+ Platform.script.resolve("../../../pkg/compiler/bin/dart2js.dart"));
+ expect(dart2js.existsSync(), equals(true));
+ File dart2jsOtherFile = new File.fromUri(Platform.script
+ .resolve("../../../pkg/compiler/lib/src/compiler.dart"));
+ expect(dart2jsOtherFile.existsSync(), equals(true));
+
+ int libraryCount = -1;
+ int sourceCount = -1;
+
+ for (int serverCloses = 0; serverCloses < 2; ++serverCloses) {
+ print("Restart #$serverCloses");
+ final StreamController<List<int>> streamController =
+ new StreamController<List<int>>();
+ final StreamController<List<int>> stdoutStreamController =
+ new StreamController<List<int>>();
+ final IOSink ioSink = new IOSink(stdoutStreamController.sink);
+ StreamController<String> receivedResults =
+ new StreamController<String>();
+
+ String boundaryKey;
+ stdoutStreamController.stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen((String s) {
+ const String RESULT_OUTPUT_SPACE = 'result ';
+ if (boundaryKey == null) {
+ if (s.startsWith(RESULT_OUTPUT_SPACE)) {
+ boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
+ }
+ } else {
+ if (s.startsWith(boundaryKey)) {
+ receivedResults.add(s.substring(boundaryKey.length + 1));
+ boundaryKey = null;
+ }
+ }
+ });
+
+ int exitcode =
+ await starter(args, input: streamController.stream, output: ioSink);
+ expect(exitcode, equals(0));
+ streamController.add('compile ${dart2js.path}\n'.codeUnits);
+ int count = 0;
+ Completer<bool> allDone = new Completer<bool>();
+ receivedResults.stream.listen((String outputFilenameAndErrorCount) {
+ int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
+ expect(delim > 0, equals(true));
+ String outputFilename =
+ outputFilenameAndErrorCount.substring(0, delim);
+ print("$outputFilename -- count $count");
+ if (count == 0) {
+ // First request is to 'compile', which results in full kernel file.
+ expect(dillFile.existsSync(), equals(true));
+ expect(outputFilename, dillFile.path);
+
+ // Dill file can be loaded and includes data.
+ Component component = loadComponentFromBinary(dillFile.path);
+ if (serverCloses == 0) {
+ libraryCount = component.libraries.length;
+ sourceCount = component.uriToSource.length;
+ expect(libraryCount > 100, equals(true));
+ expect(sourceCount >= libraryCount, equals(true),
+ reason: "Expects >= source entries than libraries.");
+ } else {
+ expect(component.libraries.length, equals(libraryCount),
+ reason: "Expects the same number of libraries "
+ "when compiling after a restart");
+ expect(component.uriToSource.length, equals(sourceCount),
+ reason: "Expects the same number of sources "
+ "when compiling after a restart");
+ }
+
+ // Include platform and verify.
+ component = loadComponentFromBinary(platformKernel.path, component);
+ expect(component.mainMethod, isNotNull);
+ verifyComponent(component);
+
+ count += 1;
+
+ // Restart with no changes
+ streamController.add('accept\n'.codeUnits);
+ streamController.add('reset\n'.codeUnits);
+ streamController.add('recompile ${dart2js.path} x$count\n'
+ 'x$count\n'
+ .codeUnits);
+ } else if (count == 1) {
+ // Restart. Expect full kernel file.
+ expect(dillFile.existsSync(), equals(true));
+ expect(outputFilename, dillFile.path);
+
+ // Dill file can be loaded and includes data.
+ Component component = loadComponentFromBinary(dillFile.path);
+ expect(component.libraries.length, equals(libraryCount),
+ reason: "Expect the same number of libraries after a reset.");
+ expect(component.uriToSource.length, equals(sourceCount),
+ reason: "Expect the same number of sources after a reset.");
+
+ // Include platform and verify.
+ component = loadComponentFromBinary(platformKernel.path, component);
+ expect(component.mainMethod, isNotNull);
+ verifyComponent(component);
+
+ count += 1;
+
+ // Reload with no changes
+ streamController.add('accept\n'.codeUnits);
+ streamController.add('recompile ${dart2js.path} x$count\n'
+ 'x$count\n'
+ .codeUnits);
+ } else if (count == 2) {
+ // Partial file. Expect to be empty.
+ expect(incrementalDillFile.existsSync(), equals(true));
+ expect(outputFilename, incrementalDillFile.path);
+
+ // Dill file can be loaded and includes no data.
+ Component component =
+ loadComponentFromBinary(incrementalDillFile.path);
+ expect(component.libraries.length, equals(0));
+
+ count += 1;
+
+ // Reload with 1 change
+ streamController.add('accept\n'.codeUnits);
+ streamController.add('recompile ${dart2js.path} x$count\n'
+ '${dart2jsOtherFile.path}\n'
+ 'x$count\n'
+ .codeUnits);
+ } else if (count == 3) {
+ // Partial file. Expect to not be empty.
+ expect(incrementalDillFile.existsSync(), equals(true));
+ expect(outputFilename, incrementalDillFile.path);
+
+ // Dill file can be loaded and includes some data.
+ Component component =
+ loadComponentFromBinary(incrementalDillFile.path);
+ expect(component.libraries, isNotEmpty);
+ expect(component.uriToSource.length >= component.libraries.length,
+ equals(true),
+ reason: "Expects >= source entries than libraries.");
+
+ count += 1;
+
+ allDone.complete(true);
+ }
+ });
+ expect(await allDone.future, true);
+ }
+ }, timeout: new Timeout.factor(8));
});
return 0;
}
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 3736600..3eaa3a3 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -103,16 +103,6 @@
}
});
- vm.stderr
- .transform(utf8.decoder)
- .transform(splitter)
- .toList()
- .then((err) {
- print(err.join('\n'));
- expect(err.isEmpty, isTrue,
- reason: "Should be no errors, but got ${err.join('\n')}");
- });
-
String portLine = await portLineCompleter.future;
final RegExp observatoryPortRegExp =
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart b/pkg/vm/testcases/bytecode/instance_creation.dart
index 5821f59..85ea5d71 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart
@@ -2,6 +2,8 @@
// 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.
+// ignore_for_file: native_function_body_in_non_sdk_code
+
class Base<T1, T2> {
T1 t1;
T2 t2;
@@ -67,6 +69,10 @@
new I.test_factory2(param: 42);
}
+class J {
+ factory J() native "agent_J";
+}
+
main() {
foo1();
foo2();
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index 32c2c32..be92aa5 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -1,6 +1,7 @@
library #lib;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
class Base<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic> extends core::Object {
generic-covariant-impl field self::Base::T1 t1 = null;
@@ -385,6 +386,22 @@
] static factory test_factory2({dynamic param = null}) → self::I
return new self::I::•(param);
}
+class J extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ NativeCall CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = NativeEntry agent_J
+}
+] @_in::ExternalName::•("agent_J")
+ external static factory •() → self::J;
+}
[@vm.bytecode=
Bytecode {
Entry 1
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index abc364d..9c486cc 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -17,6 +17,7 @@
#include <sys/utime.h> // NOLINT
#include "bin/builtin.h"
+#include "bin/directory.h"
#include "bin/log.h"
#include "bin/namespace.h"
#include "bin/utils.h"
@@ -472,6 +473,21 @@
Utf8ToWideScope system_old_path(old_path);
Utf8ToWideScope system_new_path(new_path);
DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
+ // Links on Windows appear as special directories. MoveFileExW's
+ // MOVEFILE_REPLACE_EXISTING does not allow for replacement of directories,
+ // so we need to remove it before renaming a link.
+ if (Directory::Exists(namespc, new_path) == Directory::EXISTS) {
+ bool result = true;
+ if (GetType(namespc, new_path, false) == kIsLink) {
+ result = DeleteLink(namespc, new_path);
+ } else {
+ result = Delete(namespc, new_path);
+ }
+ // Bail out if the Delete calls fail.
+ if (!result) {
+ return false;
+ }
+ }
int move_status =
MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
return (move_status != 0);
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 4bddd36a..bc95b54 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1505,7 +1505,7 @@
}
int main(int argc, char** argv) {
- const int EXTRA_VM_ARGUMENTS = 2;
+ const int EXTRA_VM_ARGUMENTS = 4;
CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
// Initialize the URL mapping array.
@@ -1516,6 +1516,16 @@
CommandLineOptions entry_points_files_array(argc);
entry_points_files = &entry_points_files_array;
+ // When running from the command line we assume that we are optimizing for
+ // throughput, and therefore use a larger new gen semi space size and a faster
+ // new gen growth factor unless others have been specified.
+ if (kWordSize <= 4) {
+ vm_options.AddArgument("--new_gen_semi_max_size=16");
+ } else {
+ vm_options.AddArgument("--new_gen_semi_max_size=32");
+ }
+ vm_options.AddArgument("--new_gen_growth_factor=4");
+
// Parse command line arguments.
if (ParseArguments(argc, argv, &vm_options, &app_script_name) < 0) {
PrintUsage();
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index b3c71de..1859422 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1159,7 +1159,7 @@
void main(int argc, char** argv) {
char* script_name;
- const int EXTRA_VM_ARGUMENTS = 8;
+ const int EXTRA_VM_ARGUMENTS = 10;
CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
CommandLineOptions dart_options(argc);
bool print_flags_seen = false;
@@ -1183,6 +1183,16 @@
Options::set_dfe(&dfe);
#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ // When running from the command line we assume that we are optimizing for
+ // throughput, and therefore use a larger new gen semi space size and a faster
+ // new gen growth factor unless others have been specified.
+ if (kWordSize <= 4) {
+ vm_options.AddArgument("--new_gen_semi_max_size=16");
+ } else {
+ vm_options.AddArgument("--new_gen_semi_max_size=32");
+ }
+ vm_options.AddArgument("--new_gen_growth_factor=4");
+
// Parse command line arguments.
if (Options::ParseArguments(argc, argv, vm_run_app_snapshot, &vm_options,
&script_name, &dart_options, &print_flags_seen,
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index b255370..9f54ee1 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -2,8 +2,6 @@
// 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.
-#include <stdio.h>
-
#include "bin/console.h"
#include "bin/dartutils.h"
#include "bin/dfe.h"
@@ -54,15 +52,15 @@
static int run_matches = 0;
void TestCase::Run() {
- OS::Print("Running test: %s\n", name());
+ bin::Log::Print("Running test: %s\n", name());
(*run_)();
- OS::Print("Done: %s\n", name());
+ bin::Log::Print("Done: %s\n", name());
}
void RawTestCase::Run() {
- OS::Print("Running test: %s\n", name());
+ bin::Log::Print("Running test: %s\n", name());
(*run_)();
- OS::Print("Done: %s\n", name());
+ bin::Log::Print("Done: %s\n", name());
}
void TestCaseBase::RunTest() {
@@ -70,7 +68,7 @@
this->Run();
run_matches++;
} else if (run_filter == kList) {
- OS::Print("%s\n", this->name());
+ bin::Log::Print("%s\n", this->name());
run_matches++;
}
}
@@ -79,17 +77,17 @@
if ((run_filter == kAllBenchmarks) ||
(strcmp(run_filter, this->name()) == 0)) {
this->Run();
- OS::Print("%s(%s): %" Pd64 "\n", this->name(), this->score_kind(),
- this->score());
+ bin::Log::Print("%s(%s): %" Pd64 "\n", this->name(), this->score_kind(),
+ this->score());
run_matches++;
} else if (run_filter == kList) {
- OS::Print("%s\n", this->name());
+ bin::Log::Print("%s\n", this->name());
run_matches++;
}
}
static void PrintUsage() {
- OS::PrintErr(
+ bin::Log::PrintErr(
"Usage: one of the following\n"
" run_vm_tests --list\n"
" run_vm_tests [--dfe=<snapshot file name>] --benchmarks\n"
@@ -212,7 +210,7 @@
// Perform platform specific initialization.
if (!dart::bin::Platform::Initialize()) {
- OS::PrintErr("Initialization failed\n");
+ bin::Log::PrintErr("Initialization failed\n");
return 1;
}
@@ -240,7 +238,7 @@
if (strstr(argv[arg_pos], "--dfe") == argv[arg_pos]) {
const char* delim = strstr(argv[1], "=");
if (delim == NULL || strlen(delim + 1) == 0) {
- OS::PrintErr("Invalid value for the option: %s\n", argv[1]);
+ bin::Log::PrintErr("Invalid value for the option: %s\n", argv[1]);
PrintUsage();
return 1;
}
@@ -294,7 +292,7 @@
TestCaseBase::RunAllRaw();
// Print a warning message if no tests or benchmarks were matched.
if (run_matches == 0) {
- OS::PrintErr("No tests matched: %s\n", run_filter);
+ bin::Log::PrintErr("No tests matched: %s\n", run_filter);
return 1;
}
if (Expect::failed()) {
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 4fc5baa..3aaeaa9 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -23,7 +23,7 @@
ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(1));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_doubleFromInteger %s\n", value.ToCString());
+ OS::PrintErr("Double_doubleFromInteger %s\n", value.ToCString());
}
return Double::New(value.AsDoubleValue());
}
@@ -33,7 +33,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_add %f + %f\n", left, right);
+ OS::PrintErr("Double_add %f + %f\n", left, right);
}
return Double::New(left + right);
}
@@ -43,7 +43,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_sub %f - %f\n", left, right);
+ OS::PrintErr("Double_sub %f - %f\n", left, right);
}
return Double::New(left - right);
}
@@ -53,7 +53,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_mul %f * %f\n", left, right);
+ OS::PrintErr("Double_mul %f * %f\n", left, right);
}
return Double::New(left * right);
}
@@ -63,7 +63,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_div %f / %f\n", left, right);
+ OS::PrintErr("Double_div %f / %f\n", left, right);
}
return Double::New(left / right);
}
@@ -88,7 +88,7 @@
DEFINE_NATIVE_ENTRY(Double_hashCode, 1) {
double val = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_hashCode %f\n", val);
+ OS::PrintErr("Double_hashCode %f\n", val);
}
if (val >= static_cast<double>(kMinInt64) &&
val <= static_cast<double>(kMaxInt64)) {
@@ -107,7 +107,7 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_trunc_div %f ~/ %f\n", left, right);
+ OS::PrintErr("Double_trunc_div %f ~/ %f\n", left, right);
}
return DoubleToInteger(trunc(left / right),
"Result of truncating division is Infinity or NaN");
@@ -132,8 +132,8 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
bool result = right.IsNull() ? false : (left.value() > right.value());
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_greaterThan %s > %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Double_greaterThan %s > %s\n", left.ToCString(),
+ right.ToCString());
}
return Bool::Get(result).raw();
}
@@ -149,7 +149,8 @@
GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
bool result = right.IsNull() ? false : (left.value() == right.value());
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Double_equal %s == %s\n", left.ToCString(), right.ToCString());
+ OS::PrintErr("Double_equal %s == %s\n", left.ToCString(),
+ right.ToCString());
}
return Bool::Get(result).raw();
}
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 4b93733..2b9f0d4 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -39,8 +39,8 @@
ASSERT(CheckInteger(right));
ASSERT(CheckInteger(left));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_bitAndFromInteger %s & %s\n", right.ToCString(),
- left.ToCString());
+ OS::PrintErr("Integer_bitAndFromInteger %s & %s\n", right.ToCString(),
+ left.ToCString());
}
const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_AND, right));
// A null result indicates that a bigint operation is required.
@@ -53,8 +53,8 @@
ASSERT(CheckInteger(right));
ASSERT(CheckInteger(left));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_bitOrFromInteger %s | %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Integer_bitOrFromInteger %s | %s\n", left.ToCString(),
+ right.ToCString());
}
const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_OR, right));
// A null result indicates that a bigint operation is required.
@@ -67,8 +67,8 @@
ASSERT(CheckInteger(right));
ASSERT(CheckInteger(left));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_bitXorFromInteger %s ^ %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Integer_bitXorFromInteger %s ^ %s\n", left.ToCString(),
+ right.ToCString());
}
const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
// A null result indicates that a bigint operation is required.
@@ -81,8 +81,8 @@
ASSERT(CheckInteger(right_int));
ASSERT(CheckInteger(left_int));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_addFromInteger %s + %s\n", left_int.ToCString(),
- right_int.ToCString());
+ OS::PrintErr("Integer_addFromInteger %s + %s\n", left_int.ToCString(),
+ right_int.ToCString());
}
const Integer& result =
Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int));
@@ -96,8 +96,8 @@
ASSERT(CheckInteger(right_int));
ASSERT(CheckInteger(left_int));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_subFromInteger %s - %s\n", left_int.ToCString(),
- right_int.ToCString());
+ OS::PrintErr("Integer_subFromInteger %s - %s\n", left_int.ToCString(),
+ right_int.ToCString());
}
const Integer& result =
Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int));
@@ -111,8 +111,8 @@
ASSERT(CheckInteger(right_int));
ASSERT(CheckInteger(left_int));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_mulFromInteger %s * %s\n", left_int.ToCString(),
- right_int.ToCString());
+ OS::PrintErr("Integer_mulFromInteger %s * %s\n", left_int.ToCString(),
+ right_int.ToCString());
}
const Integer& result =
Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int));
@@ -138,8 +138,8 @@
ASSERT(CheckInteger(right_int));
ASSERT(CheckInteger(left_int));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_moduloFromInteger %s mod %s\n", left_int.ToCString(),
- right_int.ToCString());
+ OS::PrintErr("Integer_moduloFromInteger %s mod %s\n", left_int.ToCString(),
+ right_int.ToCString());
}
if (right_int.IsZero()) {
// Should have been caught before calling into runtime.
@@ -157,8 +157,8 @@
ASSERT(CheckInteger(right));
ASSERT(CheckInteger(left));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_greaterThanFromInteger %s > %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Integer_greaterThanFromInteger %s > %s\n", left.ToCString(),
+ right.ToCString());
}
return Bool::Get(left.CompareWith(right) == 1).raw();
}
@@ -169,8 +169,8 @@
ASSERT(CheckInteger(left));
ASSERT(CheckInteger(right));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Integer_equalToInteger %s == %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Integer_equalToInteger %s == %s\n", left.ToCString(),
+ right.ToCString());
}
return Bool::Get(left.CompareWith(right) == 0).raw();
}
@@ -260,8 +260,8 @@
const Smi& left = Smi::CheckedHandle(arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, right, arguments->NativeArgAt(1));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Smi_bitAndFromSmi %s & %s\n", left.ToCString(),
- right.ToCString());
+ OS::PrintErr("Smi_bitAndFromSmi %s & %s\n", left.ToCString(),
+ right.ToCString());
}
const Smi& left_value = Smi::Cast(left);
const Smi& right_value = Smi::Cast(right);
@@ -285,8 +285,8 @@
ASSERT(CheckInteger(amount));
ASSERT(CheckInteger(value));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Smi_shlFromInt: %s << %s\n", value.ToCString(),
- amount.ToCString());
+ OS::PrintErr("Smi_shlFromInt: %s << %s\n", value.ToCString(),
+ amount.ToCString());
}
const Integer& result =
Integer::Handle(ShiftOperationHelper(Token::kSHL, value, amount));
@@ -297,7 +297,7 @@
DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) {
const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Smi_bitNegate: %s\n", operand.ToCString());
+ OS::PrintErr("Smi_bitNegate: %s\n", operand.ToCString());
}
intptr_t result = ~operand.Value();
ASSERT(Smi::IsValid(result));
@@ -307,7 +307,7 @@
DEFINE_NATIVE_ENTRY(Smi_bitLength, 1) {
const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Smi_bitLength: %s\n", operand.ToCString());
+ OS::PrintErr("Smi_bitLength: %s\n", operand.ToCString());
}
int64_t value = operand.AsInt64Value();
intptr_t result = Utils::BitLength(value);
@@ -321,7 +321,7 @@
const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0));
ASSERT(CheckInteger(operand));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Mint_bitNegate: %s\n", operand.ToCString());
+ OS::PrintErr("Mint_bitNegate: %s\n", operand.ToCString());
}
int64_t result = ~operand.value();
return Integer::New(result);
@@ -331,7 +331,7 @@
const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0));
ASSERT(CheckInteger(operand));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Mint_bitLength: %s\n", operand.ToCString());
+ OS::PrintErr("Mint_bitLength: %s\n", operand.ToCString());
}
int64_t value = operand.AsInt64Value();
intptr_t result = Utils::BitLength(value);
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index dd04cd4..c3a6a6c 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -144,15 +144,15 @@
type, instantiator_type_arguments, function_type_arguments, &bound_error);
if (FLAG_trace_type_checks) {
const char* result_str = is_instance_of ? "true" : "false";
- OS::Print("Native Object.instanceOf: result %s\n", result_str);
+ OS::PrintErr("Native Object.instanceOf: result %s\n", result_str);
const AbstractType& instance_type =
AbstractType::Handle(zone, instance.GetType(Heap::kNew));
- OS::Print(" instance type: %s\n",
- String::Handle(zone, instance_type.Name()).ToCString());
- OS::Print(" test type: %s\n",
- String::Handle(zone, type.Name()).ToCString());
+ OS::PrintErr(" instance type: %s\n",
+ String::Handle(zone, instance_type.Name()).ToCString());
+ OS::PrintErr(" test type: %s\n",
+ String::Handle(zone, type.Name()).ToCString());
if (!bound_error.IsNull()) {
- OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
+ OS::PrintErr(" bound error: %s\n", bound_error.ToErrorCString());
}
}
if (!is_instance_of && !bound_error.IsNull()) {
@@ -223,15 +223,15 @@
function_type_arguments, &bound_error);
if (FLAG_trace_type_checks) {
const char* result_str = is_instance_of ? "true" : "false";
- OS::Print("Object.as: result %s\n", result_str);
+ OS::PrintErr("Object.as: result %s\n", result_str);
const AbstractType& instance_type =
AbstractType::Handle(zone, instance.GetType(Heap::kNew));
- OS::Print(" instance type: %s\n",
- String::Handle(zone, instance_type.Name()).ToCString());
- OS::Print(" cast type: %s\n",
- String::Handle(zone, type.Name()).ToCString());
+ OS::PrintErr(" instance type: %s\n",
+ String::Handle(zone, instance_type.Name()).ToCString());
+ OS::PrintErr(" cast type: %s\n",
+ String::Handle(zone, type.Name()).ToCString());
if (!bound_error.IsNull()) {
- OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
+ OS::PrintErr(" bound error: %s\n", bound_error.ToErrorCString());
}
}
if (!is_instance_of) {
diff --git a/runtime/lib/profiler.cc b/runtime/lib/profiler.cc
index 1ff14ba..d892a5c 100644
--- a/runtime/lib/profiler.cc
+++ b/runtime/lib/profiler.cc
@@ -31,7 +31,7 @@
DEFINE_NATIVE_ENTRY(UserTag_makeCurrent, 1) {
const UserTag& self = UserTag::CheckedHandle(arguments->NativeArgAt(0));
if (FLAG_trace_intrinsified_natives) {
- OS::Print("UserTag_makeCurrent: %s\n", self.ToCString());
+ OS::PrintErr("UserTag_makeCurrent: %s\n", self.ToCString());
}
const UserTag& old = UserTag::Handle(isolate->current_tag());
self.MakeActive();
@@ -40,14 +40,14 @@
DEFINE_NATIVE_ENTRY(UserTag_defaultTag, 0) {
if (FLAG_trace_intrinsified_natives) {
- OS::Print("UserTag_defaultTag\n");
+ OS::PrintErr("UserTag_defaultTag\n");
}
return isolate->default_tag();
}
DEFINE_NATIVE_ENTRY(Profiler_getCurrentTag, 0) {
if (FLAG_trace_intrinsified_natives) {
- OS::Print("Profiler_getCurrentTag\n");
+ OS::PrintErr("Profiler_getCurrentTag\n");
}
return isolate->current_tag();
}
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index dd24564..a3f1640 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -302,26 +302,20 @@
}
compile_platform("vm_legacy_platform") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ libraries_specification_uri = "../../sdk/lib/libraries.json"
outputs = [
"$root_out_dir/vm_platform.dill",
"$root_out_dir/vm_outline.dill",
]
- inputs = [
- "../../sdk/lib/libraries.yaml",
- ]
-
args = [ "dart:core" ]
}
compile_platform("vm_platform") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ add_implicit_vm_platform_dependency = false
+
+ libraries_specification_uri = "../../sdk/lib/libraries.json"
outputs = [
"$root_out_dir/vm_platform_strong.dill",
diff --git a/runtime/vm/bit_vector.cc b/runtime/vm/bit_vector.cc
index bb1df4d..c48324b 100644
--- a/runtime/vm/bit_vector.cc
+++ b/runtime/vm/bit_vector.cc
@@ -105,11 +105,11 @@
}
void BitVector::Print() const {
- OS::Print("[");
+ OS::PrintErr("[");
for (intptr_t i = 0; i < length_; i++) {
- OS::Print(Contains(i) ? "1" : "0");
+ OS::PrintErr(Contains(i) ? "1" : "0");
}
- OS::Print("]");
+ OS::PrintErr("]");
}
} // namespace dart
diff --git a/runtime/vm/bitmap.cc b/runtime/vm/bitmap.cc
index fd1d343..79bab3c 100644
--- a/runtime/vm/bitmap.cc
+++ b/runtime/vm/bitmap.cc
@@ -70,9 +70,9 @@
void BitmapBuilder::Print() const {
for (intptr_t i = 0; i < Length(); i++) {
if (Get(i)) {
- OS::Print("1");
+ OS::PrintErr("1");
} else {
- OS::Print("0");
+ OS::PrintErr("0");
}
}
}
diff --git a/runtime/vm/bitmap_test.cc b/runtime/vm/bitmap_test.cc
index 98a5e17..2d28f8b 100644
--- a/runtime/vm/bitmap_test.cc
+++ b/runtime/vm/bitmap_test.cc
@@ -39,7 +39,7 @@
// Create a StackMap object from the builder and verify its contents.
const StackMap& stackmap1 = StackMap::Handle(StackMap::New(0, builder1, 0));
EXPECT_EQ(1024, stackmap1.Length());
- OS::Print("%s\n", stackmap1.ToCString());
+ OS::PrintErr("%s\n", stackmap1.ToCString());
value = true;
for (int32_t i = 0; i < 1024; i++) {
EXPECT_EQ(value, stackmap1.IsObject(i));
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index fe782ce..88e2407 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -28,7 +28,7 @@
intptr_t kernel_buffer_size);
static void SetupNativeResolver();
- static bool IsBootstapResolver(Dart_NativeEntryResolver resolver);
+ static bool IsBootstrapResolver(Dart_NativeEntryResolver resolver);
// Source path mapping for library URI and 'parts'.
static const char* async_source_paths_[];
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index 0b6b193..fb3d08b 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -136,7 +136,7 @@
library.set_native_entry_symbol_resolver(symbol_resolver);
}
-bool Bootstrap::IsBootstapResolver(Dart_NativeEntryResolver resolver) {
+bool Bootstrap::IsBootstrapResolver(Dart_NativeEntryResolver resolver) {
return (resolver ==
reinterpret_cast<Dart_NativeEntryResolver>(BootstrapNatives::Lookup));
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index bceab3b..5ae8029 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -190,7 +190,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
void ClassFinalizer::VerifyBootstrapClasses() {
if (FLAG_trace_class_finalization) {
- OS::Print("VerifyBootstrapClasses START.\n");
+ OS::PrintErr("VerifyBootstrapClasses START.\n");
}
ObjectStore* object_store = Isolate::Current()->object_store();
@@ -249,7 +249,7 @@
OS::Exit(255);
}
if (FLAG_trace_class_finalization) {
- OS::Print("VerifyBootstrapClasses END.\n");
+ OS::PrintErr("VerifyBootstrapClasses END.\n");
}
Isolate::Current()->heap()->Verify();
}
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 447ea45..c07f14a 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -252,7 +252,7 @@
cls = At(i);
if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
name = cls.Name();
- OS::Print("%" Pd ": %s\n", i, name.ToCString());
+ OS::PrintErr("%" Pd ": %s\n", i, name.ToCString());
}
}
}
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 869d283..378b2e6 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4987,7 +4987,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
if (FLAG_print_snapshot_sizes_verbose) {
- OS::Print(" Cluster Objs Size Fraction Cumulative\n");
+ OS::PrintErr(" Cluster Objs Size Fraction Cumulative\n");
GrowableArray<SerializationCluster*> clusters_by_size;
for (intptr_t cid = 1; cid < num_cids_; cid++) {
SerializationCluster* cluster = clusters_by_cid_[cid];
@@ -5007,9 +5007,9 @@
SerializationCluster* cluster = clusters_by_size[i];
double fraction = static_cast<double>(cluster->size()) / total_size;
cumulative_fraction += fraction;
- OS::Print("%20s %6" Pd " %8" Pd " %lf %lf\n", cluster->name(),
- cluster->num_objects(), cluster->size(), fraction,
- cumulative_fraction);
+ OS::PrintErr("%20s %6" Pd " %8" Pd " %lf %lf\n", cluster->name(),
+ cluster->num_objects(), cluster->size(), fraction,
+ cumulative_fraction);
}
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index b67e93d..65f1890 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -305,8 +305,8 @@
intptr_t i = 0;
while (it.MoveNext()) {
if (token_positions[i] != it.TokenPos().value()) {
- OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n", i,
- token_positions[i], it.TokenPos().value());
+ OS::PrintErr("[%" Pd "]: Expected: %" Pd " != %" Pd "\n", i,
+ token_positions[i], it.TokenPos().value());
}
EXPECT(token_positions[i] == it.TokenPos().value());
i++;
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index ff286b6..fb0068d 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -344,6 +344,7 @@
I->object_store()->set_completer_class(null_class);
I->object_store()->set_symbol_class(null_class);
I->object_store()->set_compiletime_error_class(null_class);
+ I->object_store()->set_growable_list_factory(null_function);
I->object_store()->set_simple_instance_of_function(null_function);
I->object_store()->set_simple_instance_of_true_function(null_function);
I->object_store()->set_simple_instance_of_false_function(null_function);
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 5f55e9f..1f079f6 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -274,8 +274,8 @@
merged->Add(successor->postorder_number());
changed = true;
if (FLAG_trace_optimization) {
- OS::Print("Merged blocks B%" Pd " and B%" Pd "\n", block->block_id(),
- successor->block_id());
+ OS::PrintErr("Merged blocks B%" Pd " and B%" Pd "\n", block->block_id(),
+ successor->block_id());
}
}
// The new block inherits the block id of the last successor to maintain
@@ -580,25 +580,25 @@
}
static void PrintBitVector(const char* tag, BitVector* v) {
- OS::Print("%s:", tag);
+ OS::PrintErr("%s:", tag);
for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
- OS::Print(" %" Pd "", it.Current());
+ OS::PrintErr(" %" Pd "", it.Current());
}
- OS::Print("\n");
+ OS::PrintErr("\n");
}
void LivenessAnalysis::Dump() {
const intptr_t block_count = postorder_.length();
for (intptr_t i = 0; i < block_count; i++) {
BlockEntryInstr* block = postorder_[i];
- OS::Print("block @%" Pd " -> ", block->block_id());
+ OS::PrintErr("block @%" Pd " -> ", block->block_id());
Instruction* last = block->last_instruction();
for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
BlockEntryInstr* succ = last->SuccessorAt(j);
- OS::Print(" @%" Pd "", succ->block_id());
+ OS::PrintErr(" @%" Pd "", succ->block_id());
}
- OS::Print("\n");
+ OS::PrintErr("\n");
PrintBitVector(" live out", live_out_[i]);
PrintBitVector(" kill", kill_[i]);
@@ -1450,8 +1450,8 @@
BlockEntryInstr* pred = block->PredecessorAt(i);
if (block->Dominates(pred)) {
if (FLAG_trace_optimization) {
- OS::Print("Back edge B%" Pd " -> B%" Pd "\n", pred->block_id(),
- block->block_id());
+ OS::PrintErr("Back edge B%" Pd " -> B%" Pd "\n", pred->block_id(),
+ block->block_id());
}
BitVector* loop_info = FindLoop(pred, block);
// Loops that share the same loop header are treated as one loop.
@@ -1474,10 +1474,10 @@
if (FLAG_trace_optimization) {
for (intptr_t i = 0; i < loop_headers->length(); ++i) {
BlockEntryInstr* header = (*loop_headers)[i];
- OS::Print("Loop header B%" Pd "\n", header->block_id());
+ OS::PrintErr("Loop header B%" Pd "\n", header->block_id());
for (BitVector::Iterator it(header->loop_info()); !it.Done();
it.Advance()) {
- OS::Print(" B%" Pd "\n", preorder_[it.Current()]->block_id());
+ OS::PrintErr(" B%" Pd "\n", preorder_[it.Current()]->block_id());
}
}
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 1b2910b..9890b36 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2829,7 +2829,7 @@
comp->RemoveFromGraph();
SetComparison(comp);
if (FLAG_trace_optimization) {
- OS::Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
+ OS::PrintErr("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
}
// Clear the comparison's temp index and ssa temp index since the
// value of the comparison is not used outside the branch anymore.
@@ -2850,7 +2850,7 @@
}
if (bit_and != NULL) {
if (FLAG_trace_optimization) {
- OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index());
+ OS::PrintErr("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index());
}
TestSmiInstr* test = new TestSmiInstr(
comparison()->token_pos(),
@@ -4630,7 +4630,7 @@
const Library& library = Library::Handle(zone, cls.library());
Dart_NativeEntryResolver resolver = library.native_entry_resolver();
- bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
+ bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
set_is_bootstrap_native(is_bootstrap_native);
const int num_params =
diff --git a/runtime/vm/compiler/backend/range_analysis_test.cc b/runtime/vm/compiler/backend/range_analysis_test.cc
index 52c8694..c67708f 100644
--- a/runtime/vm/compiler/backend/range_analysis_test.cc
+++ b/runtime/vm/compiler/backend/range_analysis_test.cc
@@ -38,11 +38,11 @@
max = Clamp(max); \
EXPECT(min.Equals(res_min)); \
if (FLAG_support_il_printer && !min.Equals(res_min)) { \
- OS::Print("%s\n", min.ToCString()); \
+ OS::PrintErr("%s\n", min.ToCString()); \
} \
EXPECT(max.Equals(res_max)); \
if (FLAG_support_il_printer && !max.Equals(res_max)) { \
- OS::Print("%s\n", max.ToCString()); \
+ OS::PrintErr("%s\n", max.ToCString()); \
} \
}
@@ -317,11 +317,11 @@
Range::Add(left_range, right_range, &min, &max, NULL); \
EXPECT(min.Equals(result_min)); \
if (FLAG_support_il_printer && !min.Equals(result_min)) { \
- OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \
+ OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
} \
EXPECT(max.Equals(result_max)); \
if (FLAG_support_il_printer && !max.Equals(result_max)) { \
- OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \
+ OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
} \
}
@@ -397,11 +397,11 @@
Range::Sub(left_range, right_range, &min, &max, NULL); \
EXPECT(min.Equals(result_min)); \
if (FLAG_support_il_printer && !min.Equals(result_min)) { \
- OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \
+ OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
} \
EXPECT(max.Equals(result_max)); \
if (FLAG_support_il_printer && !max.Equals(result_max)) { \
- OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \
+ OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
} \
}
@@ -450,11 +450,11 @@
Range::And(left_range, right_range, &min, &max); \
EXPECT(min.Equals(result_min)); \
if (FLAG_support_il_printer && !min.Equals(result_min)) { \
- OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \
+ OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
} \
EXPECT(max.Equals(result_max)); \
if (FLAG_support_il_printer && !max.Equals(result_max)) { \
- OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \
+ OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
} \
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index b100719..68ac2f7 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3,11 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/compiler/frontend/kernel_binary_flowgraph.h"
+
+#include "vm/bootstrap.h"
#include "vm/code_descriptors.h"
#include "vm/compiler/aot/precompiler.h"
#include "vm/compiler/assembler/disassembler_kbc.h"
#include "vm/compiler/frontend/prologue_builder.h"
#include "vm/compiler/jit/compiler.h"
+#include "vm/dart_entry.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
@@ -994,6 +997,7 @@
kContextOffset,
kClosureFunction,
kEndClosureFunctionScope,
+ kNativeEntry,
};
enum InvocationKind {
@@ -1332,6 +1336,10 @@
pool.SetObjectAt(i, obj);
return i; // The caller will close the scope.
} break;
+ case ConstantPoolTag::kNativeEntry: {
+ name = H.DartString(builder_->ReadStringReference()).raw();
+ obj = NativeEntry(function, name);
+ } break;
default:
UNREACHABLE();
}
@@ -1412,6 +1420,87 @@
bytecode.set_exception_handlers(Object::empty_exception_handlers());
}
}
+
+RawTypedData* BytecodeMetadataHelper::NativeEntry(const Function& function,
+ const String& external_name) {
+ Zone* zone = builder_->zone_;
+ MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
+ // This list of recognized methods must be kept in sync with the list of
+ // methods handled specially by the NativeCall bytecode in the interpreter.
+ switch (kind) {
+ case MethodRecognizer::kObjectEquals:
+ case MethodRecognizer::kStringBaseLength:
+ case MethodRecognizer::kStringBaseIsEmpty:
+ case MethodRecognizer::kGrowableArrayLength:
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ case MethodRecognizer::kTypedDataLength:
+ case MethodRecognizer::kClassIDgetID:
+ case MethodRecognizer::kGrowableArrayCapacity:
+ case MethodRecognizer::kListFactory:
+ case MethodRecognizer::kObjectArrayAllocate:
+ case MethodRecognizer::kLinkedHashMap_getIndex:
+ case MethodRecognizer::kLinkedHashMap_setIndex:
+ case MethodRecognizer::kLinkedHashMap_getData:
+ case MethodRecognizer::kLinkedHashMap_setData:
+ case MethodRecognizer::kLinkedHashMap_getHashMask:
+ case MethodRecognizer::kLinkedHashMap_setHashMask:
+ case MethodRecognizer::kLinkedHashMap_getUsedData:
+ case MethodRecognizer::kLinkedHashMap_setUsedData:
+ case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
+ case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+ break;
+ default:
+ kind = MethodRecognizer::kUnknown;
+ }
+ NativeFunctionWrapper trampoline = NULL;
+ NativeFunction native_function = NULL;
+ intptr_t argc_tag = 0;
+ if (kind == MethodRecognizer::kUnknown) {
+ if (FLAG_link_natives_lazily) {
+ trampoline = &NativeEntry::BootstrapNativeCallWrapper;
+ native_function =
+ reinterpret_cast<NativeFunction>(&NativeEntry::LinkNativeCall);
+ } else {
+ const Class& cls = Class::Handle(zone, function.Owner());
+ const Library& library = Library::Handle(zone, cls.library());
+ Dart_NativeEntryResolver resolver = library.native_entry_resolver();
+ const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
+ const int num_params =
+ NativeArguments::ParameterCountForResolution(function);
+ bool is_auto_scope = true;
+ native_function = NativeEntry::ResolveNative(library, external_name,
+ num_params, &is_auto_scope);
+ ASSERT(native_function != NULL); // TODO(regis): Should we throw instead?
+ if (is_bootstrap_native) {
+ trampoline = &NativeEntry::BootstrapNativeCallWrapper;
+ } else if (is_auto_scope) {
+ trampoline = &NativeEntry::AutoScopeNativeCallWrapper;
+ } else {
+ trampoline = &NativeEntry::NoScopeNativeCallWrapper;
+ }
+ }
+ argc_tag = NativeArguments::ComputeArgcTag(function);
+ }
+ // TODO(regis): Introduce a new VM class subclassing Object and containing
+ // these four untagged values.
+#ifdef ARCH_IS_32_BIT
+ const TypedData& native_entry = TypedData::Handle(
+ zone, TypedData::New(kTypedDataUint32ArrayCid, 4, Heap::kOld));
+ native_entry.SetUint32(0 << 2, static_cast<uint32_t>(kind));
+ native_entry.SetUint32(1 << 2, reinterpret_cast<uint32_t>(trampoline));
+ native_entry.SetUint32(2 << 2, reinterpret_cast<uint32_t>(native_function));
+ native_entry.SetUint32(3 << 2, static_cast<uint32_t>(argc_tag));
+#else
+ const TypedData& native_entry = TypedData::Handle(
+ zone, TypedData::New(kTypedDataUint64ArrayCid, 4, Heap::kOld));
+ native_entry.SetUint64(0 << 3, static_cast<uint64_t>(kind));
+ native_entry.SetUint64(1 << 3, reinterpret_cast<uint64_t>(trampoline));
+ native_entry.SetUint64(2 << 3, reinterpret_cast<uint64_t>(native_function));
+ native_entry.SetUint64(3 << 3, static_cast<uint64_t>(argc_tag));
+#endif
+ return native_entry.raw();
+}
#endif // defined(DART_USE_INTERPRETER)
StreamingScopeBuilder::StreamingScopeBuilder(ParsedFunction* parsed_function)
@@ -4259,6 +4348,13 @@
const TypeArguments& type_arguments,
const Function& constructor,
const Object& argument) {
+ // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation, so
+ // we should never end up evaluating constants using the VM's constant
+ // evaluator.
+ if (I->strong() && FLAG_precompiled_mode) {
+ UNREACHABLE();
+ }
+
// Factories have one extra argument: the type arguments.
// Constructors have 1 extra arguments: receiver.
const int kTypeArgsLen = 0;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 662514f..7c2b7b5 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -686,6 +686,8 @@
intptr_t from_index);
RawCode* ReadBytecode(const ObjectPool& pool);
void ReadExceptionsTable(const Code& bytecode);
+ RawTypedData* NativeEntry(const Function& function,
+ const String& external_name);
#endif
};
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index 0359572..fa0ae29 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -205,10 +205,12 @@
if (FLAG_trace_optimization || FLAG_trace_field_guards) {
THR_Print("Disabling unboxing of %s\n", field.ToCString());
if (!setter.IsNull()) {
- OS::Print(" setter usage count: %" Pd "\n", setter.usage_counter());
+ OS::PrintErr(" setter usage count: %" Pd "\n",
+ setter.usage_counter());
}
if (!getter.IsNull()) {
- OS::Print(" getter usage count: %" Pd "\n", getter.usage_counter());
+ OS::PrintErr(" getter usage count: %" Pd "\n",
+ getter.usage_counter());
}
}
ASSERT(field.IsOriginal());
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 952a9d7..bb61216 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -44,6 +44,7 @@
V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, Dynamic, 0x38a80b0d) \
V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, Dynamic, 0x40052c4e) \
V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, Dynamic, 0x07b89f54) \
+ V(::, _toClampedUint8, ConvertIntToClampedUint8, Smi, 0x564b0435) \
V(_StringBase, _interpolate, StringBaseInterpolate, Dynamic, 0x01ecb15a) \
V(_IntegerImplementation, toDouble, IntegerToDouble, Double, 0x05da96ed) \
V(_Double, _add, DoubleAdd, Double, 0x2a38277b) \
@@ -437,7 +438,6 @@
V(::, _toInt, ConvertMaskedInt, 0x713908fd) \
V(::, _toInt8, ConvertIntToInt8, 0x7484a780) \
V(::, _toUint8, ConvertIntToUint8, 0x0a15b522) \
- V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x564b0435) \
V(::, _toInt16, ConvertIntToInt16, 0x0a83fcc6) \
V(::, _toUint16, ConvertIntToUint16, 0x6087d1af) \
V(::, _toInt32, ConvertIntToInt32, 0x62b451b9) \
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 52ceebf..312ca7f 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -165,10 +165,10 @@
// with arguments SP[-(1+ArgC)], ..., SP[-1].
// The ICData indicates whether the first argument is a type argument vector.
//
-// - NativeCall ArgA, ArgB, ArgC
+// - NativeCall D
//
-// Invoke native function at pool[ArgB] with argc_tag at pool[ArgC] using
-// wrapper at pool[ArgA].
+// Invoke native function described by array at pool[D].
+// array[0] is wrapper, array[1] is function, array[2] is argc_tag.
//
// - PushPolymorphicInstanceCall ArgC, D
//
@@ -791,7 +791,7 @@
V(InstanceCall2Opt, A_D, num, num, ___) \
V(PushPolymorphicInstanceCall, A_D, num, num, ___) \
V(PushPolymorphicInstanceCallByRange, A_D, num, num, ___) \
- V(NativeCall, A_B_C, num, num, num) \
+ V(NativeCall, D, lit, ___, ___) \
V(OneByteStringFromCharCode, A_X, reg, xeg, ___) \
V(StringToCharCode, A_X, reg, xeg, ___) \
V(AddTOS, 0, ___, ___, ___) \
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index 77b2181f..5351e10 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -164,7 +164,7 @@
};
void StartEvent::Process() {
- OS::Print(">> StartEvent with isolate(%p)--\n", isolate());
+ OS::PrintErr(">> StartEvent with isolate(%p)--\n", isolate());
Dart_EnterIsolate(isolate());
Dart_EnterScope();
Dart_Handle result;
@@ -193,7 +193,7 @@
};
void MessageEvent::Process() {
- OS::Print("$$ MessageEvent with isolate(%p)\n", isolate());
+ OS::PrintErr("$$ MessageEvent with isolate(%p)\n", isolate());
Dart_EnterIsolate(isolate());
Dart_EnterScope();
@@ -201,7 +201,7 @@
EXPECT_VALID(result);
if (!Dart_HasLivePorts()) {
- OS::Print("<< Shutting down isolate(%p)\n", isolate());
+ OS::PrintErr("<< Shutting down isolate(%p)\n", isolate());
event_queue->RemoveEventsForIsolate(isolate());
Dart_SetMessageNotifyCallback(NULL);
Dart_ExitScope();
@@ -214,8 +214,8 @@
}
static void NotifyMessage(Dart_Isolate dest_isolate) {
- OS::Print("-- Notify isolate(%p) of pending message --\n", dest_isolate);
- OS::Print("-- Adding MessageEvent to queue --\n");
+ OS::PrintErr("-- Notify isolate(%p) of pending message --\n", dest_isolate);
+ OS::PrintErr("-- Adding MessageEvent to queue --\n");
event_queue->Add(new MessageEvent(dest_isolate));
}
@@ -247,12 +247,12 @@
free(saved_echo);
}
saved_echo = strdup(c_str);
- OS::Print("-- (isolate=%p) %s\n", Dart_CurrentIsolate(), c_str);
+ OS::PrintErr("-- (isolate=%p) %s\n", Dart_CurrentIsolate(), c_str);
Dart_ExitScope();
}
static void CustomIsolateImpl_start(Dart_NativeArguments args) {
- OS::Print("-- Enter: CustomIsolateImpl_start --\n");
+ OS::PrintErr("-- Enter: CustomIsolateImpl_start --\n");
// We would probably want to pass in the this pointer too, so we
// could associate the CustomIsolateImpl instance with the
@@ -287,7 +287,7 @@
Dart_Handle err = Dart_SendPortGetId(main_send_port, &main_port_id);
EXPECT_VALID(err);
- OS::Print("-- Adding StartEvent to queue --\n");
+ OS::PrintErr("-- Adding StartEvent to queue --\n");
event_queue->Add(new StartEvent(new_isolate, isolate_main));
// Restore the original isolate.
@@ -300,7 +300,7 @@
EXPECT_VALID(send_port);
Dart_SetReturnValue(args, send_port);
- OS::Print("-- Exit: CustomIsolateImpl_start --\n");
+ OS::PrintErr("-- Exit: CustomIsolateImpl_start --\n");
Dart_ExitScope();
}
@@ -335,14 +335,14 @@
Dart_ExitScope();
Dart_ExitIsolate();
- OS::Print("-- Starting event loop --\n");
+ OS::PrintErr("-- Starting event loop --\n");
Event* event = event_queue->Get();
while (event) {
event->Process();
delete event;
event = event_queue->Get();
}
- OS::Print("-- Finished event loop --\n");
+ OS::PrintErr("-- Finished event loop --\n");
EXPECT_STREQ("Received: 43", saved_echo);
free(saved_echo);
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 6318284..06adc84 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -246,15 +246,15 @@
}
#endif // !defined(PRODUCT)
if (FLAG_trace_isolates) {
- OS::Print("Size of vm isolate snapshot = %" Pd "\n",
- snapshot->length());
+ OS::PrintErr("Size of vm isolate snapshot = %" Pd "\n",
+ snapshot->length());
vm_isolate_->heap()->PrintSizes();
MegamorphicCacheTable::PrintSizes(vm_isolate_);
intptr_t size;
intptr_t capacity;
Symbols::GetStats(vm_isolate_, &size, &capacity);
- OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size);
- OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
+ OS::PrintErr("VM Isolate: Number of symbols : %" Pd "\n", size);
+ OS::PrintErr("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
}
} else {
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -553,7 +553,7 @@
return ApiError::New(message);
}
if (FLAG_trace_isolates) {
- OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length());
+ OS::PrintErr("Size of isolate snapshot = %" Pd "\n", snapshot->length());
}
FullSnapshotReader reader(snapshot, snapshot_instructions, shared_data,
shared_instructions, T);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index ee787e4..f0ada37 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6338,7 +6338,7 @@
const Error& err = Error::Handle(lib.Patch(patch_script));
if (!err.IsNull()) {
- OS::Print("Patching error: %s\n", err.ToErrorCString());
+ OS::PrintErr("Patching error: %s\n", err.ToErrorCString());
EXPECT(false);
}
}
@@ -8819,7 +8819,7 @@
EXPECT_VALID(result);
result = Dart_Invoke(lib, NewString("foozoo"), 0, NULL);
EXPECT(Dart_IsError(result));
- OS::Print("Patched class executed\n");
+ OS::PrintErr("Patched class executed\n");
}
TEST_CASE(DartAPI_LoadLibraryPatch_Error3) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index c157f1a..82afa1e 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -25,16 +25,6 @@
RawObject* DartEntry::InvokeFunction(const Function& function,
const Array& arguments) {
ASSERT(Thread::Current()->IsMutatorThread());
-
- // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation
- // and never start the VM service isolate. So we should never end up invoking
- // any dart code in the Dart 2.0 AOT compiler.
-#if !defined(DART_PRECOMPILED_RUNTIME)
- if (Isolate::Current()->strong() && FLAG_precompiled_mode) {
- UNREACHABLE();
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
-
const int kTypeArgsLen = 0; // No support to pass type args to generic func.
const Array& arguments_descriptor =
Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length()));
@@ -120,6 +110,15 @@
const Array& arguments,
const Array& arguments_descriptor,
uword current_sp) {
+ // We use a kernel2kernel constant evaluator in Dart 2.0 AOT compilation
+ // and never start the VM service isolate. So we should never end up invoking
+ // any dart code in the Dart 2.0 AOT compiler.
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (Isolate::Current()->strong() && FLAG_precompiled_mode) {
+ UNREACHABLE();
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
// Get the entrypoint corresponding to the function specified, this
// will result in a compilation of the function if it is not already
// compiled.
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index e922ec77..bb87152 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2906,7 +2906,7 @@
intptr_t line_number;
intptr_t column_number;
script.GetTokenLocation(breakpoint_pos, &line_number, &column_number);
- OS::Print(
+ OS::PrintErr(
"Resolved BP for "
"function '%s' at line %" Pd " col %" Pd "\n",
func.ToFullyQualifiedCString(), line_number, column_number);
@@ -2923,12 +2923,12 @@
intptr_t column_number;
script.GetTokenLocation(token_pos, &line_number, &column_number);
if (func.IsNull()) {
- OS::Print(
+ OS::PrintErr(
"Registering pending breakpoint for "
"an uncompiled function literal at line %" Pd " col %" Pd "\n",
line_number, column_number);
} else {
- OS::Print(
+ OS::PrintErr(
"Registering pending breakpoint for "
"uncompiled function '%s' at line %" Pd " col %" Pd "\n",
func.ToFullyQualifiedCString(), line_number, column_number);
@@ -3072,7 +3072,7 @@
BreakpointLocation* latent_bpt =
GetLatentBreakpoint(script_url, line_number, column_number);
if (FLAG_verbose_debug) {
- OS::Print(
+ OS::PrintErr(
"Set latent breakpoint in url '%s' at "
"line %" Pd " col %" Pd "\n",
script_url.ToCString(), line_number, column_number);
@@ -3081,7 +3081,7 @@
}
if (scripts.Length() > 1) {
if (FLAG_verbose_debug) {
- OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString());
+ OS::PrintErr("Multiple scripts match url '%s'\n", script_url.ToCString());
}
return NULL;
}
@@ -3091,15 +3091,15 @@
if (!first_token_idx.IsReal()) {
// Script does not contain the given line number.
if (FLAG_verbose_debug) {
- OS::Print("Script '%s' does not contain line number %" Pd "\n",
- script_url.ToCString(), line_number);
+ OS::PrintErr("Script '%s' does not contain line number %" Pd "\n",
+ script_url.ToCString(), line_number);
}
return NULL;
} else if (!last_token_idx.IsReal()) {
// Line does not contain any tokens.
if (FLAG_verbose_debug) {
- OS::Print("No executable code at line %" Pd " in '%s'\n", line_number,
- script_url.ToCString());
+ OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
+ script_url.ToCString());
}
return NULL;
}
@@ -3112,8 +3112,8 @@
first_token_idx.Next();
}
if ((bpt == NULL) && FLAG_verbose_debug) {
- OS::Print("No executable code at line %" Pd " in '%s'\n", line_number,
- script_url.ToCString());
+ OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
+ script_url.ToCString());
}
return bpt;
}
@@ -3449,7 +3449,7 @@
skip_next_step_ = skip_next_step;
SetAsyncSteppingFramePointer();
if (FLAG_verbose_debug) {
- OS::Print("HandleSteppingRequest- kStepInto\n");
+ OS::PrintErr("HandleSteppingRequest- kStepInto\n");
}
} else if (resume_action_ == kStepOver) {
DeoptimizeWorld();
@@ -3459,7 +3459,7 @@
stepping_fp_ = stack_trace->FrameAt(0)->fp();
SetAsyncSteppingFramePointer();
if (FLAG_verbose_debug) {
- OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
+ OS::PrintErr("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
}
} else if (resume_action_ == kStepOut) {
if (FLAG_async_debugger) {
@@ -3488,7 +3488,7 @@
}
}
if (FLAG_verbose_debug) {
- OS::Print("HandleSteppingRequest- kStepOut %" Px "\n", stepping_fp_);
+ OS::PrintErr("HandleSteppingRequest- kStepOut %" Px "\n", stepping_fp_);
}
} else if (resume_action_ == kStepRewind) {
if (FLAG_trace_rewind) {
@@ -3874,11 +3874,11 @@
ASSERT(!HasActiveBreakpoint(frame->pc()));
if (FLAG_verbose_debug) {
- OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n",
- String::Handle(frame->SourceUrl()).ToCString(),
- frame->LineNumber(),
- String::Handle(frame->QualifiedFunctionName()).ToCString(),
- frame->TokenPos().ToCString());
+ OS::PrintErr(">>> single step break at %s:%" Pd " (func %s token %s)\n",
+ String::Handle(frame->SourceUrl()).ToCString(),
+ frame->LineNumber(),
+ String::Handle(frame->QualifiedFunctionName()).ToCString(),
+ frame->TokenPos().ToCString());
}
CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(),
@@ -3923,12 +3923,12 @@
// Hit a synthetic async breakpoint.
if (FLAG_verbose_debug) {
- OS::Print(">>> hit synthetic breakpoint at %s:%" Pd
- " "
- "(token %s) (address %#" Px ")\n",
- String::Handle(cbpt->SourceUrl()).ToCString(),
- cbpt->LineNumber(), cbpt->token_pos().ToCString(),
- top_frame->pc());
+ OS::PrintErr(">>> hit synthetic breakpoint at %s:%" Pd
+ " "
+ "(token %s) (address %#" Px ")\n",
+ String::Handle(cbpt->SourceUrl()).ToCString(),
+ cbpt->LineNumber(), cbpt->token_pos().ToCString(),
+ top_frame->pc());
}
ASSERT(synthetic_async_breakpoint_ == NULL);
@@ -3946,12 +3946,12 @@
}
if (FLAG_verbose_debug) {
- OS::Print(">>> hit breakpoint %" Pd " at %s:%" Pd
- " (token %s) "
- "(address %#" Px ")\n",
- bpt_hit->id(), String::Handle(cbpt->SourceUrl()).ToCString(),
- cbpt->LineNumber(), cbpt->token_pos().ToCString(),
- top_frame->pc());
+ OS::PrintErr(">>> hit breakpoint %" Pd " at %s:%" Pd
+ " (token %s) "
+ "(address %#" Px ")\n",
+ bpt_hit->id(), String::Handle(cbpt->SourceUrl()).ToCString(),
+ cbpt->LineNumber(), cbpt->token_pos().ToCString(),
+ top_frame->pc());
}
CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
@@ -4105,8 +4105,8 @@
// be compiled already.
ASSERT(!inner_function.HasCode());
if (FLAG_verbose_debug) {
- OS::Print("Pending BP remains unresolved in inner function '%s'\n",
- inner_function.ToFullyQualifiedCString());
+ OS::PrintErr("Pending BP remains unresolved in inner function '%s'\n",
+ inner_function.ToFullyQualifiedCString());
}
continue;
}
@@ -4125,8 +4125,8 @@
loc->requested_column_number());
if (!bp_pos.IsDebugPause()) {
if (FLAG_verbose_debug) {
- OS::Print("Failed resolving breakpoint for function '%s'\n",
- String::Handle(func.name()).ToCString());
+ OS::PrintErr("Failed resolving breakpoint for function '%s'\n",
+ String::Handle(func.name()).ToCString());
}
continue;
}
@@ -4136,17 +4136,17 @@
Breakpoint* bpt = loc->breakpoints();
while (bpt != NULL) {
if (FLAG_verbose_debug) {
- OS::Print("Resolved BP %" Pd
- " to pos %s, "
- "line %" Pd " col %" Pd
- ", "
- "function '%s' (requested range %s-%s, "
- "requested col %" Pd ")\n",
- bpt->id(), loc->token_pos().ToCString(),
- loc->LineNumber(), loc->ColumnNumber(),
- func.ToFullyQualifiedCString(), requested_pos.ToCString(),
- requested_end_pos.ToCString(),
- loc->requested_column_number());
+ OS::PrintErr(
+ "Resolved BP %" Pd
+ " to pos %s, "
+ "line %" Pd " col %" Pd
+ ", "
+ "function '%s' (requested range %s-%s, "
+ "requested col %" Pd ")\n",
+ bpt->id(), loc->token_pos().ToCString(), loc->LineNumber(),
+ loc->ColumnNumber(), func.ToFullyQualifiedCString(),
+ requested_pos.ToCString(), requested_end_pos.ToCString(),
+ loc->requested_column_number());
}
SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
bpt = bpt->next();
@@ -4156,12 +4156,12 @@
if (FLAG_verbose_debug) {
Breakpoint* bpt = loc->breakpoints();
while (bpt != NULL) {
- OS::Print("Setting breakpoint %" Pd " at line %" Pd " col %" Pd
- ""
- " for %s '%s'\n",
- bpt->id(), loc->LineNumber(), loc->ColumnNumber(),
- func.IsClosureFunction() ? "closure" : "function",
- String::Handle(func.name()).ToCString());
+ OS::PrintErr("Setting breakpoint %" Pd " at line %" Pd " col %" Pd
+ ""
+ " for %s '%s'\n",
+ bpt->id(), loc->LineNumber(), loc->ColumnNumber(),
+ func.IsClosureFunction() ? "closure" : "function",
+ String::Handle(func.name()).ToCString());
bpt = bpt->next();
}
}
@@ -4213,10 +4213,10 @@
Breakpoint* bpt = matched_loc->breakpoints();
while (bpt != NULL) {
if (FLAG_verbose_debug) {
- OS::Print("No code found at line %" Pd
- ": "
- "dropping latent breakpoint %" Pd " in '%s'\n",
- line_number, bpt->id(), url.ToCString());
+ OS::PrintErr("No code found at line %" Pd
+ ": "
+ "dropping latent breakpoint %" Pd " in '%s'\n",
+ line_number, bpt->id(), url.ToCString());
}
Breakpoint* prev = bpt;
bpt = bpt->next();
@@ -4245,7 +4245,7 @@
while (bpt != NULL) {
bpt->set_bpt_location(unresolved_loc);
if (FLAG_verbose_debug) {
- OS::Print(
+ OS::PrintErr(
"Converted latent breakpoint "
"%" Pd " in '%s' at line %" Pd " col %" Pd "\n",
bpt->id(), url.ToCString(), line_number, column_number);
@@ -4273,7 +4273,7 @@
if (FLAG_verbose_debug) {
Breakpoint* bpt = loc->breakpoints();
while (bpt != NULL) {
- OS::Print(
+ OS::PrintErr(
"No match found for latent breakpoint id "
"%" Pd " with url '%s'\n",
bpt->id(), url.ToCString());
diff --git a/runtime/vm/exceptions_test.cc b/runtime/vm/exceptions_test.cc
index 55ca394..fcd8869 100644
--- a/runtime/vm/exceptions_test.cc
+++ b/runtime/vm/exceptions_test.cc
@@ -17,8 +17,8 @@
const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0));
const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1));
if (!expected.CanonicalizeEquals(actual)) {
- OS::Print("expected: '%s' actual: '%s'\n", expected.ToCString(),
- actual.ToCString());
+ OS::PrintErr("expected: '%s' actual: '%s'\n", expected.ToCString(),
+ actual.ToCString());
FATAL("Unhandled_equals fails.\n");
}
}
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 7dd0cc2..50afd6e 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -118,8 +118,10 @@
"Maximum number of polymorphic check, otherwise it is megamorphic.") \
P(max_equality_polymorphic_checks, int, 32, \
"Maximum number of polymorphic checks in equality operator,") \
- P(new_gen_semi_max_size, int, (kWordSize <= 4) ? 16 : 32, \
+ P(new_gen_semi_max_size, int, (kWordSize <= 4) ? 8 : 16, \
"Max size of new gen semi space in MB") \
+ P(new_gen_semi_initial_size, int, (kWordSize <= 4) ? 1 : 2, \
+ "Initial size of new gen semi space in MB") \
P(optimization_counter_threshold, int, 30000, \
"Function's usage-counter value before it is optimized, -1 means never") \
P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize, \
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index 9120a8e..7b454b3 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -105,34 +105,35 @@
void Print() {
if (IsUnrecognized()) {
- OS::Print("%s: unrecognized\n", name_);
+ OS::PrintErr("%s: unrecognized\n", name_);
return;
}
switch (type_) {
case kBoolean: {
- OS::Print("%s: %s (%s)\n", name_, *this->bool_ptr_ ? "true" : "false",
- comment_);
+ OS::PrintErr("%s: %s (%s)\n", name_,
+ *this->bool_ptr_ ? "true" : "false", comment_);
break;
}
case kInteger: {
- OS::Print("%s: %d (%s)\n", name_, *this->int_ptr_, comment_);
+ OS::PrintErr("%s: %d (%s)\n", name_, *this->int_ptr_, comment_);
break;
}
case kUint64: {
- OS::Print("%s: %" Pu64 " (%s)\n", name_, *this->uint64_ptr_, comment_);
+ OS::PrintErr("%s: %" Pu64 " (%s)\n", name_, *this->uint64_ptr_,
+ comment_);
break;
}
case kString: {
if (*this->charp_ptr_ != NULL) {
- OS::Print("%s: '%s' (%s)\n", name_, *this->charp_ptr_, comment_);
+ OS::PrintErr("%s: '%s' (%s)\n", name_, *this->charp_ptr_, comment_);
} else {
- OS::Print("%s: (null) (%s)\n", name_, comment_);
+ OS::PrintErr("%s: (null) (%s)\n", name_, comment_);
}
break;
}
case kOptionHandler:
case kFlagHandler: {
- OS::Print("%s: (%s)\n", name_, comment_);
+ OS::PrintErr("%s: (%s)\n", name_, comment_);
break;
}
default:
@@ -391,8 +392,8 @@
// unrecognized flags.
if (!flag->IsUnrecognized()) {
if (!SetFlagFromString(flag, argument)) {
- OS::Print("Ignoring flag: %s is an invalid value for flag %s\n",
- argument, name);
+ OS::PrintErr("Ignoring flag: %s is an invalid value for flag %s\n",
+ argument, name);
}
}
}
@@ -473,7 +474,7 @@
}
void Flags::PrintFlags() {
- OS::Print("Flag settings:\n");
+ OS::PrintErr("Flag settings:\n");
for (intptr_t i = 0; i < num_flags_; ++i) {
flags_[i]->Print();
}
diff --git a/runtime/vm/freelist.cc b/runtime/vm/freelist.cc
index 6e5dded..c90fead 100644
--- a/runtime/vm/freelist.cc
+++ b/runtime/vm/freelist.cc
@@ -265,7 +265,7 @@
small_objects += list_length;
intptr_t list_bytes = list_length * i * kObjectAlignment;
small_bytes += list_bytes;
- OS::Print(
+ OS::PrintErr(
"small %3d [%8d bytes] : "
"%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
i, i * kObjectAlignment, list_length,
@@ -322,12 +322,12 @@
intptr_t list_length = pair->second();
intptr_t list_bytes = list_length * size;
large_bytes += list_bytes;
- OS::Print("large %3" Pd " [%8" Pd
- " bytes] : "
- "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
- size / kObjectAlignment, size, list_length,
- list_bytes / static_cast<double>(KB),
- large_bytes / static_cast<double>(KB));
+ OS::PrintErr("large %3" Pd " [%8" Pd
+ " bytes] : "
+ "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
+ size / kObjectAlignment, size, list_length,
+ list_bytes / static_cast<double>(KB),
+ large_bytes / static_cast<double>(KB));
}
}
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index 24ae04c..2c408e7 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -323,7 +323,7 @@
const intptr_t num25 = NumLT25Collisions();
const intptr_t num_more = NumGT25Collisions();
// clang-format off
- OS::Print("Stats for %s table :\n"
+ OS::PrintErr("Stats for %s table :\n"
" Size of table = %" Pd ",Number of Occupied entries = %" Pd "\n"
" Number of Grows = %" Pd "\n"
" Number of lookups with < 5 collisions = %" Pd "\n"
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index d073611..23def28f 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -82,10 +82,10 @@
}
static void DumpClassHeapStats(ClassHeapStats* stats) {
- OS::Print("%" Pd " ", stats->recent.new_count);
- OS::Print("%" Pd " ", stats->post_gc.new_count);
- OS::Print("%" Pd " ", stats->pre_gc.new_count);
- OS::Print("\n");
+ OS::PrintErr("%" Pd " ", stats->recent.new_count);
+ OS::PrintErr("%" Pd " ", stats->post_gc.new_count);
+ OS::PrintErr("%" Pd " ", stats->pre_gc.new_count);
+ OS::PrintErr("\n");
}
};
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index c61a2d5..4d58732 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -2135,25 +2135,169 @@
}
{
- BYTECODE(NativeCall, A_B_C);
- NativeFunctionWrapper trampoline =
- reinterpret_cast<NativeFunctionWrapper>(LOAD_CONSTANT(rA));
- Dart_NativeFunction function =
- reinterpret_cast<Dart_NativeFunction>(LOAD_CONSTANT(rB));
- intptr_t argc_tag = reinterpret_cast<intptr_t>(LOAD_CONSTANT(rC));
- const intptr_t num_arguments = NativeArguments::ArgcBits::decode(argc_tag);
+ BYTECODE(NativeCall, __D);
+ RawTypedData* native_entry = static_cast<RawTypedData*>(LOAD_CONSTANT(rD));
+ // TODO(regis): Introduce a new VM class subclassing Object and containing
+ // the four untagged values currently stored as TypeData array elements.
+ MethodRecognizer::Kind kind =
+ static_cast<MethodRecognizer::Kind>(*(reinterpret_cast<uintptr_t*>(
+ native_entry->ptr()->data() + (0 << kWordSizeLog2))));
+ switch (kind) {
+ case MethodRecognizer::kObjectEquals: {
+ SP[-1] = SP[-1] == SP[0] ? Bool::True().raw() : Bool::False().raw();
+ SP--;
+ } break;
+ case MethodRecognizer::kStringBaseLength:
+ case MethodRecognizer::kStringBaseIsEmpty: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[String::length_offset() / kWordSize];
+ if (kind == MethodRecognizer::kStringBaseIsEmpty) {
+ SP[0] =
+ SP[0] == Smi::New(0) ? Bool::True().raw() : Bool::False().raw();
+ }
+ } break;
+ case MethodRecognizer::kGrowableArrayLength: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[GrowableObjectArray::length_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[Array::length_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kTypedDataLength: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[TypedData::length_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kClassIDgetID: {
+ SP[0] = InterpreterHelpers::GetClassIdAsSmi(SP[0]);
+ } break;
+ case MethodRecognizer::kGrowableArrayCapacity: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ instance = reinterpret_cast<RawInstance**>(
+ instance->ptr())[GrowableObjectArray::data_offset() / kWordSize];
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[Array::length_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kListFactory: {
+ // factory List<E>([int length]) {
+ // return (:arg_desc.positional_count == 2) ? new _List<E>(length)
+ // : new _GrowableList<E>(0);
+ // }
+ if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) {
+ SP[1] = SP[0]; // length
+ SP[2] = SP[-1]; // type
+ Exit(thread, FP, SP + 3, pc);
+ NativeArguments native_args(thread, 2, SP + 1, SP - 1);
+ INVOKE_RUNTIME(DRT_AllocateArray, native_args);
+ SP -= 1; // Result is in SP - 1.
+ } else {
+ // SP[0] is type.
+ *++SP = Smi::New(0); // len
+ *++SP = thread->isolate()->object_store()->growable_list_factory();
+ argdesc_ = ArgumentsDescriptor::New(0, 2); // Returns a cached desc.
+ if (!Invoke(thread, SP - 2, SP, &pc, &FP, &SP)) {
+ HANDLE_EXCEPTION;
+ }
+ }
+ } break;
+ case MethodRecognizer::kObjectArrayAllocate: {
+ SP[1] = SP[0]; // length
+ SP[2] = SP[-1]; // type
+ Exit(thread, FP, SP + 3, pc);
+ NativeArguments native_args(thread, 2, SP + 1, SP - 1);
+ INVOKE_RUNTIME(DRT_AllocateArray, native_args);
+ SP -= 1; // Result is in SP - 1.
+ } break;
+ case MethodRecognizer::kLinkedHashMap_getIndex: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::index_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kLinkedHashMap_setIndex: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::index_offset() / kWordSize] = SP[0];
+ *--SP = null_value;
+ } break;
+ case MethodRecognizer::kLinkedHashMap_getData: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::data_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kLinkedHashMap_setData: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::data_offset() / kWordSize] = SP[0];
+ *--SP = null_value;
+ } break;
+ case MethodRecognizer::kLinkedHashMap_getHashMask: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kLinkedHashMap_setHashMask: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize] =
+ SP[0];
+ *--SP = null_value;
+ } break;
+ case MethodRecognizer::kLinkedHashMap_getUsedData: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kLinkedHashMap_setUsedData: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize] =
+ SP[0];
+ *--SP = null_value;
+ } break;
+ case MethodRecognizer::kLinkedHashMap_getDeletedKeys: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
+ SP[0] = reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize];
+ } break;
+ case MethodRecognizer::kLinkedHashMap_setDeletedKeys: {
+ RawInstance* instance = reinterpret_cast<RawInstance*>(SP[-1]);
+ reinterpret_cast<RawObject**>(
+ instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize] =
+ SP[0];
+ *--SP = null_value;
+ } break;
+ default: {
+ NativeFunctionWrapper trampoline =
+ reinterpret_cast<NativeFunctionWrapper>(
+ *(reinterpret_cast<uintptr_t*>(native_entry->ptr()->data() +
+ (1 << kWordSizeLog2))));
+ Dart_NativeFunction function = reinterpret_cast<Dart_NativeFunction>(
+ *(reinterpret_cast<uintptr_t*>(native_entry->ptr()->data() +
+ (2 << kWordSizeLog2))));
+ intptr_t argc_tag =
+ static_cast<intptr_t>(*(reinterpret_cast<uintptr_t*>(
+ native_entry->ptr()->data() + (3 << kWordSizeLog2))));
+ const intptr_t num_arguments =
+ NativeArguments::ArgcBits::decode(argc_tag);
- *++SP = null_value; // Result slot.
+ *++SP = null_value; // Result slot.
- RawObject** incoming_args = SP - num_arguments;
- RawObject** return_slot = SP;
- Exit(thread, FP, SP, pc);
- NativeArguments args(thread, argc_tag, incoming_args, return_slot);
- INVOKE_NATIVE(trampoline, function,
- reinterpret_cast<Dart_NativeArguments>(&args));
+ RawObject** incoming_args = SP - num_arguments;
+ RawObject** return_slot = SP;
+ Exit(thread, FP, SP, pc);
+ NativeArguments args(thread, argc_tag, incoming_args, return_slot);
+ INVOKE_NATIVE(trampoline, function,
+ reinterpret_cast<Dart_NativeArguments>(&args));
- *(SP - num_arguments) = *return_slot;
- SP -= num_arguments;
+ *(SP - num_arguments) = *return_slot;
+ SP -= num_arguments;
+ }
+ }
DISPATCH();
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5337d5a..f0840c0 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -700,7 +700,7 @@
MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
const Error& result) {
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[!] Unhandled exception in %s:\n"
" exception: %s\n",
T->isolate()->name(), result.ToErrorCString());
@@ -1104,7 +1104,7 @@
#endif
if (FLAG_trace_isolates) {
if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) {
- OS::Print(
+ OS::PrintErr(
"[+] Starting isolate:\n"
"\tisolate: %s\n",
result->name());
@@ -1765,7 +1765,7 @@
}
if (FLAG_trace_isolates) {
heap()->PrintSizes();
- OS::Print(
+ OS::PrintErr(
"[-] Stopping isolate:\n"
"\tisolate: %s\n",
name());
@@ -1826,7 +1826,7 @@
if (FLAG_support_compiler_stats && FLAG_compiler_stats &&
!ServiceIsolate::IsServiceIsolateDescendant(this) &&
(this != Dart::vm_isolate())) {
- OS::Print("%s", aggregate_compiler_stats()->PrintToZone());
+ OS::PrintErr("%s", aggregate_compiler_stats()->PrintToZone());
}
}
@@ -2506,7 +2506,7 @@
const int64_t reload_time_micros =
OS::GetCurrentMonotonicMicros() - start_time_micros;
double reload_millis = MicrosecondsToMilliseconds(reload_time_micros);
- OS::Print("Reloading has finished! (%.2f ms)\n", reload_millis);
+ OS::PrintErr("Reloading has finished! (%.2f ms)\n", reload_millis);
}
break;
}
diff --git a/runtime/vm/json_writer.cc b/runtime/vm/json_writer.cc
index 4e7c98a..7c3aa7f 100644
--- a/runtime/vm/json_writer.cc
+++ b/runtime/vm/json_writer.cc
@@ -317,7 +317,7 @@
void JSONWriter::EnsureIntegerIsRepresentableInJavaScript(int64_t i) {
#ifdef DEBUG
if (!Utils::IsJavascriptInt(i)) {
- OS::Print(
+ OS::PrintErr(
"JSONWriter::EnsureIntegerIsRepresentableInJavaScript failed on "
"%" Pd64 "\n",
i);
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 64b6982..dd39430 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -134,7 +134,7 @@
protected:
static void ShutdownIsolate(uword parameter) {
if (FLAG_trace_kernel) {
- OS::Print(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
}
Isolate* I = reinterpret_cast<Isolate*>(parameter);
I->WaitForOutstandingSpawns();
@@ -168,7 +168,7 @@
// Shut the isolate down.
Dart::ShutdownIsolate(I);
if (FLAG_trace_kernel) {
- OS::Print(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
}
// This should be the last line so the check
// IsKernelIsolate works during the shutdown process.
@@ -184,8 +184,8 @@
const Library& root_library =
Library::Handle(Z, I->object_store()->root_library());
if (root_library.IsNull()) {
- OS::Print(DART_KERNEL_ISOLATE_NAME
- ": Embedder did not install a script.");
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME
+ ": Embedder did not install a script.");
// Kernel isolate is not supported by embedder.
return false;
}
@@ -196,8 +196,8 @@
Z, root_library.LookupFunctionAllowPrivate(entry_name));
if (entry.IsNull()) {
// Kernel isolate is not supported by embedder.
- OS::Print(DART_KERNEL_ISOLATE_NAME
- ": Embedder did not provide a main function.");
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME
+ ": Embedder did not provide a main function.");
return false;
}
ASSERT(!entry.IsNull());
@@ -207,9 +207,9 @@
if (result.IsError()) {
// Kernel isolate did not initialize properly.
const Error& error = Error::Cast(result);
- OS::Print(DART_KERNEL_ISOLATE_NAME
- ": Calling main resulted in an error: %s",
- error.ToErrorCString());
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME
+ ": Calling main resulted in an error: %s",
+ error.ToErrorCString());
return false;
}
ASSERT(result.IsReceivePort());
@@ -236,7 +236,8 @@
}
ASSERT(!Exists());
if (FLAG_trace_kernel) {
- OS::Print(DART_KERNEL_ISOLATE_NAME ": InitCallback for %s.\n", I->name());
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": InitCallback for %s.\n",
+ I->name());
}
SetKernelIsolate(I);
}
diff --git a/runtime/vm/log.h b/runtime/vm/log.h
index e28c02d..8c851a4 100644
--- a/runtime/vm/log.h
+++ b/runtime/vm/log.h
@@ -26,7 +26,7 @@
class Log {
public:
- explicit Log(LogPrinter printer = OS::Print);
+ explicit Log(LogPrinter printer = OS::PrintErr);
~Log();
static Log* Current();
diff --git a/runtime/vm/log_test.cc b/runtime/vm/log_test.cc
index f17c4d9..49ce2ea 100644
--- a/runtime/vm/log_test.cc
+++ b/runtime/vm/log_test.cc
@@ -38,7 +38,7 @@
test_output_ = buffer;
// Also print to stdout to see the overall result.
- OS::Print("%s", test_output_);
+ OS::PrintErr("%s", test_output_);
}
class LogTestHelper : public AllStatic {
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index a8811c1..7d0c165 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -99,8 +99,8 @@
max_size = buckets.Length();
}
}
- OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n", table.Length(),
- size / 1024);
+ OS::PrintErr("%" Pd " megamorphic caches using %" Pd "KB.\n", table.Length(),
+ size / 1024);
intptr_t* probe_counts = new intptr_t[max_size];
intptr_t entry_count = 0;
@@ -141,9 +141,10 @@
intptr_t cumulative_entries = 0;
for (intptr_t i = 0; i <= max_probe_count; i++) {
cumulative_entries += probe_counts[i];
- OS::Print("Megamorphic probe %" Pd ": %" Pd " (%lf)\n", i, probe_counts[i],
- static_cast<double>(cumulative_entries) /
- static_cast<double>(entry_count));
+ OS::PrintErr("Megamorphic probe %" Pd ": %" Pd " (%lf)\n", i,
+ probe_counts[i],
+ static_cast<double>(cumulative_entries) /
+ static_cast<double>(entry_count));
}
delete[] probe_counts;
}
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 1a1ca67..2bc806d 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -106,7 +106,7 @@
bool task_running;
MonitorLocker ml(&monitor_);
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[+] Starting message handler:\n"
"\thandler: %s\n",
name());
@@ -130,7 +130,7 @@
if (FLAG_trace_isolates) {
Isolate* source_isolate = Isolate::Current();
if (source_isolate) {
- OS::Print(
+ OS::PrintErr(
"[>] Posting message:\n"
"\tlen: %" Pd "\n\tsource: (%" Pd64
") %s\n\tdest: %s\n"
@@ -138,7 +138,7 @@
message->Size(), static_cast<int64_t>(source_isolate->main_port()),
source_isolate->name(), name(), message->dest_port());
} else {
- OS::Print(
+ OS::PrintErr(
"[>] Posting message:\n"
"\tlen: %" Pd
"\n\tsource: <native code>\n"
@@ -214,7 +214,7 @@
while (message != NULL) {
intptr_t message_len = message->Size();
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[<] Handling message:\n"
"\tlen: %" Pd
"\n"
@@ -235,7 +235,7 @@
message = NULL; // May be deleted by now.
ml->Enter();
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[.] Message handled (%s):\n"
"\tlen: %" Pd
"\n"
@@ -459,13 +459,13 @@
if (FLAG_trace_isolates) {
if (status != kOK && thread() != NULL) {
const Error& error = Error::Handle(thread()->sticky_error());
- OS::Print(
+ OS::PrintErr(
"[-] Stopping message handler (%s):\n"
"\thandler: %s\n"
"\terror: %s\n",
MessageStatusString(status), name(), error.ToCString());
} else {
- OS::Print(
+ OS::PrintErr(
"[-] Stopping message handler (%s):\n"
"\thandler: %s\n",
MessageStatusString(status), name());
@@ -534,7 +534,7 @@
void MessageHandler::ClosePort(Dart_Port port) {
MonitorLocker ml(&monitor_);
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[-] Closing port:\n"
"\thandler: %s\n"
"\tport: %" Pd64
@@ -547,7 +547,7 @@
void MessageHandler::CloseAllPorts() {
MonitorLocker ml(&monitor_);
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[-] Closing all ports:\n"
"\thandler: %s\n",
name());
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index d993921..3aaf67e 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -102,7 +102,7 @@
UNREACHABLE();
}
-#if defined(TARGET_ARCH_DBC)
+#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER)
uword NativeEntry::BootstrapNativeCallWrapperEntry() {
uword entry =
reinterpret_cast<uword>(NativeEntry::BootstrapNativeCallWrapper);
@@ -223,7 +223,7 @@
const Library& library = Library::Handle(zone, cls.library());
*is_bootstrap_native =
- Bootstrap::IsBootstapResolver(library.native_entry_resolver());
+ Bootstrap::IsBootstrapResolver(library.native_entry_resolver());
const String& native_name = String::Handle(zone, func.native_name());
ASSERT(!native_name.IsNull());
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 048c12e..638d1c1 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -129,7 +129,7 @@
uword pc);
static const uint8_t* ResolveSymbol(uword pc);
-#if defined(TARGET_ARCH_DBC)
+#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER)
static uword BootstrapNativeCallWrapperEntry();
static void BootstrapNativeCallWrapper(Dart_NativeArguments args,
Dart_NativeFunction func);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index beb89ec..2428bab 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9143,8 +9143,8 @@
token_objects_.Add(str_);
if (kPrintTokenObjects) {
int iid = Isolate::Current()->main_port() % 1024;
- OS::Print("%03x ident <%s -> %s>\n", iid, ident.ToCString(),
- str_.ToCString());
+ OS::PrintErr("%03x ident <%s -> %s>\n", iid, ident.ToCString(),
+ str_.ToCString());
}
}
WriteIndex(index);
@@ -12622,7 +12622,7 @@
func = GetFunction(all_libs, #class_name, #function_name); \
if (func.IsNull()) { \
has_errors = true; \
- OS::Print("Function not found %s.%s\n", #class_name, #function_name); \
+ OS::PrintErr("Function not found %s.%s\n", #class_name, #function_name); \
} else { \
CHECK_FINGERPRINT3(func, class_name, function_name, dest, fp); \
}
@@ -12662,7 +12662,7 @@
func = GetFunction(all_libs, #class_name, #factory_name); \
if (func.IsNull()) { \
has_errors = true; \
- OS::Print("Function not found %s.%s\n", #class_name, #factory_name); \
+ OS::PrintErr("Function not found %s.%s\n", #class_name, #factory_name); \
} else { \
CHECK_FINGERPRINT2(func, symbol, cid, fp); \
}
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index b9eeeba..dd182ff 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -221,6 +221,12 @@
ASSERT(!cls.IsNull());
set_pragma_class(cls);
+ cls = core_lib.LookupClassAllowPrivate(Symbols::_GrowableList());
+ ASSERT(!cls.IsNull());
+ growable_list_factory_ =
+ cls.LookupFactoryAllowPrivate(Symbols::_GrowableListFactory());
+ ASSERT(growable_list_factory_ != Function::null());
+
// Cache the core private functions used for fast instance of checks.
simple_instance_of_function_ =
PrivateObjectLookup(Symbols::_simpleInstanceOf());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 01b5a52..cf0f807 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -108,6 +108,7 @@
RW(Function, lookup_port_handler) \
RW(TypedData, empty_uint32_array) \
RW(Function, handle_message_function) \
+ RW(Function, growable_list_factory) \
RW(Function, simple_instance_of_function) \
RW(Function, simple_instance_of_true_function) \
RW(Function, simple_instance_of_false_function) \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index ed8d624..6686b52 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -150,8 +150,8 @@
type_arguments2.SetTypeAt(0, type1);
type_arguments2.SetTypeAt(1, type2);
EXPECT_NE(type_arguments1.raw(), type_arguments2.raw());
- OS::Print("1: %s\n", type_arguments1.ToCString());
- OS::Print("2: %s\n", type_arguments2.ToCString());
+ OS::PrintErr("1: %s\n", type_arguments1.ToCString());
+ OS::PrintErr("2: %s\n", type_arguments2.ToCString());
EXPECT(type_arguments1.Equals(type_arguments2));
TypeArguments& type_arguments3 = TypeArguments::Handle();
type_arguments1.Canonicalize();
@@ -3765,16 +3765,17 @@
static void PrintMetadata(const char* name, const Object& data) {
if (data.IsError()) {
- OS::Print("Error in metadata evaluation for %s: '%s'\n", name,
- Error::Cast(data).ToErrorCString());
+ OS::PrintErr("Error in metadata evaluation for %s: '%s'\n", name,
+ Error::Cast(data).ToErrorCString());
}
EXPECT(data.IsArray());
const Array& metadata = Array::Cast(data);
- OS::Print("Metadata for %s has %" Pd " values:\n", name, metadata.Length());
+ OS::PrintErr("Metadata for %s has %" Pd " values:\n", name,
+ metadata.Length());
Object& elem = Object::Handle();
for (int i = 0; i < metadata.Length(); i++) {
elem = metadata.At(i);
- OS::Print(" %d: %s\n", i, elem.ToCString());
+ OS::PrintErr(" %d: %s\n", i, elem.ToCString());
}
}
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 94bb98d..dcee83d 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -92,6 +92,9 @@
static uintptr_t GetProgramCounter();
// Print formatted output to stdout/stderr for debugging.
+ // Tracing and debugging prints from the VM should strongly prefer to use
+ // PrintErr to avoid interfering with the application's output, which may
+ // be parsed by another program.
static void Print(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
static void PrintErr(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
static void VFPrint(FILE* stream, const char* format, va_list args);
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index 16eaa14..5eab0b8 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -17,15 +17,12 @@
#include "platform/signal_blocker.h"
#include "platform/utils.h"
-#include "vm/profiler.h"
-
namespace dart {
#define VALIDATE_PTHREAD_RESULT(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL2("pthread error: %d (%s)", result, error_message); \
}
@@ -37,7 +34,6 @@
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, error_message); \
}
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 03ccfd6..4b8da4d 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -19,15 +19,12 @@
#include "platform/signal_blocker.h"
#include "platform/utils.h"
-#include "vm/profiler.h"
-
namespace dart {
#define VALIDATE_PTHREAD_RESULT(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_buf[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
FATAL2("pthread error: %d (%s)", result, \
Utils::StrError(result, error_buf, kBufferSize)); \
}
@@ -40,7 +37,6 @@
if (result != 0) { \
const int kBufferSize = 1024; \
char error_buf[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, \
Utils::StrError(result, error_buf, kBufferSize)); \
}
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index 8867693..39f0047 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -23,15 +23,12 @@
#include "platform/safe_stack.h"
#include "platform/utils.h"
-#include "vm/profiler.h"
-
namespace dart {
#define VALIDATE_PTHREAD_RESULT(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL2("pthread error: %d (%s)", result, error_message); \
}
@@ -43,7 +40,6 @@
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
- NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, error_message); \
}
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 2beff46..288f8ff 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -806,7 +806,7 @@
if ((start - last_code_collection_in_us) >
FLAG_code_collection_interval_in_us) {
if (FLAG_log_code_drop) {
- OS::Print("Trying to detach code.\n");
+ OS::PrintErr("Trying to detach code.\n");
}
page_space_controller_.set_last_code_collection_in_us(start);
return true;
@@ -933,9 +933,9 @@
NoSafepointScope no_safepoints;
if (FLAG_print_free_list_before_gc) {
- OS::Print("Data Freelist (before GC):\n");
+ OS::PrintErr("Data Freelist (before GC):\n");
freelist_[HeapPage::kData].Print();
- OS::Print("Executable Freelist (before GC):\n");
+ OS::PrintErr("Executable Freelist (before GC):\n");
freelist_[HeapPage::kExecutable].Print();
}
@@ -1054,9 +1054,9 @@
heap_->RecordTime(kSweepLargePages, end - mid3);
if (FLAG_print_free_list_after_gc) {
- OS::Print("Data Freelist (after GC):\n");
+ OS::PrintErr("Data Freelist (after GC):\n");
freelist_[HeapPage::kData].Print();
- OS::Print("Executable Freelist (after GC):\n");
+ OS::PrintErr("Executable Freelist (after GC):\n");
freelist_[HeapPage::kExecutable].Print();
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 08388da..c2090ec 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -83,8 +83,8 @@
intptr_t line, column;
script.GetTokenLocation(token_pos, &line, &column);
PrintIndent();
- OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", msg, line,
- column, token_pos.value());
+ OS::PrintErr("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", msg,
+ line, column, token_pos.value());
}
(*indent_)++;
}
@@ -99,7 +99,7 @@
private:
void PrintIndent() {
for (intptr_t i = 0; i < *indent_; i++) {
- OS::Print(". ");
+ OS::PrintErr(". ");
}
}
intptr_t* indent_;
@@ -4766,7 +4766,7 @@
String* enum_name =
ExpectUserDefinedTypeIdentifier("enum type name expected");
if (FLAG_trace_parser) {
- OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString());
+ OS::PrintErr("TopLevel parsing enum '%s'\n", enum_name->ToCString());
}
ExpectToken(Token::kLBRACE);
if (!IsIdentifier()) {
@@ -4823,7 +4823,7 @@
const TokenPosition classname_pos = TokenPos();
String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
if (FLAG_trace_parser) {
- OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
+ OS::PrintErr("TopLevel parsing class '%s'\n", class_name.ToCString());
}
Class& cls = Class::Handle(Z);
TypeArguments& orig_type_parameters = TypeArguments::Handle(Z);
@@ -5356,8 +5356,8 @@
const TokenPosition classname_pos = TokenPos();
String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
if (FLAG_trace_parser) {
- OS::Print("toplevel parsing mixin application alias class '%s'\n",
- class_name.ToCString());
+ OS::PrintErr("toplevel parsing mixin application alias class '%s'\n",
+ class_name.ToCString());
}
const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name));
if (!obj.IsNull()) {
@@ -5542,8 +5542,8 @@
Type::Cast(function_type).signature());
if (FLAG_trace_parser) {
- OS::Print("TopLevel parsing function type alias '%s'\n",
- String::Handle(Z, signature_function.Signature()).ToCString());
+ OS::PrintErr("TopLevel parsing function type alias '%s'\n",
+ String::Handle(Z, signature_function.Signature()).ToCString());
}
// The alias should not be marked as finalized yet, since it needs to be
// checked in the class finalizer for illegal self references.
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index bd06546..a04d599 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -42,7 +42,7 @@
AstPrinter ast_printer;
ast_printer.PrintFunctionNodes(*parsed_function);
} else {
- OS::Print("AST printer not supported.");
+ OS::PrintErr("AST printer not supported.");
}
retval = true;
} else {
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 3bc0370..27ee26d 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -107,7 +107,7 @@
map_[index].handler->increment_live_ports();
}
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[^] Port (%s) -> (%s): \n"
"\thandler: %s\n"
"\tport: %" Pd64 "\n",
@@ -168,7 +168,7 @@
MaintainInvariants();
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[+] Opening port: \n"
"\thandler: %s\n"
"\tport: %" Pd64 "\n",
@@ -323,9 +323,9 @@
for (intptr_t i = 0; i < capacity_; i++) {
if (map_[i].handler == handler) {
if (map_[i].state == kLivePort) {
- OS::Print("Live Port = %" Pd64 "\n", map_[i].port);
+ OS::PrintErr("Live Port = %" Pd64 "\n", map_[i].port);
msg_handler = DartLibraryCalls::LookupHandler(map_[i].port);
- OS::Print("Handler = %s\n", msg_handler.ToCString());
+ OS::PrintErr("Handler = %s\n", msg_handler.ToCString());
}
}
}
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 13ab5b0..7f424f3 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -154,9 +154,9 @@
cursor_ = 0;
if (FLAG_trace_profiler) {
- OS::Print("Profiler holds %" Pd " samples\n", capacity);
- OS::Print("Profiler sample is %" Pd " bytes\n", Sample::instance_size());
- OS::Print("Profiler memory usage = %" Pd " bytes\n", size);
+ OS::PrintErr("Profiler holds %" Pd " samples\n", capacity);
+ OS::PrintErr("Profiler sample is %" Pd " bytes\n", Sample::instance_size());
+ OS::PrintErr("Profiler memory usage = %" Pd " bytes\n", size);
}
}
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 9cdfa47..286f2dd 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -49,7 +49,7 @@
if ((size_before > 0) && FLAG_trace_profiler) {
intptr_t length_before = previous_.Length();
intptr_t length_after = current_.Length();
- OS::Print(
+ OS::PrintErr(
"Updating isolate deoptimized code array: "
"%" Pd " -> %" Pd " [%" Pd " -> %" Pd "]\n",
size_before, size_after, length_before, length_after);
@@ -163,9 +163,9 @@
ProfileFunctionSourcePosition& position = source_position_ticks_[i];
if (position.token_pos().value() == token_position.value()) {
if (FLAG_trace_profiler_verbose) {
- OS::Print("Ticking source position %s %s\n",
- exclusive ? "exclusive" : "inclusive",
- token_position.ToCString());
+ OS::PrintErr("Ticking source position %s %s\n",
+ exclusive ? "exclusive" : "inclusive",
+ token_position.ToCString());
}
// Found existing position, tick it.
position.Tick(exclusive);
@@ -179,9 +179,9 @@
// Add new one, sorted by token position value.
ProfileFunctionSourcePosition pfsp(token_position);
if (FLAG_trace_profiler_verbose) {
- OS::Print("Ticking source position %s %s\n",
- exclusive ? "exclusive" : "inclusive",
- token_position.ToCString());
+ OS::PrintErr("Ticking source position %s %s\n",
+ exclusive ? "exclusive" : "inclusive",
+ token_position.ToCString());
}
pfsp.Tick(exclusive);
@@ -1027,8 +1027,8 @@
~ProfileCodeInlinedFunctionsCache() {
if (FLAG_trace_profiler) {
intptr_t total = cache_hit_ + cache_miss_;
- OS::Print("LOOKUPS: %" Pd " HITS: %" Pd " MISSES: %" Pd "\n", total,
- cache_hit_, cache_miss_);
+ OS::PrintErr("LOOKUPS: %" Pd " HITS: %" Pd " MISSES: %" Pd "\n", total,
+ cache_hit_, cache_miss_);
}
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 31ae26e..cbe81d8 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -276,7 +276,7 @@
size = Size();
break;
default:
- OS::Print("Class Id: %" Pd "\n", class_id);
+ OS::PrintErr("Class Id: %" Pd "\n", class_id);
UNREACHABLE();
break;
}
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 4d99e0f..909f00a 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -3471,23 +3471,23 @@
};
void DotPrinter::PrintNode(const char* label, RegExpNode* node) {
- OS::Print("digraph G {\n graph [label=\"");
+ OS::PrintErr("digraph G {\n graph [label=\"");
for (intptr_t i = 0; label[i]; i++) {
switch (label[i]) {
case '\\':
- OS::Print("\\\\");
+ OS::PrintErr("\\\\");
break;
case '"':
- OS::Print("\"");
+ OS::PrintErr("\"");
break;
default:
- OS::Print("%c", label[i]);
+ OS::PrintErr("%c", label[i]);
break;
}
}
- OS::Print("\"];\n");
+ OS::PrintErr("\"];\n");
Visit(node);
- OS::Print("}\n");
+ OS::PrintErr("}\n");
}
void DotPrinter::Visit(RegExpNode* node) {
@@ -3497,7 +3497,7 @@
}
void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) {
- OS::Print(" n%p -> n%p [style=dotted];\n", from, on_failure);
+ OS::PrintErr(" n%p -> n%p [style=dotted];\n", from, on_failure);
Visit(on_failure);
}
@@ -3508,18 +3508,18 @@
if (first_) {
first_ = false;
} else {
- OS::Print("|");
+ OS::PrintErr("|");
}
}
void PrintBit(const char* name, bool value) {
if (!value) return;
PrintSeparator();
- OS::Print("{%s}", name);
+ OS::PrintErr("{%s}", name);
}
void PrintPositive(const char* name, intptr_t value) {
if (value < 0) return;
PrintSeparator();
- OS::Print("{%s|%" Pd "}", name, value);
+ OS::PrintErr("{%s|%" Pd "}", name, value);
}
private:
@@ -3527,7 +3527,7 @@
};
void DotPrinter::PrintAttributes(RegExpNode* that) {
- OS::Print(
+ OS::PrintErr(
" a%p [shape=Mrecord, color=grey, fontcolor=grey, "
"margin=0.1, fontsize=10, label=\"{",
that);
@@ -3538,17 +3538,17 @@
printer.PrintBit("SI", info->follows_start_interest);
BlockLabel* label = that->label();
if (label->IsBound()) printer.PrintPositive("@", label->Position());
- OS::Print(
+ OS::PrintErr(
"}\"];\n"
" a%p -> n%p [style=dashed, color=grey, arrowhead=none];\n",
that, that);
}
void DotPrinter::VisitChoice(ChoiceNode* that) {
- OS::Print(" n%p [shape=Mrecord, label=\"?\"];\n", that);
+ OS::PrintErr(" n%p [shape=Mrecord, label=\"?\"];\n", that);
for (intptr_t i = 0; i < that->alternatives()->length(); i++) {
GuardedAlternative alt = that->alternatives()->At(i);
- OS::Print(" n%p -> n%p", that, alt.node());
+ OS::PrintErr(" n%p -> n%p", that, alt.node());
}
for (intptr_t i = 0; i < that->alternatives()->length(); i++) {
GuardedAlternative alt = that->alternatives()->At(i);
@@ -3557,120 +3557,120 @@
}
void DotPrinter::VisitText(TextNode* that) {
- OS::Print(" n%p [label=\"", that);
+ OS::PrintErr(" n%p [label=\"", that);
for (intptr_t i = 0; i < that->elements()->length(); i++) {
- if (i > 0) OS::Print(" ");
+ if (i > 0) OS::PrintErr(" ");
TextElement elm = that->elements()->At(i);
switch (elm.text_type()) {
case TextElement::ATOM: {
ZoneGrowableArray<uint16_t>* data = elm.atom()->data();
for (intptr_t i = 0; i < data->length(); i++) {
- OS::Print("%c", static_cast<char>(data->At(i)));
+ OS::PrintErr("%c", static_cast<char>(data->At(i)));
}
break;
}
case TextElement::CHAR_CLASS: {
RegExpCharacterClass* node = elm.char_class();
- OS::Print("[");
- if (node->is_negated()) OS::Print("^");
+ OS::PrintErr("[");
+ if (node->is_negated()) OS::PrintErr("^");
for (intptr_t j = 0; j < node->ranges()->length(); j++) {
CharacterRange range = node->ranges()->At(j);
PrintUtf16(range.from());
- OS::Print("-");
+ OS::PrintErr("-");
PrintUtf16(range.to());
}
- OS::Print("]");
+ OS::PrintErr("]");
break;
}
default:
UNREACHABLE();
}
}
- OS::Print("\", shape=box, peripheries=2];\n");
+ OS::PrintErr("\", shape=box, peripheries=2];\n");
PrintAttributes(that);
- OS::Print(" n%p -> n%p;\n", that, that->on_success());
+ OS::PrintErr(" n%p -> n%p;\n", that, that->on_success());
Visit(that->on_success());
}
void DotPrinter::VisitBackReference(BackReferenceNode* that) {
- OS::Print(" n%p [label=\"$%" Pd "..$%" Pd "\", shape=doubleoctagon];\n",
- that, that->start_register(), that->end_register());
+ OS::PrintErr(" n%p [label=\"$%" Pd "..$%" Pd "\", shape=doubleoctagon];\n",
+ that, that->start_register(), that->end_register());
PrintAttributes(that);
- OS::Print(" n%p -> n%p;\n", that, that->on_success());
+ OS::PrintErr(" n%p -> n%p;\n", that, that->on_success());
Visit(that->on_success());
}
void DotPrinter::VisitEnd(EndNode* that) {
- OS::Print(" n%p [style=bold, shape=point];\n", that);
+ OS::PrintErr(" n%p [style=bold, shape=point];\n", that);
PrintAttributes(that);
}
void DotPrinter::VisitAssertion(AssertionNode* that) {
- OS::Print(" n%p [", that);
+ OS::PrintErr(" n%p [", that);
switch (that->assertion_type()) {
case AssertionNode::AT_END:
- OS::Print("label=\"$\", shape=septagon");
+ OS::PrintErr("label=\"$\", shape=septagon");
break;
case AssertionNode::AT_START:
- OS::Print("label=\"^\", shape=septagon");
+ OS::PrintErr("label=\"^\", shape=septagon");
break;
case AssertionNode::AT_BOUNDARY:
- OS::Print("label=\"\\b\", shape=septagon");
+ OS::PrintErr("label=\"\\b\", shape=septagon");
break;
case AssertionNode::AT_NON_BOUNDARY:
- OS::Print("label=\"\\B\", shape=septagon");
+ OS::PrintErr("label=\"\\B\", shape=septagon");
break;
case AssertionNode::AFTER_NEWLINE:
- OS::Print("label=\"(?<=\\n)\", shape=septagon");
+ OS::PrintErr("label=\"(?<=\\n)\", shape=septagon");
break;
}
- OS::Print("];\n");
+ OS::PrintErr("];\n");
PrintAttributes(that);
RegExpNode* successor = that->on_success();
- OS::Print(" n%p -> n%p;\n", that, successor);
+ OS::PrintErr(" n%p -> n%p;\n", that, successor);
Visit(successor);
}
void DotPrinter::VisitAction(ActionNode* that) {
- OS::Print(" n%p [", that);
+ OS::PrintErr(" n%p [", that);
switch (that->action_type_) {
case ActionNode::SET_REGISTER:
- OS::Print("label=\"$%" Pd ":=%" Pd "\", shape=octagon",
- that->data_.u_store_register.reg,
- that->data_.u_store_register.value);
+ OS::PrintErr("label=\"$%" Pd ":=%" Pd "\", shape=octagon",
+ that->data_.u_store_register.reg,
+ that->data_.u_store_register.value);
break;
case ActionNode::INCREMENT_REGISTER:
- OS::Print("label=\"$%" Pd "++\", shape=octagon",
- that->data_.u_increment_register.reg);
+ OS::PrintErr("label=\"$%" Pd "++\", shape=octagon",
+ that->data_.u_increment_register.reg);
break;
case ActionNode::STORE_POSITION:
- OS::Print("label=\"$%" Pd ":=$pos\", shape=octagon",
- that->data_.u_position_register.reg);
+ OS::PrintErr("label=\"$%" Pd ":=$pos\", shape=octagon",
+ that->data_.u_position_register.reg);
break;
case ActionNode::BEGIN_SUBMATCH:
- OS::Print("label=\"$%" Pd ":=$pos,begin\", shape=septagon",
- that->data_.u_submatch.current_position_register);
+ OS::PrintErr("label=\"$%" Pd ":=$pos,begin\", shape=septagon",
+ that->data_.u_submatch.current_position_register);
break;
case ActionNode::POSITIVE_SUBMATCH_SUCCESS:
- OS::Print("label=\"escape\", shape=septagon");
+ OS::PrintErr("label=\"escape\", shape=septagon");
break;
case ActionNode::EMPTY_MATCH_CHECK:
- OS::Print("label=\"$%" Pd "=$pos?,$%" Pd "<%" Pd "?\", shape=septagon",
- that->data_.u_empty_match_check.start_register,
- that->data_.u_empty_match_check.repetition_register,
- that->data_.u_empty_match_check.repetition_limit);
+ OS::PrintErr("label=\"$%" Pd "=$pos?,$%" Pd "<%" Pd "?\", shape=septagon",
+ that->data_.u_empty_match_check.start_register,
+ that->data_.u_empty_match_check.repetition_register,
+ that->data_.u_empty_match_check.repetition_limit);
break;
case ActionNode::CLEAR_CAPTURES: {
- OS::Print("label=\"clear $%" Pd " to $%" Pd "\", shape=septagon",
- that->data_.u_clear_captures.range_from,
- that->data_.u_clear_captures.range_to);
+ OS::PrintErr("label=\"clear $%" Pd " to $%" Pd "\", shape=septagon",
+ that->data_.u_clear_captures.range_from,
+ that->data_.u_clear_captures.range_to);
break;
}
}
- OS::Print("];\n");
+ OS::PrintErr("];\n");
PrintAttributes(that);
RegExpNode* successor = that->on_success();
- OS::Print(" n%p -> n%p;\n", that, successor);
+ OS::PrintErr(" n%p -> n%p;\n", that, successor);
Visit(successor);
}
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
index f2570c5..ecd1914 100644
--- a/runtime/vm/regexp_assembler.cc
+++ b/runtime/vm/regexp_assembler.cc
@@ -13,7 +13,7 @@
void PrintUtf16(uint16_t c) {
const char* format =
(0x20 <= c && c <= 0x7F) ? "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x";
- OS::Print(format, c);
+ OS::PrintErr(format, c);
}
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 64753cb..72b4e93 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -323,7 +323,7 @@
Object::Handle(zone, DartEntry::InvokeFunction(fun, args));
if (retval.IsError()) {
const Error& error = Error::Cast(retval);
- OS::Print("%s\n", error.ToErrorCString());
+ OS::PrintErr("%s\n", error.ToErrorCString());
// Should never happen.
UNREACHABLE();
}
@@ -569,7 +569,7 @@
#define HANDLE_DEAD_CODE_EMISSION() \
if (current_instruction_ == NULL) { \
if (FLAG_trace_irregexp) { \
- OS::Print( \
+ OS::PrintErr( \
"WARNING: Attempting to append to a closed assembler. " \
"This could be either a bug or generation of dead code " \
"inherited from V8.\n"); \
diff --git a/runtime/vm/regexp_ast.cc b/runtime/vm/regexp_ast.cc
index 2edfe08..5b51a6f 100644
--- a/runtime/vm/regexp_ast.cc
+++ b/runtime/vm/regexp_ast.cc
@@ -134,76 +134,76 @@
};
void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
- OS::Print("(|");
+ OS::PrintErr("(|");
for (intptr_t i = 0; i < that->alternatives()->length(); i++) {
- OS::Print(" ");
+ OS::PrintErr(" ");
(*that->alternatives())[i]->Accept(this, data);
}
- OS::Print(")");
+ OS::PrintErr(")");
return NULL;
}
void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
- OS::Print("(:");
+ OS::PrintErr("(:");
for (intptr_t i = 0; i < that->nodes()->length(); i++) {
- OS::Print(" ");
+ OS::PrintErr(" ");
(*that->nodes())[i]->Accept(this, data);
}
- OS::Print(")");
+ OS::PrintErr(")");
return NULL;
}
void RegExpUnparser::VisitCharacterRange(CharacterRange that) {
PrintUtf16(that.from());
if (!that.IsSingleton()) {
- OS::Print("-");
+ OS::PrintErr("-");
PrintUtf16(that.to());
}
}
void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
void* data) {
- if (that->is_negated()) OS::Print("^");
- OS::Print("[");
+ if (that->is_negated()) OS::PrintErr("^");
+ OS::PrintErr("[");
for (intptr_t i = 0; i < that->ranges()->length(); i++) {
- if (i > 0) OS::Print(" ");
+ if (i > 0) OS::PrintErr(" ");
VisitCharacterRange((*that->ranges())[i]);
}
- OS::Print("]");
+ OS::PrintErr("]");
return NULL;
}
void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
switch (that->assertion_type()) {
case RegExpAssertion::START_OF_INPUT:
- OS::Print("@^i");
+ OS::PrintErr("@^i");
break;
case RegExpAssertion::END_OF_INPUT:
- OS::Print("@$i");
+ OS::PrintErr("@$i");
break;
case RegExpAssertion::START_OF_LINE:
- OS::Print("@^l");
+ OS::PrintErr("@^l");
break;
case RegExpAssertion::END_OF_LINE:
- OS::Print("@$l");
+ OS::PrintErr("@$l");
break;
case RegExpAssertion::BOUNDARY:
- OS::Print("@b");
+ OS::PrintErr("@b");
break;
case RegExpAssertion::NON_BOUNDARY:
- OS::Print("@B");
+ OS::PrintErr("@B");
break;
}
return NULL;
}
void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
- OS::Print("'");
+ OS::PrintErr("'");
ZoneGrowableArray<uint16_t>* chardata = that->data();
for (intptr_t i = 0; i < chardata->length(); i++) {
PrintUtf16(chardata->At(i));
}
- OS::Print("'");
+ OS::PrintErr("'");
return NULL;
}
@@ -211,50 +211,50 @@
if (that->elements()->length() == 1) {
(*that->elements())[0].tree()->Accept(this, data);
} else {
- OS::Print("(!");
+ OS::PrintErr("(!");
for (intptr_t i = 0; i < that->elements()->length(); i++) {
- OS::Print(" ");
+ OS::PrintErr(" ");
(*that->elements())[i].tree()->Accept(this, data);
}
- OS::Print(")");
+ OS::PrintErr(")");
}
return NULL;
}
void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
- OS::Print("(# %" Pd " ", that->min());
+ OS::PrintErr("(# %" Pd " ", that->min());
if (that->max() == RegExpTree::kInfinity) {
- OS::Print("- ");
+ OS::PrintErr("- ");
} else {
- OS::Print("%" Pd " ", that->max());
+ OS::PrintErr("%" Pd " ", that->max());
}
- OS::Print(that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
+ OS::PrintErr(that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
that->body()->Accept(this, data);
- OS::Print(")");
+ OS::PrintErr(")");
return NULL;
}
void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
- OS::Print("(^ ");
+ OS::PrintErr("(^ ");
that->body()->Accept(this, data);
- OS::Print(")");
+ OS::PrintErr(")");
return NULL;
}
void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
- OS::Print("(-> %s", (that->is_positive() ? "+ " : "- "));
+ OS::PrintErr("(-> %s", (that->is_positive() ? "+ " : "- "));
that->body()->Accept(this, data);
- OS::Print(")");
+ OS::PrintErr(")");
return NULL;
}
void* RegExpUnparser::VisitBackReference(RegExpBackReference* that, void*) {
- OS::Print("(<- %" Pd ")", that->index());
+ OS::PrintErr("(<- %" Pd ")", that->index());
return NULL;
}
void* RegExpUnparser::VisitEmpty(RegExpEmpty*, void*) {
- OS::Print("%%");
+ OS::PrintErr("%%");
return NULL;
}
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index 27cc976..8b960b0 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -84,21 +84,21 @@
printable
? "pc = %02x, sp = %d, curpos = %d, curchar = %08x (%c), bc = %s"
: "pc = %02x, sp = %d, curpos = %d, curchar = %08x .%c., bc = %s";
- OS::Print(format, pc - code_base, stack_depth, current_position,
- current_char, printable ? current_char : '.', bytecode_name);
+ OS::PrintErr(format, pc - code_base, stack_depth, current_position,
+ current_char, printable ? current_char : '.', bytecode_name);
for (int i = 0; i < bytecode_length; i++) {
- OS::Print(", %02x", pc[i]);
+ OS::PrintErr(", %02x", pc[i]);
}
- OS::Print(" ");
+ OS::PrintErr(" ");
for (int i = 1; i < bytecode_length; i++) {
unsigned char b = pc[i];
if (b < 127 && b >= 32) {
- OS::Print("%c", b);
+ OS::PrintErr("%c", b);
} else {
- OS::Print(".");
+ OS::PrintErr(".");
}
}
- OS::Print("\n");
+ OS::PrintErr("\n");
}
}
@@ -167,7 +167,7 @@
#ifdef DEBUG
if (FLAG_trace_regexp_bytecodes) {
- OS::Print("Start irregexp bytecode interpreter\n");
+ OS::PrintErr("Start irregexp bytecode interpreter\n");
}
#endif
while (true) {
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index 4b45c37..ac3989d 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -154,7 +154,7 @@
const String& msg = String::Handle(String::NewFormattedV(format, args));
const String& snippet_msg = String::Handle(
PrependSnippet(kind, script, token_pos, report_after_token, msg));
- OS::Print("%s", snippet_msg.ToCString());
+ OS::PrintErr("%s", snippet_msg.ToCString());
return;
}
}
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index ede255c..a99794c 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -486,7 +486,7 @@
String::Handle(instantiated_type.Name()).ToCString(),
String::Handle(type.Name()).ToCString(), caller_frame->pc());
if (!bound_error.IsNull()) {
- OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
+ OS::PrintErr(" bound error: %s\n", bound_error.ToErrorCString());
}
}
const Function& function =
@@ -513,13 +513,13 @@
// inlined assembly.
if (new_cache.IsNull()) {
if (FLAG_trace_type_checks) {
- OS::Print("UpdateTypeTestCache: cache is null\n");
+ OS::PrintErr("UpdateTypeTestCache: cache is null\n");
}
return;
}
if (instance.IsSmi()) {
if (FLAG_trace_type_checks) {
- OS::Print("UpdateTypeTestCache: instance is Smi\n");
+ OS::PrintErr("UpdateTypeTestCache: instance is Smi\n");
}
return;
}
@@ -540,7 +540,7 @@
if (Closure::Cast(instance).function_type_arguments() !=
TypeArguments::null()) {
if (FLAG_trace_type_checks) {
- OS::Print(
+ OS::PrintErr(
"UpdateTypeTestCache: closure function_type_arguments is "
"not null\n");
}
@@ -1906,9 +1906,9 @@
Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
ASSERT(osr_id != Compiler::kNoOSRDeoptId);
if (FLAG_trace_osr) {
- OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
- function.ToFullyQualifiedCString(), osr_id,
- function.usage_counter());
+ OS::PrintErr("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
+ function.ToFullyQualifiedCString(), osr_id,
+ function.usage_counter());
}
// Since the code is referenced from the frame and the ZoneHandle,
@@ -2482,7 +2482,7 @@
// Print the stop message.
DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) {
- OS::Print("Stop message: %s\n", message);
+ OS::PrintErr("Stop message: %s\n", message);
}
END_LEAF_RUNTIME_ENTRY
diff --git a/runtime/vm/safepoint.cc b/runtime/vm/safepoint.cc
index 09c5646..4fb88a4 100644
--- a/runtime/vm/safepoint.cc
+++ b/runtime/vm/safepoint.cc
@@ -110,8 +110,8 @@
if (num_attempts > 10) {
// We have been waiting too long, start logging this as we might
// have an issue where a thread is not checking in for a safepoint.
- OS::Print("Attempt:%" Pd " waiting for %d threads to check in\n",
- num_attempts, number_threads_not_at_safepoint_);
+ OS::PrintErr("Attempt:%" Pd " waiting for %d threads to check in\n",
+ num_attempts, number_threads_not_at_safepoint_);
}
}
}
diff --git a/runtime/vm/scanner_test.cc b/runtime/vm/scanner_test.cc
index 38ffc86..93fa232 100644
--- a/runtime/vm/scanner_test.cc
+++ b/runtime/vm/scanner_test.cc
@@ -13,13 +13,13 @@
typedef ZoneGrowableArray<Scanner::TokenDescriptor> GrowableTokenStream;
static void LogTokenDesc(Scanner::TokenDescriptor token) {
- OS::Print("pos %2d:%d-%d token %s ", token.position.line,
- token.position.column, token.position.column,
- Token::Name(token.kind));
+ OS::PrintErr("pos %2d:%d-%d token %s ", token.position.line,
+ token.position.column, token.position.column,
+ Token::Name(token.kind));
if (token.literal != NULL) {
- OS::Print("%s", token.literal->ToCString());
+ OS::PrintErr("%s", token.literal->ToCString());
}
- OS::Print("\n");
+ OS::PrintErr("\n");
}
static void LogTokenStream(const GrowableTokenStream& token_stream) {
@@ -100,7 +100,7 @@
};
static const GrowableTokenStream& Scan(const char* source) {
- OS::Print("\nScanning: <%s>\n", source);
+ OS::PrintErr("\nScanning: <%s>\n", source);
Scanner scanner(String::Handle(String::New(source)),
String::Handle(String::New("")));
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 9ca79a7..3121e86 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -6,6 +6,7 @@
#include "vm/dart.h"
#include "vm/dart_api_state.h"
+#include "vm/flag_list.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/object.h"
@@ -31,7 +32,7 @@
new_gen_garbage_threshold,
90,
"Grow new gen when less than this percentage is garbage.");
-DEFINE_FLAG(int, new_gen_growth_factor, 4, "Grow new gen by this factor.");
+DEFINE_FLAG(int, new_gen_growth_factor, 2, "Grow new gen by this factor.");
// Scavenger uses RawObject::kMarkBit to distinguish forwarded and non-forwarded
// objects. The kMarkBit does not intersect with the target address because of
@@ -350,10 +351,9 @@
// going to use for forwarding pointers.
ASSERT(Object::tags_offset() == 0);
- // Set initial size resulting in a total of three different levels.
- const intptr_t initial_semi_capacity_in_words =
- max_semi_capacity_in_words /
- (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
+ // Set initial semi space size in words.
+ const intptr_t initial_semi_capacity_in_words = Utils::Minimum(
+ max_semi_capacity_in_words, FLAG_new_gen_semi_initial_size * MBInWords);
const intptr_t kVmNameSize = 128;
char vm_name[kVmNameSize];
diff --git a/runtime/vm/scope_timer.h b/runtime/vm/scope_timer.h
index c895225..c910e34 100644
--- a/runtime/vm/scope_timer.h
+++ b/runtime/vm/scope_timer.h
@@ -32,7 +32,8 @@
}
int64_t elapsed = GetElapsed();
double seconds = MicrosecondsToSeconds(elapsed);
- OS::Print("%s: %f seconds (%" Pd64 " \u00B5s)\n", name_, seconds, elapsed);
+ OS::PrintErr("%s: %f seconds (%" Pd64 " \u00B5s)\n", name_, seconds,
+ elapsed);
}
private:
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 3415481..f61af66 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -122,7 +122,7 @@
SimulatorDebugger::~SimulatorDebugger() {}
void SimulatorDebugger::Stop(Instr* instr, const char* message) {
- OS::Print("Simulator hit %s\n", message);
+ OS::PrintErr("Simulator hit %s\n", message);
Debug();
}
@@ -258,7 +258,7 @@
if (token_pos.IsReal()) {
script.GetTokenLocation(token_pos, &line, &column);
}
- OS::Print(
+ OS::PrintErr(
"pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc,
fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
func_name.ToCString(), url.ToCString(), line, column);
@@ -303,13 +303,13 @@
GetApproximateTokenIndex(code, frame->pc()),
code.is_optimized(), false);
} else {
- OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
- frame->pc(), frame->fp(), frame->sp(),
- frame->IsEntryFrame()
- ? "entry"
- : frame->IsExitFrame()
- ? "exit"
- : frame->IsStubFrame() ? "stub" : "invalid");
+ OS::PrintErr("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
+ frame->pc(), frame->fp(), frame->sp(),
+ frame->IsEntryFrame()
+ ? "entry"
+ : frame->IsExitFrame()
+ ? "exit"
+ : frame->IsStubFrame() ? "stub" : "invalid");
}
frame = frames.NextFrame();
}
@@ -378,12 +378,12 @@
if (last_pc != sim_->get_pc()) {
last_pc = sim_->get_pc();
if (Simulator::IsIllegalAddress(last_pc)) {
- OS::Print("pc is out of bounds: 0x%" Px "\n", last_pc);
+ OS::PrintErr("pc is out of bounds: 0x%" Px "\n", last_pc);
} else {
if (FLAG_support_disassembler) {
Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
} else {
- OS::Print("Disassembler not supported in this mode.\n");
+ OS::PrintErr("Disassembler not supported in this mode.\n");
}
}
}
@@ -399,7 +399,7 @@
"%" XSTR(ARG_SIZE) "s",
cmd, arg1, arg2);
if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
- OS::Print(
+ OS::PrintErr(
"c/cont -- continue execution\n"
"disasm -- disassemble instrs at current pc location\n"
" other variants are:\n"
@@ -421,7 +421,7 @@
"unstop -- if current pc is a stop instr make it a nop\n"
"q/quit -- Quit the debugger and exit the program\n");
} else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
- OS::Print("Quitting\n");
+ OS::PrintErr("Quitting\n");
OS::Exit(0);
} else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
@@ -435,14 +435,14 @@
uint32_t value;
if (strcmp(arg1, "icount") == 0) {
const uint64_t icount = sim_->get_icount();
- OS::Print("icount: %" Pu64 " 0x%" Px64 "\n", icount, icount);
+ OS::PrintErr("icount: %" Pu64 " 0x%" Px64 "\n", icount, icount);
} else if (GetValue(arg1, &value)) {
- OS::Print("%s: %u 0x%x\n", arg1, value, value);
+ OS::PrintErr("%s: %u 0x%x\n", arg1, value, value);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("print <reg or icount or value or *addr>\n");
+ OS::PrintErr("print <reg or icount or value or *addr>\n");
}
} else if ((strcmp(cmd, "ps") == 0) ||
(strcmp(cmd, "printsingle") == 0)) {
@@ -450,12 +450,12 @@
float fvalue;
if (GetFValue(arg1, &fvalue)) {
uint32_t value = bit_cast<uint32_t, float>(fvalue);
- OS::Print("%s: 0%u 0x%x %.8g\n", arg1, value, value, fvalue);
+ OS::PrintErr("%s: 0%u 0x%x %.8g\n", arg1, value, value, fvalue);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printfloat <sreg or *addr>\n");
+ OS::PrintErr("printfloat <sreg or *addr>\n");
}
} else if ((strcmp(cmd, "pd") == 0) ||
(strcmp(cmd, "printdouble") == 0)) {
@@ -463,13 +463,13 @@
double dvalue;
if (GetDValue(arg1, &dvalue)) {
uint64_t long_value = bit_cast<uint64_t, double>(dvalue);
- OS::Print("%s: %llu 0x%llx %.8g\n", arg1, long_value, long_value,
- dvalue);
+ OS::PrintErr("%s: %llu 0x%llx %.8g\n", arg1, long_value, long_value,
+ dvalue);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printdouble <dreg or *addr>\n");
+ OS::PrintErr("printdouble <dreg or *addr>\n");
}
} else if ((strcmp(cmd, "po") == 0) ||
(strcmp(cmd, "printobject") == 0)) {
@@ -479,20 +479,20 @@
if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
GetValue(arg1, &value)) {
if (Isolate::Current()->heap()->Contains(value)) {
- OS::Print("%s: \n", arg1);
+ OS::PrintErr("%s: \n", arg1);
#if defined(DEBUG)
const Object& obj =
Object::Handle(reinterpret_cast<RawObject*>(value));
obj.Print();
#endif // defined(DEBUG)
} else {
- OS::Print("0x%x is not an object reference\n", value);
+ OS::PrintErr("0x%x is not an object reference\n", value);
}
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printobject <*reg or *addr>\n");
+ OS::PrintErr("printobject <*reg or *addr>\n");
}
} else if (strcmp(cmd, "disasm") == 0) {
uint32_t start = 0;
@@ -505,8 +505,9 @@
// No length parameter passed, assume 10 instructions.
if (Simulator::IsIllegalAddress(start)) {
// If start isn't a valid address, warn and use PC instead.
- OS::Print("First argument yields invalid address: 0x%x\n", start);
- OS::Print("Using PC instead\n");
+ OS::PrintErr("First argument yields invalid address: 0x%x\n",
+ start);
+ OS::PrintErr("Using PC instead\n");
start = sim_->get_pc();
}
end = start + (10 * Instr::kInstrSize);
@@ -516,8 +517,9 @@
if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
if (Simulator::IsIllegalAddress(start)) {
// If start isn't a valid address, warn and use PC instead.
- OS::Print("First argument yields invalid address: 0x%x\n", start);
- OS::Print("Using PC instead\n");
+ OS::PrintErr("First argument yields invalid address: 0x%x\n",
+ start);
+ OS::PrintErr("Using PC instead\n");
start = sim_->get_pc();
}
end = start + (length * Instr::kInstrSize);
@@ -527,63 +529,63 @@
if (FLAG_support_disassembler) {
Disassembler::Disassemble(start, end);
} else {
- OS::Print("Disassembler not supported in this mode.\n");
+ OS::PrintErr("Disassembler not supported in this mode.\n");
}
} else {
- OS::Print("disasm [<address> [<number_of_instructions>]]\n");
+ OS::PrintErr("disasm [<address> [<number_of_instructions>]]\n");
}
} else if (strcmp(cmd, "gdb") == 0) {
- OS::Print("relinquishing control to gdb\n");
+ OS::PrintErr("relinquishing control to gdb\n");
OS::DebugBreak();
- OS::Print("regaining control from gdb\n");
+ OS::PrintErr("regaining control from gdb\n");
} else if (strcmp(cmd, "break") == 0) {
if (args == 2) {
uint32_t addr;
if (GetValue(arg1, &addr)) {
if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
- OS::Print("setting breakpoint failed\n");
+ OS::PrintErr("setting breakpoint failed\n");
}
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("break <addr>\n");
+ OS::PrintErr("break <addr>\n");
}
} else if (strcmp(cmd, "del") == 0) {
if (!DeleteBreakpoint(NULL)) {
- OS::Print("deleting breakpoint failed\n");
+ OS::PrintErr("deleting breakpoint failed\n");
}
} else if (strcmp(cmd, "flags") == 0) {
- OS::Print("APSR: ");
- OS::Print("N flag: %d; ", sim_->n_flag_);
- OS::Print("Z flag: %d; ", sim_->z_flag_);
- OS::Print("C flag: %d; ", sim_->c_flag_);
- OS::Print("V flag: %d\n", sim_->v_flag_);
- OS::Print("FPSCR: ");
- OS::Print("N flag: %d; ", sim_->fp_n_flag_);
- OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
- OS::Print("C flag: %d; ", sim_->fp_c_flag_);
- OS::Print("V flag: %d\n", sim_->fp_v_flag_);
+ OS::PrintErr("APSR: ");
+ OS::PrintErr("N flag: %d; ", sim_->n_flag_);
+ OS::PrintErr("Z flag: %d; ", sim_->z_flag_);
+ OS::PrintErr("C flag: %d; ", sim_->c_flag_);
+ OS::PrintErr("V flag: %d\n", sim_->v_flag_);
+ OS::PrintErr("FPSCR: ");
+ OS::PrintErr("N flag: %d; ", sim_->fp_n_flag_);
+ OS::PrintErr("Z flag: %d; ", sim_->fp_z_flag_);
+ OS::PrintErr("C flag: %d; ", sim_->fp_c_flag_);
+ OS::PrintErr("V flag: %d\n", sim_->fp_v_flag_);
} else if (strcmp(cmd, "unstop") == 0) {
intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
stop_instr->SetInstructionBits(Instr::kNopInstruction);
} else {
- OS::Print("Not at debugger stop.\n");
+ OS::PrintErr("Not at debugger stop.\n");
}
} else if (strcmp(cmd, "trace") == 0) {
if (FLAG_trace_sim_after == ULLONG_MAX) {
FLAG_trace_sim_after = sim_->get_icount();
- OS::Print("execution tracing on\n");
+ OS::PrintErr("execution tracing on\n");
} else {
FLAG_trace_sim_after = ULLONG_MAX;
- OS::Print("execution tracing off\n");
+ OS::PrintErr("execution tracing off\n");
}
} else if (strcmp(cmd, "bt") == 0) {
PrintBacktrace();
} else {
- OS::Print("Unknown command: %s\n", cmd);
+ OS::PrintErr("Unknown command: %s\n", cmd);
}
}
delete[] line;
@@ -605,7 +607,7 @@
char line_buf[256];
intptr_t offset = 0;
bool keep_going = true;
- OS::Print("%s", prompt);
+ OS::PrintErr("%s", prompt);
while (keep_going) {
if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
// fgets got an error. Just give up.
@@ -1059,8 +1061,8 @@
// Unsupported instructions use Format to print an error and stop execution.
void Simulator::Format(Instr* instr, const char* format) {
- OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
- format);
+ OS::PrintErr("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
+ format);
UNIMPLEMENTED();
}
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 020321c..51ac7bb 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -122,7 +122,7 @@
SimulatorDebugger::~SimulatorDebugger() {}
void SimulatorDebugger::Stop(Instr* instr, const char* message) {
- OS::Print("Simulator hit %s\n", message);
+ OS::PrintErr("Simulator hit %s\n", message);
Debug();
}
@@ -280,7 +280,7 @@
if (token_pos.IsReal()) {
script.GetTokenLocation(token_pos, &line, &column);
}
- OS::Print(
+ OS::PrintErr(
"pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc,
fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
func_name.ToCString(), url.ToCString(), line, column);
@@ -325,13 +325,13 @@
GetApproximateTokenIndex(code, frame->pc()),
code.is_optimized(), false);
} else {
- OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
- frame->pc(), frame->fp(), frame->sp(),
- frame->IsEntryFrame()
- ? "entry"
- : frame->IsExitFrame()
- ? "exit"
- : frame->IsStubFrame() ? "stub" : "invalid");
+ OS::PrintErr("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
+ frame->pc(), frame->fp(), frame->sp(),
+ frame->IsEntryFrame()
+ ? "entry"
+ : frame->IsExitFrame()
+ ? "exit"
+ : frame->IsStubFrame() ? "stub" : "invalid");
}
frame = frames.NextFrame();
}
@@ -400,12 +400,12 @@
if (last_pc != sim_->get_pc()) {
last_pc = sim_->get_pc();
if (Simulator::IsIllegalAddress(last_pc)) {
- OS::Print("pc is out of bounds: 0x%" Px "\n", last_pc);
+ OS::PrintErr("pc is out of bounds: 0x%" Px "\n", last_pc);
} else {
if (FLAG_support_disassembler) {
Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
} else {
- OS::Print("Disassembler not supported in this mode.\n");
+ OS::PrintErr("Disassembler not supported in this mode.\n");
}
}
}
@@ -421,7 +421,7 @@
"%" XSTR(ARG_SIZE) "s",
cmd, arg1, arg2);
if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
- OS::Print(
+ OS::PrintErr(
"c/cont -- continue execution\n"
"disasm -- disassemble instrs at current pc location\n"
" other variants are:\n"
@@ -444,7 +444,7 @@
"unstop -- if current pc is a stop instr make it a nop\n"
"q/quit -- Quit the debugger and exit the program\n");
} else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
- OS::Print("Quitting\n");
+ OS::PrintErr("Quitting\n");
OS::Exit(0);
} else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
@@ -458,26 +458,26 @@
uint64_t value;
if (strcmp(arg1, "icount") == 0) {
value = sim_->get_icount();
- OS::Print("icount: %" Pu64 " 0x%" Px64 "\n", value, value);
+ OS::PrintErr("icount: %" Pu64 " 0x%" Px64 "\n", value, value);
} else if (GetValue(arg1, &value)) {
- OS::Print("%s: %" Pu64 " 0x%" Px64 "\n", arg1, value, value);
+ OS::PrintErr("%s: %" Pu64 " 0x%" Px64 "\n", arg1, value, value);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("print <reg or icount or value or *addr>\n");
+ OS::PrintErr("print <reg or icount or value or *addr>\n");
}
} else if ((strcmp(cmd, "pf") == 0) || (strcmp(cmd, "printfloat") == 0)) {
if (args == 2) {
uint32_t value;
if (GetSValue(arg1, &value)) {
float svalue = bit_cast<float, uint32_t>(value);
- OS::Print("%s: %d 0x%x %.8g\n", arg1, value, value, svalue);
+ OS::PrintErr("%s: %d 0x%x %.8g\n", arg1, value, value, svalue);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printfloat <vreg or *addr>\n");
+ OS::PrintErr("printfloat <vreg or *addr>\n");
}
} else if ((strcmp(cmd, "pd") == 0) ||
(strcmp(cmd, "printdouble") == 0)) {
@@ -485,13 +485,13 @@
uint64_t long_value;
if (GetDValue(arg1, &long_value)) {
double dvalue = bit_cast<double, uint64_t>(long_value);
- OS::Print("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, long_value,
- long_value, dvalue);
+ OS::PrintErr("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, long_value,
+ long_value, dvalue);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printdouble <vreg or *addr>\n");
+ OS::PrintErr("printdouble <vreg or *addr>\n");
}
} else if ((strcmp(cmd, "pq") == 0) || (strcmp(cmd, "printquad") == 0)) {
if (args == 2) {
@@ -509,17 +509,19 @@
const float sval1 = bit_cast<float, int32_t>(s1);
const float sval2 = bit_cast<float, int32_t>(s2);
const float sval3 = bit_cast<float, int32_t>(s3);
- OS::Print("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, d0, d0, dval0);
- OS::Print("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, d1, d1, dval1);
- OS::Print("%s: %d 0x%x %.8g\n", arg1, s0, s0, sval0);
- OS::Print("%s: %d 0x%x %.8g\n", arg1, s1, s1, sval1);
- OS::Print("%s: %d 0x%x %.8g\n", arg1, s2, s2, sval2);
- OS::Print("%s: %d 0x%x %.8g\n", arg1, s3, s3, sval3);
+ OS::PrintErr("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, d0, d0,
+ dval0);
+ OS::PrintErr("%s: %" Pu64 " 0x%" Px64 " %.8g\n", arg1, d1, d1,
+ dval1);
+ OS::PrintErr("%s: %d 0x%x %.8g\n", arg1, s0, s0, sval0);
+ OS::PrintErr("%s: %d 0x%x %.8g\n", arg1, s1, s1, sval1);
+ OS::PrintErr("%s: %d 0x%x %.8g\n", arg1, s2, s2, sval2);
+ OS::PrintErr("%s: %d 0x%x %.8g\n", arg1, s3, s3, sval3);
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printquad <vreg or *addr>\n");
+ OS::PrintErr("printquad <vreg or *addr>\n");
}
} else if ((strcmp(cmd, "po") == 0) ||
(strcmp(cmd, "printobject") == 0)) {
@@ -529,20 +531,20 @@
if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
GetValue(arg1, &value)) {
if (Isolate::Current()->heap()->Contains(value)) {
- OS::Print("%s: \n", arg1);
+ OS::PrintErr("%s: \n", arg1);
#if defined(DEBUG)
const Object& obj =
Object::Handle(reinterpret_cast<RawObject*>(value));
obj.Print();
#endif // defined(DEBUG)
} else {
- OS::Print("0x%" Px64 " is not an object reference\n", value);
+ OS::PrintErr("0x%" Px64 " is not an object reference\n", value);
}
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("printobject <*reg or *addr>\n");
+ OS::PrintErr("printobject <*reg or *addr>\n");
}
} else if (strcmp(cmd, "disasm") == 0) {
uint64_t start = 0;
@@ -555,9 +557,10 @@
// No length parameter passed, assume 10 instructions.
if (Simulator::IsIllegalAddress(start)) {
// If start isn't a valid address, warn and use PC instead.
- OS::Print("First argument yields invalid address: 0x%" Px64 "\n",
- start);
- OS::Print("Using PC instead\n");
+ OS::PrintErr("First argument yields invalid address: 0x%" Px64
+ "\n",
+ start);
+ OS::PrintErr("Using PC instead\n");
start = sim_->get_pc();
}
end = start + (10 * Instr::kInstrSize);
@@ -567,9 +570,10 @@
if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
if (Simulator::IsIllegalAddress(start)) {
// If start isn't a valid address, warn and use PC instead.
- OS::Print("First argument yields invalid address: 0x%" Px64 "\n",
- start);
- OS::Print("Using PC instead\n");
+ OS::PrintErr("First argument yields invalid address: 0x%" Px64
+ "\n",
+ start);
+ OS::PrintErr("Using PC instead\n");
start = sim_->get_pc();
}
end = start + (length * Instr::kInstrSize);
@@ -579,58 +583,58 @@
if (FLAG_support_disassembler) {
Disassembler::Disassemble(start, end);
} else {
- OS::Print("Disassembler not supported in this mode.\n");
+ OS::PrintErr("Disassembler not supported in this mode.\n");
}
} else {
- OS::Print("disasm [<address> [<number_of_instructions>]]\n");
+ OS::PrintErr("disasm [<address> [<number_of_instructions>]]\n");
}
} else if (strcmp(cmd, "gdb") == 0) {
- OS::Print("relinquishing control to gdb\n");
+ OS::PrintErr("relinquishing control to gdb\n");
OS::DebugBreak();
- OS::Print("regaining control from gdb\n");
+ OS::PrintErr("regaining control from gdb\n");
} else if (strcmp(cmd, "break") == 0) {
if (args == 2) {
uint64_t addr;
if (GetValue(arg1, &addr)) {
if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
- OS::Print("setting breakpoint failed\n");
+ OS::PrintErr("setting breakpoint failed\n");
}
} else {
- OS::Print("%s unrecognized\n", arg1);
+ OS::PrintErr("%s unrecognized\n", arg1);
}
} else {
- OS::Print("break <addr>\n");
+ OS::PrintErr("break <addr>\n");
}
} else if (strcmp(cmd, "del") == 0) {
if (!DeleteBreakpoint(NULL)) {
- OS::Print("deleting breakpoint failed\n");
+ OS::PrintErr("deleting breakpoint failed\n");
}
} else if (strcmp(cmd, "flags") == 0) {
- OS::Print("APSR: ");
- OS::Print("N flag: %d; ", sim_->n_flag_);
- OS::Print("Z flag: %d; ", sim_->z_flag_);
- OS::Print("C flag: %d; ", sim_->c_flag_);
- OS::Print("V flag: %d\n", sim_->v_flag_);
+ OS::PrintErr("APSR: ");
+ OS::PrintErr("N flag: %d; ", sim_->n_flag_);
+ OS::PrintErr("Z flag: %d; ", sim_->z_flag_);
+ OS::PrintErr("C flag: %d; ", sim_->c_flag_);
+ OS::PrintErr("V flag: %d\n", sim_->v_flag_);
} else if (strcmp(cmd, "unstop") == 0) {
intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
if (stop_instr->IsExceptionGenOp()) {
stop_instr->SetInstructionBits(Instr::kNopInstruction);
} else {
- OS::Print("Not at debugger stop.\n");
+ OS::PrintErr("Not at debugger stop.\n");
}
} else if (strcmp(cmd, "trace") == 0) {
if (FLAG_trace_sim_after == ULLONG_MAX) {
FLAG_trace_sim_after = sim_->get_icount();
- OS::Print("execution tracing on\n");
+ OS::PrintErr("execution tracing on\n");
} else {
FLAG_trace_sim_after = ULLONG_MAX;
- OS::Print("execution tracing off\n");
+ OS::PrintErr("execution tracing off\n");
}
} else if (strcmp(cmd, "bt") == 0) {
PrintBacktrace();
} else {
- OS::Print("Unknown command: %s\n", cmd);
+ OS::PrintErr("Unknown command: %s\n", cmd);
}
}
delete[] line;
@@ -652,7 +656,7 @@
char line_buf[256];
intptr_t offset = 0;
bool keep_going = true;
- OS::Print("%s", prompt);
+ OS::PrintErr("%s", prompt);
while (keep_going) {
if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
// fgets got an error. Just give up.
@@ -1159,8 +1163,8 @@
// Unsupported instructions use Format to print an error and stop execution.
void Simulator::Format(Instr* instr, const char* format) {
- OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
- format);
+ OS::PrintErr("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
+ format);
UNIMPLEMENTED();
}
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 68ebca2..5f97708 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -391,7 +391,7 @@
str_ = String::ScrubName(str_);
cls_ = library_.LookupClassAllowPrivate(str_);
if (cls_.IsNull()) {
- OS::Print("Name of class not found %s\n", str_.ToCString());
+ OS::PrintErr("Name of class not found %s\n", str_.ToCString());
SetReadException("Invalid Class object found in message.");
}
cls_.EnsureIsFinalized(thread());
@@ -1082,7 +1082,7 @@
return true;
}
default:
- OS::Print("class id = %" Pd "\n", id);
+ OS::PrintErr("class id = %" Pd "\n", id);
break;
}
}
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index e3d9d82..cbe79e2 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -1121,7 +1121,7 @@
script ^= lib_scripts.At(i);
EXPECT(!script.IsNull());
uri = script.url();
- OS::Print("Generating source for part: %s\n", uri.ToCString());
+ OS::PrintErr("Generating source for part: %s\n", uri.ToCString());
GenerateSourceAndCheck(script);
}
}
@@ -1142,7 +1142,7 @@
lib ^= libs.At(i);
EXPECT(!lib.IsNull());
uri = lib.url();
- OS::Print("Generating source for library: %s\n", uri.ToCString());
+ OS::PrintErr("Generating source for library: %s\n", uri.ToCString());
IterateScripts(lib);
}
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index f5c5684..6facc4f 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -42,8 +42,8 @@
const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0));
const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1));
if (!expected.OperatorEquals(actual)) {
- OS::Print("expected: '%s' actual: '%s'\n", expected.ToCString(),
- actual.ToCString());
+ OS::PrintErr("expected: '%s' actual: '%s'\n", expected.ToCString(),
+ actual.ToCString());
FATAL("Expect_equals fails.\n");
}
}
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 2e8c7db..78c655e 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -676,12 +676,12 @@
intptr_t capacity = -1;
// First dump VM symbol table stats.
GetStats(Dart::vm_isolate(), &size, &capacity);
- OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size);
- OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
+ OS::PrintErr("VM Isolate: Number of symbols : %" Pd "\n", size);
+ OS::PrintErr("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
// Now dump regular isolate symbol table stats.
GetStats(isolate, &size, &capacity);
- OS::Print("Isolate: Number of symbols : %" Pd "\n", size);
- OS::Print("Isolate: Symbol table capacity : %" Pd "\n", capacity);
+ OS::PrintErr("Isolate: Number of symbols : %" Pd "\n", size);
+ OS::PrintErr("Isolate: Symbol table capacity : %" Pd "\n", capacity);
// TODO(koda): Consider recording growth and collision stats in HashTable,
// in DEBUG mode.
}
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 7f1c0d3..62d93a8 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -538,7 +538,7 @@
// False result from HandleOOBMessages signals that the isolate should
// be terminating.
if (FLAG_trace_isolates) {
- OS::Print(
+ OS::PrintErr(
"[!] Terminating isolate due to OOB message:\n"
"\tisolate: %s\n",
isolate()->name());
diff --git a/runtime/vm/thread_interrupter_fuchsia.cc b/runtime/vm/thread_interrupter_fuchsia.cc
index 375f98d..d2f19c6 100644
--- a/runtime/vm/thread_interrupter_fuchsia.cc
+++ b/runtime/vm/thread_interrupter_fuchsia.cc
@@ -37,8 +37,8 @@
class ThreadSuspendScope {
public:
explicit ThreadSuspendScope(zx_handle_t thread_handle)
- : thread_handle_(thread_handle), suspended_(true) {
- zx_status_t status = zx_task_suspend(thread_handle);
+ : thread_handle_(thread_handle), suspend_token_(ZX_HANDLE_INVALID) {
+ zx_status_t status = zx_task_suspend_token(thread_handle, &suspend_token_);
// If a thread is somewhere where suspend is impossible, zx_task_suspend()
// can return ZX_ERR_NOT_SUPPORTED.
if (status != ZX_OK) {
@@ -46,27 +46,21 @@
OS::PrintErr("ThreadInterrupter: zx_task_suspend failed: %s\n",
zx_status_get_string(status));
}
- suspended_ = false;
}
}
~ThreadSuspendScope() {
- if (suspended_) {
- zx_status_t status = zx_task_resume(thread_handle_, 0);
- if (status != ZX_OK) {
- // If we fail to resume a thread, then it's likely the program will
- // hang. Crash instead.
- FATAL1("zx_task_resume failed: %s", zx_status_get_string(status));
- }
+ if (suspend_token_ != ZX_HANDLE_INVALID) {
+ zx_handle_close(suspend_token_);
}
zx_handle_close(thread_handle_);
}
- bool suspended() const { return suspended_; }
+ bool suspended() const { return suspend_token_ != ZX_HANDLE_INVALID; }
private:
zx_handle_t thread_handle_;
- bool suspended_;
+ zx_handle_t suspend_token_; // ZX_HANDLE_INVALID when not suspended.
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ThreadSuspendScope);
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index e033319..e4155eb 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -58,7 +58,7 @@
// Check whether this attempt falls within the expected time limits.
int64_t wakeup_time = (stop - start) / kMicrosecondsPerMillisecond;
- OS::Print("wakeup_time: %" Pd64 "\n", wakeup_time);
+ OS::PrintErr("wakeup_time: %" Pd64 "\n", wakeup_time);
const int kAcceptableTimeJitter = 20; // Measured in milliseconds.
const int kAcceptableWakeupDelay = 150; // Measured in milliseconds.
if (((wait_time - kAcceptableTimeJitter) <= wakeup_time) &&
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 56b11d6..bea9fb6 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1123,7 +1123,7 @@
OS::SCreate(NULL, "%s/dart-timeline-%" Pd ".json", directory, pid);
void* file = (*file_open)(filename, true);
if (file == NULL) {
- OS::Print("Failed to write timeline file: %s\n", filename);
+ OS::PrintErr("Failed to write timeline file: %s\n", filename);
free(filename);
return;
}
@@ -1450,7 +1450,7 @@
block->Open();
head_ = block;
if (FLAG_trace_timeline) {
- OS::Print("Created new block %p\n", block);
+ OS::PrintErr("Created new block %p\n", block);
}
return head_;
}
@@ -1540,7 +1540,7 @@
OSThread* os_thread = OSThread::Current();
ASSERT(os_thread != NULL);
intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id());
- OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid);
+ OS::PrintErr("StartEvent in block %p for thread %" Px "\n", this, tid);
}
return &events_[length_++];
}
@@ -1595,7 +1595,7 @@
void TimelineEventBlock::Finish() {
if (FLAG_trace_timeline) {
- OS::Print("Finish block %p\n", this);
+ OS::PrintErr("Finish block %p\n", this);
}
in_use_ = false;
if (Service::timeline_stream.enabled()) {
diff --git a/runtime/vm/timeline_analysis.cc b/runtime/vm/timeline_analysis.cc
index 4c08d6b..cb02834 100644
--- a/runtime/vm/timeline_analysis.cc
+++ b/runtime/vm/timeline_analysis.cc
@@ -181,7 +181,7 @@
error_msg_ = zone_->VPrint(format, args);
ASSERT(error_msg_ != NULL);
if (FLAG_trace_timeline_analysis) {
- OS::Print("TimelineAnalysis error = %s\n", error_msg_);
+ OS::PrintErr("TimelineAnalysis error = %s\n", error_msg_);
}
}
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index a88106a..7e3cd7a 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -719,10 +719,10 @@
const Instructions& instructions = Instructions::Handle(code_.instructions());
uword start = instructions.PayloadStart();
if (FLAG_disassemble) {
- OS::Print("Code for test '%s' {\n", name_);
+ OS::PrintErr("Code for test '%s' {\n", name_);
uword start = instructions.PayloadStart();
Disassembler::Disassemble(start, start + assembler_->CodeSize());
- OS::Print("}\n");
+ OS::PrintErr("}\n");
}
Disassembler::Disassemble(start, start + assembler_->CodeSize(), disassembly_,
DISASSEMBLY_SIZE);
@@ -790,7 +790,7 @@
ASSERT(isolate != NULL);
const Error& error = Error::Handle(Compiler::Compile(library, script));
if (!error.IsNull()) {
- OS::Print("Error compiling test script:\n%s\n", error.ToErrorCString());
+ OS::PrintErr("Error compiling test script:\n%s\n", error.ToErrorCString());
}
return error.IsNull();
}
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index 5f0b0de..ff39c23 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -15,7 +15,6 @@
#include "platform/utils.h"
#include "vm/isolate.h"
-#include "vm/profiler.h"
namespace dart {
@@ -39,7 +38,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("munmap error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
@@ -132,7 +130,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("mprotect error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index fbcccb5..0b676c2 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -27,7 +27,7 @@
#define LOG_ERR(msg, ...) \
OS::PrintErr("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_INFO(msg, ...) \
- OS::Print("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
+ OS::PrintErr("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define LOG_ERR(msg, ...)
#define LOG_INFO(msg, ...)
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index f07eb8e..80fb7c7 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -15,7 +15,6 @@
#include "platform/utils.h"
#include "vm/isolate.h"
-#include "vm/profiler.h"
namespace dart {
@@ -39,7 +38,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("munmap error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
@@ -132,7 +130,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("mprotect error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index dbb680e..e9dcc4b 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -15,7 +15,6 @@
#include "platform/utils.h"
#include "vm/isolate.h"
-#include "vm/profiler.h"
namespace dart {
@@ -39,7 +38,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("munmap error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
@@ -132,7 +130,6 @@
int error = errno;
const int kBufferSize = 1024;
char error_buf[kBufferSize];
- NOT_IN_PRODUCT(Profiler::DumpStackTrace());
FATAL2("mprotect error: %d (%s)", error,
Utils::StrError(error, error_buf, kBufferSize));
}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 843e633..ee8e653 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -870,7 +870,8 @@
@DomName('Animation.finished')
@DocsEditable()
@Experimental() // untriaged
- final Future finished;
+ Future<Animation> get finished =>
+ promiseToFuture<Animation>(JS("", "#.finished", this));
@DomName('Animation.id')
@DocsEditable()
@@ -890,7 +891,8 @@
@DomName('Animation.ready')
@DocsEditable()
@Experimental() // untriaged
- final Future ready;
+ Future<Animation> get ready =>
+ promiseToFuture<Animation>(JS("", "#.ready", this));
@DomName('Animation.startTime')
@DocsEditable()
@@ -2118,7 +2120,8 @@
@DomName('BeforeInstallPromptEvent.userChoice')
@DocsEditable()
@Experimental() // untriaged
- final Future userChoice;
+ Future<Map<String, dynamic>> get userChoice =>
+ promiseToFutureAsMap(JS("", "#.userChoice", this));
@DomName('BeforeInstallPromptEvent.prompt')
@DocsEditable()
@@ -19387,7 +19390,8 @@
@DomName('FetchEvent.preloadResponse')
@DocsEditable()
@Experimental() // untriaged
- final Future preloadResponse;
+ Future get preloadResponse =>
+ promiseToFuture(JS("", "#.preloadResponse", this));
@DomName('FetchEvent.request')
@DocsEditable()
@@ -20108,7 +20112,8 @@
@DomName('FontFace.loaded')
@DocsEditable()
@Experimental() // untriaged
- final Future loaded;
+ Future<FontFace> get loaded =>
+ promiseToFuture<FontFace>(JS("", "#.loaded", this));
@DomName('FontFace.status')
@DocsEditable()
@@ -25820,7 +25825,7 @@
@DomName('MediaKeySession.closed')
@DocsEditable()
@Experimental() // untriaged
- final Future closed;
+ Future<void> get closed => promiseToFuture<void>(JS("", "#.closed", this));
@DomName('MediaKeySession.expiration')
@DocsEditable()
@@ -33137,7 +33142,9 @@
@DomName('PresentationReceiver.connectionList')
@DocsEditable()
@Experimental() // untriaged
- final Future connectionList;
+ Future<PresentationConnectionList> get connectionList =>
+ promiseToFuture<PresentationConnectionList>(
+ JS("", "#.connectionList", this));
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -33330,7 +33337,7 @@
@DomName('PromiseRejectionEvent.promise')
@DocsEditable()
@Experimental() // untriaged
- final Future promise;
+ Future get promise => promiseToFuture(JS("", "#.promise", this));
@DomName('PromiseRejectionEvent.reason')
@DocsEditable()
@@ -36013,7 +36020,8 @@
@DomName('ServiceWorkerContainer.ready')
@DocsEditable()
@Experimental() // untriaged
- final Future ready;
+ Future<ServiceWorkerRegistration> get ready =>
+ promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));
@DomName('ServiceWorkerContainer.getRegistration')
@DocsEditable()
diff --git a/tests/html/html.status b/tests/html/html.status
index 9fe79e4..647ae2e 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -401,7 +401,6 @@
[ $compiler == dart2js && $browser ]
custom/created_callback_test: Fail # Support for created constructor. Issue 14835
-fontface_loaded_test: Fail # Support for promises.
[ $compiler == dart2js && $browser && $csp ]
custom/element_upgrade_test: Fail # Issue 17298
@@ -522,6 +521,9 @@
custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
fontface_test: Fail # Fontface not supported on these.
+[ $compiler == dart2js && ($runtime == safari || $ie) ]
+fontface_loaded_test: Fail # Not supported on these.
+
[ $runtime == chrome && $system == macos ]
canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Skip # Times out. Please triage this failure.
diff --git a/tests/lib_2/html/fontface_loaded_test.dart b/tests/lib_2/html/fontface_loaded_test.dart
index a9334b6..7f2ebc5 100644
--- a/tests/lib_2/html/fontface_loaded_test.dart
+++ b/tests/lib_2/html/fontface_loaded_test.dart
@@ -32,22 +32,33 @@
treeSanitizer: new NullTreeSanitizer());
document.head.append(style);
- test('document fonts - temporary', () {
+ test('document fonts - temporary', () async {
var atLeastOneFont = false;
- var loaded = <Future>[];
- document.fonts.forEach((FontFace fontFace, _, __) {
+ var loaded = <Future<FontFace>>[];
+ document.fonts.forEach((FontFace fontFace, _, __) async {
atLeastOneFont = true;
- Future f1 = fontFace.loaded;
- Future f2 = fontFace.loaded;
+ var f1 = fontFace.loaded;
+ var f2 = fontFace.loaded;
loaded.add(fontFace.load());
loaded.add(f1);
loaded.add(f2);
});
expect(atLeastOneFont, isTrue);
- return Future.wait(loaded).then(expectAsync((_) {
+ return Future.wait(loaded).then(expectAsync((_) async {
document.fonts.forEach((fontFace, _, __) {
expect(fontFace.status, 'loaded');
});
+ expect(loaded.length, 3);
+ for (var loadedEntry in loaded) {
+ var fontFace = await loadedEntry;
+ expect(fontFace.status, 'loaded');
+ var fontFamily = fontFace.family;
+ if (fontFamily.startsWith('"')) {
+ // FF wraps family in quotes - remove the quotes.
+ fontFamily = fontFamily.substring(1, fontFamily.length - 1);
+ }
+ expect(fontFamily, 'Ahem');
+ }
}));
});
}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index e3b55be..ca9b2be 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -186,6 +186,7 @@
html/fileapi_supported_throws_test: RuntimeError
html/filereader_test: RuntimeError
html/filteredelementlist_test: RuntimeError
+html/fontface_loaded_test: RuntimeError
html/fontface_test: RuntimeError
html/form_data_test: RuntimeError
html/form_element_test: RuntimeError
@@ -339,7 +340,6 @@
collection/list_test: RuntimeError
[ $compiler == dart2js && $runtime != d8 && $runtime != jsshell ]
-html/fontface_loaded_test: RuntimeError
html/html_mock_test: RuntimeError # Issue 31038
html/input_element_attributes_test: RuntimeError
html/js_dart_functions_test: RuntimeError # does not implement Dart 2 implicit `.call` tearoff
@@ -462,6 +462,7 @@
html/element_types_shadow_test: RuntimeError # Issue 29922
html/file_sample_test: Skip # FileSystem not supported on Safari.
html/fileapi_supported_throws_test: Skip # FileSystem not supported on Safari
+html/fontface_loaded_test: RuntimeError # FontFace polyfill?
html/js_mock_test: RuntimeError # Issue 32286
html/storage_promise_test: RuntimeError # Not supported on Safari
html/xhr_test: RuntimeError
@@ -474,7 +475,6 @@
[ $compiler == dart2js && $browser ]
html/custom/created_callback_test: RuntimeError
-html/fontface_loaded_test: Fail # Support for promises.
html/js_typed_interop_lazy_test/01: RuntimeError
html/notification_permission_test: Timeout, Pass # Issue 32002
html/private_extension_member_test: RuntimeError
@@ -688,7 +688,6 @@
[ $compiler == dart2js && $fasta && $host_checked ]
html/custom/mirrors_2_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
html/custom/mirrors_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-html/fontface_loaded_test: RuntimeError # TypeError: Cannot read property 'createFragment$3$treeSanitizer$validator' of undefined
html/indexeddb_3_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
html/indexeddb_5_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
html/js_array_test: CompileTimeError
@@ -725,7 +724,6 @@
html/event_customevent_test: RuntimeError
html/file_sample_test: RuntimeError
html/fileapi_entry_test: RuntimeError
-html/fontface_loaded_test: RuntimeError
html/indexeddb_1_test/functional: RuntimeError
html/indexeddb_2_test: RuntimeError
html/indexeddb_3_test: RuntimeError
@@ -791,3 +789,6 @@
html/custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Polyfill does not support
html/custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
html/fontface_test: Fail # Fontface not supported on these.
+
+[ $compiler == dart2js && ($runtime == safari || $ie) ]
+html/fontface_loaded_test: RuntimeError # FontFace polyfill?
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index bbfa3a4..db43afe 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -82,7 +82,6 @@
html/custom_elements_test: Skip # Issue 29922
html/deferred_multi_app_htmltest: Skip # Issue 29919
html/element_classes_test: RuntimeError # Issue 29922
-html/fontface_loaded_test: RuntimeError
html/isolates_test: RuntimeError # Issue 29922
html/js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue 29922
html/js_typed_interop_side_cast_exp_test/01: RuntimeError # Requires --experimental-trust-js-interop-type-annotations flag.
diff --git a/tests/standalone_2/io/code_collection_test.dart b/tests/standalone_2/io/code_collection_test.dart
index 1ee3b4f..99344df 100644
--- a/tests/standalone_2/io/code_collection_test.dart
+++ b/tests/standalone_2/io/code_collection_test.dart
@@ -12,7 +12,7 @@
x = x + 1;
// Print marker message while foo is on the stack so the code cannot be
// collected.
- print("foo=$x");
+ stderr.write("foo=$x\n");
return x;
}
@@ -56,7 +56,7 @@
if (arguments.contains("--run")) {
doTest();
} else {
- // Run the test and capture stdout.
+ // Run the test and capture stderr.
var args = packageOptions();
args.addAll([
"--verbose-gc",
@@ -72,13 +72,13 @@
Expect.equals(0, pr.exitCode);
- // Code drops are logged with --log-code-drop. Look through stdout for the
+ // Code drops are logged with --log-code-drop. Look through stderr for the
// message that foo's code was dropped.
- print(pr.stdout);
+ print(pr.stderr);
bool saw_foo2 = false;
bool saw_detaching_foo = false;
bool saw_foo3 = false;
- pr.stdout.split("\n").forEach((line) {
+ pr.stderr.split("\n").forEach((line) {
if (line.contains("foo=2")) {
Expect.isFalse(saw_foo2, "foo=2 ran twice");
saw_foo2 = true;
diff --git a/tests/standalone_2/io/issue_30687_test.dart b/tests/standalone_2/io/issue_30687_test.dart
new file mode 100644
index 0000000..96b514d
--- /dev/null
+++ b/tests/standalone_2/io/issue_30687_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2017, 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 'dart:io';
+
+import 'package:expect/expect.dart';
+
+main() async {
+ Link link1 = new Link(
+ Directory.systemTemp.path + Platform.pathSeparator + 'link1.lnk');
+ Link link2 = new Link(
+ Directory.systemTemp.path + Platform.pathSeparator + 'link2.lnk');
+
+ Directory target1 = new Directory(
+ Directory.systemTemp.path + Platform.pathSeparator + 'target1');
+ Directory target2 = new Directory(
+ Directory.systemTemp.path + Platform.pathSeparator + 'target2');
+
+ target1.createSync();
+ target2.createSync();
+
+ Expect.isTrue(target1.existsSync());
+ Expect.isTrue(target2.existsSync());
+
+ link1.createSync(target1.path);
+ link2.createSync(target2.path);
+ Expect.isTrue(link1.existsSync());
+ Expect.isTrue(link2.existsSync());
+
+ try {
+ Link renamed = await link1.rename(link2.path);
+ Expect.isFalse(link1.existsSync());
+ Expect.isTrue(renamed.existsSync());
+ Expect.equals(renamed.path, link2.path);
+ } finally {
+ target1.delete();
+ target2.delete();
+ link2.delete();
+ if (link1.existsSync()) {
+ link1.delete();
+ }
+ }
+}
diff --git a/tests/standalone_2/io/stdio_implicit_close_script.dart b/tests/standalone_2/io/stdio_implicit_close_script.dart
index 4be58a88..2b09e2f 100644
--- a/tests/standalone_2/io/stdio_implicit_close_script.dart
+++ b/tests/standalone_2/io/stdio_implicit_close_script.dart
@@ -7,9 +7,8 @@
void main(List<String> arguments) {
// Access stdout and stderr so that the system grabs a handle to it. This
// initializes some internal structures.
- if (stdout.hashCode == -1234 && stderr.hashCode == (stderr.hashCode + 1)) {
- throw "we have other problems.";
- }
+ stdout.write("APPLE");
+ stderr.write("BANANA");
if (arguments.contains("stdout")) {
stdout.close();
diff --git a/tests/standalone_2/io/stdio_implicit_close_test.dart b/tests/standalone_2/io/stdio_implicit_close_test.dart
index 4fcd719..0df0e04 100644
--- a/tests/standalone_2/io/stdio_implicit_close_test.dart
+++ b/tests/standalone_2/io/stdio_implicit_close_test.dart
@@ -13,11 +13,7 @@
var scriptFile = "stdio_implicit_close_script.dart";
var script = Platform.script.resolve(scriptFile).toFilePath();
- // Relying on these flags to print something specific on stdout and stderr
- // is brittle, but otherwise we would need to add our own flag.
var arguments = [
- "--print-metrics", // Prints on stderr.
- "--timing", // Prints on stdout.
script,
];
if (closeStdout) arguments.add("stdout");
@@ -32,17 +28,8 @@
print(result.stderr);
Expect.equals(0, result.exitCode);
- if (closeStdout) {
- Expect.equals("", result.stdout);
- } else {
- Expect.isTrue(result.stdout.contains("Timing for"));
- }
-
- if (closeStderr) {
- Expect.equals("", result.stderr);
- } else {
- Expect.isTrue(result.stderr.contains("Printing metrics"));
- }
+ Expect.isTrue(result.stdout.contains("APPLE"));
+ Expect.isTrue(result.stderr.contains("BANANA"));
asyncEnd();
});
diff --git a/tools/VERSION b/tools/VERSION
index ffb6364..ee58962 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 62
+PRERELEASE 63
PRERELEASE_PATCH 0
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index a2be3ca..919e1bb 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -72,6 +72,9 @@
./tools/build.py --mode=release --arch=ia32 create_sdk
./tools/build.py --mode=release --arch=ia32 runtime
tar -czf linux-ia32_profile.tar.gz \
+ --exclude .git \
+ --exclude .gitignore \
+ -- \
third_party/d8/linux/ia32/natives_blob.bin \
third_party/d8/linux/ia32/snapshot_blob.bin \
out/ReleaseIA32/vm_outline.dill \
@@ -92,8 +95,7 @@
pkg \
runtime/bin \
runtime/lib \
- --exclude .git \
- --exclude .gitignore || (rm -f linux-ia32_profile.tar.gz; exit 1)
+ || (rm -f linux-ia32_profile.tar.gz; exit 1)
strip -w \
-K 'kDartVmSnapshotData' \
-K 'kDartVmSnapshotInstructions' \
@@ -171,6 +173,9 @@
-K '_ZN4dart7Version7commit_E' \
-K '_ZN4dart9Bootstrap*_paths_E' third_party/d8/linux/ia32/d8
tar -czf linux-ia32.tar.gz \
+ --exclude .git \
+ --exclude .gitignore \
+ -- \
third_party/d8/linux/ia32/natives_blob.bin \
third_party/d8/linux/ia32/snapshot_blob.bin \
out/ReleaseIA32/vm_outline.dill \
@@ -192,8 +197,7 @@
pkg \
runtime/bin \
runtime/lib \
- --exclude .git \
- --exclude .gitignore || (rm -f linux-ia32.tar.gz; exit 1)
+ || (rm -f linux-ia32.tar.gz; exit 1)
elif [ "$command" = linux-ia32-benchmark ]; then
rm -rf tmp
mkdir tmp
@@ -237,6 +241,9 @@
./tools/build.py --mode=release --arch=simdbc64 runtime
./tools/build.py --mode=release --arch=x64 runtime_kernel
tar -czf linux-x64_profile.tar.gz \
+ --exclude .git \
+ --exclude .gitignore \
+ -- \
third_party/d8/linux/x64/natives_blob.bin \
third_party/d8/linux/x64/snapshot_blob.bin \
out/ReleaseX64/vm_outline.dill \
@@ -260,8 +267,7 @@
pkg \
runtime/bin \
runtime/lib \
- --exclude .git \
- --exclude .gitignore || (rm -f linux-x64_profile.tar.gz; exit 1)
+ || (rm -f linux-x64_profile.tar.gz; exit 1)
strip -w \
-K 'kDartVmSnapshotData' \
-K 'kDartVmSnapshotInstructions' \
@@ -358,6 +364,9 @@
-K '_ZN4dart7Version7commit_E' \
-K '_ZN4dart9Bootstrap*_paths_E' out/ReleaseX64/dart_precompiled_runtime
tar -czf linux-x64.tar.gz \
+ --exclude .git \
+ --exclude .gitignore \
+ -- \
third_party/d8/linux/x64/natives_blob.bin \
third_party/d8/linux/x64/snapshot_blob.bin \
out/ReleaseX64/vm_outline.dill \
@@ -381,8 +390,7 @@
pkg \
runtime/bin \
runtime/lib \
- --exclude .git \
- --exclude .gitignore || (rm -f linux-x64.tar.gz; exit 1)
+ || (rm -f linux-x64.tar.gz; exit 1)
elif [ "$command" = linux-x64-benchmark ]; then
rm -rf tmp
mkdir tmp
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 324900c..458d810 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -771,12 +771,14 @@
parameterized Promise type.
'''
promise_attributes = monitored.Dict('systemhtml.promise_attr_type', {
- "Animation.finished": {"type": "Animation"},
- "Animation.ready": {"type": "Animation"},
- "FontFace.loaded": {"type": "FontFace"},
- "FontFaceSet.ready": {"type": "FontFaceSet"},
- "PresentationReceiver.connectionList": {"type": "PresentationConnectionList"},
- "ServiceWorkerContainer.ready": {"type": "ServiceWorkerRegistration"},
+ "Animation.finished": {"type": "Animation"},
+ "Animation.ready": {"type": "Animation"},
+ "BeforeInstallPromptEvent.userChoice": {"type": "dictionary"},
+ "FontFace.loaded": {"type": "FontFace"},
+ "FontFaceSet.ready": {"type": "FontFaceSet"},
+ "MediaKeySession.closed": {"type": "void"},
+ "PresentationReceiver.connectionList": {"type": "PresentationConnectionList"},
+ "ServiceWorkerContainer.ready": {"type": "ServiceWorkerRegistration"},
})
promise_operations = monitored.Dict('systemhtml.promise_oper_type', {
@@ -1125,6 +1127,8 @@
metadata = self._Metadata(attribute.type.id, attribute.id, output_type)
rename = self._RenamingAnnotation(attribute.id, html_name)
if not read_only:
+ if attribute.type.id == 'Promise':
+ _logger.warn('R/W member is a Promise: %s.%s' % (self._interface.id, html_name))
self._members_emitter.Emit(
'\n $RENAME$METADATA$TYPE $NAME;'
'\n',
@@ -1134,17 +1138,44 @@
TYPE=output_type)
else:
template = '\n $RENAME$(ANNOTATIONS)final $TYPE $NAME;\n'
- # Need to use a getter for list.length properties so we can add a
- # setter which throws an exception, satisfying List API.
- if self._interface_type_info.list_item_type() and html_name == 'length':
- template = ('\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
- 'JS("$TYPE", "#.$NAME", this);\n')
- self._members_emitter.Emit(
- template,
- RENAME=rename,
- ANNOTATIONS=metadata,
- NAME=html_name,
- TYPE=input_type if output_type == 'double' else output_type)
+ if attribute.type.id == 'Promise':
+ lookupOp = "%s.%s" % (self._interface.id, html_name)
+ promiseFound = _GetPromiseAttributeType(lookupOp)
+ promiseType = 'Future'
+ promiseCall = 'promiseToFuture'
+ if promiseFound is not (None):
+ if 'maplike' in promiseFound:
+ promiseCall = 'promiseToFuture<dynamic>'
+ promiseType = 'Future'
+ elif promiseFound['type'] == 'dictionary':
+ # It's a dictionary so return as a Map.
+ promiseCall = 'promiseToFutureAsMap'
+ promiseType = 'Future<Map<String, dynamic>>'
+ else:
+ paramType = promiseFound['type']
+ promiseCall = 'promiseToFuture<%s>' % paramType
+ promiseType = 'Future<%s>' % paramType
+
+ template = '\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => $PROMISE_CALL(JS("", "#.$NAME", this));\n'
+
+ self._members_emitter.Emit(template,
+ RENAME=rename,
+ ANNOTATIONS=metadata,
+ TYPE=promiseType,
+ PROMISE_CALL=promiseCall,
+ NAME=html_name)
+ else:
+ # Need to use a getter for list.length properties so we can add a
+ # setter which throws an exception, satisfying List API.
+ if self._interface_type_info.list_item_type() and html_name == 'length':
+ template = ('\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
+ 'JS("$TYPE", "#.$NAME", this);\n')
+ self._members_emitter.Emit(
+ template,
+ RENAME=rename,
+ ANNOTATIONS=metadata,
+ NAME=html_name,
+ TYPE=input_type if output_type == 'double' else output_type)
def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
self._AddRenamingGetter(attribute, html_name)
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg
index 9c3f0bf..54077f3 100644
--- a/tools/infra/config/cq.cfg
+++ b/tools/infra/config/cq.cfg
@@ -12,7 +12,6 @@
dry_run_access_list: "project-dart-tryjob-access"
allow_submit_with_open_deps: true
}
- sign_cla {}
tree_status {
tree_status_url: "https://dart-status.appspot.com"
}
diff --git a/utils/compile_platform.gni b/utils/compile_platform.gni
index 5158a53..9c157b7 100644
--- a/utils/compile_platform.gni
+++ b/utils/compile_platform.gni
@@ -14,17 +14,36 @@
_dart_root = get_path_info("..", "abspath")
template("compile_platform") {
- assert(defined(invoker.sources), "Need 'sources' in $target_name")
+ assert(defined(invoker.libraries_specification_uri),
+ "Need 'libraries_specification_uri' in $target_name")
assert(defined(invoker.outputs), "Need 'outputs' in $target_name")
assert(defined(invoker.args), "Need 'args' in $target_name")
+ if (defined(invoker.single_root_scheme)) {
+ assert(defined(invoker.single_root_base),
+ "Need 'single_root_base' in $target_name")
+ }
+ if (defined(invoker.single_root_base)) {
+ assert(defined(invoker.single_root_scheme),
+ "Need 'single_root_scheme' in $target_name")
+ }
assert(!defined(invoker.script), "Remove 'script' from $target_name")
assert(!defined(invoker.depfile), "Remove 'depfile' from $target_name")
+ # In order to automatically compute dependencies, we need to add a dependency
+ # on vm_outline.dill. This is used to include the source code of Fasta itself
+ # in the dependency file. Without this, a change to Fasta wouldn't cause the
+ # platform dill files to be rebuilt. However, when building
+ # vm_outline_strong.dill, we shouldn't list it as a dependency as this would
+ # lead to cyclic dependencies.
+ add_implicit_vm_platform_dependency = true
+ if (defined(invoker.add_implicit_vm_platform_dependency)) {
+ add_implicit_vm_platform_dependency =
+ invoker.add_implicit_vm_platform_dependency
+ }
+
action(target_name) {
script = "$_dart_root/tools/compile_platform.py"
- sources = invoker.sources
-
outputs = invoker.outputs
inputs = []
@@ -39,6 +58,10 @@
inputs += invoker.inputs
}
+ if (add_implicit_vm_platform_dependency) {
+ inputs += [ "$root_out_dir/vm_outline_strong.dill" ]
+ deps += [ "$_dart_root/runtime/vm:vm_platform" ]
+ }
depfile = outputs[0] + ".d"
if (_is_fuchsia) {
@@ -58,7 +81,17 @@
}
args += invoker.args
- args += rebase_path(sources, root_build_dir)
+ if (defined(invoker.single_root_scheme)) {
+ args += ["--single-root-scheme=" + invoker.single_root_scheme]
+ }
+ if (defined(invoker.single_root_base)) {
+ args += ["--single-root-base=" + invoker.single_root_base]
+ }
+ if (defined(invoker.single_root_scheme)) {
+ args += [invoker.libraries_specification_uri]
+ } else {
+ args += [rebase_path(invoker.libraries_specification_uri, root_build_dir)]
+ }
args += rebase_path(outputs, root_build_dir)
}
}
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index fbc9258..c94d732 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -76,9 +76,9 @@
}
compile_platform("compile_dart2js_platform") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ single_root_scheme = "org-dartlang-sdk"
+ single_root_base = "../../"
+ libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
outputs = [
"$root_out_dir/dart2js_platform.dill",
@@ -92,9 +92,9 @@
}
compile_platform("compile_dart2js_platform_strong") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ single_root_scheme = "org-dartlang-sdk"
+ single_root_base = "../../"
+ libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
outputs = [
"$root_out_dir/dart2js_platform_strong.dill",
@@ -109,9 +109,9 @@
}
compile_platform("compile_dart2js_server_platform") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ single_root_scheme = "org-dartlang-sdk"
+ single_root_base = "../../"
+ libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
outputs = [
"$root_out_dir/dart2js_server_platform.dill",
@@ -125,9 +125,9 @@
}
compile_platform("compile_dart2js_server_platform_strong") {
- sources = [
- "../../sdk/lib/libraries.json",
- ]
+ single_root_scheme = "org-dartlang-sdk"
+ single_root_base = "../../"
+ libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
outputs = [
"$root_out_dir/dart2js_server_platform_strong.dill",