Version 1.17.0-dev.3.0
Merge commit 'c1e6aef400fd131ee8b260ef5bd90ef2aa9c9de1' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b247533..4daba9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,21 @@
`NetworkInterface.list` is supported, and `false` otherwise. Currently,
`NetworkInterface.list` is not supported on Android.
+### Tool Changes
+
+* Pub
+ * TAR files created while publishing a package on Mac OS and Linux now use a
+ more portable format.
+
+ * Errors caused by invalid arguments now print the full usage information for
+ the command.
+
+ * SDK constraints for dependency overrides are no longer considered when
+ determining the total SDK constraint for a lockfile.
+
+ * A bug has been fixed in which a lockfile was considered up-to-date when it
+ actually wasn't.
+
## 1.16.0 - 2016-04-26
### Core library changes
diff --git a/DEPS b/DEPS
index a040da2..1339596 100644
--- a/DEPS
+++ b/DEPS
@@ -30,7 +30,7 @@
# Revisions of /third_party/* dependencies.
"args_tag": "@0.13.4",
- "async_tag": "@1.9.0",
+ "async_tag": "@1.10.0",
"barback-0.13.0_rev": "@34853",
"barback-0.14.0_rev": "@36398",
"barback-0.14.1_rev": "@38525",
@@ -41,7 +41,7 @@
"charcode_tag": "@1.1.0",
"chrome_rev" : "@19997",
"cli_util_tag" : "@0.0.1+2",
- "collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
+ "collection_tag": "@1.6.0",
"convert_tag": "@1.0.0",
"crypto_tag" : "@1.1.0",
"csslib_tag" : "@0.12.0",
@@ -49,8 +49,8 @@
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.4",
"dartdoc_tag" : "@v0.9.0",
- "dev_compiler_rev": "@ec95b3c45819f4d0de847588fdaa752a8e4651fb",
- "fixnum_tag": "@0.10.4",
+ "dev_compiler_rev": "@a0557e2f76fc85a6e71fe8391d1beda69905a548",
+ "fixnum_tag": "@0.10.5",
"func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
"glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
"html_tag" : "@0.12.1+1",
@@ -62,7 +62,7 @@
"intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.0",
- "linter_rev": "@6d3bdf09b4326a411e44ff472953edd9003bc33a",
+ "linter_rev": "@ecfaed3ea52ea2b5a7d9e0a7db94cf1f92208280",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
"matcher_tag": "@0.12.0",
@@ -79,7 +79,7 @@
"pool_tag": "@1.2.1",
"protobuf_tag": "@0.5.1+1",
"pub_cache_tag": "@v0.1.0",
- "pub_rev": "@217fc8ae2bdee58ebf4b11a6fa3d49624d90c0c4",
+ "pub_rev": "@0b96a97d61673cea04f69eb47b2ef2b5b37337d3",
"pub_semver_tag": "@1.2.1",
"quiver_tag": "@0.21.4",
"resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
@@ -102,7 +102,7 @@
"typed_data_tag": "@1.1.2",
"usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
"utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
- "watcher_tag": "@0.9.7",
+ "watcher_tag": "@0.9.7+2",
"web_components_rev": "@6349e09f9118dce7ae1b309af5763745e25a9d61",
"web_socket_channel_tag": "@1.0.0",
"WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
@@ -163,7 +163,7 @@
Var("dart_root") + "/third_party/pkg/cli_util":
(Var("github_mirror") % "cli_util") + Var("cli_util_tag"),
Var("dart_root") + "/third_party/pkg/collection":
- (Var("github_mirror") % "collection") + Var("collection_rev"),
+ (Var("github_mirror") % "collection") + Var("collection_tag"),
Var("dart_root") + "/third_party/pkg/convert":
"https://github.com/dart-lang/convert.git" + Var("convert_tag"),
Var("dart_root") + "/third_party/pkg/crypto":
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 5ba7fa1..833b0ec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -9,12 +9,12 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/optype.dart';
const ASYNC = 'async';
const ASYNC_STAR = 'async*';
@@ -221,11 +221,20 @@
@override
visitForStatement(ForStatement node) {
+ // Actual: for (va^)
+ // Parsed: for (va^; ;)
+ if (node.initialization == entity && entity is SimpleIdentifier) {
+ if (_isNextTokenSynthetic(entity, TokenType.SEMICOLON)) {
+ _addSuggestion(Keyword.VAR, DART_RELEVANCE_HIGH);
+ }
+ }
+ // Actual: for (int x i^)
+ // Parsed: for (int x; i^;)
// Handle the degenerate case while typing - for (int x i^)
- if (node.condition == entity && entity is SimpleIdentifier) {
- Token entityToken = (entity as SimpleIdentifier).beginToken;
- if (entityToken.previous.isSynthetic &&
- entityToken.previous.type == TokenType.SEMICOLON) {
+ if (node.condition == entity &&
+ entity is SimpleIdentifier &&
+ node.variables != null) {
+ if (_isPreviousTokenSynthetic(entity, TokenType.SEMICOLON)) {
_addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
}
}
@@ -252,7 +261,11 @@
@override
visitIfStatement(IfStatement node) {
- if (entity == node.thenStatement) {
+ if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) {
+ // Actual: if (x i^)
+ // Parsed: if (x) i^
+ _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+ } else if (entity == node.thenStatement) {
_addStatementKeywords(node);
} else if (entity == node.condition) {
_addExpressionKeywords(node);
@@ -570,4 +583,22 @@
bool _inWhileLoop(AstNode node) =>
node.getAncestor((p) => p is WhileStatement) != null;
+
+ static bool _isNextTokenSynthetic(Object entity, TokenType type) {
+ if (entity is AstNode) {
+ Token token = entity.beginToken;
+ Token nextToken = token.next;
+ return nextToken.isSynthetic && nextToken.type == type;
+ }
+ return false;
+ }
+
+ static bool _isPreviousTokenSynthetic(Object entity, TokenType type) {
+ if (entity is AstNode) {
+ Token token = entity.beginToken;
+ Token previousToken = token.previous;
+ return previousToken.isSynthetic && previousToken.type == type;
+ }
+ return false;
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 5c10beb..b019d30 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -112,17 +112,19 @@
@override
void visitPropertyAccessorElement(PropertyAccessorElement element) {
- int relevance;
- if (element.library == containingLibrary) {
- if (element.enclosingElement is ClassElement) {
- relevance = DART_RELEVANCE_LOCAL_FIELD;
+ if (optype.includeReturnValueSuggestions) {
+ int relevance;
+ if (element.library == containingLibrary) {
+ if (element.enclosingElement is ClassElement) {
+ relevance = DART_RELEVANCE_LOCAL_FIELD;
+ } else {
+ relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+ }
} else {
- relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+ relevance = DART_RELEVANCE_DEFAULT;
}
- } else {
- relevance = DART_RELEVANCE_DEFAULT;
+ addSuggestion(element, prefix: prefix, relevance: relevance);
}
- addSuggestion(element, prefix: prefix, relevance: relevance);
}
@override
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
index e8cc82d..3ddc75d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -464,12 +464,37 @@
@override
void visitForStatement(ForStatement node) {
- optype.includeReturnValueSuggestions = true;
- optype.includeTypeNameSuggestions = true;
- optype.includeVoidReturnSuggestions = true;
- // TODO (danrubel) void return suggestions only belong after
- // the 2nd semicolon. Return value suggestions only belong after the
- // first or second semicolon.
+ var entity = this.entity;
+ if (_isEntityPrevTokenSynthetic()) {
+ // Actual: for (var v i^)
+ // Parsed: for (var i; i^;)
+ } else if (entity is Token &&
+ entity.isSynthetic &&
+ node.leftSeparator == entity) {
+ // Actual: for (String ^)
+ // Parsed: for (String; ;)
+ // ^
+ optype.includeVarNameSuggestions = true;
+ } else {
+ // for (^) {}
+ // for (Str^ str = null;) {}
+ // In theory it is possible to specify any expression in initializer,
+ // but for any practical use we need only types.
+ if (entity == node.initialization || entity == node.variables) {
+ optype.includeTypeNameSuggestions = true;
+ }
+ // for (; ^) {}
+ if (entity == node.condition) {
+ optype.includeTypeNameSuggestions = true;
+ optype.includeReturnValueSuggestions = true;
+ }
+ // for (; ; ^) {}
+ if (node.updaters.contains(entity)) {
+ optype.includeTypeNameSuggestions = true;
+ optype.includeReturnValueSuggestions = true;
+ optype.includeVoidReturnSuggestions = true;
+ }
+ }
}
@override
@@ -496,7 +521,10 @@
@override
void visitIfStatement(IfStatement node) {
- if (identical(entity, node.condition)) {
+ if (_isEntityPrevTokenSynthetic()) {
+ // Actual: if (var v i^)
+ // Parsed: if (v) i^;
+ } else if (identical(entity, node.condition)) {
optype.includeReturnValueSuggestions = true;
optype.includeTypeNameSuggestions = true;
} else if (identical(entity, node.thenStatement) ||
@@ -765,6 +793,16 @@
}
@override
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ if (entity is Token) {
+ Token token = entity;
+ if (token.isSynthetic || token.lexeme == ';') {
+ optype.includeVarNameSuggestions = true;
+ }
+ }
+ }
+
+ @override
void visitTypeArgumentList(TypeArgumentList node) {
NodeList<TypeName> arguments = node.arguments;
for (TypeName typeName in arguments) {
@@ -817,16 +855,6 @@
}
@override
- void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- if (entity is Token) {
- Token token = entity;
- if (token.isSynthetic || token.lexeme == ';') {
- optype.includeVarNameSuggestions = true;
- }
- }
- }
-
- @override
void visitVariableDeclarationStatement(VariableDeclarationStatement node) {}
@override
@@ -836,4 +864,20 @@
optype.includeTypeNameSuggestions = true;
}
}
+
+ bool _isEntityPrevToken(TokenType expectedType) {
+ Object entity = this.entity;
+ if (entity is SimpleIdentifier && entity.token.isSynthetic) {
+ return entity.token.previous.type == expectedType;
+ }
+ return false;
+ }
+
+ bool _isEntityPrevTokenSynthetic() {
+ Object entity = this.entity;
+ if (entity is AstNode && entity.beginToken.previous?.isSynthetic ?? false) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index bf5e47d..7270ac2 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -270,18 +270,22 @@
* Index declarations in the given partially resolved [unit].
*/
void indexDeclarations(CompilationUnit unit) {
- PackageIndexAssembler assembler = new PackageIndexAssembler();
- assembler.indexDeclarations(unit);
- _putUnitIndexBuilder(unit, assembler);
+ String key = _getUnitKeyForElement(unit.element);
+ if (!indexMap.containsKey(key)) {
+ PackageIndexAssembler assembler = new PackageIndexAssembler();
+ assembler.indexDeclarations(unit);
+ _putUnitIndexBuilder(key, assembler);
+ }
}
/**
* Index the given fully resolved [unit].
*/
void indexUnit(CompilationUnit unit) {
+ String key = _getUnitKeyForElement(unit.element);
PackageIndexAssembler assembler = new PackageIndexAssembler();
assembler.indexUnit(unit);
- _putUnitIndexBuilder(unit, assembler);
+ _putUnitIndexBuilder(key, assembler);
}
/**
@@ -315,13 +319,11 @@
return locations;
}
- void _putUnitIndexBuilder(
- CompilationUnit unit, PackageIndexAssembler assembler) {
+ void _putUnitIndexBuilder(String key, PackageIndexAssembler assembler) {
PackageIndexBuilder indexBuilder = assembler.assemble();
// Put the index into the map.
List<int> indexBytes = indexBuilder.toBuffer();
PackageIndex index = new PackageIndex.fromBuffer(indexBytes);
- String key = _getUnitKeyForElement(unit.element);
indexMap[key] = index;
}
}
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 9b58405..58f4aaa 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -17,9 +17,9 @@
import 'integration_test_methods.dart';
import 'protocol_matchers.dart';
-const Matcher isBool = const isInstanceOf<bool>('bool');
+const Matcher isBool = const isInstanceOf<bool>();
-const Matcher isInt = const isInstanceOf<int>('int');
+const Matcher isInt = const isInstanceOf<int>();
const Matcher isNotification = const MatchesJsonObject(
'notification', const {'event': isString},
@@ -27,7 +27,7 @@
const Matcher isObject = isMap;
-const Matcher isString = const isInstanceOf<String>('String');
+const Matcher isString = const isInstanceOf<String>();
final Matcher isResponse = new MatchesJsonObject('response', {'id': isString},
optionalFields: {'result': anything, 'error': isRequestError});
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 335a9b3..504d536 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -47,6 +47,7 @@
}
class bool extends Object {}
+
abstract class num implements Comparable<num> {
bool operator <(num other);
bool operator <=(num other);
@@ -55,12 +56,21 @@
num operator +(num other);
num operator -(num other);
num operator *(num other);
- num operator %(num other);
num operator /(num other);
+ int operator ^(int other);
+ int operator &(int other);
+ int operator |(int other);
+ int operator <<(int other);
+ int operator >>(int other);
+ int operator ~/(num other);
+ num operator %(num other);
+ int operator ~();
int toInt();
+ double toDouble();
num abs();
int round();
}
+
abstract class int extends num {
bool get isEven => false;
int operator -();
@@ -68,7 +78,36 @@
{ int radix,
int onError(String source) });
}
-class double extends num {}
+
+abstract class double extends num {
+ static const double NAN = 0.0 / 0.0;
+ static const double INFINITY = 1.0 / 0.0;
+ static const double NEGATIVE_INFINITY = -INFINITY;
+ static const double MIN_POSITIVE = 5e-324;
+ static const double MAX_FINITE = 1.7976931348623157e+308;
+
+ double remainder(num other);
+ double operator +(num other);
+ double operator -(num other);
+ double operator *(num other);
+ double operator %(num other);
+ double operator /(num other);
+ int operator ~/(num other);
+ double operator -();
+ double abs();
+ double get sign;
+ int round();
+ int floor();
+ int ceil();
+ int truncate();
+ double roundToDouble();
+ double floorToDouble();
+ double ceilToDouble();
+ double truncateToDouble();
+ external static double parse(String source,
+ [double onError(String source)]);
+}
+
class DateTime extends Object {}
class Null extends Object {}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 4547bcc..2dddbf9 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -252,9 +252,8 @@
pumpEventQueue().then((_) {
responseController.addError(new NoResponseException(request));
});
- return responseController.stream.firstWhere((response) {
- return response.id == id;
- });
+ return new Future<Response>(() =>
+ responseController.stream.firstWhere((response) => response.id == id));
}
}
@@ -297,7 +296,7 @@
return socket1;
}
- void add(T text) => controller.add(text);
+ void add(dynamic text) => controller.add(text as T);
void allowMultipleListeners() {
stream = stream.asBroadcastStream();
@@ -306,14 +305,14 @@
Future close([int code, String reason]) =>
controller.close().then((_) => twin.controller.close());
- StreamSubscription<T> listen(void onData(T event),
+ StreamSubscription<T> listen(void onData(dynamic event),
{Function onError, void onDone(), bool cancelOnError}) =>
- stream.listen(onData,
+ stream.listen((T data) => onData(data),
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
- Stream<T> where(bool test(T t)) => stream.where(test);
+ Stream<T> where(bool test(dynamic t)) => stream.where((T data) => test(data));
}
class MockSource extends StringTypedMock implements Source {
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 51125e7..84b1781 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -313,7 +313,7 @@
// The current DartCompletionRequest#resolveExpression resolves
// the world (which it should not) and causes the imported library
// to be resolved.
- assertSuggestFunction('hasLength', /* null */ 'bool');
+ assertSuggestFunction('hasLength', /* null */ 'bool');
assertNotSuggested('main');
}
@@ -779,7 +779,7 @@
// 'num',
// false,
// COMPLETION_RELEVANCE_LOW);
- assertSuggestTopLevelVar('T1', null);
+ assertNotSuggested('T1');
assertNotSuggested('_T2');
//assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
assertNotSuggested('_T4');
@@ -902,7 +902,7 @@
// 'num',
// false,
// COMPLETION_RELEVANCE_LOW);
- assertSuggestTopLevelVar('T1', null);
+ assertNotSuggested('T1');
assertNotSuggested('_T2');
//assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
assertNotSuggested('_T4');
@@ -1009,7 +1009,7 @@
// 'num',
// false,
// COMPLETION_RELEVANCE_LOW);
- assertSuggestTopLevelVar('T1', null);
+ assertNotSuggested('T1');
assertNotSuggested('_T2');
//assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
assertNotSuggested('_T4');
@@ -2155,17 +2155,35 @@
}
test_ForStatement_initializer() async {
- // SimpleIdentifier ForStatement
- addTestSource('main() {List a; for (^)}');
+ addTestSource('''
+import 'dart:math';
+main() {
+ List localVar;
+ for (^) {}
+}
+''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertNotSuggested('a');
+ assertNotSuggested('localVar');
+ assertNotSuggested('PI');
assertSuggestClass('Object');
assertSuggestClass('int');
}
+ test_ForStatement_initializer_variableName_afterType() async {
+ addTestSource('main() { for (String ^) }');
+ await computeSuggestions();
+ assertNotSuggested('int');
+ }
+
+ test_ForStatement_typing_inKeyword() async {
+ addTestSource('main() { for (var v i^) }');
+ await computeSuggestions();
+ assertNotSuggested('int');
+ }
+
test_ForStatement_updaters() async {
// SimpleIdentifier ForStatement
addTestSource('main() {for (int index = 0; index < 10; i^)}');
@@ -2347,7 +2365,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -2379,7 +2397,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -2412,7 +2430,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -2498,6 +2516,12 @@
assertNotSuggested('==');
}
+ test_IfStatement_typing_isKeyword() async {
+ addTestSource('main() { if (v i^) }');
+ await computeSuggestions();
+ assertNotSuggested('int');
+ }
+
test_ImportDirective_dart() async {
// SimpleStringLiteral ImportDirective
addTestSource('''
@@ -2644,7 +2668,7 @@
// The current DartCompletionRequest#resolveExpression resolves
// the world (which it should not) and causes the imported library
// to be resolved.
- assertSuggestTopLevelVar('T1', /* null */ 'int');
+ assertNotSuggested('T1');
assertNotSuggested('T2');
}
@@ -3304,7 +3328,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -3335,7 +3359,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -3366,7 +3390,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -3399,7 +3423,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertSuggestClass('Object');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('F1');
assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
@@ -3618,7 +3642,7 @@
// Suggested by LocalLibraryContributor
assertNotSuggested('A');
assertNotSuggested('F1');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('_d');
assertNotSuggested('z');
assertNotSuggested('m');
@@ -3658,7 +3682,7 @@
// Suggested by LocalLibraryContributor
assertNotSuggested('B');
assertNotSuggested('F1');
- assertSuggestTopLevelVar('T1', 'int');
+ assertNotSuggested('T1');
assertNotSuggested('_d');
assertNotSuggested('z');
assertNotSuggested('m');
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 2e7e48b..a52a862 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -658,6 +658,12 @@
assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
}
+ test_for_expression_in_inInitializer() async {
+ addTestSource('main() {for (int i^)}');
+ await computeSuggestions();
+ assertSuggestKeywords([]);
+ }
+
test_for_expression_init() async {
addTestSource('main() {for (int x = i^)}');
await computeSuggestions();
@@ -670,6 +676,12 @@
assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
}
+ test_for_initialization_var() async {
+ addTestSource('main() {for (^)}');
+ await computeSuggestions();
+ assertSuggestKeywords([Keyword.VAR], relevance: DART_RELEVANCE_HIGH);
+ }
+
test_function_async() async {
addTestSource('main()^');
await computeSuggestions();
@@ -858,6 +870,18 @@
pseudoKeywords: ['await', 'yield', 'yield*']);
}
+ test_if_condition_isKeyword() async {
+ addTestSource('main() { if (v i^) {} }');
+ await computeSuggestions();
+ assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+ }
+
+ test_if_condition_isKeyword2() async {
+ addTestSource('main() { if (v i^ && false) {} }');
+ await computeSuggestions();
+ assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+ }
+
test_if_expression_in_class() async {
addTestSource('class A {foo() {if (^) }}');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index a53e433..7851d49 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -60,8 +60,7 @@
assertNotSuggested('T1');
assertNotSuggested('_d');
assertNotSuggested('z');
- assertSuggestTopLevelVar('m', 'dynamic',
- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+ assertNotSuggested('m');
}
test_partFile_Constructor2() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index a61c9da..ef90952 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -2170,7 +2170,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestLocalVariable('a', 'List');
+ assertNotSuggested('a');
assertNotSuggested('Object');
assertNotSuggested('int');
}
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
index f5c89bb..9a6982b6 100644
--- a/pkg/analysis_server/test/services/completion/dart/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -99,6 +99,19 @@
assertOpType(namedArgs: true, returnValue: true, typeNames: true);
}
+ test_ArgumentList_namedParam() {
+ // SimpleIdentifier NamedExpression ArgumentList MethodInvocation
+ // ExpressionStatement
+ addTestSource('void main() {expect(foo: ^)}');
+ assertOpType(returnValue: true, typeNames: true);
+ }
+
+ test_ArgumentList_prefixedIdentifier() {
+ // SimpleIdentifier PrefixedIdentifier ArgumentList
+ addTestSource('void main() {expect(aa.^)}');
+ assertOpType(returnValue: true, typeNames: true, prefixed: true);
+ }
+
test_ArgumentList_resolved() {
// ArgumentList MethodInvocation ExpressionStatement Block
addTestSource('void main() {int.parse(^)}', resolved: true);
@@ -123,19 +136,6 @@
assertOpType(namedArgs: true);
}
- test_ArgumentList_namedParam() {
- // SimpleIdentifier NamedExpression ArgumentList MethodInvocation
- // ExpressionStatement
- addTestSource('void main() {expect(foo: ^)}');
- assertOpType(returnValue: true, typeNames: true);
- }
-
- test_ArgumentList_prefixedIdentifier() {
- // SimpleIdentifier PrefixedIdentifier ArgumentList
- addTestSource('void main() {expect(aa.^)}');
- assertOpType(returnValue: true, typeNames: true, prefixed: true);
- }
-
test_AsExpression() {
// SimpleIdentifier TypeName AsExpression
addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
@@ -668,15 +668,29 @@
test_ForStatement_condition() {
// SimpleIdentifier ForStatement
addTestSource('main() {for (int index = 0; i^)}');
- // TODO (danrubel) may want to exclude methods/functions with void return
- assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+ assertOpType(returnValue: true, typeNames: true);
}
test_ForStatement_initializer() {
// SimpleIdentifier ForStatement
addTestSource('main() {List a; for (^)}');
- // TODO (danrubel) may want to exclude methods/functions with void return
- assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+ assertOpType(typeNames: true);
+ }
+
+ test_ForStatement_initializer_inKeyword() {
+ addTestSource('main() { for (var v i^) }');
+ assertOpType();
+ }
+
+ test_ForStatement_initializer_type() {
+ // SimpleIdentifier ForStatement
+ addTestSource('main() {List a; for (i^ v = 0;)}');
+ assertOpType(typeNames: true);
+ }
+
+ test_ForStatement_initializer_variableNameEmpty_afterType() {
+ addTestSource('main() { for (String ^) }');
+ assertOpType(varNames: true);
}
test_ForStatement_updaters() {
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
index a99d34a..5a1f093 100644
--- a/pkg/analysis_server/test/services/index/index_test.dart
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -248,6 +248,28 @@
findLocationTest(locations, 'test();', false);
}
+ test_indexDeclarations_afterIndexUnit() async {
+ resolveTestUnit('''
+var a = 0;
+var b = a + 1;
+''');
+ index.indexUnit(testUnit);
+ TopLevelVariableElement a = findElement('a');
+ // We can find references.
+ {
+ List<Location> locations = await index.getRelations(
+ a.getter, IndexRelationKind.IS_REFERENCED_BY);
+ findLocationTest(locations, 'a + 1', false);
+ }
+ // Attempt to index just declarations - we still can find references.
+ index.indexDeclarations(testUnit);
+ {
+ List<Location> locations = await index.getRelations(
+ a.getter, IndexRelationKind.IS_REFERENCED_BY);
+ findLocationTest(locations, 'a + 1', false);
+ }
+ }
+
test_indexDeclarations_nullUnit() async {
index.indexDeclarations(null);
}
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index ffdfd4c..b67ce1a 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -36,8 +36,9 @@
this.range = new SourceRange(offset, length);
}
- bool operator ==(SearchMatch match) {
- return match.element == this.element &&
+ bool operator ==(Object match) {
+ return match is SearchMatch &&
+ match.element == this.element &&
match.kind == this.kind &&
match.isResolved == this.isResolved &&
match.isQualified == this.isQualified &&
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 89be5a5..c33b26d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -4579,16 +4579,22 @@
NodeList<Combinator> combinators1 = import1.combinators;
List<String> allHides1 = new List<String>();
List<String> allShows1 = new List<String>();
- for (Combinator combinator in combinators1) {
+ int length1 = combinators1.length;
+ for (int i = 0; i < length1; i++) {
+ Combinator combinator = combinators1[i];
if (combinator is HideCombinator) {
NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
- for (SimpleIdentifier simpleIdentifier in hides) {
+ int hideLength = hides.length;
+ for (int j = 0; j < hideLength; j++) {
+ SimpleIdentifier simpleIdentifier = hides[j];
allHides1.add(simpleIdentifier.name);
}
} else {
NodeList<SimpleIdentifier> shows =
(combinator as ShowCombinator).shownNames;
- for (SimpleIdentifier simpleIdentifier in shows) {
+ int showLength = shows.length;
+ for (int j = 0; j < showLength; j++) {
+ SimpleIdentifier simpleIdentifier = shows[j];
allShows1.add(simpleIdentifier.name);
}
}
@@ -4596,16 +4602,22 @@
NodeList<Combinator> combinators2 = import2.combinators;
List<String> allHides2 = new List<String>();
List<String> allShows2 = new List<String>();
- for (Combinator combinator in combinators2) {
+ int length2 = combinators2.length;
+ for (int i = 0; i < length2; i++) {
+ Combinator combinator = combinators2[i];
if (combinator is HideCombinator) {
NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
- for (SimpleIdentifier simpleIdentifier in hides) {
+ int hideLength = hides.length;
+ for (int j = 0; j < hideLength; j++) {
+ SimpleIdentifier simpleIdentifier = hides[j];
allHides2.add(simpleIdentifier.name);
}
} else {
NodeList<SimpleIdentifier> shows =
(combinator as ShowCombinator).shownNames;
- for (SimpleIdentifier simpleIdentifier in shows) {
+ int showLength = shows.length;
+ for (int j = 0; j < showLength; j++) {
+ SimpleIdentifier simpleIdentifier = shows[j];
allShows2.add(simpleIdentifier.name);
}
}
diff --git a/pkg/analyzer/lib/dart/ast/token.dart b/pkg/analyzer/lib/dart/ast/token.dart
index 77226be..14ba3f9 100644
--- a/pkg/analyzer/lib/dart/ast/token.dart
+++ b/pkg/analyzer/lib/dart/ast/token.dart
@@ -360,7 +360,9 @@
static Token lexicallyFirst(List<Token> tokens) {
Token first = null;
int offset = -1;
- for (Token token in tokens) {
+ int length = tokens.length;
+ for (int i = 0; i < length; i++) {
+ Token token = tokens[i];
if (token != null && (offset < 0 || token.offset < offset)) {
first = token;
offset = token.offset;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a320b8d..1a73457 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1862,6 +1862,11 @@
*/
abstract class TypeParameterizedElement implements Element {
/**
+ * The type of this element, which will be a parameterized type.
+ */
+ ParameterizedType get type;
+
+ /**
* Return a list containing all of the type parameters declared by this
* element directly. This does not include type parameters that are declared
* by any enclosing elements.
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 803137d..307e1d9 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -248,7 +248,7 @@
}
@override
- Future catchError(Function onError, {bool test(Object error)}) =>
+ Future<T> catchError(Function onError, {bool test(Object error)}) =>
_completer._outerCompleter.future.catchError(onError, test: test);
@override
@@ -284,7 +284,7 @@
void cancel() {}
@override
- Future catchError(Function onError, {bool test(Object error)}) =>
+ Future<T> catchError(Function onError, {bool test(Object error)}) =>
_future.catchError(onError, test: test);
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index ad6c9c8..e5509f1 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -69,7 +69,9 @@
@override
void _appendStringValue(StringBuffer buffer) {
- for (StringLiteralImpl stringLiteral in strings) {
+ int length = strings.length;
+ for (int i = 0; i < length; i++) {
+ StringLiteralImpl stringLiteral = strings[i];
stringLiteral._appendStringValue(buffer);
}
}
@@ -159,8 +161,10 @@
_comment?.accept(visitor);
_metadata.accept(visitor);
} else {
- for (AstNode child in sortedCommentAndAnnotations) {
- child.accept(visitor);
+ List<AstNode> children = sortedCommentAndAnnotations;
+ int length = children.length;
+ for (int i = 0; i < length; i++) {
+ children[i].accept(visitor);
}
}
}
@@ -1837,7 +1841,9 @@
@override
ConstructorDeclaration getConstructor(String name) {
- for (ClassMember classMember in _members) {
+ int length = _members.length;
+ for (int i = 0; i < length; i++) {
+ ClassMember classMember = _members[i];
if (classMember is ConstructorDeclaration) {
ConstructorDeclaration constructor = classMember;
SimpleIdentifier constructorName = constructor.name;
@@ -1854,12 +1860,16 @@
@override
VariableDeclaration getField(String name) {
- for (ClassMember classMember in _members) {
+ int memberLength = _members.length;
+ for (int i = 0; i < memberLength; i++) {
+ ClassMember classMember = _members[i];
if (classMember is FieldDeclaration) {
FieldDeclaration fieldDeclaration = classMember;
NodeList<VariableDeclaration> fields =
fieldDeclaration.fields.variables;
- for (VariableDeclaration field in fields) {
+ int fieldLength = fields.length;
+ for (int i = 0; i < fieldLength; i++) {
+ VariableDeclaration field = fields[i];
SimpleIdentifier fieldName = field.name;
if (fieldName != null && name == fieldName.name) {
return field;
@@ -1872,7 +1882,9 @@
@override
MethodDeclaration getMethod(String name) {
- for (ClassMember classMember in _members) {
+ int length = _members.length;
+ for (int i = 0; i < length; i++) {
+ ClassMember classMember = _members[i];
if (classMember is MethodDeclaration) {
MethodDeclaration method = classMember;
SimpleIdentifier methodName = method.name;
@@ -2426,7 +2438,9 @@
_directives.accept(visitor);
_declarations.accept(visitor);
} else {
- for (AstNode child in sortedDirectivesAndDeclarations) {
+ int length = sortedDirectivesAndDeclarations.length;
+ for (int i = 0; i < length; i++) {
+ AstNode child = sortedDirectivesAndDeclarations[i];
child.accept(visitor);
}
}
@@ -4671,7 +4685,9 @@
// TODO(paulberry): include commas.
ChildEntities result = new ChildEntities()..add(leftParenthesis);
bool leftDelimiterNeeded = leftDelimiter != null;
- for (FormalParameter parameter in _parameters) {
+ int length = _parameters.length;
+ for (int i = 0; i < length; i++) {
+ FormalParameter parameter = _parameters[i];
if (leftDelimiterNeeded && leftDelimiter.offset < parameter.offset) {
result.add(leftDelimiter);
leftDelimiterNeeded = false;
@@ -6676,7 +6692,9 @@
String get name {
StringBuffer buffer = new StringBuffer();
bool needsPeriod = false;
- for (SimpleIdentifier identifier in _components) {
+ int length = _components.length;
+ for (int i = 0; i < length; i++) {
+ SimpleIdentifier identifier = _components[i];
if (needsPeriod) {
buffer.write(".");
} else {
@@ -7672,9 +7690,18 @@
@override
bool addAll(Iterable<E> nodes) {
if (nodes != null && !nodes.isEmpty) {
- _elements.addAll(nodes);
- for (E node in nodes) {
- _owner._becomeParentOf(node as AstNodeImpl);
+ if (nodes is List<E>) {
+ int length = nodes.length;
+ for (int i = 0; i < length; i++) {
+ E node = nodes[i];
+ _elements.add(node);
+ _owner._becomeParentOf(node as AstNodeImpl);
+ }
+ } else {
+ for (E node in nodes) {
+ _elements.add(node);
+ _owner._becomeParentOf(node as AstNodeImpl);
+ }
}
return true;
}
@@ -7813,8 +7840,10 @@
_comment?.accept(visitor);
_metadata.accept(visitor);
} else {
- for (AstNode child in sortedCommentAndAnnotations) {
- child.accept(visitor);
+ List<AstNode> children = sortedCommentAndAnnotations;
+ int length = children.length;
+ for (int i = 0; i < length; i++) {
+ children[i].accept(visitor);
}
}
}
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 80e736b..62b3ec8 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -48,6 +48,13 @@
}
@override
+ FunctionExpression visitFunctionExpression(FunctionExpression node) {
+ FunctionExpression expression = super.visitFunctionExpression(node);
+ expression.element = node.element;
+ return expression;
+ }
+
+ @override
InstanceCreationExpression visitInstanceCreationExpression(
InstanceCreationExpression node) {
InstanceCreationExpression expression =
@@ -172,8 +179,10 @@
super.visitAnnotation(node);
ElementAnnotation elementAnnotation = node.elementAnnotation;
if (elementAnnotation == null) {
- // Analyzer ignores annotations on "part of" directives.
- assert(node.parent is PartOfDirective);
+ // Analyzer ignores annotations on "part of" directives and on enum
+ // constant declarations.
+ assert(node.parent is PartOfDirective ||
+ node.parent is EnumConstantDeclaration);
} else {
constantsToCompute.add(elementAnnotation);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2175e9e..bcac6b1 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -208,7 +208,7 @@
// Use a list to keep track of the classes we've seen, so that we won't
// go into an infinite loop in the event of a non-trivial loop in the
// class hierarchy.
- List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
+ List<ClassElement> classesSeen = <ClassElement>[this];
while (nearestNonMixinClass.isMixinApplication) {
if (classesSeen.contains(nearestNonMixinClass)) {
// Loop in the class hierarchy (which is reported elsewhere). Don't
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 7d08ca8..f2e9a15 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -24,6 +24,13 @@
typedef FunctionTypedElement FunctionTypedElementComputer();
/**
+ * Computer of type arguments which is used to delay computing of type
+ * arguments until they are requested, instead of at the [ParameterizedType]
+ * creation time.
+ */
+typedef List<DartType> TypeArgumentsComputer();
+
+/**
* A [Type] that represents the type 'bottom'.
*/
class BottomTypeImpl extends TypeImpl {
@@ -1117,7 +1124,13 @@
/**
* A list containing the actual types of the type arguments.
*/
- List<DartType> typeArguments = DartType.EMPTY_LIST;
+ List<DartType> _typeArguments = DartType.EMPTY_LIST;
+
+ /**
+ * If not `null` and [_typeArguments] is `null`, the actual type arguments
+ * should be computed (once) using this function.
+ */
+ TypeArgumentsComputer _typeArgumentsComputer;
/**
* The set of typedefs which should not be expanded when exploring this type,
@@ -1136,10 +1149,10 @@
* with the given [name] and [typeArguments].
*/
InterfaceTypeImpl.elementWithNameAndArgs(
- ClassElement element, String name, List<DartType> typeArguments)
+ ClassElement element, String name, this._typeArgumentsComputer)
: prunedTypedefs = null,
super(element, name) {
- this.typeArguments = typeArguments;
+ _typeArguments = null;
}
/**
@@ -1301,6 +1314,23 @@
}
@override
+ List<DartType> get typeArguments {
+ if (_typeArguments == null) {
+ _typeArguments = _typeArgumentsComputer();
+ _typeArgumentsComputer = null;
+ }
+ return _typeArguments;
+ }
+
+ /**
+ * Set [typeArguments].
+ */
+ void set typeArguments(List<DartType> typeArguments) {
+ _typeArguments = typeArguments;
+ _typeArgumentsComputer = null;
+ }
+
+ @override
List<TypeParameterElement> get typeParameters => element.typeParameters;
@override
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 3f449de..6bdabc9 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -262,15 +262,13 @@
} else {
resultMap = new Map<String, ExecutableElement>();
}
- ClassElement superclassElt = null;
InterfaceType supertype = classElt.supertype;
- if (supertype != null) {
- superclassElt = supertype.element;
- } else {
+ if (supertype == null) {
// classElt is Object
_classLookup[classElt] = resultMap;
return resultMap;
}
+ ClassElement superclassElt = supertype.element;
if (superclassElt != null) {
if (!visitedClasses.contains(superclassElt)) {
visitedClasses.add(superclassElt);
@@ -309,14 +307,9 @@
visitedClasses.add(mixinElement);
try {
Map<String, ExecutableElement> map =
- new Map<String, ExecutableElement>.from(
- _computeClassChainLookupMap(mixinElement, visitedClasses));
+ new Map<String, ExecutableElement>();
//
- // Substitute the super types down the hierarchy.
- //
- _substituteTypeParametersDownHierarchy(mixin, map);
- //
- // Include the members from the superclass in the resultMap.
+ // Include the members from the mixin in the resultMap.
//
_recordMapWithClassMembers(map, mixin, false);
//
@@ -608,6 +601,16 @@
*/
void _recordMapWithClassMembers(Map<String, ExecutableElement> map,
InterfaceType type, bool doIncludeAbstract) {
+ Set<InterfaceType> seenTypes = new HashSet<InterfaceType>();
+ while (type.element.isMixinApplication) {
+ List<InterfaceType> mixins = type.mixins;
+ if (!seenTypes.add(type) || mixins.isEmpty) {
+ // In the case of a circularity in the type hierarchy, just don't add
+ // any members to the map.
+ return;
+ }
+ type = mixins.last;
+ }
List<MethodElement> methods = type.methods;
for (MethodElement method in methods) {
if (method.isAccessibleIn(_library) &&
@@ -850,13 +853,8 @@
for (Map<String, ExecutableElement> lookupMap in lookupMaps) {
for (String memberName in lookupMap.keys) {
// Get the list value out of the unionMap
- List<ExecutableElement> list = unionMap[memberName];
- // If we haven't created such a map for this key yet, do create it and
- // put the list entry into the unionMap.
- if (list == null) {
- list = new List<ExecutableElement>();
- unionMap[memberName] = list;
- }
+ List<ExecutableElement> list = unionMap.putIfAbsent(
+ memberName, () => new List<ExecutableElement>());
// Fetch the entry out of this lookupMap
ExecutableElement newExecutableElementEntry = lookupMap[memberName];
if (list.isEmpty) {
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index c7b502f..724ddc5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -470,7 +470,10 @@
SimpleIdentifier prefixNode = node.prefix;
if (prefixNode != null) {
String prefixName = prefixNode.name;
- for (PrefixElement prefixElement in _definingLibrary.prefixes) {
+ List<PrefixElement> prefixes = _definingLibrary.prefixes;
+ int count = prefixes.length;
+ for (int i = 0; i < count; i++) {
+ PrefixElement prefixElement = prefixes[i];
if (prefixElement.displayName == prefixName) {
prefixNode.staticElement = prefixElement;
break;
@@ -1391,7 +1394,10 @@
Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
Element element = null;
Scope nameScope = _resolver.nameScope;
- for (ImportElement importElement in _definingLibrary.imports) {
+ List<ImportElement> imports = _definingLibrary.imports;
+ int length = imports.length;
+ for (int i = 0; i < length; i++) {
+ ImportElement importElement = imports[i];
PrefixElement prefixElement = importElement.prefix;
if (prefixElement != null) {
Identifier prefixedIdentifier = new PrefixedIdentifierImpl.temp(
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 6d2f8b9..537ca31 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5225,27 +5225,25 @@
if (type == null) {
return;
}
- // prepare ClassElement
Element element = type.element;
- if (element is ClassElement) {
+ if (element is TypeParameterizedElement) {
// prepare type parameters
- List<DartType> typeParameters = element.type.typeArguments;
- List<TypeParameterElement> boundingElts = element.typeParameters;
+ List<TypeParameterElement> parameterElements = element.typeParameters;
+ List<DartType> parameterTypes = element.type.typeArguments;
+ List<DartType> arguments = (type as ParameterizedType).typeArguments;
// iterate over each bounded type parameter and corresponding argument
NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
- List<DartType> typeArguments = (type as InterfaceType).typeArguments;
int loopThroughIndex =
- math.min(typeNameArgList.length, boundingElts.length);
-
- bool shouldSubstitute = typeArguments.length != 0 &&
- typeArguments.length == typeParameters.length;
+ math.min(typeNameArgList.length, parameterElements.length);
+ bool shouldSubstitute = arguments.length != 0 &&
+ arguments.length == parameterTypes.length;
for (int i = 0; i < loopThroughIndex; i++) {
TypeName argTypeName = typeNameArgList[i];
DartType argType = argTypeName.type;
- DartType boundType = boundingElts[i].bound;
+ DartType boundType = parameterElements[i].bound;
if (argType != null && boundType != null) {
if (shouldSubstitute) {
- boundType = boundType.substitute2(typeArguments, typeParameters);
+ boundType = boundType.substitute2(arguments, parameterTypes);
}
if (!_typeSystem.isSubtypeOf(argType, boundType)) {
ErrorCode errorCode;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 7f00554..777d130 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1060,7 +1060,8 @@
*/
static void patchTopLevelAccessors(LibraryElementImpl library) {
// Without parts getters/setters already share the same variable element.
- if (library.parts.isEmpty) {
+ List<CompilationUnitElement> parts = library.parts;
+ if (parts.isEmpty) {
return;
}
// Collect getters and setters.
@@ -1068,11 +1069,15 @@
new HashMap<String, PropertyAccessorElement>();
List<PropertyAccessorElement> setters = <PropertyAccessorElement>[];
_collectAccessors(getters, setters, library.definingCompilationUnit);
- for (CompilationUnitElement unit in library.parts) {
+ int partLength = parts.length;
+ for (int i = 0; i < partLength; i++) {
+ CompilationUnitElement unit = parts[i];
_collectAccessors(getters, setters, unit);
}
// Move every setter to the corresponding getter's variable (if exists).
- for (PropertyAccessorElement setter in setters) {
+ int setterLength = setters.length;
+ for (int j = 0; j < setterLength; j++) {
+ PropertyAccessorElement setter = setters[j];
PropertyAccessorElement getter = getters[setter.displayName];
if (getter != null) {
TopLevelVariableElementImpl variable = getter.variable;
@@ -1091,7 +1096,10 @@
*/
static void _collectAccessors(Map<String, PropertyAccessorElement> getters,
List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
- for (PropertyAccessorElement accessor in unit.accessors) {
+ List<PropertyAccessorElement> accessors = unit.accessors;
+ int length = accessors.length;
+ for (int i = 0; i < length; i++) {
+ PropertyAccessorElement accessor = accessors[i];
if (accessor.isGetter) {
if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
getters[accessor.displayName] = accessor;
@@ -1316,9 +1324,10 @@
}
}
if (reportEqualKeys) {
- for (Expression key in invalidKeys) {
+ int length = invalidKeys.length;
+ for (int i = 0; i < length; i++) {
_errorReporter.reportErrorForNode(
- StaticWarningCode.EQUAL_KEYS_IN_MAP, key);
+ StaticWarningCode.EQUAL_KEYS_IN_MAP, invalidKeys[i]);
}
}
return null;
@@ -1470,7 +1479,9 @@
* @param errorCode the error code to be used
*/
void _reportErrors(List<AnalysisError> errors, ErrorCode errorCode) {
- for (AnalysisError data in errors) {
+ int length = errors.length;
+ for (int i = 0; i < length; i++) {
+ AnalysisError data = errors[i];
ErrorCode dataErrorCode = data.errorCode;
if (identical(dataErrorCode,
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) ||
@@ -1980,7 +1991,9 @@
return null;
}
}
- for (DartType type in visitedTypes) {
+ int length = visitedTypes.length;
+ for (int j = 0; j < length; j++) {
+ DartType type = visitedTypes[j];
if (_typeSystem.isSubtypeOf(currentType, type)) {
CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
int offset = catchClause.offset;
@@ -2684,7 +2697,9 @@
Element _findWithNameAndOffset(
List<Element> elements, AstNode node, String name, int offset,
{bool required: true}) {
- for (Element element in elements) {
+ int length = elements.length;
+ for (int i = 0; i < length; i++) {
+ Element element = elements[i];
if (element.nameOffset == offset && element.name == name) {
return element;
}
@@ -2692,7 +2707,8 @@
if (!required) {
return null;
}
- for (Element element in elements) {
+ for (int i = 0; i < length; i++) {
+ Element element = elements[i];
if (element.name == name) {
_mismatch(
'Found element with name "$name" at ${element.nameOffset}, '
@@ -2853,7 +2869,9 @@
if (source == null) {
return null;
}
- for (ExportElement export in exports) {
+ int length = exports.length;
+ for (int i = 0; i < length; i++) {
+ ExportElement export = exports[i];
if (export.exportedLibrary.source == source) {
// Must have the same offset.
if (export.nameOffset != node.offset) {
@@ -2884,7 +2902,9 @@
}
SimpleIdentifier prefix = node.prefix;
bool foundSource = false;
- for (ImportElement element in imports) {
+ int length = imports.length;
+ for (int i = 0; i < length; i++) {
+ ImportElement element = imports[i];
if (element.importedLibrary.source == source) {
foundSource = true;
// Must have the same offset.
@@ -3180,7 +3200,9 @@
if (_fields == null) {
return null;
}
- for (FieldElement field in _fields) {
+ int length = _fields.length;
+ for (int i = 0; i < length; i++) {
+ FieldElement field = _fields[i];
if (field.name == fieldName) {
return field;
}
@@ -3192,7 +3214,9 @@
if (_topLevelVariables == null) {
return null;
}
- for (TopLevelVariableElement variable in _topLevelVariables) {
+ int length = _topLevelVariables.length;
+ for (int i = 0; i < length; i++) {
+ TopLevelVariableElement variable = _topLevelVariables[i];
if (variable.name == variableName) {
return variable;
}
@@ -3980,7 +4004,10 @@
// If the element is multiply defined then call this method recursively for
// each of the conflicting elements.
if (element is MultiplyDefinedElement) {
- for (Element elt in element.conflictingElements) {
+ List<Element> conflictingElements = element.conflictingElements;
+ int length = conflictingElements.length;
+ for (int i = 0; i < length; i++) {
+ Element elt = conflictingElements[i];
_visitIdentifier(identifier, elt);
}
return;
@@ -4206,7 +4233,9 @@
void generateForLibrary() {
PerformanceStatistics.hints.makeCurrentWhile(() {
- for (CompilationUnit unit in _compilationUnits) {
+ int length = _compilationUnits.length;
+ for (int i = 0; i < length; i++) {
+ CompilationUnit unit = _compilationUnits[i];
CompilationUnitElement element = unit.element;
if (element != null) {
_generateForCompilationUnit(unit, element.source);
@@ -4407,9 +4436,10 @@
* hints to
*/
void generateDuplicateImportHints(ErrorReporter errorReporter) {
- for (ImportDirective duplicateImport in _duplicateImports) {
+ int length = _duplicateImports.length;
+ for (int i = 0; i < length; i++) {
errorReporter.reportErrorForNode(
- HintCode.DUPLICATE_IMPORT, duplicateImport.uri);
+ HintCode.DUPLICATE_IMPORT, _duplicateImports[i].uri);
}
}
@@ -4422,7 +4452,9 @@
* hints
*/
void generateUnusedImportHints(ErrorReporter errorReporter) {
- for (ImportDirective unusedImport in _unusedImports) {
+ int length = _unusedImports.length;
+ for (int i = 0; i < length; i++) {
+ ImportDirective unusedImport = _unusedImports[i];
// Check that the import isn't dart:core
ImportElement importElement = unusedImport.element;
if (importElement != null) {
@@ -4452,7 +4484,9 @@
// This is then an "unused import", rather than unused shown names.
return;
}
- for (Identifier identifier in identifiers) {
+ int length = identifiers.length;
+ for (int i = 0; i < length; i++) {
+ Identifier identifier = identifiers[i];
reporter.reportErrorForNode(
HintCode.UNUSED_SHOWN_NAME, identifier, [identifier.name]);
}
@@ -4472,9 +4506,13 @@
.forEach((PrefixElement prefix, List<Element> elements) {
List<ImportDirective> importDirectives = _prefixElementMap[prefix];
if (importDirectives != null) {
- for (ImportDirective importDirective in importDirectives) {
+ int importLength = importDirectives.length;
+ for (int i = 0; i < importLength; i++) {
+ ImportDirective importDirective = importDirectives[i];
_unusedImports.remove(importDirective);
- for (Element element in elements) {
+ int elementLength = elements.length;
+ for (int j = 0; j < elementLength; j++) {
+ Element element = elements[j];
_removeFromUnusedShownNamesMap(element, importDirective);
}
}
@@ -4522,7 +4560,10 @@
if (!visitedLibraries.add(library)) {
return;
}
- for (ExportElement exportElt in library.exports) {
+ List<ExportElement> exports = library.exports;
+ int length = exports.length;
+ for (int i = 0; i < length; i++) {
+ ExportElement exportElt = exports[i];
LibraryElement exportedLibrary = exportElt.exportedLibrary;
_putIntoLibraryMap(exportedLibrary, importDirective);
_addAdditionalLibrariesForExports(
@@ -4597,7 +4638,9 @@
if (identifiers == null) {
return;
}
- for (Identifier identifier in identifiers) {
+ int length = identifiers.length;
+ for (int i = 0; i < length; i++) {
+ Identifier identifier = identifiers[i];
if (element is PropertyAccessorElement) {
// If the getter or setter of a variable is used, then the variable (the
// shown name) is used.
@@ -4821,14 +4864,18 @@
return true;
}
- for (final parent in t1.mixins) {
- if (match(parent, visited)) {
+ List<InterfaceType> mixins = t1.mixins;
+ int mixinLength = mixins.length;
+ for (int i = 0; i < mixinLength; i++) {
+ if (match(mixins[i], visited)) {
return true;
}
}
- for (final parent in t1.interfaces) {
- if (match(parent, visited)) {
+ List<InterfaceType> interfaces = t1.interfaces;
+ int interfaceLength = interfaces.length;
+ for (int j = 0; j < interfaceLength; j++) {
+ if (match(interfaces[j], visited)) {
return true;
}
}
@@ -4995,7 +5042,14 @@
void _resolveFieldDeclaration(FieldDeclaration node) {
if (!node.isStatic) {
for (VariableDeclaration field in node.fields.variables) {
- field.initializer?.accept(this);
+ if (field.initializer != null) {
+ field.initializer.accept(this);
+ FieldElement fieldElement = field.name.staticElement;
+ if (fieldElement.initializer != null) {
+ (fieldElement.initializer as ExecutableElementImpl).returnType =
+ field.initializer.staticType;
+ }
+ }
}
}
}
@@ -5158,7 +5212,9 @@
* Add all of the [variables] with initializers to [propagableVariables].
*/
void _addPropagableVariables(List<VariableDeclaration> variables) {
- for (VariableDeclaration variable in variables) {
+ int length = variables.length;
+ for (int i = 0; i < length; i++) {
+ VariableDeclaration variable = variables[i];
if (variable.name.name.isNotEmpty && variable.initializer != null) {
VariableElement element = variable.element;
if (element.isConst || element.isFinal) {
@@ -5176,7 +5232,9 @@
* refer to a field whose type was inferred.
*/
void _addStaticVariables(List<VariableDeclaration> variables) {
- for (VariableDeclaration variable in variables) {
+ int length = variables.length;
+ for (int i = 0; i < length; i++) {
+ VariableDeclaration variable = variables[i];
if (variable.name.name.isNotEmpty && variable.initializer != null) {
staticVariables.add(variable.element);
}
@@ -7388,7 +7446,9 @@
int unnamedParameterCount = 0;
List<ParameterElement> unnamedParameters = new List<ParameterElement>();
HashMap<String, ParameterElement> namedParameters = null;
- for (ParameterElement parameter in parameters) {
+ int length = parameters.length;
+ for (int i = 0; i < length; i++) {
+ ParameterElement parameter = parameters[i];
ParameterKind kind = parameter.parameterKind;
if (kind == ParameterKind.REQUIRED) {
unnamedParameters.add(parameter);
@@ -7935,9 +7995,11 @@
new CaughtException(new AnalysisException(), null));
} else {
nameScope = new EnclosedScope(nameScope);
- for (TypeParameterElement typeParameter
- in parameterElement.typeParameters) {
- nameScope.define(typeParameter);
+ List<TypeParameterElement> typeParameters =
+ parameterElement.typeParameters;
+ int length = typeParameters.length;
+ for (int i = 0; i < length; i++) {
+ nameScope.define(typeParameters[i]);
}
}
super.visitFunctionTypedFormalParameter(node);
@@ -8183,14 +8245,18 @@
}
}
List<InterfaceType> interfaceTypes = classElement.interfaces;
- for (InterfaceType interfaceType in interfaceTypes) {
+ int interfaceLength = interfaceTypes.length;
+ for (int i = 0; i < interfaceLength; i++) {
+ InterfaceType interfaceType = interfaceTypes[i];
ClassElement interfaceElement = interfaceType.element;
if (interfaceElement != null) {
_putInSubtypeMap(interfaceElement, classElement);
}
}
List<InterfaceType> mixinTypes = classElement.mixins;
- for (InterfaceType mixinType in mixinTypes) {
+ int mixinLength = mixinTypes.length;
+ for (int i = 0; i < mixinLength; i++) {
+ InterfaceType mixinType = mixinTypes[i];
ClassElement mixinElement = mixinType.element;
if (mixinElement != null) {
_putInSubtypeMap(mixinElement, classElement);
@@ -8207,7 +8273,9 @@
*/
void _computeSubtypesInCompilationUnit(CompilationUnitElement unitElement) {
List<ClassElement> classElements = unitElement.types;
- for (ClassElement classElement in classElements) {
+ int length = classElements.length;
+ for (int i = 0; i < length; i++) {
+ ClassElement classElement = classElements[i];
_computeSubtypesInClass(classElement);
}
}
@@ -8227,15 +8295,21 @@
_visitedLibraries.add(libraryElement);
_computeSubtypesInCompilationUnit(libraryElement.definingCompilationUnit);
List<CompilationUnitElement> parts = libraryElement.parts;
- for (CompilationUnitElement part in parts) {
+ int partLength = parts.length;
+ for (int i = 0; i < partLength; i++) {
+ CompilationUnitElement part = parts[i];
_computeSubtypesInCompilationUnit(part);
}
List<LibraryElement> imports = libraryElement.importedLibraries;
- for (LibraryElement importElt in imports) {
+ int importLength = imports.length;
+ for (int i = 0; i < importLength; i++) {
+ LibraryElement importElt = imports[i];
_computeSubtypesInLibrary(importElt.library);
}
List<LibraryElement> exports = libraryElement.exportedLibraries;
- for (LibraryElement exportElt in exports) {
+ int exportLength = exports.length;
+ for (int i = 0; i < exportLength; i++) {
+ LibraryElement exportElt = exports[i];
_computeSubtypesInLibrary(exportElt.library);
}
}
@@ -8718,7 +8792,9 @@
*/
InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) {
InterfaceType type = null;
- for (Element element in elements) {
+ int length = elements.length;
+ for (int i = 0; i < length; i++) {
+ Element element = elements[i];
if (element is ClassElement) {
if (type != null) {
return null;
@@ -8940,7 +9016,9 @@
* the branching, then its propagated type is reset to `null`.
*/
void mergeOverrides(List<Map<VariableElement, DartType>> perBranchOverrides) {
- for (Map<VariableElement, DartType> branch in perBranchOverrides) {
+ int length = perBranchOverrides.length;
+ for (int i = 0; i < length; i++) {
+ Map<VariableElement, DartType> branch = perBranchOverrides[i];
branch.forEach((VariableElement variable, DartType branchType) {
DartType currentType = currentScope.getType(variable);
if (currentType != branchType) {
@@ -10562,7 +10640,9 @@
factory UsedLocalElements.merge(List<UsedLocalElements> parts) {
UsedLocalElements result = new UsedLocalElements();
- for (UsedLocalElements part in parts) {
+ int length = parts.length;
+ for (int i = 0; i < length; i++) {
+ UsedLocalElements part = parts[i];
result.elements.addAll(part.elements);
result.catchExceptionElements.addAll(part.catchExceptionElements);
result.catchStackTraceElements.addAll(part.catchStackTraceElements);
@@ -10801,7 +10881,9 @@
@override
DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
Element element = node.staticElement;
- for (ParameterElement parameterElement in parameterElements) {
+ int length = parameterElements.length;
+ for (int i = 0; i < length; i++) {
+ ParameterElement parameterElement = parameterElements[i];
if (identical(parameterElement, element) && parameterElement != null) {
DartType type = parameterElement.type;
if (type != null) {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 7eb4a8b..fefd3eb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -341,14 +341,23 @@
}
ExecutableElement staticMethodElement = node.staticElement;
DartType staticType = _computeStaticReturnType(staticMethodElement);
- staticType = _refineBinaryExpressionType(node, staticType, _getStaticType);
+ staticType = _typeSystem.refineBinaryExpressionType(
+ _typeProvider,
+ node.leftOperand.staticType,
+ node.operator.type,
+ node.rightOperand.staticType,
+ staticType);
_recordStaticType(node, staticType);
MethodElement propagatedMethodElement = node.propagatedElement;
if (!identical(propagatedMethodElement, staticMethodElement)) {
DartType propagatedType =
_computeStaticReturnType(propagatedMethodElement);
- propagatedType =
- _refineBinaryExpressionType(node, propagatedType, _getBestType);
+ propagatedType = _typeSystem.refineBinaryExpressionType(
+ _typeProvider,
+ node.leftOperand.bestType,
+ node.operator.type,
+ node.rightOperand.bestType,
+ propagatedType);
_resolver.recordPropagatedTypeIfBetter(node, propagatedType);
}
return null;
@@ -1634,13 +1643,6 @@
}
/**
- * Return the best type of the given [expression].
- */
- DartType _getBestType(Expression expression) {
- return expression.bestType;
- }
-
- /**
* If the given element name can be mapped to the name of a class defined within the given
* library, return the type specified by the argument.
*
@@ -2178,50 +2180,6 @@
}
/**
- * Attempts to make a better guess for the type of the given binary
- * [expression], given that resolution has so far produced the [currentType].
- * The [typeAccessor] is used to access the corresponding type of the left
- * and right operands.
- */
- DartType _refineBinaryExpressionType(
- BinaryExpression expression, DartType currentType,
- [DartType typeAccessor(Expression node)]) {
- TokenType operator = expression.operator.type;
- // bool
- if (operator == TokenType.AMPERSAND_AMPERSAND ||
- operator == TokenType.BAR_BAR ||
- operator == TokenType.EQ_EQ ||
- operator == TokenType.BANG_EQ) {
- return _typeProvider.boolType;
- }
- DartType intType = _typeProvider.intType;
- if (typeAccessor(expression.leftOperand) == intType) {
- // int op double
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR) {
- DartType doubleType = _typeProvider.doubleType;
- if (typeAccessor(expression.rightOperand) == doubleType) {
- return doubleType;
- }
- }
- // int op int
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR ||
- operator == TokenType.TILDE_SLASH) {
- if (typeAccessor(expression.rightOperand) == intType) {
- return intType;
- }
- }
- }
- // default
- return currentType;
- }
-
- /**
* Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
* implement those tags.
*
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 526d067..877944a 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'dart:math' as math;
+import 'package:analyzer/dart/ast/token.dart' show TokenType;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -347,6 +348,39 @@
}
@override
+ DartType refineBinaryExpressionType(
+ TypeProvider typeProvider,
+ DartType leftType,
+ TokenType operator,
+ DartType rightType,
+ DartType currentType) {
+ if (leftType is TypeParameterType &&
+ leftType.element.bound == typeProvider.numType) {
+ if (rightType == leftType || rightType == typeProvider.intType) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.STAR_EQ) {
+ return leftType;
+ }
+ }
+ if (rightType == typeProvider.doubleType) {
+ if (operator == TokenType.PLUS ||
+ operator == TokenType.MINUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.SLASH) {
+ return typeProvider.doubleType;
+ }
+ }
+ return currentType;
+ }
+ return super.refineBinaryExpressionType(
+ typeProvider, leftType, operator, rightType, currentType);
+ }
+
+ @override
DartType typeToConcreteType(TypeProvider typeProvider, DartType t) {
if (t is FunctionType) {
return functionTypeToConcreteType(typeProvider, t);
@@ -942,6 +976,59 @@
}
/**
+ * Attempts to make a better guess for the type of a binary with the given
+ * [operator], given that resolution has so far produced the [currentType].
+ */
+ DartType refineBinaryExpressionType(
+ TypeProvider typeProvider,
+ DartType leftType,
+ TokenType operator,
+ DartType rightType,
+ DartType currentType) {
+ // bool
+ if (operator == TokenType.AMPERSAND_AMPERSAND ||
+ operator == TokenType.BAR_BAR ||
+ operator == TokenType.EQ_EQ ||
+ operator == TokenType.BANG_EQ) {
+ return typeProvider.boolType;
+ }
+ DartType intType = typeProvider.intType;
+ if (leftType == intType) {
+ // int op double
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ) {
+ DartType doubleType = typeProvider.doubleType;
+ if (rightType == doubleType) {
+ return doubleType;
+ }
+ }
+ // int op int
+ if (operator == TokenType.MINUS ||
+ operator == TokenType.PERCENT ||
+ operator == TokenType.PLUS ||
+ operator == TokenType.STAR ||
+ operator == TokenType.TILDE_SLASH ||
+ operator == TokenType.MINUS_EQ ||
+ operator == TokenType.PERCENT_EQ ||
+ operator == TokenType.PLUS_EQ ||
+ operator == TokenType.STAR_EQ ||
+ operator == TokenType.TILDE_SLASH_EQ) {
+ if (rightType == intType) {
+ return intType;
+ }
+ }
+ }
+ // default
+ return currentType;
+ }
+
+ /**
* Given a [DartType] type, return the [TypeParameterElement]s corresponding
* to its formal type parameters (if any).
*
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index b47ef55..9b80057 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -548,8 +548,7 @@
/**
* If this is an instantiation of a generic type or generic executable, the
- * type arguments used to instantiate it. Trailing type arguments of type
- * `dynamic` are omitted.
+ * type arguments used to instantiate it (if any).
*/
void set typeArguments(List<EntityRefBuilder> _value) {
assert(!_finished);
@@ -3538,6 +3537,7 @@
bool _finished = false;
List<UnlinkedConstBuilder> _arguments;
+ List<String> _argumentNames;
UnlinkedConstBuilder _expression;
idl.UnlinkedConstructorInitializerKind _kind;
String _name;
@@ -3555,6 +3555,19 @@
}
@override
+ List<String> get argumentNames => _argumentNames ??= <String>[];
+
+ /**
+ * If there are `m` [arguments] and `n` [argumentNames], then each argument
+ * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+ * with the name at `n + i - m`.
+ */
+ void set argumentNames(List<String> _value) {
+ assert(!_finished);
+ _argumentNames = _value;
+ }
+
+ @override
UnlinkedConstBuilder get expression => _expression;
/**
@@ -3591,8 +3604,9 @@
_name = _value;
}
- UnlinkedConstructorInitializerBuilder({List<UnlinkedConstBuilder> arguments, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
+ UnlinkedConstructorInitializerBuilder({List<UnlinkedConstBuilder> arguments, List<String> argumentNames, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
: _arguments = arguments,
+ _argumentNames = argumentNames,
_expression = expression,
_kind = kind,
_name = name;
@@ -3609,11 +3623,15 @@
assert(!_finished);
_finished = true;
fb.Offset offset_arguments;
+ fb.Offset offset_argumentNames;
fb.Offset offset_expression;
fb.Offset offset_name;
if (!(_arguments == null || _arguments.isEmpty)) {
offset_arguments = fbBuilder.writeList(_arguments.map((b) => b.finish(fbBuilder)).toList());
}
+ if (!(_argumentNames == null || _argumentNames.isEmpty)) {
+ offset_argumentNames = fbBuilder.writeList(_argumentNames.map((b) => fbBuilder.writeString(b)).toList());
+ }
if (_expression != null) {
offset_expression = _expression.finish(fbBuilder);
}
@@ -3624,6 +3642,9 @@
if (offset_arguments != null) {
fbBuilder.addOffset(3, offset_arguments);
}
+ if (offset_argumentNames != null) {
+ fbBuilder.addOffset(4, offset_argumentNames);
+ }
if (offset_expression != null) {
fbBuilder.addOffset(1, offset_expression);
}
@@ -3650,6 +3671,7 @@
_UnlinkedConstructorInitializerImpl(this._bp);
List<idl.UnlinkedConst> _arguments;
+ List<String> _argumentNames;
idl.UnlinkedConst _expression;
idl.UnlinkedConstructorInitializerKind _kind;
String _name;
@@ -3661,6 +3683,12 @@
}
@override
+ List<String> get argumentNames {
+ _argumentNames ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 4, const <String>[]);
+ return _argumentNames;
+ }
+
+ @override
idl.UnlinkedConst get expression {
_expression ??= const _UnlinkedConstReader().vTableGet(_bp, 1, null);
return _expression;
@@ -3684,6 +3712,7 @@
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
if (arguments.isNotEmpty) _result["arguments"] = arguments.map((_value) => _value.toJson()).toList();
+ if (argumentNames.isNotEmpty) _result["argumentNames"] = argumentNames;
if (expression != null) _result["expression"] = expression.toJson();
if (kind != idl.UnlinkedConstructorInitializerKind.field) _result["kind"] = kind.toString().split('.')[1];
if (name != '') _result["name"] = name;
@@ -3693,6 +3722,7 @@
@override
Map<String, Object> toMap() => {
"arguments": arguments,
+ "argumentNames": argumentNames,
"expression": expression,
"kind": kind,
"name": name,
@@ -6477,8 +6507,8 @@
/**
* If this [UnlinkedPublicName] is a class, the list of members which can be
- * referenced from constants or factory redirects - static constant fields,
- * static methods, and constructors. Otherwise empty.
+ * referenced statically - static fields, static methods, and constructors.
+ * Otherwise empty.
*
* Unnamed constructors are not included since they do not constitute a
* separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 44d5544..8df99fe 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -614,7 +614,15 @@
/**
* Pop the top value from the stack and raise an exception with this value.
*/
- throwException
+ throwException,
+
+ /**
+ * Obtain two values `n` and `m` from [UnlinkedConst.ints]. Then, starting at
+ * the executable element for the expression being evaluated, if n > 0, pop to
+ * the nth enclosing function element. Then, push the mth local function of
+ * that element onto the stack.
+ */
+ pushLocalFunctionReference
}
/**
@@ -902,8 +910,7 @@
/**
* If this is an instantiation of a generic type or generic executable, the
- * type arguments used to instantiate it. Trailing type arguments of type
- * `dynamic` are omitted.
+ * type arguments used to instantiate it (if any).
*/
typeArguments:[EntityRef] (id: 1);
}
@@ -1471,6 +1478,13 @@
arguments:[UnlinkedConst] (id: 3);
/**
+ * If there are `m` [arguments] and `n` [argumentNames], then each argument
+ * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+ * with the name at `n + i - m`.
+ */
+ argumentNames:[string] (id: 4);
+
+ /**
* If [kind] is `field`, the expression of the field initializer.
* Otherwise `null`.
*/
@@ -2021,8 +2035,8 @@
/**
* If this [UnlinkedPublicName] is a class, the list of members which can be
- * referenced from constants or factory redirects - static constant fields,
- * static methods, and constructors. Otherwise empty.
+ * referenced statically - static fields, static methods, and constructors.
+ * Otherwise empty.
*
* Unnamed constructors are not included since they do not constitute a
* separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 7992ccc..65b092d 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -202,8 +202,7 @@
/**
* If this is an instantiation of a generic type or generic executable, the
- * type arguments used to instantiate it. Trailing type arguments of type
- * `dynamic` are omitted.
+ * type arguments used to instantiate it (if any).
*/
@Id(1)
List<EntityRef> get typeArguments;
@@ -1454,6 +1453,14 @@
* Pop the top value from the stack and raise an exception with this value.
*/
throwException,
+
+ /**
+ * Obtain two values `n` and `m` from [UnlinkedConst.ints]. Then, starting at
+ * the executable element for the expression being evaluated, if n > 0, pop to
+ * the nth enclosing function element. Then, push the mth local function of
+ * that element onto the stack.
+ */
+ pushLocalFunctionReference,
}
/**
@@ -1468,6 +1475,14 @@
List<UnlinkedConst> get arguments;
/**
+ * If there are `m` [arguments] and `n` [argumentNames], then each argument
+ * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+ * with the name at `n + i - m`.
+ */
+ @Id(4)
+ List<String> get argumentNames;
+
+ /**
* If [kind] is `field`, the expression of the field initializer.
* Otherwise `null`.
*/
@@ -2287,8 +2302,8 @@
/**
* If this [UnlinkedPublicName] is a class, the list of members which can be
- * referenced from constants or factory redirects - static constant fields,
- * static methods, and constructors. Otherwise empty.
+ * referenced statically - static fields, static methods, and constructors.
+ * Otherwise empty.
*
* Unnamed constructors are not included since they do not constitute a
* separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index e68b5df..bc2fc0d 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -180,14 +180,21 @@
return result;
} else if (type is TypeParameterType) {
TypeParameterElementForLink element = type.element;
- result.paramReference =
- typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
+ if (typeParameterContext.isTypeParameterInScope(element)) {
+ result.paramReference =
+ typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
+ } else {
+ // Out-of-scope type parameters only occur in circumstances where they
+ // are irrelevant (i.e. when a type parameter is unused). So we can
+ // safely convert them to `dynamic`.
+ result.reference = compilationUnit.addRawReference('dynamic');
+ }
return result;
} else if (type is FunctionType) {
Element element = type.element;
if (element is FunctionElementForLink_FunctionTypedParam) {
result.reference =
- compilationUnit.addReference(element.innermostExecutable);
+ compilationUnit.addReference(element.typeParameterContext);
result.implicitFunctionTypeIndices = element.implicitFunctionTypeIndices;
_storeTypeArguments(
type.typeArguments, result, compilationUnit, typeParameterContext);
@@ -205,6 +212,29 @@
type.typeArguments, result, compilationUnit, typeParameterContext);
return result;
}
+ if (element is FunctionTypeAliasElementForLink) {
+ result.reference = compilationUnit.addReference(element);
+ _storeTypeArguments(
+ type.typeArguments, result, compilationUnit, typeParameterContext);
+ return result;
+ }
+ if (element is FunctionElement && element.enclosingElement == null) {
+ // Element is a synthetic function element that was generated on the fly
+ // to represent a type that has no associated source code location.
+ result.syntheticReturnType = _createLinkedType(
+ element.returnType, compilationUnit, typeParameterContext);
+ result.syntheticParams = element.parameters
+ .map((ParameterElement param) => _serializeSyntheticParam(
+ param, compilationUnit, typeParameterContext))
+ .toList();
+ return result;
+ }
+ if (element is FunctionElement) {
+ // Element is a local function inside another executable.
+ result.reference = compilationUnit.addReference(element);
+ // TODO(paulberry): do I need to store type arguments?
+ return result;
+ }
// TODO(paulberry): implement other cases.
throw new UnimplementedError('${element.runtimeType}');
}
@@ -213,10 +243,48 @@
}
/**
+ * Create an [UnlinkedParam] representing the given [parameter], which should be
+ * a parameter of a synthetic function type (e.g. one produced during type
+ * inference as a result of computing the least upper bound of two function
+ * types).
+ */
+UnlinkedParamBuilder _serializeSyntheticParam(
+ ParameterElement parameter,
+ CompilationUnitElementInBuildUnit compilationUnit,
+ TypeParameterizedElementForLink typeParameterContext) {
+ UnlinkedParamBuilder b = new UnlinkedParamBuilder();
+ b.name = parameter.name;
+ switch (parameter.parameterKind) {
+ case ParameterKind.REQUIRED:
+ b.kind = UnlinkedParamKind.required;
+ break;
+ case ParameterKind.POSITIONAL:
+ b.kind = UnlinkedParamKind.positional;
+ break;
+ case ParameterKind.NAMED:
+ b.kind = UnlinkedParamKind.named;
+ break;
+ }
+ DartType type = parameter.type;
+ if (!parameter.hasImplicitType) {
+ if (type is FunctionType && type.element.isSynthetic) {
+ b.isFunctionTyped = true;
+ b.type = _createLinkedType(
+ type.returnType, compilationUnit, typeParameterContext);
+ b.parameters = type.parameters
+ .map((parameter) => _serializeSyntheticParam(
+ parameter, compilationUnit, typeParameterContext))
+ .toList();
+ } else {
+ b.type = _createLinkedType(type, compilationUnit, typeParameterContext);
+ }
+ }
+ return b;
+}
+
+/**
* Store the given [typeArguments] in [encodedType], using [compilationUnit] and
* [typeParameterContext] to serialize them.
- *
- * Trailing arguments of type `dynamic` are dropped.
*/
void _storeTypeArguments(
List<DartType> typeArguments,
@@ -224,20 +292,13 @@
CompilationUnitElementInBuildUnit compilationUnit,
TypeParameterizedElementForLink typeParameterContext) {
int count = typeArguments.length;
- while (count > 0) {
- if (typeArguments[count - 1].isDynamic) {
- count--;
- } else {
- List<EntityRefBuilder> encodedTypeArguments =
- new List<EntityRefBuilder>(count);
- for (int i = 0; i < count; i++) {
- encodedTypeArguments[i] = _createLinkedType(
- typeArguments[i], compilationUnit, typeParameterContext);
- }
- encodedType.typeArguments = encodedTypeArguments;
- break;
- }
+ List<EntityRefBuilder> encodedTypeArguments =
+ new List<EntityRefBuilder>(count);
+ for (int i = 0; i < count; i++) {
+ encodedTypeArguments[i] = _createLinkedType(
+ typeArguments[i], compilationUnit, typeParameterContext);
}
+ encodedType.typeArguments = encodedTypeArguments;
}
/**
@@ -306,6 +367,9 @@
LibraryElementForLink get library => enclosingElement.library;
@override
+ List<MethodElementForLink> get methods;
+
+ @override
String get name;
@override
@@ -319,20 +383,16 @@
for (ConstructorElementForLink constructor in constructors) {
_containedNames[constructor.name] = constructor;
}
- for (FieldElementForLink field in fields) {
- // TODO(paulberry): do we need to handle nonstatic fields for
- // consistent behavior with erroneous code?
- if (field.isStatic) {
- _containedNames[field.name] = field;
- }
- }
for (PropertyAccessorElementForLink accessor in accessors) {
- if (accessor.isStatic && !accessor.isSynthetic) {
- // TODO(paulberry): add synthetic elements too?
+ if (accessor.isStatic) {
_containedNames[accessor.name] = accessor;
}
}
- // TODO(paulberry): add methods.
+ for (MethodElementForLink method in methods) {
+ if (method.isStatic) {
+ _containedNames[method.name] = method;
+ }
+ }
}
return _containedNames.putIfAbsent(
name, () => UndefinedElementForLink.instance);
@@ -368,16 +428,16 @@
List<MethodElementForLink> _methods;
List<InterfaceType> _mixins;
List<InterfaceType> _interfaces;
- List<PropertyAccessorElement> _accessors;
+ List<PropertyAccessorElementForLink> _accessors;
ClassElementForLink_Class(
CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
: super(enclosingElement);
@override
- List<PropertyAccessorElement> get accessors {
+ List<PropertyAccessorElementForLink> get accessors {
if (_accessors == null) {
- _accessors = <PropertyAccessorElement>[];
+ _accessors = <PropertyAccessorElementForLink>[];
Map<String, SyntheticVariableElementForLink> syntheticVariables =
<String, SyntheticVariableElementForLink>{};
for (UnlinkedExecutable unlinkedExecutable
@@ -392,7 +452,7 @@
SyntheticVariableElementForLink syntheticVariable = syntheticVariables
.putIfAbsent(name, () => new SyntheticVariableElementForLink());
PropertyAccessorElementForLink_Executable accessor =
- new PropertyAccessorElementForLink_Executable(
+ new PropertyAccessorElementForLink_Executable(enclosingElement,
this, unlinkedExecutable, syntheticVariable);
_accessors.add(accessor);
if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
@@ -403,11 +463,9 @@
}
}
for (FieldElementForLink_ClassField field in fields) {
- _accessors
- .add(new PropertyAccessorElementForLink_Variable(field, false));
+ _accessors.add(field.getter);
if (!field.isConst && !field.isFinal) {
- _accessors
- .add(new PropertyAccessorElementForLink_Variable(field, true));
+ _accessors.add(field.setter);
}
}
}
@@ -415,6 +473,9 @@
}
@override
+ CompilationUnitElementForLink get compilationUnit => enclosingElement;
+
+ @override
List<ConstructorElementForLink> get constructors {
if (_constructors == null) {
_constructors = <ConstructorElementForLink>[];
@@ -459,6 +520,9 @@
_unlinkedClass.interfaces.map(_computeInterfaceType).toList();
@override
+ bool get isMixinApplication => _unlinkedClass.isMixinApplication;
+
+ @override
bool get isObject => _unlinkedClass.hasNoSupertype;
@override
@@ -521,12 +585,13 @@
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
int numTypeParameters = _unlinkedClass.typeParameters.length;
if (numTypeParameters != 0) {
- List<DartType> typeArguments = new List<DartType>(numTypeParameters);
- for (int i = 0; i < numTypeParameters; i++) {
- typeArguments[i] = getTypeArgument(i);
- }
- return new InterfaceTypeImpl.elementWithNameAndArgs(
- this, name, typeArguments);
+ return new InterfaceTypeImpl.elementWithNameAndArgs(this, name, () {
+ List<DartType> typeArguments = new List<DartType>(numTypeParameters);
+ for (int i = 0; i < numTypeParameters; i++) {
+ typeArguments[i] = getTypeArgument(i);
+ }
+ return typeArguments;
+ });
} else {
return _type ??= new InterfaceTypeImpl(this);
}
@@ -603,15 +668,22 @@
InterfaceType _type;
List<FieldElementForLink_EnumField> _fields;
+ List<PropertyAccessorElementForLink> _accessors;
+ DartType _valuesType;
ClassElementForLink_Enum(
CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
: super(enclosingElement);
@override
- List<PropertyAccessorElement> get accessors {
- // TODO(paulberry): do we need to include synthetic accessors?
- return const [];
+ List<PropertyAccessorElementForLink> get accessors {
+ if (_accessors == null) {
+ _accessors = <PropertyAccessorElementForLink>[];
+ for (FieldElementForLink_EnumField field in fields) {
+ _accessors.add(field.getter);
+ }
+ }
+ return _accessors;
}
@override
@@ -639,7 +711,7 @@
bool get isObject => false;
@override
- List<MethodElement> get methods => const [];
+ List<MethodElementForLink> get methods => const [];
@override
List<InterfaceType> get mixins => const [];
@@ -659,6 +731,12 @@
@override
ConstructorElementForLink get unnamedConstructor => null;
+ /**
+ * Get the type of the enum's static member `values`.
+ */
+ DartType get valuesType =>
+ _valuesType ??= library._linker.typeProvider.listType.instantiate([type]);
+
@override
DartType buildType(DartType getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) =>
@@ -699,6 +777,8 @@
List<TopLevelVariableElementForLink> _topLevelVariables;
List<ClassElementForLink_Enum> _enums;
List<TopLevelFunctionElementForLink> _functions;
+ List<PropertyAccessorElementForLink> _accessors;
+ List<FunctionTypeAliasElementForLink> _functionTypeAliases;
/**
* Index of this unit in the list of units in the enclosing library.
@@ -711,6 +791,43 @@
_unlinkedUnit = unlinkedUnit;
@override
+ List<PropertyAccessorElementForLink> get accessors {
+ if (_accessors == null) {
+ _accessors = <PropertyAccessorElementForLink>[];
+ Map<String, SyntheticVariableElementForLink> syntheticVariables =
+ <String, SyntheticVariableElementForLink>{};
+ for (UnlinkedExecutable unlinkedExecutable in _unlinkedUnit.executables) {
+ if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
+ unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+ String name = unlinkedExecutable.name;
+ if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+ assert(name.endsWith('='));
+ name = name.substring(0, name.length - 1);
+ }
+ SyntheticVariableElementForLink syntheticVariable = syntheticVariables
+ .putIfAbsent(name, () => new SyntheticVariableElementForLink());
+ PropertyAccessorElementForLink_Executable accessor =
+ new PropertyAccessorElementForLink_Executable(
+ this, null, unlinkedExecutable, syntheticVariable);
+ _accessors.add(accessor);
+ if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
+ syntheticVariable._getter = accessor;
+ } else {
+ syntheticVariable._setter = accessor;
+ }
+ }
+ }
+ for (TopLevelVariableElementForLink variable in topLevelVariables) {
+ _accessors.add(variable.getter);
+ if (!variable.isConst && !variable.isFinal) {
+ _accessors.add(variable.setter);
+ }
+ }
+ }
+ return _accessors;
+ }
+
+ @override
LibraryElementForLink get enclosingElement;
@override
@@ -738,6 +855,13 @@
}
@override
+ List<FunctionTypeAliasElementForLink> get functionTypeAliases =>
+ _functionTypeAliases ??= _unlinkedUnit.typedefs
+ .map((UnlinkedTypedef t) =>
+ new FunctionTypeAliasElementForLink(this, t))
+ .toList();
+
+ @override
String get identifier => _absoluteUri;
/**
@@ -804,12 +928,16 @@
for (ClassElementForLink_Enum enm in enums) {
_containedNames[enm.name] = enm;
}
- for (TopLevelVariableElementForLink variable in topLevelVariables) {
- _containedNames[variable.name] = variable;
- }
for (TopLevelFunctionElementForLink function in functions) {
_containedNames[function.name] = function;
}
+ for (PropertyAccessorElementForLink accessor in accessors) {
+ _containedNames[accessor.name] = accessor;
+ }
+ for (FunctionTypeAliasElementForLink functionTypeAlias
+ in functionTypeAliases) {
+ _containedNames[functionTypeAlias.name] = functionTypeAlias;
+ }
// TODO(paulberry): fill in other top level entities (typedefs
// and executables).
}
@@ -950,11 +1078,22 @@
int numTypeParameters: 0,
int unitNum: 0,
int containingReference: 0,
+ int localIndex: 0,
ReferenceKind kind: ReferenceKind.classOrEnum}) {
List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
for (int i = 0; i < linkedReferences.length; i++) {
LinkedReferenceBuilder linkedReference = linkedReferences[i];
+ int candidateContainingReference = i < unlinkedReferences.length
+ ? unlinkedReferences[i].prefixReference
+ : linkedReference.containingReference;
+ if (candidateContainingReference != 0 &&
+ linkedReferences[candidateContainingReference].kind ==
+ ReferenceKind.prefix) {
+ // We don't need to match containing references when they are prefixes,
+ // since the relevant information is in linkedReference.dependency.
+ candidateContainingReference = 0;
+ }
if (linkedReference.dependency == dependency &&
(i < unlinkedReferences.length
? unlinkedReferences[i].name
@@ -962,11 +1101,9 @@
name &&
linkedReference.numTypeParameters == numTypeParameters &&
linkedReference.unit == unitNum &&
- (i < unlinkedReferences.length
- ? unlinkedReferences[i].prefixReference
- : linkedReference.containingReference) ==
- containingReference &&
- linkedReference.kind == kind) {
+ candidateContainingReference == containingReference &&
+ linkedReference.kind == kind &&
+ linkedReference.localIndex == localIndex) {
return i;
}
}
@@ -977,7 +1114,8 @@
numTypeParameters: numTypeParameters,
unit: unitNum,
containingReference: containingReference,
- kind: kind));
+ kind: kind,
+ localIndex: localIndex));
return result;
}
@@ -992,6 +1130,12 @@
dependency: library.addDependency(element.library),
numTypeParameters: element.typeParameters.length,
unitNum: element.enclosingElement.unitNum);
+ } else if (element is FunctionTypeAliasElementForLink) {
+ return addRawReference(element.name,
+ dependency: library.addDependency(element.library),
+ numTypeParameters: element.typeParameters.length,
+ unitNum: element.enclosingElement.unitNum,
+ kind: ReferenceKind.typedef);
} else if (element is ExecutableElementForLink) {
ClassElementForLink_Class enclosingClass = element.enclosingClass;
ReferenceKind kind;
@@ -1013,6 +1157,28 @@
containingReference:
enclosingClass != null ? addReference(enclosingClass) : null,
kind: kind);
+ } else if (element is FunctionElementForLink_Local) {
+ FunctionElementImpl parent = element.enclosingElement;
+ int localIndex = parent.functions.indexOf(element);
+ assert(localIndex != -1);
+ return addRawReference(element.name,
+ containingReference: addReference(parent),
+ kind: ReferenceKind.function,
+ localIndex: localIndex);
+ } else if (element is FunctionElementForLink_Initializer) {
+ return addRawReference('',
+ containingReference: addReference(element.enclosingElement),
+ kind: ReferenceKind.function);
+ } else if (element is TopLevelVariableElementForLink) {
+ return addRawReference(element.name,
+ kind: ReferenceKind.topLevelPropertyAccessor);
+ } else if (element is FieldElementForLink_ClassField) {
+ ClassElementForLink_Class enclosingClass = element.enclosingElement;
+ // TODO(paulberry): do we need to set numTypeParameters to nonzero if the
+ // class has type parameters?
+ return addRawReference(element.name,
+ containingReference: addReference(enclosingClass),
+ kind: ReferenceKind.propertyAccessor);
}
// TODO(paulberry): implement other cases
throw new UnimplementedError('${element.runtimeType}');
@@ -1223,7 +1389,7 @@
// Note: non-static const isn't allowed but we handle it anyway so
// that we won't be confused by incorrect code.
if ((field.isFinal || field.isConst) && !field.isStatic) {
- safeAddDependency(field.asConstVariable);
+ safeAddDependency(field.getter.asConstVariable);
}
}
for (ParameterElementForLink parameterElement
@@ -1242,7 +1408,7 @@
EntityRef redirectedConstructor =
constructorElement._unlinkedExecutable.redirectedConstructor;
if (redirectedConstructor != null) {
- return constructorElement.enclosingUnit
+ return constructorElement.compilationUnit
._resolveRef(redirectedConstructor.reference)
.asConstructor;
} else {
@@ -1619,7 +1785,6 @@
DartType _declaredReturnType;
DartType _inferredReturnType;
FunctionTypeImpl _type;
- List<TypeParameterElementForLink> _typeParameters;
String _name;
String _displayName;
@@ -1629,13 +1794,11 @@
*/
final ClassElementForLink_Class enclosingClass;
- /**
- * Return the compilation unit in which this executable appears.
- */
- final CompilationUnitElementForLink enclosingUnit;
+ @override
+ final CompilationUnitElementForLink compilationUnit;
ExecutableElementForLink(
- this.enclosingUnit, this.enclosingClass, this._unlinkedExecutable);
+ this.compilationUnit, this.enclosingClass, this._unlinkedExecutable);
/**
* If the executable element had an explicitly declared return type, return
@@ -1646,7 +1809,7 @@
return null;
} else {
return _declaredReturnType ??=
- enclosingUnit._resolveTypeRef(_unlinkedExecutable.returnType, this);
+ compilationUnit._resolveTypeRef(_unlinkedExecutable.returnType, this);
}
}
@@ -1662,7 +1825,7 @@
}
@override
- Element get enclosingElement => enclosingClass ?? enclosingUnit;
+ Element get enclosingElement => enclosingClass ?? compilationUnit;
@override
TypeParameterizedElementForLink get enclosingTypeParameterContext =>
@@ -1684,7 +1847,7 @@
assert(_unlinkedExecutable.returnType == null);
if (Linker._initializerTypeInferenceCycle != null &&
Linker._initializerTypeInferenceCycle ==
- enclosingUnit.library.libraryCycleForLink) {
+ compilationUnit.library.libraryCycleForLink) {
// We are currently computing the type of an initializer expression in the
// current library cycle, so type inference results should be ignored.
return _computeDefaultReturnType();
@@ -1693,10 +1856,10 @@
if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
// TODO(paulberry): implement.
throw new UnimplementedError();
- } else if (enclosingUnit.isInBuildUnit) {
+ } else if (compilationUnit.isInBuildUnit) {
_inferredReturnType = _computeDefaultReturnType();
} else {
- _inferredReturnType = enclosingUnit.getLinkedType(
+ _inferredReturnType = compilationUnit.getLinkedType(
_unlinkedExecutable.inferredReturnTypeSlot, this);
}
}
@@ -1704,9 +1867,6 @@
}
@override
- ExecutableElementForLink get innermostExecutable => this;
-
- @override
bool get isStatic => _unlinkedExecutable.isStatic;
@override
@@ -1739,6 +1899,9 @@
FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
@override
+ TypeParameterizedElementForLink get typeParameterContext => this;
+
+ @override
List<UnlinkedParam> get unlinkedParameters => _unlinkedExecutable.parameters;
@override
@@ -1781,6 +1944,7 @@
class ExprTypeComputer {
VariableElementForLink variable;
+ FunctionElementForLink_Initializer initializer;
CompilationUnitElementForLink unit;
LibraryElementForLink library;
Linker linker;
@@ -1795,6 +1959,7 @@
ExprTypeComputer(VariableElementForLink variableElement) {
this.variable = variableElement;
+ initializer = variableElement.initializer;
unit = variableElement.compilationUnit;
library = unit.enclosingElement;
linker = library._linker;
@@ -1961,6 +2126,11 @@
stack.removeLast();
stack.add(BottomTypeImpl.instance);
break;
+ case UnlinkedConstOperation.pushLocalFunctionReference:
+ int popCount = _getNextInt();
+ assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
+ stack.add(initializer.functions[_getNextInt()].type);
+ break;
default:
// TODO(paulberry): implement.
throw new UnimplementedError('$operation');
@@ -2108,12 +2278,23 @@
ConstructorElementForLink element =
unit._resolveRef(ref.reference).asConstructor;
if (element != null) {
- stack.add(element.enclosingClass.buildType(
- (int i) => i >= ref.typeArguments.length
- ? DynamicTypeImpl.instance
- : unit._resolveTypeRef(
- ref.typeArguments[i], variable._typeParameterContext),
- const []));
+ ClassElementForLink_Class enclosingClass = element.enclosingClass;
+ stack.add(enclosingClass.buildType((int i) {
+ // Type argument explicitly specified.
+ if (i < ref.typeArguments.length) {
+ return unit._resolveTypeRef(
+ ref.typeArguments[i], variable._typeParameterContext);
+ }
+ // In strong mode, type argument defaults to bound (if any).
+ if (linker.strongMode) {
+ TypeParameterElement typeParameter = enclosingClass.typeParameters[i];
+ if (typeParameter.bound != null) {
+ return typeParameter.bound;
+ }
+ }
+ // Otherwise type argument defaults to `dynamic`.
+ return DynamicTypeImpl.instance;
+ }, const []));
} else {
stack.add(DynamicTypeImpl.instance);
}
@@ -2318,7 +2499,8 @@
MethodElement method = left.lookUpMethod(operator.lexeme, library);
if (method != null) {
DartType type = method.returnType;
- type = _refineBinaryExpressionType(operator, type, left, right);
+ type = linker.typeSystem.refineBinaryExpressionType(
+ typeProvider, left, operator, right, type);
stack.add(type);
return;
}
@@ -2337,35 +2519,6 @@
_pushBinaryOperatorType(propertyType, operator, operandType);
}
- DartType _refineBinaryExpressionType(TokenType operator, DartType currentType,
- DartType leftType, DartType rightType) {
- DartType intType = typeProvider.intType;
- if (leftType == intType) {
- // int op double
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR) {
- DartType doubleType = typeProvider.doubleType;
- if (rightType == doubleType) {
- return doubleType;
- }
- }
- // int op int
- if (operator == TokenType.MINUS ||
- operator == TokenType.PERCENT ||
- operator == TokenType.PLUS ||
- operator == TokenType.STAR ||
- operator == TokenType.TILDE_SLASH) {
- if (rightType == intType) {
- return intType;
- }
- }
- }
- // default
- return currentType;
- }
-
static TokenType _convertAssignOperatorToTokenType(
UnlinkedExprAssignOperator o) {
switch (o) {
@@ -2418,8 +2571,13 @@
* Element representing a field resynthesized from a summary during
* linking.
*/
-abstract class FieldElementForLink
- implements FieldElement, ReferenceableElementForLink {}
+abstract class FieldElementForLink implements FieldElement {
+ @override
+ PropertyAccessorElementForLink get getter;
+
+ @override
+ PropertyAccessorElementForLink get setter;
+}
/**
* Specialization of [FieldElementForLink] for class fields.
@@ -2481,27 +2639,16 @@
*/
final UnlinkedEnumValue unlinkedEnumValue;
+ PropertyAccessorElementForLink_EnumField _getter;
+
@override
final ClassElementForLink_Enum enclosingElement;
FieldElementForLink_EnumField(this.unlinkedEnumValue, this.enclosingElement);
@override
- ConstructorElementForLink get asConstructor => null;
-
- @override
- ConstVariableNode get asConstVariable {
- // Even though enum fields are constants, there is no need to include them
- // in the const dependency graph because they can't participate in a
- // circularity.
- return null;
- }
-
- @override
- DartType get asStaticType => enclosingElement.type;
-
- @override
- TypeInferenceNode get asTypeInferenceNode => null;
+ PropertyAccessorElementForLink_EnumField get getter =>
+ _getter ??= new PropertyAccessorElementForLink_EnumField(this);
@override
bool get isStatic => true;
@@ -2514,13 +2661,9 @@
unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
@override
- DartType buildType(DartType getTypeArgument(int i),
- List<int> implicitFunctionTypeIndices) =>
- DynamicTypeImpl.instance;
-
- @override
- ReferenceableElementForLink getContainedName(String name) =>
- UndefinedElementForLink.instance;
+ DartType get type => unlinkedEnumValue == null
+ ? enclosingElement.valuesType
+ : enclosingElement.type;
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -2540,7 +2683,7 @@
final ParameterElementForLink enclosingElement;
@override
- final ExecutableElementForLink innermostExecutable;
+ final TypeParameterizedElementForLink typeParameterContext;
@override
final List<UnlinkedParam> unlinkedParameters;
@@ -2548,8 +2691,8 @@
DartType _returnType;
List<int> _implicitFunctionTypeIndices;
- FunctionElementForLink_FunctionTypedParam(
- this.enclosingElement, this.innermostExecutable, this.unlinkedParameters);
+ FunctionElementForLink_FunctionTypedParam(this.enclosingElement,
+ this.typeParameterContext, this.unlinkedParameters);
@override
List<int> get implicitFunctionTypeIndices {
@@ -2569,7 +2712,7 @@
_returnType = DynamicTypeImpl.instance;
} else {
_returnType = enclosingElement.compilationUnit._resolveTypeRef(
- enclosingElement._unlinkedParam.type, innermostExecutable);
+ enclosingElement._unlinkedParam.type, typeParameterContext);
}
}
return _returnType;
@@ -2591,9 +2734,21 @@
*/
final VariableElementForLink _variable;
+ List<FunctionElementForLink_Local> _functions;
+
FunctionElementForLink_Initializer(this._variable);
@override
+ VariableElementForLink get enclosingElement => _variable;
+
+ @override
+ List<FunctionElementForLink_Local> get functions => _functions ??= _variable
+ .unlinkedVariable.initializer.localFunctions
+ .map(
+ (UnlinkedExecutable ex) => new FunctionElementForLink_Local(this, ex))
+ .toList();
+
+ @override
DartType get returnType {
// If this is a variable whose type needs inferring, infer it.
if (_variable.hasImplicitType) {
@@ -2619,6 +2774,135 @@
}
/**
+ * Element representing a local function (possibly a closure) inside another
+ * executable.
+ */
+class FunctionElementForLink_Local implements FunctionElementImpl {
+ /**
+ * The unlinked representation of the local function in the summary.
+ */
+ final UnlinkedExecutable _executable;
+
+ @override
+ final FunctionElementImpl enclosingElement;
+
+ DartType _type;
+
+ FunctionElementForLink_Local(this.enclosingElement, this._executable);
+
+ @override
+ String get name => _executable.name;
+
+ @override
+ DartType get type => _type ??= new FunctionTypeImpl(this);
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * Element representing a typedef resynthesized from a summary during linking.
+ */
+class FunctionTypeAliasElementForLink extends Object
+ with TypeParameterizedElementForLink, ParameterParentElementForLink
+ implements
+ FunctionTypeAliasElement,
+ ReferenceableElementForLink,
+ ElementImpl {
+ @override
+ final CompilationUnitElementForLink enclosingElement;
+
+ /**
+ * The unlinked representation of the typedef in the summary.
+ */
+ final UnlinkedTypedef _unlinkedTypedef;
+
+ FunctionTypeImpl _type;
+ DartType _returnType;
+
+ FunctionTypeAliasElementForLink(this.enclosingElement, this._unlinkedTypedef);
+
+ @override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable {
+ // When a typedef name is used as a constant variable, it doesn't depend on
+ // anything, so it is not necessary to include it in the constant
+ // dependency graph.
+ return null;
+ }
+
+ @override
+ DartType get asStaticType {
+ return enclosingElement.enclosingElement._linker.typeProvider.typeType;
+ }
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
+ CompilationUnitElementForLink get compilationUnit => enclosingElement;
+
+ @override
+ TypeParameterizedElementForLink get enclosingTypeParameterContext => null;
+
+ @override
+ String get identifier => _unlinkedTypedef.name;
+
+ @override
+ List<int> get implicitFunctionTypeIndices => const <int>[];
+
+ @override
+ bool get isSynthetic => false;
+
+ @override
+ LibraryElementForLink get library => enclosingElement.library;
+
+ @override
+ String get name => _unlinkedTypedef.name;
+
+ @override
+ DartType get returnType => _returnType ??=
+ enclosingElement._resolveTypeRef(_unlinkedTypedef.returnType, this);
+
+ @override
+ TypeParameterizedElementForLink get typeParameterContext => this;
+
+ @override
+ List<UnlinkedParam> get unlinkedParameters => _unlinkedTypedef.parameters;
+
+ @override
+ List<UnlinkedTypeParam> get _unlinkedTypeParams =>
+ _unlinkedTypedef.typeParameters;
+
+ @override
+ DartType buildType(
+ DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
+ int numTypeParameters = _unlinkedTypedef.typeParameters.length;
+ if (numTypeParameters != 0) {
+ List<DartType> typeArguments = new List<DartType>(numTypeParameters);
+ for (int i = 0; i < numTypeParameters; i++) {
+ typeArguments[i] = getTypeArgument(i);
+ }
+ return new FunctionTypeImpl.elementWithNameAndArgs(
+ this, name, typeArguments, true);
+ } else {
+ return _type ??= new FunctionTypeImpl.forTypedef(this);
+ }
+ }
+
+ @override
+ ReferenceableElementForLink getContainedName(String name) {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
* Specialization of [DependencyWalker] for linking library cycles.
*/
class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> {
@@ -3164,19 +3448,42 @@
* Element representing a method resynthesized from a summary during linking.
*/
class MethodElementForLink extends ExecutableElementForLink
- implements MethodElementImpl {
+ implements MethodElementImpl, ReferenceableElementForLink {
MethodElementForLink(ClassElementForLink_Class enclosingClass,
UnlinkedExecutable unlinkedExecutable)
: super(enclosingClass.enclosingElement, enclosingClass,
unlinkedExecutable);
@override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable => null;
+
+ @override
+ DartType get asStaticType => type;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
String get identifier => name;
@override
ElementKind get kind => ElementKind.METHOD;
@override
+ DartType buildType(DartType getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeImpl.instance;
+
+ @override
+ ReferenceableElementForLink getContainedName(String name) {
+ // TODO(paulberry): handle references to `call`.
+ return UndefinedElementForLink.instance;
+ }
+
+ @override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@override
@@ -3226,47 +3533,61 @@
* Element used for references that result from trying to access a non-static
* member of an element that is not a container (e.g. accessing the "length"
* property of a constant).
+ *
+ * Accesses to a chain of non-static members separated by '.' are andled by
+ * creating a [NonstaticMemberElementForLink] that points to another
+ * [NonstaticMemberElementForLink], to whatever nesting level is necessary.
*/
class NonstaticMemberElementForLink implements ReferenceableElementForLink {
/**
- * The non-static element of this link element.
+ * The [ReferenceableElementForLink] which is the target of the non-static
+ * reference.
*/
- final Element element;
+ final ReferenceableElementForLink _target;
/**
- * If the thing from which a member was accessed is a constant, the
- * associated [ConstNode]. Otherwise `null`.
+ * The name of the non-static members that is being accessed.
*/
- final ConstVariableNode _constNode;
+ final String _name;
- NonstaticMemberElementForLink(this.element, this._constNode);
+ /**
+ * The library in which the access occurs. This determines whether private
+ * names are accessible.
+ */
+ final LibraryElementForLink _library;
+
+ NonstaticMemberElementForLink(this._library, this._target, this._name);
@override
ConstructorElementForLink get asConstructor => null;
@override
- ConstVariableNode get asConstVariable => _constNode;
+ ConstVariableNode get asConstVariable => _target.asConstVariable;
@override
DartType get asStaticType {
- Element element = this.element;
- if (element is PropertyAccessorElement) {
- if (element.isGetter) {
- return element.returnType;
+ if (_library._linker.strongMode) {
+ DartType targetType = _target.asStaticType;
+ if (targetType is InterfaceType) {
+ PropertyAccessorElement getter =
+ targetType.lookUpGetter(_name, _library);
+ if (getter != null) {
+ return getter.returnType;
+ }
+ MethodElement method = targetType.lookUpMethod(_name, _library);
+ if (method != null) {
+ return method.type;
+ }
}
- return DynamicTypeImpl.instance;
+ // TODO(paulberry): handle .call on function types and .toString or
+ // .hashCode on all types.
}
- if (element is MethodElement) {
- return element.type;
- }
+ // TODO(paulberry, scheglov): implement for propagated types
return DynamicTypeImpl.instance;
}
@override
- TypeInferenceNode get asTypeInferenceNode {
- // TODO(paulberry): implement.
- return null;
- }
+ TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode;
@override
DartType buildType(DartType getTypeArgument(int i),
@@ -3275,15 +3596,7 @@
@override
ReferenceableElementForLink getContainedName(String name) {
- if (element != null) {
- DartType type = asStaticType;
- if (type is InterfaceType) {
- Element nameElement = type.lookUpGetter(name, element.library);
- nameElement ??= type.lookUpMethod(name, element.library);
- return new NonstaticMemberElementForLink(nameElement, _constNode);
- }
- }
- return this;
+ return new NonstaticMemberElementForLink(_library, this, name);
}
}
@@ -3298,9 +3611,9 @@
final UnlinkedParam _unlinkedParam;
/**
- * The innermost executable element containing this parameter.
+ * The innermost enclosing element that can declare type parameters.
*/
- final ExecutableElementForLink _innermostExecutable;
+ final TypeParameterizedElementForLink _typeParameterContext;
/**
* If this parameter has a default value and the enclosing library
@@ -3326,13 +3639,16 @@
DartType _declaredType;
ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
- this._innermostExecutable, this.compilationUnit, this._parameterIndex) {
+ this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
if (_unlinkedParam.defaultValue != null) {
_constNode = new ConstParameterNode(this);
}
}
@override
+ String get displayName => _unlinkedParam.name;
+
+ @override
bool get hasImplicitType =>
!_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
@@ -3359,18 +3675,18 @@
if (_unlinkedParam.isFunctionTyped) {
_declaredType = new FunctionTypeImpl(
new FunctionElementForLink_FunctionTypedParam(
- this, _innermostExecutable, _unlinkedParam.parameters));
+ this, _typeParameterContext, _unlinkedParam.parameters));
} else if (_unlinkedParam.type == null) {
if (!compilationUnit.isInBuildUnit) {
_inferredType = compilationUnit.getLinkedType(
- _unlinkedParam.inferredTypeSlot, _innermostExecutable);
+ _unlinkedParam.inferredTypeSlot, _typeParameterContext);
return _inferredType;
} else {
_declaredType = DynamicTypeImpl.instance;
}
} else {
_declaredType = compilationUnit._resolveTypeRef(
- _unlinkedParam.type, _innermostExecutable);
+ _unlinkedParam.type, _typeParameterContext);
}
}
return _declaredType;
@@ -3388,7 +3704,7 @@
*/
void link(CompilationUnitElementInBuildUnit compilationUnit) {
compilationUnit._storeLinkedType(
- _unlinkedParam.inferredTypeSlot, _inferredType, _innermostExecutable);
+ _unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
}
@override
@@ -3437,12 +3753,6 @@
List<int> get implicitFunctionTypeIndices;
/**
- * Get the innermost enclosing ExecutableElement (which may be [this], or may
- * be a parent when there are function-typed parameters).
- */
- ExecutableElementForLink get innermostExecutable;
-
- /**
* Get all the parameters of this element.
*/
List<ParameterElementForLink> get parameters {
@@ -3453,13 +3763,20 @@
for (int i = 0; i < numParameters; i++) {
UnlinkedParam unlinkedParam = unlinkedParameters[i];
_parameters[i] = new ParameterElementForLink(this, unlinkedParam,
- innermostExecutable, innermostExecutable.enclosingUnit, i);
+ typeParameterContext, typeParameterContext.compilationUnit, i);
}
}
return _parameters;
}
/**
+ * Get the innermost enclosing element that can declare type parameters (which
+ * may be [this], or may be a parent when there are function-typed
+ * parameters).
+ */
+ TypeParameterizedElementForLink get typeParameterContext;
+
+ /**
* Get the list of unlinked parameters of this element.
*/
List<UnlinkedParam> get unlinkedParameters;
@@ -3475,6 +3792,92 @@
}
/**
+ * Specialization of [PropertyAccessorElementForLink] for synthetic accessors
+ * implied by the synthetic fields of an enum declaration.
+ */
+class PropertyAccessorElementForLink_EnumField
+ implements PropertyAccessorElementForLink {
+ @override
+ final FieldElementForLink_EnumField variable;
+
+ FunctionTypeImpl _type;
+
+ PropertyAccessorElementForLink_EnumField(this.variable);
+
+ @override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable => null;
+
+ @override
+ DartType get asStaticType => returnType;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
+ Element get enclosingElement => variable.enclosingElement;
+
+ @override
+ bool get isGetter => true;
+
+ @override
+ bool get isSetter => false;
+
+ @override
+ bool get isStatic => variable.isStatic;
+
+ @override
+ bool get isSynthetic => true;
+
+ @override
+ ElementKind get kind => ElementKind.GETTER;
+
+ @override
+ LibraryElementForLink get library =>
+ variable.enclosingElement.enclosingElement.enclosingElement;
+
+ @override
+ String get name => variable.name;
+
+ @override
+ List<ParameterElement> get parameters => const [];
+
+ @override
+ DartType get returnType => variable.type;
+
+ @override
+ FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
+
+ @override
+ List<TypeParameterElement> get typeParameters => const [];
+
+ @override
+ DartType buildType(DartType getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeImpl.instance;
+
+ @override
+ ReferenceableElementForLink getContainedName(String name) {
+ return new NonstaticMemberElementForLink(library, this, name);
+ }
+
+ @override
+ bool isAccessibleIn(LibraryElement library) =>
+ !Identifier.isPrivateName(name) || identical(this.library, library);
+
+ @override
+ void link(CompilationUnitElementInBuildUnit compilationUnit) {}
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ String toString() => '$enclosingElement.$name';
+}
+
+/**
* Specialization of [PropertyAccessorElementForLink] for non-synthetic
* accessors explicitly declared in the source code.
*/
@@ -3484,11 +3887,11 @@
SyntheticVariableElementForLink variable;
PropertyAccessorElementForLink_Executable(
+ CompilationUnitElementForLink enclosingUnit,
ClassElementForLink_Class enclosingClass,
UnlinkedExecutable unlinkedExecutable,
this.variable)
- : super(enclosingClass.enclosingElement, enclosingClass,
- unlinkedExecutable);
+ : super(enclosingUnit, enclosingClass, unlinkedExecutable);
@override
ConstructorElementForLink get asConstructor => null;
@@ -3524,8 +3927,9 @@
DynamicTypeImpl.instance;
@override
- ReferenceableElementForLink getContainedName(String name) =>
- UndefinedElementForLink.instance;
+ ReferenceableElementForLink getContainedName(String name) {
+ return new NonstaticMemberElementForLink(library, this, name);
+ }
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -3550,6 +3954,18 @@
PropertyAccessorElementForLink_Variable(this.variable, this.isSetter);
@override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable => variable._constNode;
+
+ @override
+ DartType get asStaticType => returnType;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => variable._typeInferenceNode;
+
+ @override
Element get enclosingElement => variable.enclosingElement;
@override
@@ -3600,6 +4016,11 @@
return const [];
}
+ @override
+ DartType buildType(DartType getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeImpl.instance;
+
/**
* Compute the type of the corresponding variable, which may depend on the
* progress of type inference.
@@ -3619,6 +4040,11 @@
}
@override
+ ReferenceableElementForLink getContainedName(String name) {
+ return new NonstaticMemberElementForLink(library, this, name);
+ }
+
+ @override
bool isAccessibleIn(LibraryElement library) =>
!Identifier.isPrivateName(name) || identical(this.library, library);
@@ -3786,14 +4212,20 @@
*/
class TopLevelVariableElementForLink extends VariableElementForLink
implements TopLevelVariableElement {
- TopLevelVariableElementForLink(CompilationUnitElement enclosingElement,
+ TopLevelVariableElementForLink(CompilationUnitElementForLink enclosingElement,
UnlinkedVariable unlinkedVariable)
: super(unlinkedVariable, enclosingElement);
@override
+ CompilationUnitElementForLink get enclosingElement => compilationUnit;
+
+ @override
bool get isStatic => true;
@override
+ LibraryElementForLink get library => compilationUnit.library;
+
+ @override
TypeParameterizedElementForLink get _typeParameterContext => null;
/**
@@ -3802,7 +4234,7 @@
*/
void link(CompilationUnitElementInBuildUnit compilationUnit) {
if (hasImplicitType) {
- TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
+ TypeInferenceNode typeInferenceNode = this._typeInferenceNode;
if (typeInferenceNode != null) {
compilationUnit._storeLinkedType(
unlinkedVariable.inferredTypeSlot, inferredType, null);
@@ -3918,6 +4350,9 @@
new ExprTypeComputer(variableElement).compute();
}
}
+
+ @override
+ String toString() => 'TypeInferenceNode($variableElement)';
}
/**
@@ -3942,6 +4377,8 @@
TypeParameterTypeImpl _type;
ElementLocation _location;
+ DartType _bound;
+
TypeParameterElementForLink(
this.enclosingElement, this._unlinkedTypeParam, this.nestingLevel);
@@ -3950,8 +4387,8 @@
if (_unlinkedTypeParam.bound == null) {
return null;
}
- // TODO(scheglov) implement
- throw new UnimplementedError();
+ return _bound ??= enclosingElement.compilationUnit
+ ._resolveTypeRef(_unlinkedTypeParam.bound, enclosingElement);
}
@override
@@ -3984,6 +4421,11 @@
int _nestingLevel;
/**
+ * Get the compilation unit in which this element is declared.
+ */
+ CompilationUnitElementForLink get compilationUnit;
+
+ /**
* Get the type parameter context enclosing this one, if any.
*/
TypeParameterizedElementForLink get enclosingTypeParameterContext;
@@ -4045,6 +4487,20 @@
throw new RangeError('Invalid type parameter index');
}
}
+
+ /**
+ * Find out if the given [typeParameter] is in scope in this context.
+ */
+ bool isTypeParameterInScope(TypeParameterElementForLink typeParameter) {
+ if (typeParameter.enclosingElement == this) {
+ return true;
+ } else if (enclosingTypeParameterContext != null) {
+ return enclosingTypeParameterContext
+ .isTypeParameterInScope(typeParameter);
+ } else {
+ return false;
+ }
+ }
}
class TypeProviderForLink implements TypeProvider {
@@ -4227,11 +4683,8 @@
* Element representing a top level variable resynthesized from a
* summary during linking.
*/
-class VariableElementForLink
- implements
- VariableElementImpl,
- PropertyInducingElement,
- ReferenceableElementForLink {
+abstract class VariableElementForLink
+ implements VariableElementImpl, PropertyInducingElement {
/**
* The unlinked representation of the variable in the summary.
*/
@@ -4254,6 +4707,8 @@
FunctionElementForLink_Initializer _initializer;
DartType _inferredType;
DartType _declaredType;
+ PropertyAccessorElementForLink_Variable _getter;
+ PropertyAccessorElementForLink_Variable _setter;
/**
* The compilation unit in which this variable appears.
@@ -4269,18 +4724,6 @@
}
}
- @override
- ConstructorElementForLink get asConstructor => null;
-
- @override
- ConstVariableNode get asConstVariable => _constNode;
-
- @override
- DartType get asStaticType => type;
-
- @override
- TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode;
-
/**
* If the variable has an explicitly declared return type, return it.
* Otherwise return `null`.
@@ -4295,6 +4738,10 @@
}
@override
+ PropertyAccessorElementForLink_Variable get getter =>
+ _getter ??= new PropertyAccessorElementForLink_Variable(this, false);
+
+ @override
bool get hasImplicitType => unlinkedVariable.type == null;
/**
@@ -4356,6 +4803,16 @@
}
@override
+ PropertyAccessorElementForLink_Variable get setter {
+ if (!isConst && !isFinal) {
+ return _setter ??=
+ new PropertyAccessorElementForLink_Variable(this, true);
+ } else {
+ return null;
+ }
+ }
+
+ @override
DartType get type => declaredType ?? inferredType;
@override
@@ -4370,34 +4827,8 @@
TypeParameterizedElementForLink get _typeParameterContext;
@override
- DartType buildType(DartType getTypeArgument(int i),
- List<int> implicitFunctionTypeIndices) =>
- DynamicTypeImpl.instance;
-
- ReferenceableElementForLink getContainedName(String name) {
- Element element = _getContainedElement(name);
- return new NonstaticMemberElementForLink(element, _constNode);
- }
-
- @override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
- /**
- * Return the contained element with the given [name], or `null` if the lookup
- * fails. Currently only static types are supported in the linker, so lookup
- * is performed only in the strong mode.
- */
- Element _getContainedElement(String name) {
- Linker linker = compilationUnit.library._linker;
- if (linker.strongMode) {
- DartType type = asStaticType;
- if (type is InterfaceType) {
- Element result = type.lookUpGetter(name, compilationUnit.library);
- result ??= type.lookUpMethod(name, compilationUnit.library);
- return result;
- }
- }
- // TODO(scheglov): implement for propagated types
- return null;
- }
+ @override
+ String toString() => '$enclosingElement.$name';
}
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index e765fae..eb6020f 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -3,6 +3,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -86,6 +87,36 @@
}
return false;
}
+ } else if (target is LibrarySpecificUnit) {
+ String uriString = target.library.uri.toString();
+ if (!_resynthesizer.hasLibrarySummary(uriString)) {
+ return false;
+ }
+ if (result == CREATED_RESOLVED_UNIT1 ||
+ result == CREATED_RESOLVED_UNIT2 ||
+ result == CREATED_RESOLVED_UNIT3 ||
+ result == CREATED_RESOLVED_UNIT4 ||
+ result == CREATED_RESOLVED_UNIT5 ||
+ result == CREATED_RESOLVED_UNIT6 ||
+ result == CREATED_RESOLVED_UNIT7 ||
+ result == CREATED_RESOLVED_UNIT8 ||
+ result == CREATED_RESOLVED_UNIT9 ||
+ result == CREATED_RESOLVED_UNIT10 ||
+ result == CREATED_RESOLVED_UNIT11 ||
+ result == CREATED_RESOLVED_UNIT12) {
+ entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (result == COMPILATION_UNIT_ELEMENT) {
+ String libraryUri = target.library.uri.toString();
+ String unitUri = target.unit.uri.toString();
+ CompilationUnitElement unit = _resynthesizer.getElement(
+ new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+ if (unit != null) {
+ entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
} else if (target is VariableElement) {
if (!_resynthesizer
.hasLibrarySummary(target.library.source.uri.toString())) {
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 684113e..9cd9007 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -68,9 +68,7 @@
node.typeParameters?.typeParameters?.length ?? 0);
if (cls != null) {
for (ClassMember member in node.members) {
- if (member is FieldDeclaration &&
- member.isStatic &&
- member.fields.isConst) {
+ if (member is FieldDeclaration && member.isStatic) {
for (VariableDeclaration field in member.fields.variables) {
String name = field.name.name;
if (isPublic(name)) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 749812e..acc6ff3 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -283,9 +283,10 @@
_ConstExprBuilder(this.resynthesizer, this.uc);
- Expression get expr => stack.single;
-
Expression build() {
+ if (!uc.isValidConst) {
+ return AstFactory.identifier3(r'$$invalidConstExpr$$');
+ }
for (UnlinkedConstOperation operation in uc.operations) {
switch (operation) {
case UnlinkedConstOperation.pushNull:
@@ -459,7 +460,9 @@
case UnlinkedConstOperation.typeCast:
case UnlinkedConstOperation.typeCheck:
case UnlinkedConstOperation.throwException:
- throw new UnimplementedError('$operation');
+ case UnlinkedConstOperation.pushLocalFunctionReference:
+ throw new UnimplementedError(
+ 'Unexpected $operation in a constant expression.');
}
}
return stack.single;
@@ -511,10 +514,13 @@
TypeName _buildTypeAst(DartType type) {
List<TypeName> argumentNodes;
if (type is ParameterizedType) {
- List<DartType> typeArguments = type.typeArguments;
- argumentNodes = typeArguments.every((a) => a.isDynamic)
- ? null
- : typeArguments.map(_buildTypeAst).toList();
+ if (!resynthesizer.libraryResynthesizer.typesWithImplicitTypeArguments
+ .contains(type)) {
+ List<DartType> typeArguments = type.typeArguments;
+ argumentNodes = typeArguments.every((a) => a.isDynamic)
+ ? null
+ : typeArguments.map(_buildTypeAst).toList();
+ }
}
TypeName node = AstFactory.typeName4(type.name, argumentNodes);
node.type = type;
@@ -940,6 +946,13 @@
final Map<String, Map<String, Element>> resynthesizedElements =
<String, Map<String, Element>>{};
+ /**
+ * Types with implicit type arguments, which are the same as type parameter
+ * bounds (in strong mode), or `dynamic` (in spec mode).
+ */
+ final Set<DartType> typesWithImplicitTypeArguments =
+ new Set<DartType>.identity();
+
_LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
this.unlinkedUnits, this.librarySource) {
isCoreLibrary = librarySource.uri.toString() == 'dart:core';
@@ -1248,8 +1261,8 @@
String partUri;
if (unit != 0) {
String uri = dependency.parts[unit - 1];
- Source partSource = summaryResynthesizer.sourceFactory
- .resolveUri(referencedLibrarySource, uri);
+ Source partSource =
+ summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
partUri = partSource.uri.toString();
} else {
partUri = referencedLibraryUri;
@@ -1277,6 +1290,11 @@
*/
class _ReferenceInfo {
/**
+ * The [_LibraryResynthesizer] which is being used to obtain summaries.
+ */
+ final _LibraryResynthesizer libraryResynthesizer;
+
+ /**
* The enclosing [_ReferenceInfo], or `null` for top-level elements.
*/
final _ReferenceInfo enclosing;
@@ -1314,12 +1332,12 @@
* the type itself. Otherwise, pass `null` and the type will be computed
* when appropriate.
*/
- _ReferenceInfo(this.enclosing, this.name, this.element, DartType specialType,
- this.numTypeParameters) {
+ _ReferenceInfo(this.libraryResynthesizer, this.enclosing, this.name,
+ this.element, DartType specialType, this.numTypeParameters) {
if (specialType != null) {
type = specialType;
} else {
- type = _buildType((_) => DynamicTypeImpl.instance, const []);
+ type = _buildType(true, 0, (_) => DynamicTypeImpl.instance, const []);
}
}
@@ -1336,12 +1354,13 @@
* If the entity referred to by this [_ReferenceInfo] is not a type, `null`
* is returned.
*/
- DartType buildType(
+ DartType buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
DartType result =
(numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty)
? type
- : _buildType(getTypeArgument, implicitFunctionTypeIndices);
+ : _buildType(instantiateToBoundsAllowed, numTypeArguments,
+ getTypeArgument, implicitFunctionTypeIndices);
if (result == null) {
// TODO(paulberry): figure out how to handle this case (which should
// only occur in the event of erroneous code).
@@ -1351,27 +1370,51 @@
}
/**
- * If this reference refers to a type, build a [DartType] which instantiates
- * it with type arguments returned by [getTypeArgument]. Otherwise return
- * `null`.
+ * If this reference refers to a type, build a [DartType]. Otherwise return
+ * `null`. If [numTypeArguments] is the same as the [numTypeParameters],
+ * the type in instantiated with type arguments returned by [getTypeArgument],
+ * otherwise it is instantiated with type parameter bounds (if strong mode),
+ * or with `dynamic` type arguments.
*
* If [implicitFunctionTypeIndices] is not null, a [DartType] should be
* created which refers to a function type implicitly defined by one of the
* element's parameters. [implicitFunctionTypeIndices] is interpreted as in
* [EntityRef.implicitFunctionTypeIndices].
*/
- DartType _buildType(
+ DartType _buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
ElementHandle element = this.element; // To allow type promotion
if (element is ClassElementHandle) {
- return new InterfaceTypeImpl.elementWithNameAndArgs(element, name,
- _buildTypeArguments(numTypeParameters, getTypeArgument));
- } else if (element is FunctionTypeAliasElementHandle) {
- return new FunctionTypeImpl.elementWithNameAndArgs(
- element,
- name,
- _buildTypeArguments(numTypeParameters, getTypeArgument),
- numTypeParameters != 0);
+ List<DartType> typeArguments = null;
+ // If type arguments are specified, use them.
+ // Otherwise, delay until they are requested.
+ if (numTypeParameters == 0) {
+ typeArguments = const <DartType>[];
+ } else if (numTypeArguments == numTypeParameters) {
+ typeArguments = new List<DartType>(numTypeParameters);
+ for (int i = 0; i < numTypeParameters; i++) {
+ typeArguments[i] = getTypeArgument(i);
+ }
+ }
+ InterfaceTypeImpl type =
+ new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () {
+ if (typeArguments == null) {
+ typeArguments = element.typeParameters.map((typeParameter) {
+ DartType bound = typeParameter.bound;
+ return libraryResynthesizer.summaryResynthesizer.strongMode &&
+ instantiateToBoundsAllowed &&
+ bound != null ? bound : DynamicTypeImpl.instance;
+ }).toList();
+ }
+ return typeArguments;
+ });
+ // Mark the type as having implicit type arguments, so that we don't
+ // attempt to request them during constant expression resynthesizing.
+ if (typeArguments == null) {
+ libraryResynthesizer.typesWithImplicitTypeArguments.add(type);
+ }
+ // Done.
+ return type;
} else if (element is FunctionTypedElement) {
int numTypeArguments;
FunctionTypedElementComputer computer;
@@ -1384,6 +1427,12 @@
}
return element;
};
+ } else if (element is FunctionTypeAliasElementHandle) {
+ return new FunctionTypeImpl.elementWithNameAndArgs(
+ element,
+ name,
+ _buildTypeArguments(numTypeParameters, getTypeArgument),
+ numTypeParameters != 0);
} else {
// For a type that refers to a generic executable, the type arguments are
// not supposed to include the arguments to the executable itself.
@@ -1675,29 +1724,6 @@
}
/**
- * Resynthesize the [ConstructorInitializer] in context of
- * [currentConstructor], which is used to resolve constructor parameter names.
- */
- ConstructorInitializer buildConstantInitializer(
- UnlinkedConstructorInitializer serialized) {
- UnlinkedConstructorInitializerKind kind = serialized.kind;
- String name = serialized.name;
- List<Expression> arguments =
- serialized.arguments.map(_buildConstExpression).toList();
- switch (kind) {
- case UnlinkedConstructorInitializerKind.field:
- return AstFactory.constructorFieldInitializer(
- false, name, _buildConstExpression(serialized.expression));
- case UnlinkedConstructorInitializerKind.superInvocation:
- return AstFactory.superConstructorInvocation2(
- name.isNotEmpty ? name : null, arguments);
- case UnlinkedConstructorInitializerKind.thisInvocation:
- return AstFactory.redirectingConstructorInvocation2(
- name.isNotEmpty ? name : null, arguments);
- }
- }
-
- /**
* Resynthesize a [ConstructorElement] and place it in the given [holder].
* [classType] is the type of the class for which this element is a
* constructor.
@@ -1723,7 +1749,7 @@
currentConstructor.const2 = serializedExecutable.isConst;
currentConstructor.constantInitializers = serializedExecutable
.constantInitializers
- .map(buildConstantInitializer)
+ .map(buildConstructorInitializer)
.toList();
if (serializedExecutable.isRedirectedConstructor) {
if (serializedExecutable.isFactory) {
@@ -1749,6 +1775,41 @@
}
/**
+ * Resynthesize the [ConstructorInitializer] in context of
+ * [currentConstructor], which is used to resolve constructor parameter names.
+ */
+ ConstructorInitializer buildConstructorInitializer(
+ UnlinkedConstructorInitializer serialized) {
+ UnlinkedConstructorInitializerKind kind = serialized.kind;
+ String name = serialized.name;
+ List<Expression> arguments = <Expression>[];
+ {
+ int numArguments = serialized.arguments.length;
+ int numNames = serialized.argumentNames.length;
+ for (int i = 0; i < numArguments; i++) {
+ Expression expression = _buildConstExpression(serialized.arguments[i]);
+ int nameIndex = numNames + i - numArguments;
+ if (nameIndex >= 0) {
+ expression = AstFactory.namedExpression2(
+ serialized.argumentNames[nameIndex], expression);
+ }
+ arguments.add(expression);
+ }
+ }
+ switch (kind) {
+ case UnlinkedConstructorInitializerKind.field:
+ return AstFactory.constructorFieldInitializer(
+ false, name, _buildConstExpression(serialized.expression));
+ case UnlinkedConstructorInitializerKind.superInvocation:
+ return AstFactory.superConstructorInvocation2(
+ name.isNotEmpty ? name : null, arguments);
+ case UnlinkedConstructorInitializerKind.thisInvocation:
+ return AstFactory.redirectingConstructorInvocation2(
+ name.isNotEmpty ? name : null, arguments);
+ }
+ }
+
+ /**
* Build the documentation for the given [element]. Does nothing if
* [serializedDocumentationComment] is `null`.
*/
@@ -2139,13 +2200,20 @@
FunctionElementImpl parameterTypeElement =
new FunctionElementImpl('', -1);
parameterTypeElement.synthetic = true;
- parameterElement.parameters =
- serializedParameter.parameters.map(buildParameter).toList();
- parameterTypeElement.enclosingElement = parameterElement;
- parameterTypeElement.shareParameters(parameterElement.parameters);
+ List<ParameterElement> subParameters = serializedParameter.parameters
+ .map((UnlinkedParam p) => buildParameter(p, synthetic: synthetic))
+ .toList();
+ if (synthetic) {
+ parameterTypeElement.parameters = subParameters;
+ } else {
+ parameterElement.parameters = subParameters;
+ parameterTypeElement.shareParameters(subParameters);
+ parameterTypeElement.enclosingElement = parameterElement;
+ }
parameterTypeElement.returnType = buildType(serializedParameter.type);
parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
parameterTypeElement, null, getCurrentTypeArguments(), false);
+ parameterTypeElement.type = parameterElement.type;
} else {
if (serializedParameter.isInitializingFormal &&
serializedParameter.type == null) {
@@ -2195,7 +2263,8 @@
* deserialized, so handles are used to avoid having to deserialize other
* libraries in the process.
*/
- DartType buildType(EntityRef type, {bool defaultVoid: false}) {
+ DartType buildType(EntityRef type,
+ {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
if (type == null) {
if (defaultVoid) {
return VoidTypeImpl.instance;
@@ -2226,7 +2295,10 @@
}
_ReferenceInfo referenceInfo = referenceInfos[type.reference];
return referenceInfo.buildType(
- getTypeArgument, type.implicitFunctionTypeIndices);
+ instantiateToBoundsAllowed,
+ type.typeArguments.length,
+ getTypeArgument,
+ type.implicitFunctionTypeIndices);
}
}
@@ -2371,7 +2443,8 @@
void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
TypeParameterElementImpl typeParameterElement) {
if (serializedTypeParameter.bound != null) {
- typeParameterElement.bound = buildType(serializedTypeParameter.bound);
+ typeParameterElement.bound = buildType(serializedTypeParameter.bound,
+ instantiateToBoundsAllowed: false);
}
}
@@ -2523,7 +2596,7 @@
break;
}
}
- referenceInfos[i] = new _ReferenceInfo(
+ referenceInfos[i] = new _ReferenceInfo(libraryResynthesizer,
enclosingInfo, name, element, type, numTypeParameters);
}
}
@@ -2610,7 +2683,7 @@
bool isClass = info.element is ClassElement;
_ReferenceInfo classInfo = isClass ? info : info.enclosing;
List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList();
- return classInfo.buildType((i) {
+ return classInfo.buildType(true, typeArguments.length, (i) {
if (i < typeArguments.length) {
return typeArguments[i];
} else {
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 35c6d01..8349428 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -29,12 +29,21 @@
final _SummarizeAstVisitor visitor;
/**
+ * If the expression being serialized can contain closures, map whose
+ * keys are the offsets of local function nodes representing those closures,
+ * and whose values are indices of those local functions relative to their
+ * siblings.
+ */
+ final Map<int, int> localClosureIndexMap;
+
+ /**
* If a constructor initializer expression is being serialized, the names of
* the constructor parameters. Otherwise `null`.
*/
final Set<String> constructorParameterNames;
- _ConstExprSerializer(this.visitor, this.constructorParameterNames);
+ _ConstExprSerializer(
+ this.visitor, this.localClosureIndexMap, this.constructorParameterNames);
@override
bool isConstructorParameterName(String name) {
@@ -74,6 +83,18 @@
}
}
+ @override
+ List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
+ int localIndex;
+ if (localClosureIndexMap == null) {
+ return null;
+ } else {
+ localIndex = localClosureIndexMap[functionExpression.offset];
+ assert(localIndex != null);
+ return <int>[0, localIndex];
+ }
+ }
+
EntityRefBuilder serializeIdentifier(Identifier identifier) {
EntityRefBuilder b = new EntityRefBuilder();
if (identifier is SimpleIdentifier) {
@@ -317,6 +338,14 @@
Block enclosingBlock = null;
/**
+ * If an expression is being serialized which can contain closures, map whose
+ * keys are the offsets of local function nodes representing those closures,
+ * and whose values are indices of those local functions relative to their
+ * siblings.
+ */
+ Map<int, int> _localClosureIndexMap;
+
+ /**
* Create a slot id for storing a propagated or inferred type or const cycle
* info.
*/
@@ -359,7 +388,9 @@
return const <UnlinkedConstBuilder>[];
}
return annotations.map((Annotation a) {
- _ConstExprSerializer serializer = new _ConstExprSerializer(this, null);
+ Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+ _ConstExprSerializer serializer =
+ new _ConstExprSerializer(this, localClosureIndexMap, null);
serializer.serializeAnnotation(a);
return serializer.toBuilder();
}).toList();
@@ -487,10 +518,11 @@
/**
* Serialize the given [expression], creating an [UnlinkedConstBuilder].
*/
- UnlinkedConstBuilder serializeConstExpr(Expression expression,
+ UnlinkedConstBuilder serializeConstExpr(
+ Map<int, int> localClosureIndexMap, Expression expression,
[Set<String> constructorParameterNames]) {
- _ConstExprSerializer serializer =
- new _ConstExprSerializer(this, constructorParameterNames);
+ _ConstExprSerializer serializer = new _ConstExprSerializer(
+ this, localClosureIndexMap, constructorParameterNames);
serializer.serialize(expression);
return serializer.toBuilder();
}
@@ -793,20 +825,8 @@
'Unexpected identifier type: ${identifier.runtimeType}');
}
if (typeArguments != null) {
- // Trailing type arguments of type 'dynamic' should be omitted.
- NodeList<TypeName> args = typeArguments.arguments;
- int numArgsToSerialize = args.length;
- while (
- numArgsToSerialize > 0 && isDynamic(args[numArgsToSerialize - 1])) {
- --numArgsToSerialize;
- }
- if (numArgsToSerialize > 0) {
- List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
- for (int i = 0; i < numArgsToSerialize; i++) {
- serializedArguments.add(serializeTypeName(args[i]));
- }
- b.typeArguments = serializedArguments;
- }
+ b.typeArguments =
+ typeArguments.arguments.map(serializeTypeName).toList();
}
return b;
}
@@ -862,12 +882,15 @@
b.documentationComment = serializeDocumentation(documentationComment);
b.annotations = serializeAnnotations(annotations);
b.codeRange = serializeCodeRange(variables.parent);
+ Map<int, int> localClosureIndexMap = _withLocalClosureIndexMap(() {
+ b.initializer = serializeInitializerFunction(variable.initializer);
+ });
if (variable.isConst ||
variable.isFinal && isField && !isDeclaredStatic ||
variables.type == null) {
Expression initializer = variable.initializer;
if (initializer != null) {
- b.constExpr = serializeConstExpr(initializer);
+ b.constExpr = serializeConstExpr(localClosureIndexMap, initializer);
}
}
if (variable.initializer != null &&
@@ -881,7 +904,6 @@
}
b.visibleOffset = scopeNode?.offset;
b.visibleLength = scopeNode?.length;
- b.initializer = serializeInitializerFunction(variable.initializer);
this.variables.add(b);
}
}
@@ -965,9 +987,11 @@
if (node.redirectedConstructor != null) {
b.isRedirectedConstructor = true;
TypeName typeName = node.redirectedConstructor.type;
- b.redirectedConstructor = new _ConstExprSerializer(this, null)
- .serializeConstructorRef(null, typeName.name,
- typeName.typeArguments, node.redirectedConstructor.name);
+ Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+ b.redirectedConstructor =
+ new _ConstExprSerializer(this, localClosureIndexMap, null)
+ .serializeConstructorRef(null, typeName.name,
+ typeName.typeArguments, node.redirectedConstructor.name);
}
} else {
for (ConstructorInitializer initializer in node.initializers) {
@@ -988,10 +1012,12 @@
if (node.constKeyword != null) {
Set<String> constructorParameterNames =
node.parameters.parameters.map((p) => p.identifier.name).toSet();
+ Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
b.constantInitializers = node.initializers
.map((ConstructorInitializer initializer) =>
serializeConstructorInitializer(initializer, (Expression expr) {
- return serializeConstExpr(expr, constructorParameterNames);
+ return serializeConstExpr(
+ localClosureIndexMap, expr, constructorParameterNames);
}))
.toList();
}
@@ -1004,7 +1030,9 @@
DefaultFormalParameter node) {
UnlinkedParamBuilder b = node.parameter.accept(this);
if (node.defaultValue != null) {
- b.defaultValue = serializeConstExpr(node.defaultValue);
+ Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+ b.defaultValue =
+ serializeConstExpr(localClosureIndexMap, node.defaultValue);
b.defaultValueCode = node.defaultValue.toSource();
}
b.initializer = serializeInitializerFunction(node.defaultValue);
@@ -1107,6 +1135,9 @@
@override
void visitFunctionExpression(FunctionExpression node) {
if (node.parent is! FunctionDeclaration) {
+ if (_localClosureIndexMap != null) {
+ _localClosureIndexMap[node.offset] = executables.length;
+ }
executables.add(serializeExecutable(
node,
null,
@@ -1269,6 +1300,21 @@
}
/**
+ * Execute [callback], gathering any local closures in
+ * [_localClosureIndexMap], and return the resulting map.
+ *
+ * Properly handles cases where one closure is nested within another.
+ */
+ Map<int, int> _withLocalClosureIndexMap(void callback()) {
+ Map<int, int> prevLocalClosureIndexMap = _localClosureIndexMap;
+ _localClosureIndexMap = <int, int>{};
+ callback();
+ Map<int, int> localClosureIndexMap = _localClosureIndexMap;
+ _localClosureIndexMap = prevLocalClosureIndexMap;
+ return localClosureIndexMap;
+ }
+
+ /**
* Helper method to determine if a given [typeName] refers to `dynamic`.
*/
static bool isDynamic(TypeName typeName) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 17a0b51..f8f6aab 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -22,19 +22,35 @@
name: node.fieldName.name,
expression: serializeConstExpr(node.expression));
}
+
+ List<UnlinkedConstBuilder> arguments = <UnlinkedConstBuilder>[];
+ List<String> argumentNames = <String>[];
+ void serializeArguments(List<Expression> args) {
+ for (Expression arg in args) {
+ if (arg is NamedExpression) {
+ NamedExpression namedExpression = arg;
+ argumentNames.add(namedExpression.name.label.name);
+ arg = namedExpression.expression;
+ }
+ arguments.add(serializeConstExpr(arg));
+ }
+ }
+
if (node is RedirectingConstructorInvocation) {
+ serializeArguments(node.argumentList.arguments);
return new UnlinkedConstructorInitializerBuilder(
kind: UnlinkedConstructorInitializerKind.thisInvocation,
name: node?.constructorName?.name,
- arguments:
- node.argumentList.arguments.map(serializeConstExpr).toList());
+ arguments: arguments,
+ argumentNames: argumentNames);
}
if (node is SuperConstructorInvocation) {
+ serializeArguments(node.argumentList.arguments);
return new UnlinkedConstructorInitializerBuilder(
kind: UnlinkedConstructorInitializerKind.superInvocation,
name: node?.constructorName?.name,
- arguments:
- node.argumentList.arguments.map(serializeConstExpr).toList());
+ arguments: arguments,
+ argumentNames: argumentNames);
}
throw new StateError('Unexpected initializer type ${node.runtimeType}');
}
@@ -45,11 +61,16 @@
*/
abstract class AbstractConstExprSerializer {
/**
- * See [UnlinkedConstBuilder.isInvalid].
+ * See [UnlinkedConstBuilder.isValidConst].
*/
bool isValidConst = true;
/**
+ * See [UnlinkedConstBuilder.nmae].
+ */
+ String name = null;
+
+ /**
* See [UnlinkedConstBuilder.operations].
*/
final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
@@ -91,6 +112,11 @@
*/
void serialize(Expression expr) {
try {
+ if (expr is NamedExpression) {
+ NamedExpression namedExpression = expr;
+ name = namedExpression.name.label.name;
+ expr = namedExpression.expression;
+ }
_serialize(expr);
} on StateError {
isValidConst = false;
@@ -117,6 +143,18 @@
EntityRefBuilder serializeIdentifier(Identifier identifier);
/**
+ * Return a pair of ints showing how the given [functionExpression] is nested
+ * within the constant currently being serialized. The first int indicates
+ * how many levels of function nesting must be popped in order to reach the
+ * parent of the [functionExpression]. The second int is the index of the
+ * [functionExpression] within its parent element.
+ *
+ * If the constant being summarized is in a context where local function
+ * references are not allowed, return `null`.
+ */
+ List<int> serializeFunctionExpression(FunctionExpression functionExpression);
+
+ /**
* Return [EntityRefBuilder] that corresponds to the given [expr], which
* must be a sequence of identifiers.
*/
@@ -277,8 +315,14 @@
_serializeCascadeExpression(expr);
} else if (expr is FunctionExpression) {
isValidConst = false;
- // TODO(scheglov) implement
- operations.add(UnlinkedConstOperation.pushNull);
+ List<int> indices = serializeFunctionExpression(expr);
+ if (indices != null) {
+ ints.addAll(serializeFunctionExpression(expr));
+ operations.add(UnlinkedConstOperation.pushLocalFunctionReference);
+ } else {
+ // Invalid expression; just push null.
+ operations.add(UnlinkedConstOperation.pushNull);
+ }
} else if (expr is FunctionExpressionInvocation) {
isValidConst = false;
// TODO(scheglov) implement
@@ -456,8 +500,8 @@
ArgumentList argumentList = invocation.argumentList;
if (_isIdentifierSequence(methodName)) {
EntityRefBuilder ref = serializeIdentifierSequence(methodName);
- references.add(ref);
_serializeArguments(argumentList);
+ references.add(ref);
operations.add(UnlinkedConstOperation.invokeMethodRef);
} else {
if (!invocation.isCascaded) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index b8828ec..cd2adec 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -355,7 +355,7 @@
kind: ReferenceKind.classOrEnum,
name: cls.name,
numTypeParameters: cls.typeParameters.length,
- members: serializeClassConstMembers(cls)));
+ members: serializeClassStaticMembers(cls)));
}
}
for (ClassElement enm in compilationUnit.enums) {
@@ -363,7 +363,7 @@
names.add(new UnlinkedPublicNameBuilder(
kind: ReferenceKind.classOrEnum,
name: enm.name,
- members: serializeClassConstMembers(enm)));
+ members: serializeClassStaticMembers(enm)));
}
}
for (FunctionElement function in compilationUnit.functions) {
@@ -519,7 +519,7 @@
}
return element.metadata.map((ElementAnnotation a) {
_ConstExprSerializer serializer =
- new _ConstExprSerializer(this, element, null);
+ new _ConstExprSerializer(this, element, null, null);
serializer
.serializeAnnotation((a as ElementAnnotationImpl).annotationAst);
return serializer.toBuilder();
@@ -594,11 +594,11 @@
}
/**
- * If [cls] is a class, return the list of its members available for
- * constants - static constant fields, static methods and constructors.
- * Otherwise return `null`.
+ * If [cls] is a class, return the list of its static members - static
+ * constant fields, static methods and constructors. Otherwise return `null`.
*/
- List<UnlinkedPublicNameBuilder> serializeClassConstMembers(ClassElement cls) {
+ List<UnlinkedPublicNameBuilder> serializeClassStaticMembers(
+ ClassElement cls) {
if (cls.isMixinApplication) {
// Mixin application members can't be determined directly from the AST so
// we can't store them in UnlinkedPublicName.
@@ -607,16 +607,6 @@
}
if (cls.kind == ElementKind.CLASS) {
List<UnlinkedPublicNameBuilder> bs = <UnlinkedPublicNameBuilder>[];
- for (FieldElement field in cls.fields) {
- if (field.isStatic && field.isConst && field.isPublic) {
- // TODO(paulberry): include non-consts
- // TODO(paulberry): should numTypeParameters include class params?
- bs.add(new UnlinkedPublicNameBuilder(
- name: field.name,
- kind: ReferenceKind.propertyAccessor,
- numTypeParameters: 0));
- }
- }
for (MethodElement method in cls.methods) {
if (method.isStatic && method.isPublic) {
// TODO(paulberry): should numTypeParameters include class params?
@@ -627,11 +617,7 @@
}
}
for (PropertyAccessorElement accessor in cls.accessors) {
- if (accessor.isStatic &&
- accessor.isGetter &&
- accessor.isPublic &&
- !accessor.isSynthetic) {
- // TODO(paulberry): combine with field code above.
+ if (accessor.isStatic && accessor.isGetter && accessor.isPublic) {
// TODO(paulberry): should numTypeParameters include class params?
bs.add(new UnlinkedPublicNameBuilder(
name: accessor.name, kind: ReferenceKind.propertyAccessor));
@@ -678,11 +664,11 @@
/**
* Serialize the given [expression], creating an [UnlinkedConstBuilder].
*/
- UnlinkedConstBuilder serializeConstExpr(
- Element context, Expression expression,
+ UnlinkedConstBuilder serializeConstExpr(Element context,
+ ExecutableElement executableContext, Expression expression,
[Set<String> constructorParameterNames]) {
- _ConstExprSerializer serializer =
- new _ConstExprSerializer(this, context, constructorParameterNames);
+ _ConstExprSerializer serializer = new _ConstExprSerializer(
+ this, context, executableContext, constructorParameterNames);
serializer.serialize(expression);
return serializer.toBuilder();
}
@@ -797,7 +783,7 @@
.map((ConstructorInitializer initializer) =>
serializeConstructorInitializer(
initializer,
- (expr) => serializeConstExpr(
+ (expr) => serializeConstExpr(executableElement,
executableElement, expr, constructorParameterNames)))
.toList();
}
@@ -937,7 +923,10 @@
ConstVariableElement constParameter = parameter as ConstVariableElement;
Expression initializer = constParameter.constantInitializer;
if (initializer != null) {
- b.defaultValue = serializeConstExpr(parameter, initializer);
+ b.defaultValue = serializeConstExpr(
+ parameter,
+ parameter.getAncestor((Element e) => e is ExecutableElement),
+ initializer);
b.defaultValueCode = parameter.defaultValueCode;
}
}
@@ -1063,19 +1052,19 @@
ParameterElement parameterElement = typeElement.enclosingElement;
while (true) {
Element parent = parameterElement.enclosingElement;
- if (parent is ExecutableElement) {
- Element grandParent = parent.enclosingElement;
+ if (parent is ParameterElement) {
+ // Function-typed parameter inside a function-typed parameter.
b.implicitFunctionTypeIndices
.insert(0, parent.parameters.indexOf(parameterElement));
- if (grandParent is ParameterElement) {
- // Function-typed parameter inside a function-typed parameter.
- parameterElement = grandParent;
- continue;
- } else {
- // Function-typed parameter inside a top level function or method.
- b.reference = _getElementReferenceId(parent);
- break;
- }
+ parameterElement = parent;
+ continue;
+ } else if (parent is FunctionTypedElement) {
+ b.implicitFunctionTypeIndices
+ .insert(0, parent.parameters.indexOf(parameterElement));
+ // Function-typed parameter inside a top level function, method, or
+ // typedef.
+ b.reference = _getElementReferenceId(parent);
+ break;
} else {
throw new StateError(
'Unexpected element enclosing parameter: ${parent.runtimeType}');
@@ -1086,20 +1075,9 @@
}
List<DartType> typeArguments = getTypeArguments(type);
if (typeArguments != null) {
- // Trailing type arguments of type 'dynamic' should be omitted.
- int numArgsToSerialize = typeArguments.length;
- while (numArgsToSerialize > 0 &&
- typeArguments[numArgsToSerialize - 1].isDynamic) {
- --numArgsToSerialize;
- }
- if (numArgsToSerialize > 0) {
- List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
- for (int i = 0; i < numArgsToSerialize; i++) {
- serializedArguments
- .add(serializeTypeRef(typeArguments[i], context));
- }
- b.typeArguments = serializedArguments;
- }
+ b.typeArguments = typeArguments
+ .map((typeArgument) => serializeTypeRef(typeArgument, context))
+ .toList();
}
}
return b;
@@ -1159,7 +1137,8 @@
ConstVariableElement constVariable = variable as ConstVariableElement;
Expression initializer = constVariable.constantInitializer;
if (initializer != null) {
- b.constExpr = serializeConstExpr(variable, initializer);
+ b.constExpr =
+ serializeConstExpr(variable, variable.initializer, initializer);
}
}
if (variable is PropertyInducingElement) {
@@ -1319,6 +1298,7 @@
class _ConstExprSerializer extends AbstractConstExprSerializer {
final _CompilationUnitSerializer serializer;
final Element context;
+ final ExecutableElement executableContext;
/**
* If a constructor initializer expression is being serialized, the names of
@@ -1326,8 +1306,8 @@
*/
final Set<String> constructorParameterNames;
- _ConstExprSerializer(
- this.serializer, this.context, this.constructorParameterNames);
+ _ConstExprSerializer(this.serializer, this.context, this.executableContext,
+ this.constructorParameterNames);
@override
bool isConstructorParameterName(String name) {
@@ -1388,6 +1368,21 @@
}
}
+ @override
+ List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
+ if (executableContext == null) {
+ return null;
+ }
+ ExecutableElement functionElement = functionExpression.element;
+ // TOOD(paulberry): handle the situation where [functionExpression] is not
+ // an immediate child of [executableContext].
+ assert(functionElement.enclosingElement == executableContext);
+ int popCount = 0;
+ int localIndex = executableContext.functions.indexOf(functionElement);
+ assert(localIndex != -1);
+ return <int>[popCount, localIndex];
+ }
+
EntityRefBuilder serializeIdentifier(Identifier identifier,
{int prefixReference: 0}) {
if (identifier is SimpleIdentifier) {
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 77303c3..2dfa154 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -104,7 +104,8 @@
result == CREATED_RESOLVED_UNIT8 ||
result == CREATED_RESOLVED_UNIT9 ||
result == CREATED_RESOLVED_UNIT10 ||
- result == CREATED_RESOLVED_UNIT11) {
+ result == CREATED_RESOLVED_UNIT11 ||
+ result == CREATED_RESOLVED_UNIT12) {
entry.setValue(result, true, TargetedResult.EMPTY_LIST);
return true;
}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index ca0f09d..b1b6d95 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -1234,7 +1234,10 @@
// Build the enum members if they have not already been created.
//
EnumDeclaration findFirstEnum() {
- for (CompilationUnitMember member in unit.declarations) {
+ NodeList<CompilationUnitMember> members = unit.declarations;
+ int length = members.length;
+ for (int i = 0; i < length; i++) {
+ CompilationUnitMember member = members[i];
if (member is EnumDeclaration) {
return member;
}
@@ -1407,7 +1410,9 @@
definingCompilationUnit.element;
Map<Source, CompilationUnit> partUnitMap =
new HashMap<Source, CompilationUnit>();
- for (CompilationUnit partUnit in partUnits) {
+ int partLength = partUnits.length;
+ for (int i = 0; i < partLength; i++) {
+ CompilationUnit partUnit = partUnits[i];
Source partSource = partUnit.element.source;
partUnitMap[partSource] = partUnit;
}
@@ -1422,7 +1427,10 @@
List<Directive> directivesToResolve = <Directive>[];
List<CompilationUnitElementImpl> sourcedCompilationUnits =
<CompilationUnitElementImpl>[];
- for (Directive directive in definingCompilationUnit.directives) {
+ NodeList<Directive> directives = definingCompilationUnit.directives;
+ int directiveLength = directives.length;
+ for (int i = 0; i < directiveLength; i++) {
+ Directive directive = directives[i];
if (directive is LibraryDirective) {
libraryNameNode = directive.name;
directivesToResolve.add(directive);
@@ -1533,7 +1541,9 @@
// TODO(brianwilkerson) This updates the state of the AST structures but
// does not associate a new result with it.
//
- for (Directive directive in directivesToResolve) {
+ int length = directivesToResolve.length;
+ for (int i = 0; i < length; i++) {
+ Directive directive = directivesToResolve[i];
directive.element = libraryElement;
}
//
@@ -1549,7 +1559,10 @@
* [element] does not define an entry point.
*/
FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
- for (FunctionElement function in element.functions) {
+ List<FunctionElement> functions = element.functions;
+ int length = functions.length;
+ for (int i = 0; i < length; i++) {
+ FunctionElement function = functions[i];
if (function.isEntryPoint) {
return function;
}
@@ -1563,7 +1576,10 @@
*/
String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
List<Directive> directivesToResolve) {
- for (Directive directive in partUnit.directives) {
+ NodeList<Directive> directives = partUnit.directives;
+ int length = directives.length;
+ for (int i = 0; i < length; i++) {
+ Directive directive = directives[i];
if (directive is PartOfDirective) {
directivesToResolve.add(directive);
LibraryIdentifier libraryName = directive.libraryName;
@@ -1580,7 +1596,10 @@
* import directive with a `dart-ext:` URI.
*/
bool _hasExtUri(CompilationUnit unit) {
- for (Directive directive in unit.directives) {
+ NodeList<Directive> directives = unit.directives;
+ int length = directives.length;
+ for (int i = 0; i < length; i++) {
+ Directive directive = directives[i];
if (directive is ImportDirective) {
if (DartUriResolver.isDartExtUri(directive.uriContent)) {
return true;
@@ -1921,7 +1940,9 @@
} else {
List<ConstantEvaluationTarget> constantsInCycle =
<ConstantEvaluationTarget>[];
- for (WorkItem workItem in dependencyCycle) {
+ int length = dependencyCycle.length;
+ for (int i = 0; i < length; i++) {
+ WorkItem workItem = dependencyCycle[i];
if (workItem.descriptor == DESCRIPTOR) {
constantsInCycle.add(workItem.target);
}
@@ -2104,9 +2125,11 @@
deps.addAll(l.units);
}
}
- for (LibraryElement l in component) {
- l.importedLibraries.forEach(addLibrary);
- l.exportedLibraries.forEach(addLibrary);
+ int length = component.length;
+ for (int i = 0; i < length; i++) {
+ LibraryElement library = component[i];
+ library.importedLibraries.forEach(addLibrary);
+ library.exportedLibraries.forEach(addLibrary);
}
//
// Record outputs.
@@ -2385,7 +2408,9 @@
if (targetSource != null) {
List<Source> librarySources =
context.getLibrariesContaining(targetSource);
- for (Source librarySource in librarySources) {
+ int length = librarySources.length;
+ for (int i = 0; i < length; i++) {
+ Source librarySource = librarySources[i];
AnalysisCache cache = context.analysisCache;
ReferencedNames referencedNames =
cache.getValue(librarySource, REFERENCED_NAMES);
@@ -2443,11 +2468,17 @@
// Prepare inputs.
//
EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
- for (ResultDescriptor result in enginePlugin.dartErrorsForSource) {
+ List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
+ int sourceLength = errorsForSource.length;
+ for (int i = 0; i < sourceLength; i++) {
+ ResultDescriptor result = errorsForSource[i];
String inputName = result.name + '_input';
errorLists.add(getRequiredInput(inputName));
}
- for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
+ List<ResultDescriptor> errorsForUnit = enginePlugin.dartErrorsForUnit;
+ int unitLength = errorsForUnit.length;
+ for (int i = 0; i < unitLength; i++) {
+ ResultDescriptor result = errorsForUnit[i];
String inputName = result.name + '_input';
Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName);
for (List<AnalysisError> errors in errorMap.values) {
@@ -2544,12 +2575,18 @@
inputs[PARSED_UNIT_INPUT] = PARSED_UNIT.of(source);
EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
// for Source
- for (ResultDescriptor result in enginePlugin.dartErrorsForSource) {
+ List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
+ int sourceLength = errorsForSource.length;
+ for (int i = 0; i < sourceLength; i++) {
+ ResultDescriptor result = errorsForSource[i];
String inputName = result.name + '_input';
inputs[inputName] = result.of(source);
}
// for LibrarySpecificUnit
- for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
+ List<ResultDescriptor> errorsForUnit = enginePlugin.dartErrorsForUnit;
+ int unitLength = errorsForUnit.length;
+ for (int i = 0; i < unitLength; i++) {
+ ResultDescriptor result = errorsForUnit[i];
String inputName = result.name + '_input';
inputs[inputName] =
CONTAINING_LIBRARIES.of(source).toMap((Source library) {
@@ -2936,7 +2973,9 @@
bool timeVisits = analysisOptions.enableTiming;
List<Linter> linters = getLints(context);
- for (Linter linter in linters) {
+ int length = linters.length;
+ for (int i = 0; i < length; i++) {
+ Linter linter = linters[i];
AstVisitor visitor = linter.getVisitor();
if (visitor != null) {
linter.reporter = errorReporter;
@@ -3586,7 +3625,10 @@
HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>();
HashSet<Source> exportedSourceSet = new HashSet<Source>();
HashSet<Source> includedSourceSet = new HashSet<Source>();
- for (Directive directive in unit.directives) {
+ NodeList<Directive> directives = unit.directives;
+ int length = directives.length;
+ for (int i = 0; i < length; i++) {
+ Directive directive = directives[i];
if (directive is PartOfDirective) {
hasPartOfDirective = true;
} else {
@@ -4666,8 +4708,9 @@
List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
// Compute referenced names.
ReferencedNames referencedNames = new ReferencedNames();
- for (CompilationUnit unit in units) {
- new ReferencedNamesBuilder(referencedNames).build(unit);
+ int length = units.length;
+ for (int i = 0; i < length; i++) {
+ new ReferencedNamesBuilder(referencedNames).build(units[i]);
}
//
// Record outputs.
@@ -5595,7 +5638,10 @@
* exists and report an error if it does not.
*/
void validateDirectives(CompilationUnit unit) {
- for (Directive directive in unit.directives) {
+ NodeList<Directive> directives = unit.directives;
+ int length = directives.length;
+ for (int i = 0; i < length; i++) {
+ Directive directive = directives[i];
if (directive is UriBasedDirective) {
validateReferencedSource(directive);
}
@@ -5717,14 +5763,20 @@
if (_libraries.add(library)) {
if (kind == _SourceClosureKind.IMPORT ||
kind == _SourceClosureKind.IMPORT_EXPORT) {
- for (ImportElement importElement in library.imports) {
+ List<ImportElement> imports = library.imports;
+ int length = imports.length;
+ for (int i = 0; i < length; i++) {
+ ImportElement importElement = imports[i];
Source importedSource = importElement.importedLibrary.source;
_newSources.add(importedSource);
}
}
if (kind == _SourceClosureKind.EXPORT ||
kind == _SourceClosureKind.IMPORT_EXPORT) {
- for (ExportElement exportElement in library.exports) {
+ List<ExportElement> exports = library.exports;
+ int length = exports.length;
+ for (int i = 0; i < length; i++) {
+ ExportElement exportElement = exports[i];
Source exportedSource = exportElement.exportedLibrary.source;
_newSources.add(exportedSource);
}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3e6f6f5..6b0049b 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -622,8 +622,8 @@
var staticInfo;
var rhsType = _getStaticType(expr.rightHandSide);
var lhsType = _getStaticType(expr.leftHandSide);
- var returnType = _specializedBinaryReturnType(
- op, lhsType, rhsType, functionType.returnType);
+ var returnType = rules.refineBinaryExpressionType(
+ typeProvider, lhsType, op, rhsType, functionType.returnType);
if (!rules.isSubtypeOf(returnType, lhsType)) {
final numType = typeProvider.numType;
@@ -921,32 +921,6 @@
CoercionInfo.set(info.node, info);
}
}
-
- DartType _specializedBinaryReturnType(
- TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
- // This special cases binary return types as per 16.26 and 16.27 of the
- // Dart language spec.
- switch (op) {
- case TokenType.PLUS:
- case TokenType.MINUS:
- case TokenType.STAR:
- case TokenType.TILDE_SLASH:
- case TokenType.PERCENT:
- case TokenType.PLUS_EQ:
- case TokenType.MINUS_EQ:
- case TokenType.STAR_EQ:
- case TokenType.TILDE_SLASH_EQ:
- case TokenType.PERCENT_EQ:
- if (t1 == typeProvider.intType && t2 == typeProvider.intType) return t1;
- if (t1 == typeProvider.doubleType && t2 == typeProvider.doubleType)
- return t1;
- // This particular combo is not spelled out in the spec, but all
- // implementations and analyzer seem to follow this.
- if (t1 == typeProvider.doubleType && t2 == typeProvider.intType)
- return t1;
- }
- return normalReturnType;
- }
}
/// Checks for overriding declarations of fields and methods. This is used to
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 126b5a6..9e15c290 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.27.4-alpha.1
+version: 0.27.4-alpha.2
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index e4f8395..06d6c98 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -280,6 +280,32 @@
_assertNoErrors(classB);
}
+ void test_getMapOfMembersInheritedFromInterfaces_field_indirectWith() {
+ // class A { int f; }
+ // class B extends A {}
+ // class C extends Object with B {}
+ ClassElementImpl classA = ElementFactory.classElement2('A');
+ String fieldName = "f";
+ FieldElement fieldF = ElementFactory.fieldElement(
+ fieldName, false, false, false, _typeProvider.intType);
+ classA.fields = <FieldElement>[fieldF];
+ classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
+
+ ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+
+ ClassElementImpl classC = ElementFactory.classElement2('C');
+ classC.mixins = <InterfaceType>[classB.type];
+
+ Map<String, ExecutableElement> mapC =
+ _inheritanceManager.getMembersInheritedFromInterfaces(classC);
+ expect(mapC, hasLength(_numOfMembersInObject + 2));
+ expect(mapC[fieldName], same(fieldF.getter));
+ expect(mapC['$fieldName='], same(fieldF.setter));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ _assertNoErrors(classC);
+ }
+
void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
// class A {}
ClassElementImpl classA = ElementFactory.classElement2("A");
@@ -869,6 +895,30 @@
_assertNoErrors(classA);
}
+ void test_getMembersInheritedFromClasses_field_indirectWith() {
+ // class A { int f; }
+ // class B extends A {}
+ // class C extends Object with B {}
+ ClassElementImpl classA = ElementFactory.classElement2('A');
+ String fieldName = "f";
+ FieldElement fieldF = ElementFactory.fieldElement(
+ fieldName, false, false, false, _typeProvider.intType);
+ classA.fields = <FieldElement>[fieldF];
+ classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
+
+ ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+
+ ClassElementImpl classC = ElementFactory.classElement2('C');
+ classC.mixins = <InterfaceType>[classB.type];
+
+ Map<String, ExecutableElement> mapC =
+ _inheritanceManager.getMembersInheritedFromClasses(classC);
+ expect(mapC, hasLength(_numOfMembersInObject));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ _assertNoErrors(classC);
+ }
+
void test_lookupInheritance_interface_getter() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index e458070..41a5185 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -5112,6 +5112,30 @@
verify([source]);
}
+ void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+typedef F<T extends A>();
+F<A> fa;
+F<B> fb;
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_noBound() {
+ Source source = addSource(r'''
+typedef F<T>();
+F<int> f1;
+F<String> f2;
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_typeArgumentNotMatchingBounds_typeArgumentList_0() {
Source source = addSource("abstract class A<T extends A>{}");
computeLibrarySourceErrors(source);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 9b3f082..381313e 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1381,6 +1381,17 @@
[StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
}
+ void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() {
+ assertErrorsInCode(
+ r'''
+class A {}
+class B {}
+typedef F<T extends A>();
+F<B> fff;
+''',
+ [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ }
+
void test_typeArgumentNotMatchingBounds_parameter() {
assertErrorsInCode(
r'''
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f8fc40d..9eb44ab 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -4,6 +4,7 @@
library analyzer.test.generated.static_warning_code_test;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:unittest/unittest.dart';
@@ -2862,6 +2863,23 @@
verify([source]);
}
+ void
+ test_nonAbstractClassInheritsAbstractMemberTwo_variable_fromMixin_missingBoth() {
+ // 26411
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ int f;
+}
+class B extends A {}
+class C extends Object with B {}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source,
+ [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
+ verify([source]);
+ }
+
void test_nonTypeInCatchClause_noElement() {
Source source = addSource(r'''
f() {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index f6f898a..344612b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1588,886 +1588,918 @@
class DirectedGraphTest_Node {}
class Getter_NodeReplacerTest_test_annotation
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<Annotation, ArgumentList> {
@override
ArgumentList get(Annotation node) => node.arguments;
}
class Getter_NodeReplacerTest_test_annotation_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<Annotation, Identifier> {
@override
Identifier get(Annotation node) => node.name;
}
class Getter_NodeReplacerTest_test_annotation_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<Annotation, SimpleIdentifier> {
@override
SimpleIdentifier get(Annotation node) => node.constructorName;
}
class Getter_NodeReplacerTest_test_asExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AsExpression, TypeName> {
@override
TypeName get(AsExpression node) => node.type;
}
class Getter_NodeReplacerTest_test_asExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AsExpression, Expression> {
@override
Expression get(AsExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_assertStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AssertStatement, Expression> {
@override
Expression get(AssertStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_assertStatement_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AssertStatement, Expression> {
@override
Expression get(AssertStatement node) => node.message;
}
class Getter_NodeReplacerTest_test_assignmentExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AssignmentExpression, Expression> {
@override
Expression get(AssignmentExpression node) => node.rightHandSide;
}
class Getter_NodeReplacerTest_test_assignmentExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AssignmentExpression, Expression> {
@override
Expression get(AssignmentExpression node) => node.leftHandSide;
}
class Getter_NodeReplacerTest_test_awaitExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AwaitExpression, Expression> {
@override
Expression get(AwaitExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_binaryExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<BinaryExpression, Expression> {
@override
Expression get(BinaryExpression node) => node.leftOperand;
}
class Getter_NodeReplacerTest_test_binaryExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<BinaryExpression, Expression> {
@override
Expression get(BinaryExpression node) => node.rightOperand;
}
class Getter_NodeReplacerTest_test_blockFunctionBody
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<BlockFunctionBody, Block> {
@override
Block get(BlockFunctionBody node) => node.block;
}
class Getter_NodeReplacerTest_test_breakStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<BreakStatement, SimpleIdentifier> {
@override
SimpleIdentifier get(BreakStatement node) => node.label;
}
class Getter_NodeReplacerTest_test_cascadeExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CascadeExpression, Expression> {
@override
Expression get(CascadeExpression node) => node.target;
}
class Getter_NodeReplacerTest_test_catchClause
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
@override
SimpleIdentifier get(CatchClause node) => node.stackTraceParameter;
}
class Getter_NodeReplacerTest_test_catchClause_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
@override
SimpleIdentifier get(CatchClause node) => node.exceptionParameter;
}
class Getter_NodeReplacerTest_test_catchClause_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CatchClause, TypeName> {
@override
TypeName get(CatchClause node) => node.exceptionType;
}
class Getter_NodeReplacerTest_test_classDeclaration
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, ImplementsClause> {
@override
ImplementsClause get(ClassDeclaration node) => node.implementsClause;
}
class Getter_NodeReplacerTest_test_classDeclaration_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, WithClause> {
@override
WithClause get(ClassDeclaration node) => node.withClause;
}
class Getter_NodeReplacerTest_test_classDeclaration_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, NativeClause> {
@override
NativeClause get(ClassDeclaration node) => node.nativeClause;
}
class Getter_NodeReplacerTest_test_classDeclaration_4
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, ExtendsClause> {
@override
ExtendsClause get(ClassDeclaration node) => node.extendsClause;
}
class Getter_NodeReplacerTest_test_classDeclaration_5
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, TypeParameterList> {
@override
TypeParameterList get(ClassDeclaration node) => node.typeParameters;
}
class Getter_NodeReplacerTest_test_classDeclaration_6
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(ClassDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_classTypeAlias
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassTypeAlias, TypeName> {
@override
TypeName get(ClassTypeAlias node) => node.superclass;
}
class Getter_NodeReplacerTest_test_classTypeAlias_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassTypeAlias, ImplementsClause> {
@override
ImplementsClause get(ClassTypeAlias node) => node.implementsClause;
}
class Getter_NodeReplacerTest_test_classTypeAlias_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassTypeAlias, WithClause> {
@override
WithClause get(ClassTypeAlias node) => node.withClause;
}
class Getter_NodeReplacerTest_test_classTypeAlias_4
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassTypeAlias, SimpleIdentifier> {
@override
SimpleIdentifier get(ClassTypeAlias node) => node.name;
}
class Getter_NodeReplacerTest_test_classTypeAlias_5
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ClassTypeAlias, TypeParameterList> {
@override
TypeParameterList get(ClassTypeAlias node) => node.typeParameters;
}
class Getter_NodeReplacerTest_test_commentReference
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CommentReference, Identifier> {
@override
Identifier get(CommentReference node) => node.identifier;
}
class Getter_NodeReplacerTest_test_compilationUnit
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<CompilationUnit, ScriptTag> {
@override
ScriptTag get(CompilationUnit node) => node.scriptTag;
}
class Getter_NodeReplacerTest_test_conditionalExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
@override
Expression get(ConditionalExpression node) => node.elseExpression;
}
class Getter_NodeReplacerTest_test_conditionalExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
@override
Expression get(ConditionalExpression node) => node.thenExpression;
}
class Getter_NodeReplacerTest_test_conditionalExpression_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
@override
Expression get(ConditionalExpression node) => node.condition;
}
class Getter_NodeReplacerTest_test_constructorDeclaration
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<ConstructorDeclaration, ConstructorName> {
@override
ConstructorName get(ConstructorDeclaration node) =>
node.redirectedConstructor;
}
class Getter_NodeReplacerTest_test_constructorDeclaration_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<ConstructorDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(ConstructorDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_constructorDeclaration_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConstructorDeclaration, Identifier> {
@override
Identifier get(ConstructorDeclaration node) => node.returnType;
}
class Getter_NodeReplacerTest_test_constructorDeclaration_4
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<ConstructorDeclaration, FormalParameterList> {
@override
FormalParameterList get(ConstructorDeclaration node) => node.parameters;
}
class Getter_NodeReplacerTest_test_constructorDeclaration_5
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConstructorDeclaration, FunctionBody> {
@override
FunctionBody get(ConstructorDeclaration node) => node.body;
}
class Getter_NodeReplacerTest_test_constructorFieldInitializer
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<ConstructorFieldInitializer, SimpleIdentifier> {
@override
SimpleIdentifier get(ConstructorFieldInitializer node) => node.fieldName;
}
class Getter_NodeReplacerTest_test_constructorFieldInitializer_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<ConstructorFieldInitializer, Expression> {
@override
Expression get(ConstructorFieldInitializer node) => node.expression;
}
class Getter_NodeReplacerTest_test_constructorName
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConstructorName, TypeName> {
@override
TypeName get(ConstructorName node) => node.type;
}
class Getter_NodeReplacerTest_test_constructorName_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ConstructorName, SimpleIdentifier> {
@override
SimpleIdentifier get(ConstructorName node) => node.name;
}
class Getter_NodeReplacerTest_test_continueStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ContinueStatement, SimpleIdentifier> {
@override
SimpleIdentifier get(ContinueStatement node) => node.label;
}
class Getter_NodeReplacerTest_test_declaredIdentifier
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<DeclaredIdentifier, TypeName> {
@override
TypeName get(DeclaredIdentifier node) => node.type;
}
class Getter_NodeReplacerTest_test_declaredIdentifier_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<DeclaredIdentifier, SimpleIdentifier> {
@override
SimpleIdentifier get(DeclaredIdentifier node) => node.identifier;
}
class Getter_NodeReplacerTest_test_defaultFormalParameter
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<DefaultFormalParameter, NormalFormalParameter> {
@override
NormalFormalParameter get(DefaultFormalParameter node) => node.parameter;
}
class Getter_NodeReplacerTest_test_defaultFormalParameter_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<DefaultFormalParameter, Expression> {
@override
Expression get(DefaultFormalParameter node) => node.defaultValue;
}
class Getter_NodeReplacerTest_test_doStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<DoStatement, Expression> {
@override
Expression get(DoStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_doStatement_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<DoStatement, Statement> {
@override
Statement get(DoStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_enumConstantDeclaration
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<EnumConstantDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(EnumConstantDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_enumDeclaration
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<EnumDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(EnumDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_expressionFunctionBody
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ExpressionFunctionBody, Expression> {
@override
Expression get(ExpressionFunctionBody node) => node.expression;
}
class Getter_NodeReplacerTest_test_expressionStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ExpressionStatement, Expression> {
@override
Expression get(ExpressionStatement node) => node.expression;
}
class Getter_NodeReplacerTest_test_extendsClause
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ExtendsClause, TypeName> {
@override
TypeName get(ExtendsClause node) => node.superclass;
}
class Getter_NodeReplacerTest_test_fieldDeclaration
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FieldDeclaration, VariableDeclarationList> {
@override
VariableDeclarationList get(FieldDeclaration node) => node.fields;
}
class Getter_NodeReplacerTest_test_fieldFormalParameter
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FieldFormalParameter, FormalParameterList> {
@override
FormalParameterList get(FieldFormalParameter node) => node.parameters;
}
class Getter_NodeReplacerTest_test_fieldFormalParameter_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FieldFormalParameter, TypeName> {
@override
TypeName get(FieldFormalParameter node) => node.type;
}
class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, Statement> {
@override
Statement get(ForEachStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, SimpleIdentifier> {
@override
SimpleIdentifier get(ForEachStatement node) => node.identifier;
}
class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, Expression> {
@override
Expression get(ForEachStatement node) => node.iterable;
}
class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, Expression> {
@override
Expression get(ForEachStatement node) => node.iterable;
}
class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, DeclaredIdentifier> {
@override
DeclaredIdentifier get(ForEachStatement node) => node.loopVariable;
}
class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForEachStatement, Statement> {
@override
Statement get(ForEachStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_forStatement_withInitialization
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, Statement> {
@override
Statement get(ForStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_forStatement_withInitialization_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, Expression> {
@override
Expression get(ForStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_forStatement_withInitialization_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, Expression> {
@override
Expression get(ForStatement node) => node.initialization;
}
class Getter_NodeReplacerTest_test_forStatement_withVariables
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, Statement> {
@override
Statement get(ForStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_forStatement_withVariables_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, VariableDeclarationList> {
@override
VariableDeclarationList get(ForStatement node) => node.variables;
}
class Getter_NodeReplacerTest_test_forStatement_withVariables_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ForStatement, Expression> {
@override
Expression get(ForStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_functionDeclaration
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionDeclaration, TypeName> {
@override
TypeName get(FunctionDeclaration node) => node.returnType;
}
class Getter_NodeReplacerTest_test_functionDeclaration_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionDeclaration, FunctionExpression> {
@override
FunctionExpression get(FunctionDeclaration node) => node.functionExpression;
}
class Getter_NodeReplacerTest_test_functionDeclaration_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(FunctionDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_functionDeclarationStatement
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionDeclarationStatement,
+ FunctionDeclaration> {
@override
FunctionDeclaration get(FunctionDeclarationStatement node) =>
node.functionDeclaration;
}
class Getter_NodeReplacerTest_test_functionExpression
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionExpression, FormalParameterList> {
@override
FormalParameterList get(FunctionExpression node) => node.parameters;
}
class Getter_NodeReplacerTest_test_functionExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionExpression, FunctionBody> {
@override
FunctionBody get(FunctionExpression node) => node.body;
}
class Getter_NodeReplacerTest_test_functionExpressionInvocation
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionExpressionInvocation, Expression> {
@override
Expression get(FunctionExpressionInvocation node) => node.function;
}
class Getter_NodeReplacerTest_test_functionExpressionInvocation_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionExpressionInvocation, ArgumentList> {
@override
ArgumentList get(FunctionExpressionInvocation node) => node.argumentList;
}
class Getter_NodeReplacerTest_test_functionTypeAlias
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionTypeAlias, TypeParameterList> {
@override
TypeParameterList get(FunctionTypeAlias node) => node.typeParameters;
}
class Getter_NodeReplacerTest_test_functionTypeAlias_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionTypeAlias, FormalParameterList> {
@override
FormalParameterList get(FunctionTypeAlias node) => node.parameters;
}
class Getter_NodeReplacerTest_test_functionTypeAlias_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionTypeAlias, TypeName> {
@override
TypeName get(FunctionTypeAlias node) => node.returnType;
}
class Getter_NodeReplacerTest_test_functionTypeAlias_4
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionTypeAlias, SimpleIdentifier> {
@override
SimpleIdentifier get(FunctionTypeAlias node) => node.name;
}
class Getter_NodeReplacerTest_test_functionTypedFormalParameter
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<FunctionTypedFormalParameter, TypeName> {
@override
TypeName get(FunctionTypedFormalParameter node) => node.returnType;
}
class Getter_NodeReplacerTest_test_functionTypedFormalParameter_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<FunctionTypedFormalParameter,
+ FormalParameterList> {
@override
FormalParameterList get(FunctionTypedFormalParameter node) => node.parameters;
}
class Getter_NodeReplacerTest_test_ifStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IfStatement, Expression> {
@override
Expression get(IfStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_ifStatement_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IfStatement, Statement> {
@override
Statement get(IfStatement node) => node.elseStatement;
}
class Getter_NodeReplacerTest_test_ifStatement_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IfStatement, Statement> {
@override
Statement get(IfStatement node) => node.thenStatement;
}
class Getter_NodeReplacerTest_test_importDirective
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ImportDirective, SimpleIdentifier> {
@override
SimpleIdentifier get(ImportDirective node) => node.prefix;
}
class Getter_NodeReplacerTest_test_indexExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IndexExpression, Expression> {
@override
Expression get(IndexExpression node) => node.target;
}
class Getter_NodeReplacerTest_test_indexExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IndexExpression, Expression> {
@override
Expression get(IndexExpression node) => node.index;
}
class Getter_NodeReplacerTest_test_instanceCreationExpression
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<InstanceCreationExpression, ArgumentList> {
@override
ArgumentList get(InstanceCreationExpression node) => node.argumentList;
}
class Getter_NodeReplacerTest_test_instanceCreationExpression_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<InstanceCreationExpression, ConstructorName> {
@override
ConstructorName get(InstanceCreationExpression node) => node.constructorName;
}
class Getter_NodeReplacerTest_test_interpolationExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<InterpolationExpression, Expression> {
@override
Expression get(InterpolationExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_isExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IsExpression, Expression> {
@override
Expression get(IsExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_isExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<IsExpression, TypeName> {
@override
TypeName get(IsExpression node) => node.type;
}
-class Getter_NodeReplacerTest_test_label implements NodeReplacerTest_Getter {
+class Getter_NodeReplacerTest_test_label
+ implements NodeReplacerTest_Getter<Label, SimpleIdentifier> {
@override
SimpleIdentifier get(Label node) => node.label;
}
class Getter_NodeReplacerTest_test_labeledStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<LabeledStatement, Statement> {
@override
Statement get(LabeledStatement node) => node.statement;
}
class Getter_NodeReplacerTest_test_libraryDirective
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<LibraryDirective, LibraryIdentifier> {
@override
LibraryIdentifier get(LibraryDirective node) => node.name;
}
class Getter_NodeReplacerTest_test_mapLiteralEntry
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MapLiteralEntry, Expression> {
@override
Expression get(MapLiteralEntry node) => node.value;
}
class Getter_NodeReplacerTest_test_mapLiteralEntry_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MapLiteralEntry, Expression> {
@override
Expression get(MapLiteralEntry node) => node.key;
}
class Getter_NodeReplacerTest_test_methodDeclaration
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodDeclaration, TypeName> {
@override
TypeName get(MethodDeclaration node) => node.returnType;
}
class Getter_NodeReplacerTest_test_methodDeclaration_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodDeclaration, FunctionBody> {
@override
FunctionBody get(MethodDeclaration node) => node.body;
}
class Getter_NodeReplacerTest_test_methodDeclaration_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(MethodDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_methodDeclaration_4
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodDeclaration, FormalParameterList> {
@override
FormalParameterList get(MethodDeclaration node) => node.parameters;
}
class Getter_NodeReplacerTest_test_methodInvocation
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodInvocation, ArgumentList> {
@override
ArgumentList get(MethodInvocation node) => node.argumentList;
}
class Getter_NodeReplacerTest_test_methodInvocation_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodInvocation, Expression> {
@override
Expression get(MethodInvocation node) => node.target;
}
class Getter_NodeReplacerTest_test_methodInvocation_3
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<MethodInvocation, SimpleIdentifier> {
@override
SimpleIdentifier get(MethodInvocation node) => node.methodName;
}
class Getter_NodeReplacerTest_test_namedExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<NamedExpression, Label> {
@override
Label get(NamedExpression node) => node.name;
}
class Getter_NodeReplacerTest_test_namedExpression_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<NamedExpression, Expression> {
@override
Expression get(NamedExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_nativeClause
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<NativeClause, StringLiteral> {
@override
StringLiteral get(NativeClause node) => node.name;
}
class Getter_NodeReplacerTest_test_nativeFunctionBody
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<NativeFunctionBody, StringLiteral> {
@override
StringLiteral get(NativeFunctionBody node) => node.stringLiteral;
}
class Getter_NodeReplacerTest_test_parenthesizedExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ParenthesizedExpression, Expression> {
@override
Expression get(ParenthesizedExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_partOfDirective
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PartOfDirective, LibraryIdentifier> {
@override
LibraryIdentifier get(PartOfDirective node) => node.libraryName;
}
class Getter_NodeReplacerTest_test_postfixExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PostfixExpression, Expression> {
@override
Expression get(PostfixExpression node) => node.operand;
}
class Getter_NodeReplacerTest_test_prefixedIdentifier
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PrefixedIdentifier, SimpleIdentifier> {
@override
SimpleIdentifier get(PrefixedIdentifier node) => node.identifier;
}
class Getter_NodeReplacerTest_test_prefixedIdentifier_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PrefixedIdentifier, SimpleIdentifier> {
@override
SimpleIdentifier get(PrefixedIdentifier node) => node.prefix;
}
class Getter_NodeReplacerTest_test_prefixExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PrefixExpression, Expression> {
@override
Expression get(PrefixExpression node) => node.operand;
}
class Getter_NodeReplacerTest_test_propertyAccess
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PropertyAccess, Expression> {
@override
Expression get(PropertyAccess node) => node.target;
}
class Getter_NodeReplacerTest_test_propertyAccess_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<PropertyAccess, SimpleIdentifier> {
@override
SimpleIdentifier get(PropertyAccess node) => node.propertyName;
}
class Getter_NodeReplacerTest_test_redirectingConstructorInvocation
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<RedirectingConstructorInvocation,
+ SimpleIdentifier> {
@override
SimpleIdentifier get(RedirectingConstructorInvocation node) =>
node.constructorName;
}
class Getter_NodeReplacerTest_test_redirectingConstructorInvocation_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<RedirectingConstructorInvocation,
+ ArgumentList> {
@override
ArgumentList get(RedirectingConstructorInvocation node) => node.argumentList;
}
class Getter_NodeReplacerTest_test_returnStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ReturnStatement, Expression> {
@override
Expression get(ReturnStatement node) => node.expression;
}
class Getter_NodeReplacerTest_test_simpleFormalParameter
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<SimpleFormalParameter, TypeName> {
@override
TypeName get(SimpleFormalParameter node) => node.type;
}
class Getter_NodeReplacerTest_test_superConstructorInvocation
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<SuperConstructorInvocation, SimpleIdentifier> {
@override
SimpleIdentifier get(SuperConstructorInvocation node) => node.constructorName;
}
class Getter_NodeReplacerTest_test_superConstructorInvocation_2
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<SuperConstructorInvocation, ArgumentList> {
@override
ArgumentList get(SuperConstructorInvocation node) => node.argumentList;
}
class Getter_NodeReplacerTest_test_switchCase
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<SwitchCase, Expression> {
@override
Expression get(SwitchCase node) => node.expression;
}
class Getter_NodeReplacerTest_test_switchStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<SwitchStatement, Expression> {
@override
Expression get(SwitchStatement node) => node.expression;
}
class Getter_NodeReplacerTest_test_throwExpression
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<ThrowExpression, Expression> {
@override
Expression get(ThrowExpression node) => node.expression;
}
class Getter_NodeReplacerTest_test_topLevelVariableDeclaration
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<TopLevelVariableDeclaration,
+ VariableDeclarationList> {
@override
VariableDeclarationList get(TopLevelVariableDeclaration node) =>
node.variables;
}
class Getter_NodeReplacerTest_test_tryStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TryStatement, Block> {
@override
Block get(TryStatement node) => node.finallyBlock;
}
class Getter_NodeReplacerTest_test_tryStatement_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TryStatement, Block> {
@override
Block get(TryStatement node) => node.body;
}
-class Getter_NodeReplacerTest_test_typeName implements NodeReplacerTest_Getter {
+class Getter_NodeReplacerTest_test_typeName
+ implements NodeReplacerTest_Getter<TypeName, TypeArgumentList> {
@override
TypeArgumentList get(TypeName node) => node.typeArguments;
}
class Getter_NodeReplacerTest_test_typeName_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TypeName, Identifier> {
@override
Identifier get(TypeName node) => node.name;
}
class Getter_NodeReplacerTest_test_typeParameter
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TypeParameter, TypeName> {
@override
TypeName get(TypeParameter node) => node.bound;
}
class Getter_NodeReplacerTest_test_typeParameter_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TypeParameter, SimpleIdentifier> {
@override
SimpleIdentifier get(TypeParameter node) => node.name;
}
class Getter_NodeReplacerTest_test_variableDeclaration
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<VariableDeclaration, SimpleIdentifier> {
@override
SimpleIdentifier get(VariableDeclaration node) => node.name;
}
class Getter_NodeReplacerTest_test_variableDeclaration_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<VariableDeclaration, Expression> {
@override
Expression get(VariableDeclaration node) => node.initializer;
}
class Getter_NodeReplacerTest_test_variableDeclarationList
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<VariableDeclarationList, TypeName> {
@override
TypeName get(VariableDeclarationList node) => node.type;
}
class Getter_NodeReplacerTest_test_variableDeclarationStatement
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<VariableDeclarationStatement,
+ VariableDeclarationList> {
@override
VariableDeclarationList get(VariableDeclarationStatement node) =>
node.variables;
}
class Getter_NodeReplacerTest_test_whileStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<WhileStatement, Expression> {
@override
Expression get(WhileStatement node) => node.condition;
}
class Getter_NodeReplacerTest_test_whileStatement_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<WhileStatement, Statement> {
@override
Statement get(WhileStatement node) => node.body;
}
class Getter_NodeReplacerTest_test_yieldStatement
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<YieldStatement, Expression> {
@override
Expression get(YieldStatement node) => node.expression;
}
class Getter_NodeReplacerTest_testAnnotatedNode
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<AnnotatedNode, Comment> {
@override
Comment get(AnnotatedNode node) => node.documentationComment;
}
class Getter_NodeReplacerTest_testNormalFormalParameter
- implements NodeReplacerTest_Getter {
+ implements
+ NodeReplacerTest_Getter<NormalFormalParameter, SimpleIdentifier> {
@override
SimpleIdentifier get(NormalFormalParameter node) => node.identifier;
}
class Getter_NodeReplacerTest_testNormalFormalParameter_2
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<NormalFormalParameter, Comment> {
@override
Comment get(NormalFormalParameter node) => node.documentationComment;
}
class Getter_NodeReplacerTest_testTypedLiteral
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<TypedLiteral, TypeArgumentList> {
@override
TypeArgumentList get(TypedLiteral node) => node.typeArguments;
}
class Getter_NodeReplacerTest_testUriBasedDirective
- implements NodeReplacerTest_Getter {
+ implements NodeReplacerTest_Getter<UriBasedDirective, StringLiteral> {
@override
StringLiteral get(UriBasedDirective node) => node.uri;
}
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index e7021f0..6539e67 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -141,7 +141,36 @@
{ int radix,
int onError(String source) });
}
-class double extends num {}
+
+abstract class double extends num {
+ static const double NAN = 0.0 / 0.0;
+ static const double INFINITY = 1.0 / 0.0;
+ static const double NEGATIVE_INFINITY = -INFINITY;
+ static const double MIN_POSITIVE = 5e-324;
+ static const double MAX_FINITE = 1.7976931348623157e+308;
+
+ double remainder(num other);
+ double operator +(num other);
+ double operator -(num other);
+ double operator *(num other);
+ double operator %(num other);
+ double operator /(num other);
+ int operator ~/(num other);
+ double operator -();
+ double abs();
+ double get sign;
+ int round();
+ int floor();
+ int ceil();
+ int truncate();
+ double roundToDouble();
+ double floorToDouble();
+ double ceilToDouble();
+ double truncateToDouble();
+ external static double parse(String source,
+ [double onError(String source)]);
+}
+
class DateTime extends Object {}
class Null extends Object {}
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index a922cf5..f4fd958 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -61,6 +61,15 @@
expect(_findAnnotations(), contains(_node));
}
+ void test_visitAnnotation_enumConstant() {
+ // Analyzer ignores annotations on enum constant declarations.
+ Annotation annotation = AstFactory.annotation2(
+ AstFactory.identifier3('A'), null, AstFactory.argumentList());
+ _node = new EnumConstantDeclaration(
+ null, <Annotation>[annotation], AstFactory.identifier3('C'));
+ expect(_findConstants(), isEmpty);
+ }
+
/**
* Test an annotation that represents the invocation of a constant
* constructor.
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index ef33f95..3883876 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -587,14 +587,57 @@
void test_parameterParentElementForLink_innermostExecutable() {
createLinker('void f(void g(void h())) {}');
TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
- expect(f.innermostExecutable, same(f));
+ expect(f.typeParameterContext, same(f));
ParameterElementForLink g = f.parameters[0];
FunctionType gType = g.type;
FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
- expect(gTypeElement.innermostExecutable, same(f));
+ expect(gTypeElement.typeParameterContext, same(f));
ParameterElementForLink h = gTypeElement.parameters[0];
FunctionType hType = h.type;
FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
- expect(hTypeElement.innermostExecutable, same(f));
+ expect(hTypeElement.typeParameterContext, same(f));
+ }
+
+ void test_typeParameter_isTypeParameterInScope_direct() {
+ createLinker('class C<T, U> {}');
+ ClassElementForLink_Class c = testLibrary.getContainedName('C');
+ TypeParameterElementForLink t = c.typeParameters[0];
+ TypeParameterElementForLink u = c.typeParameters[1];
+ expect(c.isTypeParameterInScope(t), true);
+ expect(c.isTypeParameterInScope(u), true);
+ }
+
+ void test_typeParameter_isTypeParameterInScope_indirect() {
+ createLinker('class C<T, U> { f<V, W>() {} }');
+ ClassElementForLink_Class c = testLibrary.getContainedName('C');
+ MethodElementForLink f = c.methods[0];
+ TypeParameterElementForLink t = c.typeParameters[0];
+ TypeParameterElementForLink u = c.typeParameters[1];
+ expect(f.isTypeParameterInScope(t), true);
+ expect(f.isTypeParameterInScope(u), true);
+ }
+
+ void test_typeParameter_isTypeParameterInScope_reversed() {
+ createLinker('class C<T, U> { f<V, W>() {} }');
+ ClassElementForLink_Class c = testLibrary.getContainedName('C');
+ MethodElementForLink f = c.methods[0];
+ TypeParameterElementForLink v = f.typeParameters[0];
+ TypeParameterElementForLink w = f.typeParameters[1];
+ expect(c.isTypeParameterInScope(v), false);
+ expect(c.isTypeParameterInScope(w), false);
+ }
+
+ void test_typeParameter_isTypeParameterInScope_unrelated() {
+ createLinker('class C<T, U> {} class D<V, W> {}');
+ ClassElementForLink_Class c = testLibrary.getContainedName('C');
+ ClassElementForLink_Class d = testLibrary.getContainedName('D');
+ TypeParameterElementForLink t = c.typeParameters[0];
+ TypeParameterElementForLink u = c.typeParameters[1];
+ TypeParameterElementForLink v = d.typeParameters[0];
+ TypeParameterElementForLink w = d.typeParameters[1];
+ expect(c.isTypeParameterInScope(v), false);
+ expect(c.isTypeParameterInScope(w), false);
+ expect(d.isTypeParameterInScope(t), false);
+ expect(d.isTypeParameterInScope(u), false);
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 420b70f..47faf81 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -66,7 +66,7 @@
}
@override
- void compareLocalVariableElementLists(ExecutableElement resynthesized,
+ void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
ExecutableElement original, String desc) {
// We don't resynthesize local elements during link.
// So, we should not compare them.
@@ -124,12 +124,6 @@
@override
@failingTest
- void test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel() {
- super.test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel();
- }
-
- @override
- @failingTest
void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
super.test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel();
}
@@ -153,15 +147,9 @@
}
@override
- @failingTest
- void test_downwardsInferenceOnFunctionOfTUsingTheT() {
- super.test_downwardsInferenceOnFunctionOfTUsingTheT();
- }
-
- @override
- @failingTest
- void test_downwardsInferenceOnGenericFunctionExpressions() {
- super.test_downwardsInferenceOnGenericFunctionExpressions();
+ void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
+ variablesWithNotConstInitializers.add('a2');
+ super.test_canInferAlsoFromStaticAndInstanceFieldsFlagOn();
}
@override
@@ -523,42 +511,6 @@
super.test_inferenceInCyclesIsDeterministic();
}
- @override
- @failingTest
- void test_instantiateToBounds_generic2_hasBound_definedAfter() {
- super.test_instantiateToBounds_generic2_hasBound_definedAfter();
- }
-
- @override
- @failingTest
- void test_instantiateToBounds_generic2_hasBound_definedBefore() {
- super.test_instantiateToBounds_generic2_hasBound_definedBefore();
- }
-
- @override
- @failingTest
- void test_instantiateToBounds_generic2_noBound() {
- super.test_instantiateToBounds_generic2_noBound();
- }
-
- @override
- @failingTest
- void test_instantiateToBounds_generic_hasBound_definedAfter() {
- super.test_instantiateToBounds_generic_hasBound_definedAfter();
- }
-
- @override
- @failingTest
- void test_instantiateToBounds_generic_hasBound_definedBefore() {
- super.test_instantiateToBounds_generic_hasBound_definedBefore();
- }
-
- @override
- @failingTest
- void test_instantiateToBounds_notGeneric() {
- super.test_instantiateToBounds_notGeneric();
- }
-
void test_invokeMethod_notGeneric_genericClass() {
var unit = checkFile(r'''
class C<T> {
@@ -579,12 +531,6 @@
expect(unit.topLevelVariables[0].type.toString(), 'int');
}
- @override
- @failingTest
- void test_nullLiteralShouldNotInferAsBottom() {
- super.test_nullLiteralShouldNotInferAsBottom();
- }
-
LibraryElementImpl _checkSource(
SummaryResynthesizer resynthesizer, Source source) {
LibraryElementImpl resynthesized =
@@ -624,12 +570,6 @@
void test_inferred_function_type_in_generic_class_constructor() {
super.test_inferred_function_type_in_generic_class_constructor();
}
-
- @override
- @failingTest
- void test_type_reference_to_import_part_in_subdir() {
- super.test_type_reference_to_import_part_in_subdir();
- }
}
/**
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index c3ae04d..30221bb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -43,6 +43,12 @@
abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest {
Set<Source> otherLibrarySources = new Set<Source>();
+ /**
+ * Names of variables which have initializers that are not valid constants,
+ * so they are not resynthesized.
+ */
+ Set<String> variablesWithNotConstInitializers = new Set<String>();
+
bool get checkPropagatedTypes => true;
/**
@@ -334,7 +340,11 @@
} else if (oItem is ConstructorFieldInitializer &&
rItem is ConstructorFieldInitializer) {
compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
- compareConstAsts(rItem.expression, oItem.expression, desc);
+ if (variablesWithNotConstInitializers.contains(rItem.fieldName.name)) {
+ _assertUnresolvedIdentifier(rItem.expression, desc);
+ } else {
+ compareConstAsts(rItem.expression, oItem.expression, desc);
+ }
} else if (oItem is SuperConstructorInvocation &&
rItem is SuperConstructorInvocation) {
compareElements(rItem.staticElement, oItem.staticElement, desc);
@@ -648,7 +658,13 @@
}
expect(original, isNotNull);
expect(resynthesized, isNotNull, reason: desc);
- expect(rImpl.runtimeType, oImpl.runtimeType);
+ if (rImpl is DefaultParameterElementImpl && oImpl is ParameterElementImpl) {
+ // This is ok provided the resynthesized parameter element doesn't have
+ // any evaluation result.
+ expect(rImpl.evaluationResult, isNull);
+ } else {
+ expect(rImpl.runtimeType, oImpl.runtimeType);
+ }
expect(resynthesized.kind, original.kind);
expect(resynthesized.location, original.location, reason: desc);
expect(resynthesized.name, original.name);
@@ -702,27 +718,7 @@
original.typeParameters[i],
'$desc type parameter ${original.typeParameters[i].name}');
}
- if (original is! Member) {
- List<FunctionElement> rFunctions = resynthesized.functions;
- List<FunctionElement> oFunctions = original.functions;
- expect(rFunctions, hasLength(oFunctions.length));
- for (int i = 0; i < oFunctions.length; i++) {
- compareFunctionElements(rFunctions[i], oFunctions[i],
- '$desc local function ${oFunctions[i].name}');
- }
- }
- if (original is! Member) {
- List<LabelElement> rLabels = resynthesized.labels;
- List<LabelElement> oLabels = original.labels;
- expect(rLabels, hasLength(oLabels.length));
- for (int i = 0; i < oLabels.length; i++) {
- compareLabelElements(
- rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
- }
- }
- if (original is! Member) {
- compareLocalVariableElementLists(resynthesized, original, desc);
- }
+ compareLocalElementsOfExecutable(resynthesized, original, desc);
}
void compareExportElements(ExportElementImpl resynthesized,
@@ -800,14 +796,34 @@
compareElements(resynthesized, original, desc);
}
- void compareLocalVariableElementLists(ExecutableElement resynthesized,
+ void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
ExecutableElement original, String desc) {
- List<LocalVariableElement> rVariables = resynthesized.localVariables;
- List<LocalVariableElement> oVariables = original.localVariables;
- expect(rVariables, hasLength(oVariables.length));
- for (int i = 0; i < oVariables.length; i++) {
- compareVariableElements(rVariables[i], oVariables[i],
- '$desc local variable ${oVariables[i].name}');
+ if (original is! Member) {
+ List<FunctionElement> rFunctions = resynthesized.functions;
+ List<FunctionElement> oFunctions = original.functions;
+ expect(rFunctions, hasLength(oFunctions.length));
+ for (int i = 0; i < oFunctions.length; i++) {
+ compareFunctionElements(rFunctions[i], oFunctions[i],
+ '$desc local function ${oFunctions[i].name}');
+ }
+ }
+ if (original is! Member) {
+ List<LabelElement> rLabels = resynthesized.labels;
+ List<LabelElement> oLabels = original.labels;
+ expect(rLabels, hasLength(oLabels.length));
+ for (int i = 0; i < oLabels.length; i++) {
+ compareLabelElements(
+ rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
+ }
+ }
+ if (original is! Member) {
+ List<LocalVariableElement> rVariables = resynthesized.localVariables;
+ List<LocalVariableElement> oVariables = original.localVariables;
+ expect(rVariables, hasLength(oVariables.length));
+ for (int i = 0; i < oVariables.length; i++) {
+ compareVariableElements(rVariables[i], oVariables[i],
+ '$desc local variable ${oVariables[i].name}');
+ }
}
}
@@ -1078,8 +1094,12 @@
resynthesized.constantValue, original.constantValue, desc);
} else {
Expression initializer = resynthesizedActual.constantInitializer;
- compareConstAsts(initializer, originalActual.constantInitializer,
- '$desc initializer');
+ if (variablesWithNotConstInitializers.contains(resynthesized.name)) {
+ _assertUnresolvedIdentifier(initializer, desc);
+ } else {
+ compareConstAsts(initializer, originalActual.constantInitializer,
+ '$desc initializer');
+ }
}
}
checkPossibleMember(resynthesized, original, desc);
@@ -1195,6 +1215,12 @@
super.setUp();
prepareAnalysisContext(createOptions());
}
+
+ void _assertUnresolvedIdentifier(Expression initializer, String desc) {
+ expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc);
+ SimpleIdentifier identifier = initializer;
+ expect(identifier.staticElement, isNull, reason: desc);
+ }
}
@reflectiveTest
@@ -1657,6 +1683,7 @@
}
test_const_invalid_field_const() {
+ variablesWithNotConstInitializers.add('f');
checkLibrary(
r'''
class C {
@@ -1668,6 +1695,7 @@
}
test_const_invalid_field_final() {
+ variablesWithNotConstInitializers.add('f');
checkLibrary(
r'''
class C {
@@ -1679,6 +1707,7 @@
}
test_const_invalid_topLevel() {
+ variablesWithNotConstInitializers.add('v');
checkLibrary(
r'''
const v = 1 + foo();
@@ -2421,6 +2450,7 @@
}
test_constructor_initializers_field_notConst() {
+ variablesWithNotConstInitializers.add('x');
checkLibrary(
'''
class C {
@@ -2452,6 +2482,17 @@
''');
}
+ test_constructor_initializers_superInvocation_namedExpression() {
+ checkLibrary('''
+class A {
+ const A.aaa(a, {int b});
+}
+class C extends A {
+ const C() : super.aaa(1, b: 2);
+}
+''');
+ }
+
test_constructor_initializers_superInvocation_unnamed() {
checkLibrary('''
class A {
@@ -2472,6 +2513,15 @@
''');
}
+ test_constructor_initializers_thisInvocation_namedExpression() {
+ checkLibrary('''
+class C {
+ const C() : this.named(1, b: 2);
+ const C.named(a, {int b});
+}
+''');
+ }
+
test_constructor_initializers_thisInvocation_unnamed() {
checkLibrary('''
class C {
@@ -3191,6 +3241,14 @@
checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
}
+ void test_inferedType_usesSyntheticFunctionType_functionTypedParam() {
+ checkLibrary('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = [f, g];
+''');
+ }
+
test_inferred_function_type_for_variable_in_generic_function() {
// In the code below, `x` has an inferred type of `() => int`, with 2
// (unused) type parameters from the enclosing top level function.
@@ -3296,6 +3354,14 @@
' abstract class D<U, V> { Map<V, U> get v; }');
}
+ void test_inferred_type_refers_to_function_typed_param_of_typedef() {
+ checkLibrary('''
+typedef void F(int g(String s));
+h(F f) => null;
+var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
+''');
+ }
+
test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
checkLibrary('class C<T, U> extends D<U, int> { void f(int x, g) {} }'
' abstract class D<V, W> { void f(int x, W g(V s)); }');
@@ -3314,6 +3380,20 @@
' abstract class D { void f(int x, int g(String s)); }');
}
+ test_inferred_type_refers_to_nested_function_typed_param() {
+ checkLibrary('''
+f(void g(int x, void h())) => null;
+var v = f((x, y) {});
+''');
+ }
+
+ test_inferred_type_refers_to_nested_function_typed_param_named() {
+ checkLibrary('''
+f({void g(int x, void h())}) => null;
+var v = f(g: (x, y) {});
+''');
+ }
+
test_inferred_type_refers_to_setter_function_typed_parameter_type() {
checkLibrary('class C extends D { void set f(g) {} }'
' abstract class D { void set f(int g(String s)); }');
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 13f10ce..b034228 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -66,6 +66,24 @@
@override
@failingTest
+ test_inferred_type_refers_to_function_typed_param_of_typedef() {
+ super.test_inferred_type_refers_to_function_typed_param_of_typedef();
+ }
+
+ @override
+ @failingTest
+ test_inferred_type_refers_to_nested_function_typed_param() {
+ super.test_inferred_type_refers_to_nested_function_typed_param();
+ }
+
+ @override
+ @failingTest
+ test_inferred_type_refers_to_nested_function_typed_param_named() {
+ super.test_inferred_type_refers_to_nested_function_typed_param_named();
+ }
+
+ @override
+ @failingTest
test_initializer_executable_with_bottom_return_type() {
super.test_initializer_executable_with_bottom_return_type();
}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 7e25284..0abc4de 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -43,7 +43,8 @@
Map<String, Object> result = <String, Object>{};
obj.toMap().forEach((String key, Object value) {
bool orderByName = false;
- if (obj is UnlinkedPublicNamespace && key == 'names') {
+ if (obj is UnlinkedPublicNamespace && key == 'names' ||
+ obj is UnlinkedPublicName && key == 'members') {
orderByName = true;
}
result[key] = canonicalize(value, orderByName: orderByName);
@@ -356,7 +357,7 @@
*/
void checkInferredTypeSlot(
int slotId, String absoluteUri, String relativeUri, String expectedName,
- {bool allowTypeParameters: false,
+ {int numTypeArguments: 0,
ReferenceKind expectedKind: ReferenceKind.classOrEnum,
int expectedTargetUnit: 0,
LinkedUnit linkedSourceUnit,
@@ -365,7 +366,7 @@
bool onlyInStrongMode: true}) {
if (strongMode || !onlyInStrongMode) {
checkLinkedTypeSlot(slotId, absoluteUri, relativeUri, expectedName,
- allowTypeArguments: allowTypeParameters,
+ numTypeArguments: numTypeArguments,
expectedKind: expectedKind,
expectedTargetUnit: expectedTargetUnit,
linkedSourceUnit: linkedSourceUnit,
@@ -399,10 +400,17 @@
}
/**
+ * Verify that the given [typeRef] represents the type `dynamic`.
+ */
+ void checkLinkedDynamicTypeRef(EntityRef typeRef) {
+ checkLinkedTypeRef(typeRef, null, null, 'dynamic');
+ }
+
+ /**
* Verify that the given [typeRef] represents a reference to a type declared
* in a file reachable via [absoluteUri] and [relativeUri], having name
- * [expectedName]. If [allowTypeArguments] is true, allow the type
- * reference to supply type arguments. [expectedKind] is the kind of object
+ * [expectedName]. Verify that the number of type arguments
+ * is equal to [numTypeArguments]. [expectedKind] is the kind of object
* referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
* compilation unit within which the [typeRef] appears; if not specified they
* are assumed to refer to the defining compilation unit.
@@ -413,7 +421,7 @@
*/
void checkLinkedTypeRef(EntityRef typeRef, String absoluteUri,
String relativeUri, String expectedName,
- {bool allowTypeArguments: false,
+ {int numTypeArguments: 0,
ReferenceKind expectedKind: ReferenceKind.classOrEnum,
int expectedTargetUnit: 0,
LinkedUnit linkedSourceUnit,
@@ -424,9 +432,7 @@
reason: 'No entry in linkedSourceUnit.types matching slotId');
expect(typeRef.paramReference, 0);
int index = typeRef.reference;
- if (!allowTypeArguments) {
- expect(typeRef.typeArguments, isEmpty);
- }
+ expect(typeRef.typeArguments, hasLength(numTypeArguments));
checkReferenceIndex(index, absoluteUri, relativeUri, expectedName,
expectedKind: expectedKind,
expectedTargetUnit: expectedTargetUnit,
@@ -438,8 +444,8 @@
/**
* Verify that the given [slotId] represents a reference to a type declared
* in a file reachable via [absoluteUri] and [relativeUri], having name
- * [expectedName]. If [allowTypeArguments] is true, allow the type
- * reference to supply type arguments. [expectedKind] is the kind of object
+ * [expectedName]. Verify that the number of type arguments
+ * is equal to [numTypeArguments]. [expectedKind] is the kind of object
* referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
* compilation unit within which the [typeRef] appears; if not specified they
* are assumed to refer to the defining compilation unit.
@@ -450,7 +456,7 @@
*/
void checkLinkedTypeSlot(
int slotId, String absoluteUri, String relativeUri, String expectedName,
- {bool allowTypeArguments: false,
+ {int numTypeArguments: 0,
ReferenceKind expectedKind: ReferenceKind.classOrEnum,
int expectedTargetUnit: 0,
LinkedUnit linkedSourceUnit,
@@ -467,7 +473,7 @@
absoluteUri,
relativeUri,
expectedName,
- allowTypeArguments: allowTypeArguments,
+ numTypeArguments: numTypeArguments,
expectedKind: expectedKind,
expectedTargetUnit: expectedTargetUnit,
linkedSourceUnit: linkedSourceUnit,
@@ -572,8 +578,8 @@
* Verify that the given [typeRef] represents a reference to a type declared
* in a file reachable via [absoluteUri] and [relativeUri], having name
* [expectedName]. If [expectedPrefix] is supplied, verify that the type is
- * reached via the given prefix. If [allowTypeParameters] is true, allow the
- * type reference to supply type parameters. [expectedKind] is the kind of
+ * reached via the given prefix. Verify that the number of type arguments
+ * is equal to [numTypeArguments]. [expectedKind] is the kind of
* object referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer
* to the compilation unit within which the [typeRef] appears; if not
* specified they are assumed to refer to the defining compilation unit.
@@ -589,7 +595,7 @@
String expectedName,
{String expectedPrefix,
List<_PrefixExpectation> prefixExpectations,
- bool allowTypeParameters: false,
+ int numTypeArguments: 0,
ReferenceKind expectedKind: ReferenceKind.classOrEnum,
int expectedTargetUnit: 0,
LinkedUnit linkedSourceUnit,
@@ -601,9 +607,7 @@
expect(typeRef, new isInstanceOf<EntityRef>());
expect(typeRef.paramReference, 0);
int index = typeRef.reference;
- if (!allowTypeParameters) {
- expect(typeRef.typeArguments, isEmpty);
- }
+ expect(typeRef.typeArguments, hasLength(numTypeArguments));
UnlinkedReference reference = checkReferenceIndex(
index, absoluteUri, relativeUri, expectedName,
expectedKind: expectedKind,
@@ -1097,7 +1101,12 @@
test_class_alias_reference_generic() {
EntityRef typeRef = serializeTypeText('C',
otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
- checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+ checkTypeRef(typeRef, null, null, 'C',
+ numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_class_alias_reference_generic_imported() {
@@ -1106,7 +1115,11 @@
EntityRef typeRef =
serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
- numTypeParameters: 2);
+ numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_class_alias_supertype() {
@@ -1156,17 +1169,19 @@
Map<String, UnlinkedPublicName> executablesMap =
<String, UnlinkedPublicName>{};
className.members.forEach((e) => executablesMap[e.name] = e);
- expect(executablesMap, hasLength(2));
- {
- UnlinkedPublicName executable = executablesMap['fieldStaticConst'];
- expect(executable.kind, ReferenceKind.propertyAccessor);
+ expect(executablesMap, hasLength(4));
+ Map<String, ReferenceKind> expectedExecutableKinds =
+ <String, ReferenceKind>{
+ 'fieldStaticConst': ReferenceKind.propertyAccessor,
+ 'fieldStaticFinal': ReferenceKind.propertyAccessor,
+ 'fieldStatic': ReferenceKind.propertyAccessor,
+ 'methodStaticPublic': ReferenceKind.method,
+ };
+ expectedExecutableKinds.forEach((String name, ReferenceKind expectedKind) {
+ UnlinkedPublicName executable = executablesMap[name];
+ expect(executable.kind, expectedKind);
expect(executable.members, isEmpty);
- }
- {
- UnlinkedPublicName executable = executablesMap['methodStaticPublic'];
- expect(executable.kind, ReferenceKind.method);
- expect(executable.members, isEmpty);
- }
+ });
}
test_class_constMembers_constructors() {
@@ -1317,7 +1332,12 @@
test_class_reference_generic() {
EntityRef typeRef =
serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
- checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+ checkTypeRef(typeRef, null, null, 'C',
+ numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_class_reference_generic_imported() {
@@ -1325,7 +1345,11 @@
EntityRef typeRef =
serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
- numTypeParameters: 2);
+ numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_class_superclass() {
@@ -1344,10 +1368,16 @@
test_class_type_param_bound() {
UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
expect(cls.typeParameters, hasLength(1));
- expect(cls.typeParameters[0].name, 'T');
- expect(cls.typeParameters[0].bound, isNotNull);
- checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
- allowTypeParameters: true, numTypeParameters: 1);
+ {
+ UnlinkedTypeParam typeParameter = cls.typeParameters[0];
+ expect(typeParameter.name, 'T');
+ expect(typeParameter.bound, isNotNull);
+ checkTypeRef(typeParameter.bound, 'dart:core', 'dart:core', 'List',
+ numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeParameter.bound.typeArguments[0]);
+ }
+ }
}
test_class_type_param_f_bound() {
@@ -1742,6 +1772,57 @@
strings: ['T']);
}
+ test_constExpr_functionExpression_asArgument() {
+ // Even though function expressions are not allowed in constant
+ // declarations, they might occur due to erroneous code, so make sure they
+ // function correctly.
+ UnlinkedVariable variable = serializeVariableText('''
+const v = foo(5, () => 42);
+foo(a, b) {}
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushLocalFunctionReference,
+ UnlinkedConstOperation.invokeMethodRef
+ ], ints: [
+ 5,
+ 0,
+ 0,
+ 0,
+ 2
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+ expectedKind: ReferenceKind.topLevelFunction)
+ ]);
+ }
+
+ test_constExpr_functionExpression_asArgument_multiple() {
+ // Even though function expressions are not allowed in constant
+ // declarations, they might occur due to erroneous code, so make sure they
+ // function correctly.
+ UnlinkedVariable variable = serializeVariableText('''
+const v = foo(5, () => 42, () => 43);
+foo(a, b, c) {}
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushLocalFunctionReference,
+ UnlinkedConstOperation.pushLocalFunctionReference,
+ UnlinkedConstOperation.invokeMethodRef
+ ], ints: [
+ 5,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 3
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+ expectedKind: ReferenceKind.topLevelFunction)
+ ]);
+ }
+
test_constExpr_invokeConstructor_generic_named() {
UnlinkedVariable variable = serializeVariableText('''
class C<K, V> {
@@ -1762,7 +1843,7 @@
new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
numTypeParameters: 2)
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
}
@@ -1796,7 +1877,7 @@
relativeUri: 'a.dart',
numTypeParameters: 2)
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
}
@@ -1831,7 +1912,7 @@
numTypeParameters: 2),
new _PrefixExpectation(ReferenceKind.prefix, 'p')
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
}
@@ -1855,7 +1936,7 @@
checkTypeRef(r, null, null, 'C',
expectedKind: ReferenceKind.classOrEnum,
numTypeParameters: 2,
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
}
@@ -1884,7 +1965,7 @@
checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
expectedKind: ReferenceKind.classOrEnum,
numTypeParameters: 2,
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
}
@@ -1913,7 +1994,7 @@
checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
expectedKind: ReferenceKind.classOrEnum,
numTypeParameters: 2,
- allowTypeParameters: true,
+ numTypeArguments: 2,
prefixExpectations: [
new _PrefixExpectation(ReferenceKind.prefix, 'p')
]);
@@ -3433,6 +3514,57 @@
operators: [UnlinkedConstOperation.pushString], strings: ['bbb']);
}
+ test_constructor_initializers_thisInvocation_namedExpression() {
+ UnlinkedExecutable executable =
+ findExecutable('', executables: serializeClassText(r'''
+class C {
+ const C() : this.named(1, b: 2, c: 3);
+ const C.named(a, {int b, int c});
+}
+''').executables);
+ expect(executable.constantInitializers, hasLength(1));
+ UnlinkedConstructorInitializer initializer =
+ executable.constantInitializers[0];
+ expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation);
+ expect(initializer.name, 'named');
+ expect(initializer.expression, isNull);
+ expect(initializer.arguments, hasLength(3));
+ _assertUnlinkedConst(initializer.arguments[0],
+ operators: [UnlinkedConstOperation.pushInt], ints: [1]);
+ _assertUnlinkedConst(initializer.arguments[1],
+ operators: [UnlinkedConstOperation.pushInt], ints: [2]);
+ _assertUnlinkedConst(initializer.arguments[2],
+ operators: [UnlinkedConstOperation.pushInt], ints: [3]);
+ expect(initializer.argumentNames, ['b', 'c']);
+ }
+
+ test_constructor_initializers_superInvocation_namedExpression() {
+ UnlinkedExecutable executable =
+ findExecutable('', executables: serializeClassText(r'''
+class A {
+ const A(a, {int b, int c});
+}
+class C extends A {
+ const C() : super(1, b: 2, c: 3);
+}
+''').executables);
+ expect(executable.constantInitializers, hasLength(1));
+ UnlinkedConstructorInitializer initializer =
+ executable.constantInitializers[0];
+ expect(
+ initializer.kind, UnlinkedConstructorInitializerKind.superInvocation);
+ expect(initializer.name, '');
+ expect(initializer.expression, isNull);
+ expect(initializer.arguments, hasLength(3));
+ _assertUnlinkedConst(initializer.arguments[0],
+ operators: [UnlinkedConstOperation.pushInt], ints: [1]);
+ _assertUnlinkedConst(initializer.arguments[1],
+ operators: [UnlinkedConstOperation.pushInt], ints: [2]);
+ _assertUnlinkedConst(initializer.arguments[2],
+ operators: [UnlinkedConstOperation.pushInt], ints: [3]);
+ expect(initializer.argumentNames, ['b', 'c']);
+ }
+
test_constructor_initializers_thisInvocation_unnamed() {
UnlinkedExecutable executable =
findExecutable('named', executables: serializeClassText(r'''
@@ -3734,7 +3866,7 @@
new _PrefixExpectation(ReferenceKind.classOrEnum, 'D',
numTypeParameters: 2)
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -3797,7 +3929,7 @@
absoluteUri: absUri('/foo.dart'),
relativeUri: 'foo.dart')
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -3862,7 +3994,7 @@
relativeUri: 'foo.dart'),
new _PrefixExpectation(ReferenceKind.prefix, 'foo')
],
- allowTypeParameters: true);
+ numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -3901,7 +4033,7 @@
expect(executable.isFactory, isTrue);
expect(executable.redirectedConstructorName, isEmpty);
checkTypeRef(executable.redirectedConstructor, null, null, 'D',
- allowTypeParameters: true, numTypeParameters: 2);
+ numTypeParameters: 2, numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -3954,7 +4086,7 @@
expect(executable.redirectedConstructorName, isEmpty);
checkTypeRef(
executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D',
- allowTypeParameters: true, numTypeParameters: 2);
+ numTypeParameters: 2, numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -4008,7 +4140,7 @@
expect(executable.redirectedConstructorName, isEmpty);
checkTypeRef(
executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D',
- allowTypeParameters: true, numTypeParameters: 2, expectedPrefix: 'foo');
+ numTypeParameters: 2, expectedPrefix: 'foo', numTypeArguments: 2);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
}
@@ -6723,11 +6855,13 @@
''');
_assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
- UnlinkedConstOperation.pushNull,
+ UnlinkedConstOperation.pushLocalFunctionReference,
UnlinkedConstOperation.invokeMethodRef
], ints: [
5,
0,
+ 0,
+ 0,
2
], referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -6735,6 +6869,33 @@
]);
}
+ test_expr_functionExpression_asArgument_multiple() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = foo(5, () => 42, () => 43);
+foo(a, b, c) {}
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushLocalFunctionReference,
+ UnlinkedConstOperation.pushLocalFunctionReference,
+ UnlinkedConstOperation.invokeMethodRef
+ ], ints: [
+ 5,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 3
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+ expectedKind: ReferenceKind.topLevelFunction)
+ ]);
+ }
+
test_expr_functionExpression_withBlockBody() {
if (skipNonConstInitializers) {
return;
@@ -6743,7 +6904,9 @@
final v = () { return 42; };
''');
_assertUnlinkedConst(variable.constExpr,
- isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ isValidConst: false,
+ operators: [UnlinkedConstOperation.pushLocalFunctionReference],
+ ints: [0, 0]);
}
test_expr_functionExpression_withExpressionBody() {
@@ -6754,7 +6917,9 @@
final v = () => 42;
''');
_assertUnlinkedConst(variable.constExpr,
- isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ isValidConst: false,
+ operators: [UnlinkedConstOperation.pushLocalFunctionReference],
+ ints: [0, 0]);
}
test_expr_functionExpressionInvocation_withBlockBody() {
@@ -6882,6 +7047,29 @@
]);
}
+ test_expr_invokeMethodRef_with_reference_arg() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+f(x) => null;
+final u = null;
+final v = f(u);
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushReference,
+ UnlinkedConstOperation.invokeMethodRef
+ ], ints: [
+ 0,
+ 1
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'u',
+ expectedKind: ReferenceKind.topLevelPropertyAccessor),
+ (EntityRef r) => checkTypeRef(r, null, null, 'f',
+ expectedKind: ReferenceKind.topLevelFunction)
+ ]);
+ }
+
test_expr_throwException() {
if (skipNonConstInitializers) {
return;
@@ -6946,6 +7134,9 @@
expect(variable.constExpr, isNull);
expect(findExecutable('i', executables: cls.executables), isNull);
expect(findExecutable('i=', executables: cls.executables), isNull);
+ expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
}
test_field_const() {
@@ -7096,6 +7287,17 @@
serializeClassText('class C { static int i; }').fields[0];
expect(variable.isStatic, isTrue);
expect(variable.constExpr, isNull);
+ expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'i');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
+ ReferenceKind.propertyAccessor);
+ expect(
+ unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
+ 0);
+ expect(
+ unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
}
test_field_static_final() {
@@ -7389,7 +7591,12 @@
UnlinkedVariable variable =
serializeVariableText('import "dart:async" as a; a.Future v;');
checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
- expectedPrefix: 'a', numTypeParameters: 1);
+ expectedPrefix: 'a',
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(variable.type.typeArguments[0]);
+ }
}
test_import_prefixes_take_precedence_over_imported_names() {
@@ -7419,7 +7626,10 @@
UnlinkedVariable variable =
serializeVariableText('import "dart:async"; Future v;');
checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
- numTypeParameters: 1);
+ numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(variable.type.typeArguments[0]);
+ }
}
test_import_reference_merged_no_prefix() {
@@ -7430,10 +7640,24 @@
Future f;
Stream s;
''');
- checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
- numTypeParameters: 1);
- checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
- expectedTargetUnit: 1, numTypeParameters: 1);
+ {
+ EntityRef typeRef = findVariable('f').type;
+ checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future',
+ numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
+ {
+ EntityRef typeRef = findVariable('s').type;
+ checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream',
+ expectedTargetUnit: 1,
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
}
test_import_reference_merged_prefixed() {
@@ -7444,10 +7668,27 @@
a.Future f;
a.Stream s;
''');
- checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
- expectedPrefix: 'a', numTypeParameters: 1);
- checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
- expectedTargetUnit: 1, expectedPrefix: 'a', numTypeParameters: 1);
+ {
+ EntityRef typeRef = findVariable('f').type;
+ checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future',
+ expectedPrefix: 'a',
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
+ {
+ EntityRef typeRef = findVariable('s').type;
+ checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream',
+ expectedTargetUnit: 1,
+ expectedPrefix: 'a',
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
}
test_import_reference_merged_prefixed_separate_libraries() {
@@ -7513,6 +7754,34 @@
expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
}
+ test_inferred_function_type_parameter_type_with_unrelated_type_param() {
+ if (!strongMode || skipFullyLinkedData) {
+ return;
+ }
+ // The type that is inferred for C.f's parameter g is "() -> void".
+ // Since the associated element for that function type is B.f's parameter g,
+ // and B has a type parameter, the inferred type will record a type
+ // parameter. However, since that type parameter is irrelevant, the summary
+ // should encode it as `dynamic`.
+ UnlinkedClass c = serializeClassText('''
+abstract class B<T> {
+ void f(void g());
+}
+class C<T> extends B<T> {
+ void f(g) {}
+}
+''');
+ expect(c.executables, hasLength(1));
+ UnlinkedExecutable f = c.executables[0];
+ expect(f.parameters, hasLength(1));
+ UnlinkedParam g = f.parameters[0];
+ expect(g.name, 'g');
+ EntityRef typeRef = getTypeRefForSlot(g.inferredTypeSlot);
+ checkLinkedTypeRef(typeRef, null, null, 'f',
+ expectedKind: ReferenceKind.method, numTypeArguments: 1);
+ checkLinkedDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+
test_inferred_type_keeps_leading_dynamic() {
if (!strongMode || skipFullyLinkedData) {
return;
@@ -7522,12 +7791,24 @@
EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
// Check that x has inferred type `Map<dynamic, int>`.
checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
- allowTypeArguments: true, numTypeParameters: 2);
- expect(type.typeArguments, hasLength(2));
+ numTypeParameters: 2, numTypeArguments: 2);
checkLinkedTypeRef(type.typeArguments[0], null, null, 'dynamic');
checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
}
+ test_inferred_type_reference_shared_prefixed() {
+ if (!strongMode || skipFullyLinkedData) {
+ return;
+ }
+ // Variable `y` has an inferred type of `p.C`. Verify that the reference
+ // used by the explicit type of `x` is re-used for the inferred type.
+ addNamedSource('/a.dart', 'class C {}');
+ serializeLibraryText('import "a.dart" as p; p.C x; var y = new p.C();');
+ EntityRef xType = findVariable('x').type;
+ EntityRef yType = getTypeRefForSlot(findVariable('y').inferredTypeSlot);
+ expect(yType.reference, xType.reference);
+ }
+
test_inferred_type_refers_to_bound_type_param() {
if (!strongMode || skipFullyLinkedData) {
return;
@@ -7539,11 +7820,31 @@
EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
// Check that v has inferred type Map<T, int>.
checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
- allowTypeArguments: true, numTypeParameters: 2);
+ numTypeParameters: 2, numTypeArguments: 2);
checkParamTypeRef(type.typeArguments[0], 1);
checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
}
+ test_inferred_type_refers_to_function_typed_param_of_typedef() {
+ if (!strongMode || skipFullyLinkedData) {
+ return;
+ }
+ UnlinkedVariable v = serializeVariableText('''
+typedef void F(int g(String s));
+h(F f) => null;
+var v = h((y) {});
+''');
+ expect(v.initializer.localFunctions, hasLength(1));
+ UnlinkedExecutable closure = v.initializer.localFunctions[0];
+ expect(closure.parameters, hasLength(1));
+ UnlinkedParam y = closure.parameters[0];
+ expect(y.name, 'y');
+ EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+ checkLinkedTypeRef(typeRef, null, null, 'F',
+ expectedKind: ReferenceKind.typedef);
+ expect(typeRef.implicitFunctionTypeIndices, [0]);
+ }
+
test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
if (!strongMode || skipFullyLinkedData) {
return;
@@ -7636,6 +7937,44 @@
checkReferenceIndex(linkedReference.containingReference, null, null, 'D');
}
+ test_inferred_type_refers_to_nested_function_typed_param() {
+ if (!strongMode || skipFullyLinkedData) {
+ return;
+ }
+ UnlinkedVariable v = serializeVariableText('''
+f(void g(int x, void h())) => null;
+var v = f((x, y) {});
+''');
+ expect(v.initializer.localFunctions, hasLength(1));
+ UnlinkedExecutable closure = v.initializer.localFunctions[0];
+ expect(closure.parameters, hasLength(2));
+ UnlinkedParam y = closure.parameters[1];
+ expect(y.name, 'y');
+ EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+ checkLinkedTypeRef(typeRef, null, null, 'f',
+ expectedKind: ReferenceKind.topLevelFunction);
+ expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
+ }
+
+ test_inferred_type_refers_to_nested_function_typed_param_named() {
+ if (!strongMode || skipFullyLinkedData) {
+ return;
+ }
+ UnlinkedVariable v = serializeVariableText('''
+f({void g(int x, void h())}) => null;
+var v = f(g: (x, y) {});
+''');
+ expect(v.initializer.localFunctions, hasLength(1));
+ UnlinkedExecutable closure = v.initializer.localFunctions[0];
+ expect(closure.parameters, hasLength(2));
+ UnlinkedParam y = closure.parameters[1];
+ expect(y.name, 'y');
+ EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+ checkLinkedTypeRef(typeRef, null, null, 'f',
+ expectedKind: ReferenceKind.topLevelFunction);
+ expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
+ }
+
test_inferred_type_refers_to_setter_function_typed_parameter_type() {
if (!strongMode || skipFullyLinkedData) {
return;
@@ -7672,12 +8011,11 @@
UnlinkedClass cls =
serializeClassText('class C { final x = <int, dynamic>{}; }');
EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
- // Check that x has inferred type `Map<int>`. The trailing type argument
- // `dynamic` is omitted.
+ // Check that x has inferred type `Map<int, dynamic>`.
checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
- allowTypeArguments: true, numTypeParameters: 2);
- expect(type.typeArguments, hasLength(1));
+ numTypeParameters: 2, numTypeArguments: 2);
checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
+ checkLinkedDynamicTypeRef(type.typeArguments[1]);
}
test_inferred_type_skips_unnecessary_dynamic() {
@@ -7686,9 +8024,9 @@
}
UnlinkedClass cls = serializeClassText('class C { final x = []; }');
EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
- // Check that x has inferred type `List`, not `List<dynamic>`.
+ // Check that x has inferred type `List<dynamic>`.
checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'List',
- numTypeParameters: 1);
+ numTypeParameters: 1, numTypeArguments: 1);
}
test_initializer_executable_with_bottom_return_type() {
@@ -8694,8 +9032,8 @@
// ids should be reused.
addNamedSource('/a.dart', 'part of foo; final v = 0;');
serializeLibraryText('library foo; part "a.dart"; final w = 0;');
- expect(unlinkedUnits[0].variables[0].propagatedTypeSlot, 1);
- expect(unlinkedUnits[1].variables[0].propagatedTypeSlot, 1);
+ expect(unlinkedUnits[1].variables[0].propagatedTypeSlot,
+ unlinkedUnits[0].variables[0].propagatedTypeSlot);
}
test_syntheticFunctionType_genericClosure() {
@@ -8821,32 +9159,29 @@
test_type_arguments_explicit() {
EntityRef typeRef = serializeTypeText('List<int>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
- allowTypeParameters: true, numTypeParameters: 1);
- expect(typeRef.typeArguments, hasLength(1));
+ numTypeParameters: 1, numTypeArguments: 1);
checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
}
test_type_arguments_explicit_dynamic() {
EntityRef typeRef = serializeTypeText('List<dynamic>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
- allowTypeParameters: true, numTypeParameters: 1);
- expect(typeRef.typeArguments, isEmpty);
+ numTypeParameters: 1, numTypeArguments: 1);
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
}
test_type_arguments_explicit_dynamic_dynamic() {
EntityRef typeRef = serializeTypeText('Map<dynamic, dynamic>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
- allowTypeParameters: true, numTypeParameters: 2);
- // Trailing type arguments of type `dynamic` are omitted.
- expect(typeRef.typeArguments, isEmpty);
+ numTypeParameters: 2, numTypeArguments: 2);
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
}
test_type_arguments_explicit_dynamic_int() {
EntityRef typeRef = serializeTypeText('Map<dynamic, int>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
- allowTypeParameters: true, numTypeParameters: 2);
- // Leading type arguments of type `dynamic` are not omitted.
- expect(typeRef.typeArguments.length, 2);
+ numTypeParameters: 2, numTypeArguments: 2);
checkDynamicTypeRef(typeRef.typeArguments[0]);
checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
}
@@ -8855,26 +9190,24 @@
EntityRef typeRef =
serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
checkTypeRef(typeRef, null, null, 'F',
- allowTypeParameters: true,
expectedKind: ReferenceKind.typedef,
- numTypeParameters: 1);
- expect(typeRef.typeArguments, isEmpty);
+ numTypeParameters: 1,
+ numTypeArguments: 1);
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
}
test_type_arguments_explicit_String_dynamic() {
EntityRef typeRef = serializeTypeText('Map<String, dynamic>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
- allowTypeParameters: true, numTypeParameters: 2);
- // Trailing type arguments of type `dynamic` are omitted.
- expect(typeRef.typeArguments.length, 1);
+ numTypeParameters: 2, numTypeArguments: 2);
checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
}
test_type_arguments_explicit_String_int() {
EntityRef typeRef = serializeTypeText('Map<String, int>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
- allowTypeParameters: true, numTypeParameters: 2);
- expect(typeRef.typeArguments.length, 2);
+ numTypeParameters: 2, numTypeArguments: 2);
checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
}
@@ -8883,35 +9216,53 @@
EntityRef typeRef =
serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
checkTypeRef(typeRef, null, null, 'F',
- allowTypeParameters: true,
expectedKind: ReferenceKind.typedef,
- numTypeParameters: 1);
- expect(typeRef.typeArguments, hasLength(1));
+ numTypeParameters: 1,
+ numTypeArguments: 1);
checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
}
test_type_arguments_implicit() {
EntityRef typeRef = serializeTypeText('List');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
- allowTypeParameters: true, numTypeParameters: 1);
- expect(typeRef.typeArguments, isEmpty);
+ numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
}
test_type_arguments_implicit_typedef() {
EntityRef typeRef =
serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
checkTypeRef(typeRef, null, null, 'F',
- allowTypeParameters: true,
expectedKind: ReferenceKind.typedef,
- numTypeParameters: 1);
- expect(typeRef.typeArguments, isEmpty);
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
+
+ test_type_arguments_implicit_typedef_withBound() {
+ EntityRef typeRef = serializeTypeText('F',
+ otherDeclarations: 'typedef T F<T extends num>();');
+ checkTypeRef(typeRef, null, null, 'F',
+ expectedKind: ReferenceKind.typedef,
+ numTypeParameters: 1,
+ numTypeArguments: !checkAstDerivedData ? 1 : 0);
+ if (!checkAstDerivedData) {
+ if (strongMode) {
+ checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'num');
+ } else {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ }
+ }
}
test_type_arguments_order() {
EntityRef typeRef = serializeTypeText('Map<int, Object>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
- allowTypeParameters: true, numTypeParameters: 2);
- expect(typeRef.typeArguments, hasLength(2));
+ numTypeParameters: 2, numTypeArguments: 2);
checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
}
@@ -9235,7 +9586,13 @@
EntityRef typeRef =
serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
checkTypeRef(typeRef, null, null, 'F',
- numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+ numTypeParameters: 2,
+ expectedKind: ReferenceKind.typedef,
+ numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_typedef_reference_generic_imported() {
@@ -9243,7 +9600,13 @@
EntityRef typeRef =
serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
- numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+ numTypeParameters: 2,
+ expectedKind: ReferenceKind.typedef,
+ numTypeArguments: !checkAstDerivedData ? 2 : 0);
+ if (!checkAstDerivedData) {
+ checkDynamicTypeRef(typeRef.typeArguments[0]);
+ checkDynamicTypeRef(typeRef.typeArguments[1]);
+ }
}
test_typedef_return_type_explicit() {
@@ -9531,9 +9894,9 @@
UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
- allowTypeArguments: true, numTypeParameters: 2);
- expect(type.typeArguments, hasLength(1));
+ numTypeParameters: 2, numTypeArguments: 2);
checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
+ checkLinkedDynamicTypeRef(type.typeArguments[1]);
}
test_variable_propagatedTypeSlot_const() {
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 28ab23a..5fbc192 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2051,7 +2051,7 @@
typedef void ToVoid<T>(T x);
class F {
void set f(ToVoid<dynamic> x) {}
- void set g(ToVoid<int> x) {}
+ void set g(ToVoid<int> x) {}
void set h(dynamic x) {}
void set i(int x) {}
}
@@ -2343,8 +2343,8 @@
x = /*info:DOWN_CAST_IMPLICIT*/x + z;
x += /*info:DOWN_CAST_IMPLICIT*/z;
- y = /*info:DOWN_CAST_IMPLICIT*/y + z;
- y += /*info:DOWN_CAST_IMPLICIT*/z;
+ y = y + z;
+ y += z;
dynamic w = 42;
x += /*info:DYNAMIC_CAST*/w;
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index d1ebb09..83d6485 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -382,7 +382,7 @@
}
''');
var f = mainUnit.functions[0].localVariables[0];
- expect(f.type.toString(), '() → (int) → num');
+ expect(f.type.toString(), '() → (int) → double');
}
void test_blockBodiedLambdas_nestedLambdas_topLevel() {
@@ -393,7 +393,7 @@
};
''');
var f = mainUnit.topLevelVariables[0];
- expect(f.type.toString(), '() → (int) → num');
+ expect(f.type.toString(), '() → (int) → double');
}
void test_blockBodiedLambdas_noReturn() {
@@ -1257,6 +1257,17 @@
expect(x.type.toString(), 'int');
}
+ void test_fieldRefersToTopLevelGetter() {
+ var mainUnit = checkFile('''
+class C {
+ final x = y;
+}
+int get y => null;
+''');
+ var x = mainUnit.types[0].fields[0];
+ expect(x.type.toString(), 'int');
+ }
+
void test_genericMethods_basicDownwardInference() {
checkFile(r'''
/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
@@ -1383,6 +1394,48 @@
''');
}
+ void test_genericMethods_inferGenericFunctionParameterType() {
+ var mainUnit = checkFile('''
+class C<T> extends D<T> {
+ f/*<U>*/(x) {}
+}
+class D<T> {
+ F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+}
+typedef void F<V>(V v);
+''');
+ var f = mainUnit.getType('C').methods[0];
+ expect(f.type.toString(), '<U>(U) → (U) → void');
+ }
+
+ void test_genericMethods_inferGenericFunctionParameterType2() {
+ var mainUnit = checkFile('''
+class C<T> extends D<T> {
+ f/*<U>*/(g) => null;
+}
+abstract class D<T> {
+ void f/*<U>*/(G/*<U>*/ g);
+}
+typedef List<V> G<V>();
+''');
+ var f = mainUnit.getType('C').methods[0];
+ expect(f.type.toString(), '<U>(() → List<U>) → void');
+ }
+
+ void test_genericMethods_inferGenericFunctionReturnType() {
+ var mainUnit = checkFile('''
+class C<T> extends D<T> {
+ f/*<U>*/(x) {}
+}
+class D<T> {
+ F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+}
+typedef V F<V>();
+''');
+ var f = mainUnit.getType('C').methods[0];
+ expect(f.type.toString(), '<U>(U) → () → U');
+ }
+
void test_genericMethods_inferGenericInstantiation() {
checkFile('''
import 'dart:math' as math;
@@ -1790,6 +1843,56 @@
''');
}
+ void test_inferedType_usesSyntheticFunctionType() {
+ var mainUnit = checkFile('''
+int f() => null;
+String g() => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<() → Object>');
+ }
+
+ void test_inferedType_usesSyntheticFunctionType_functionTypedParam() {
+ var mainUnit = checkFile('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<((String) → int) → Object>');
+ }
+
+ void test_inferedType_usesSyntheticFunctionType_namedParam() {
+ var mainUnit = checkFile('''
+int f({int x}) => null;
+String g({int x}) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<({x: int}) → Object>');
+ }
+
+ void test_inferedType_usesSyntheticFunctionType_positionalParam() {
+ var mainUnit = checkFile('''
+int f([int x]) => null;
+String g([int x]) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<([int]) → Object>');
+ }
+
+ void test_inferedType_usesSyntheticFunctionType_requiredParam() {
+ var mainUnit = checkFile('''
+int f(int x) => null;
+String g(int x) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<(int) → Object>');
+ }
+
void test_inferenceInCyclesIsDeterministic() {
addFile(
'''
@@ -2143,6 +2246,39 @@
''');
}
+ void test_inferred_nonstatic_field_depends_on_static_field_complex() {
+ var mainUnit = checkFile('''
+class C {
+ static var x = 'x';
+ var y = /*info:INFERRED_TYPE_LITERAL*/{
+ 'a': /*info:INFERRED_TYPE_LITERAL*/{'b': 'c'},
+ 'd': /*info:INFERRED_TYPE_LITERAL*/{'e': x}
+ };
+}
+''');
+ var x = mainUnit.getType('C').fields[0];
+ expect(x.name, 'x');
+ expect(x.type.toString(), 'String');
+ var y = mainUnit.getType('C').fields[1];
+ expect(y.name, 'y');
+ expect(y.type.toString(), 'Map<String, Map<String, String>>');
+ }
+
+ void test_inferred_nonstatic_field_depends_on_toplevel_var_simple() {
+ var mainUnit = checkFile('''
+var x = 'x';
+class C {
+ var y = x;
+}
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.name, 'x');
+ expect(x.type.toString(), 'String');
+ var y = mainUnit.getType('C').fields[0];
+ expect(y.name, 'y');
+ expect(y.type.toString(), 'String');
+ }
+
void test_inferredInitializingFormalChecksDefaultValue() {
checkFile('''
class Foo {
@@ -2151,6 +2287,60 @@
}''');
}
+ void test_inferredType_blockBodiedClosure_noArguments() {
+ var mainUnit = checkFile('''
+class C {
+ static final v = () {};
+}
+''');
+ var v = mainUnit.getType('C').fields[0];
+ expect(v.type.toString(), '() → dynamic');
+ }
+
+ void test_inferredType_blockClosure_noArgs_noReturn() {
+ var mainUnit = checkFile('''
+var f = () {};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → dynamic');
+ }
+
+ void test_inferredType_isEnum() {
+ var mainUnit = checkFile('''
+enum E { v1 }
+final x = E.v1;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'E');
+ }
+
+ void test_inferredType_isEnumValues() {
+ var mainUnit = checkFile('''
+enum E { v1 }
+final x = E.values;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'List<E>');
+ }
+
+ void test_inferredType_isTypedef() {
+ var mainUnit = checkFile('''
+typedef void F();
+final x = <String, F>{};
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'Map<String, () → void>');
+ }
+
+ void test_inferredType_isTypedef_parameterized() {
+ var mainUnit = checkFile('''
+typedef T F<T>();
+final x = <String, F<int>>{};
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'Map<String, () → int>');
+ }
+
void test_inferStaticsTransitively() {
addFile(
'''
@@ -2667,6 +2857,22 @@
expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
}
+ void test_instantiateToBounds_invokeConstructor_noBound() {
+ var unit = checkFile('''
+class C<T> {}
+var x = new C();
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'C<dynamic>');
+ }
+
+ void test_instantiateToBounds_invokeConstructor_typeArgsExact() {
+ var unit = checkFile('''
+class C<T extends num> {}
+var x = new C<int>();
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+ }
+
void test_instantiateToBounds_notGeneric() {
var unit = checkFile(r'''
class A {}
@@ -2912,6 +3118,109 @@
''');
}
+ void test_referenceToFieldOfStaticField() {
+ var mainUnit = checkFile('''
+class C {
+ static D d;
+}
+class D {
+ int i;
+}
+final x = C.d.i;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'int');
+ }
+
+ void test_referenceToFieldOfStaticGetter() {
+ var mainUnit = checkFile('''
+class C {
+ static D get d => null;
+}
+class D {
+ int i;
+}
+final x = C.d.i;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'int');
+ }
+
+ void test_referenceToTypedef() {
+ var mainUnit = checkFile('''
+typedef void F();
+final x = F;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.type.toString(), 'Type');
+ }
+
+ void test_refineBinaryExpressionType_typeParameter_T_double() {
+ checkFile('''
+class C<T extends num> {
+ T a;
+
+ void op(double b) {
+ double r1 = a + b;
+ double r2 = a - b;
+ double r3 = a * b;
+ double r4 = a / b;
+ }
+}
+ ''');
+ }
+
+ void test_refineBinaryExpressionType_typeParameter_T_int() {
+ checkFile('''
+class C<T extends num> {
+ T a;
+
+ void op(int b) {
+ T r1 = a + b;
+ T r2 = a - b;
+ T r3 = a * b;
+ }
+
+ void opEq(int b) {
+ a += b;
+ a -= b;
+ a *= b;
+ }
+}
+ ''');
+ }
+
+ void test_refineBinaryExpressionType_typeParameter_T_T() {
+ checkFile('''
+class C<T extends num> {
+ T a;
+
+ void op(T b) {
+ T r1 = a + b;
+ T r2 = a - b;
+ T r3 = a * b;
+ }
+
+ void opEq(T b) {
+ a += b;
+ a -= b;
+ a *= b;
+ }
+}
+ ''');
+ }
+
+ void test_staticMethod_tearoff() {
+ var mainUnit = checkFile('''
+const v = C.f;
+class C {
+ static int f(String s) => null;
+}
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), '(String) → int');
+ }
+
void test_staticRefersToNonStaticField_inOtherLibraryCycle() {
addFile(
'''
@@ -2962,6 +3271,42 @@
}
''');
}
+
+ void test_typeInferenceDependency_staticVariable_inIdentifierSequence() {
+ // Check that type inference dependencies are properly checked when a static
+ // variable appears in the middle of a string of identifiers separated by
+ // '.'.
+ var mainUnit = checkFile('''
+final a = /*info:DYNAMIC_INVOKE*/C.d.i;
+class C {
+ static final d = new D(a);
+}
+class D {
+ D(_);
+ int i;
+}
+''');
+ // No type should be inferred for a because there is a circular reference
+ // between a and C.d.
+ var a = mainUnit.topLevelVariables[0];
+ expect(a.type.toString(), 'dynamic');
+ }
+
+ void test_typeInferenceDependency_topLevelVariable_inIdentifierSequence() {
+ // Check that type inference dependencies are properly checked when a top
+ // level variable appears at the beginning of a string of identifiers
+ // separated by '.'.
+ var mainUnit = checkFile('''
+final a = /*info:DYNAMIC_INVOKE*/c.i;
+final c = new C(a);
+class C {
+ C(_);
+ int i;
+}
+''');
+ // No type should be inferred for a because there is a circular reference
+ // between a and c.
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
index 8b38e73..a964675 100644
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ b/pkg/analyzer/tool/summary/dump_inferred_types.dart
@@ -18,8 +18,10 @@
for (String arg in args) {
PackageBundle bundle =
new PackageBundle.fromBuffer(new File(arg).readAsBytesSync());
- collector.visitPackageBundle(bundle);
+ collector.visitPackageBundle(bundle, arg);
}
+ collector.dumpLibraryIndex();
+ collector.dumpPartIndex();
collector.dumpCollectedTypes();
}
@@ -32,6 +34,8 @@
LinkedUnit linkedUnit;
final Map<String, String> inferredTypes = <String, String>{};
List<String> typeParamsInScope = <String>[];
+ final Map<String, Set<String>> libraryIndex = <String, Set<String>>{};
+ final Map<String, Set<String>> partIndex = <String, Set<String>>{};
/**
* If an inferred type exists matching the given [slot], record that it is the
@@ -63,6 +67,11 @@
properties.remove('initializer');
} else if (obj is UnlinkedExecutable) {
collectInferredType(obj.inferredReturnTypeSlot, path);
+ // As a temporary measure, prevent recursion into the executable's local
+ // variables and local functions, since AST-based type inference doesn't
+ // infer locals correctly yet. TODO(paulberry): fix if necessary.
+ properties.remove('localFunctions');
+ properties.remove('localVariables');
} else if (obj is UnlinkedParam) {
collectInferredType(obj.inferredTypeSlot, path);
// As a temporary measure, prevent recursion into the parameter's
@@ -76,6 +85,7 @@
* Print out all the inferred types collected so far, in alphabetical order.
*/
void dumpCollectedTypes() {
+ print('Collected types (${inferredTypes.length}):');
List<String> paths = inferredTypes.keys.toList();
paths.sort();
for (String path in paths) {
@@ -84,6 +94,38 @@
}
/**
+ * Print out an index mapping library names to the summary files containing
+ * them.
+ */
+ void dumpLibraryIndex() {
+ print('Library index:');
+ List<String> libraryNames = libraryIndex.keys.toList();
+ libraryNames.sort();
+ for (String libraryName in libraryNames) {
+ List<String> summaryFiles = libraryIndex[libraryName].toList();
+ summaryFiles.sort();
+ print('$libraryName -> ${summaryFiles.join(', ')}');
+ }
+ print('');
+ }
+
+ /**
+ * Print out an index mapping part file names to the summary files containing
+ * them.
+ */
+ void dumpPartIndex() {
+ print('Part index:');
+ List<String> partNames = partIndex.keys.toList();
+ partNames.sort();
+ for (String partName in partNames) {
+ List<String> summaryFiles = partIndex[partName].toList();
+ summaryFiles.sort();
+ print('$partName -> ${summaryFiles.join(', ')}');
+ }
+ print('');
+ }
+
+ /**
* Interpret the given [param] as a parameter in a synthetic typedef, and
* format it as a string.
*/
@@ -173,8 +215,12 @@
typeParamsInScope.length - entityRef.paramReference];
}
String result = formatReference(entityRef.reference, typeOf: true);
- if (entityRef.typeArguments.isNotEmpty) {
- result += '<${entityRef.typeArguments.map(formatType).join(', ')}>';
+ List<EntityRef> typeArguments = entityRef.typeArguments.toList();
+ while (typeArguments.isNotEmpty && isDynamic(typeArguments.last)) {
+ typeArguments.removeLast();
+ }
+ if (typeArguments.isNotEmpty) {
+ result += '<${typeArguments.map(formatType).join(', ')}>';
}
if (implicitFunctionTypeIndices.isNotEmpty) {
result =
@@ -184,6 +230,17 @@
}
/**
+ * Determine if the given [entityRef] represents the pseudo-type `dynamic`.
+ */
+ bool isDynamic(EntityRef entityRef) {
+ if (entityRef.syntheticReturnType != null ||
+ entityRef.paramReference != 0) {
+ return false;
+ }
+ return formatReference(entityRef.reference, typeOf: true) == 'dynamic';
+ }
+
+ /**
* Collect all the inferred types contained in [obj], which is reachable via
* [path]. [properties] is the result of calling `obj.toMap()`, and may be
* modified before returning.
@@ -223,14 +280,18 @@
/**
* Collect all the inferred types contained in [bundle].
*/
- void visitPackageBundle(PackageBundle bundle) {
+ void visitPackageBundle(PackageBundle bundle, String summaryPath) {
Map<String, LinkedLibrary> linkedLibraries = <String, LinkedLibrary>{};
Map<String, UnlinkedUnit> unlinkedUnits = <String, UnlinkedUnit>{};
for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
linkedLibraries[bundle.linkedLibraryUris[i]] = bundle.linkedLibraries[i];
}
for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
- unlinkedUnits[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+ String unitUriString = bundle.unlinkedUnitUris[i];
+ partIndex
+ .putIfAbsent(unitUriString, () => new Set<String>())
+ .add(summaryPath);
+ unlinkedUnits[unitUriString] = bundle.unlinkedUnits[i];
}
// Figure out which unlinked units are a part of another library so we won't
// visit them redundantly.
@@ -248,6 +309,9 @@
if (partOfUris.contains(libraryUriString)) {
return;
}
+ libraryIndex
+ .putIfAbsent(libraryUriString, () => new Set<String>())
+ .add(summaryPath);
Uri libraryUri = Uri.parse(libraryUriString);
UnlinkedUnit definingUnlinkedUnit = unlinkedUnits[libraryUriString];
if (definingUnlinkedUnit != null) {
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index b3e9398..6c4fbcd 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
@@ -25,8 +24,6 @@
/// The maximum number of sources for which AST structures should be kept in the cache.
const int _maxCacheSize = 512;
-DirectoryBasedDartSdk sdk;
-
int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
/// Analyzes single library [File].
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index e60ec09..d49a519 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -324,6 +324,11 @@
// Parse the source and serialize its AST.
Uri uri = Uri.parse(absoluteUri);
Source source = context.sourceFactory.forUri2(uri);
+ if (!source.exists()) {
+ // TODO(paulberry): we should report a warning/error because DDC
+ // compilations are unlikely to work.
+ return null;
+ }
return uriToUnit.putIfAbsent(uri, () {
CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 6a67547..aaff20d 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -73,9 +73,6 @@
/// The plugins that are defined outside the `analyzer_cli` package.
List<Plugin> _userDefinedPlugins = <Plugin>[];
- /// Indicates whether the analyzer is running in batch mode.
- bool _isBatch;
-
/// The context that was most recently created by a call to [_analyzeAll], or
/// `null` if [_analyzeAll] hasn't been called yet.
AnalysisContext _context;
@@ -93,6 +90,9 @@
@override
ResolverProvider packageResolverProvider;
+ /// SDK instance.
+ DirectoryBasedDartSdk sdk;
+
/// Collected analysis statistics.
final AnalysisStats stats = new AnalysisStats();
@@ -120,9 +120,6 @@
// Parse commandline options.
CommandLineOptions options = CommandLineOptions.parse(args);
- // Cache options of interest to inform analysis.
- _setupEnv(options);
-
// Do analysis.
if (options.buildMode) {
ErrorSeverity severity = _buildModeAnalyze(options);
@@ -130,7 +127,7 @@
if (severity == ErrorSeverity.ERROR) {
exitCode = severity.ordinal;
}
- } else if (_isBatch) {
+ } else if (options.shouldBatch) {
_BatchRunner.runAsBatch(args, (List<String> args) {
CommandLineOptions options = CommandLineOptions.parse(args);
return _analyzeAll(options);
@@ -306,7 +303,7 @@
/// [AnalyzeFunctionBodiesPredicate] that implements this policy.
AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy(
CommandLineOptions options) {
- if (_isBatch) {
+ if (options.shouldBatch) {
// As analyzer is currently implemented, once a file has been diet
// parsed, it can't easily be un-diet parsed without creating a brand new
// context and losing caching. In batch mode, we can't predict which
@@ -507,19 +504,22 @@
// Create a context.
_context = AnalysisEngine.instance.createAnalysisContext();
- // Choose a package resolution policy and a diet parsing policy based on
- // the command-line options.
- SourceFactory sourceFactory = _chooseUriResolutionPolicy(
- options, (_context as InternalAnalysisContext).embedderYamlLocator);
AnalyzeFunctionBodiesPredicate dietParsingPolicy =
_chooseDietParsingPolicy(options);
-
- _context.sourceFactory = sourceFactory;
-
setAnalysisContextOptions(_context, options,
(AnalysisOptionsImpl contextOptions) {
contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
});
+
+ // Once options are processed, setup the SDK.
+ _setupSdk(options);
+
+ // Choose a package resolution policy and a diet parsing policy based on
+ // the command-line options.
+ SourceFactory sourceFactory = _chooseUriResolutionPolicy(
+ options, (_context as InternalAnalysisContext).embedderYamlLocator);
+
+ _context.sourceFactory = sourceFactory;
}
/// Return discovered packagespec, or `null` if none is found.
@@ -582,15 +582,17 @@
return errorSeverity;
}
- void _setupEnv(CommandLineOptions options) {
- // In batch mode, SDK is specified on the main command line rather than in
- // the command lines sent to stdin. So process it before deciding whether
- // to activate batch mode.
+ void _setupSdk(CommandLineOptions options) {
if (sdk == null) {
- sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
- sdk.analysisOptions = createAnalysisOptionsForCommandLineOptions(options);
+ String dartSdkPath = options.dartSdkPath;
+ sdk = new DirectoryBasedDartSdk(new JavaFile(dartSdkPath));
+ sdk.useSummary = options.sourceFiles.every((String sourcePath) {
+ sourcePath = path.absolute(sourcePath);
+ sourcePath = path.normalize(sourcePath);
+ return !path.isWithin(dartSdkPath, sourcePath);
+ });
+ sdk.analysisOptions = context.analysisOptions;
}
- _isBatch = options.shouldBatch;
}
static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions(
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 3f26109..ae8466c 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -508,7 +508,7 @@
exitHandler(0);
return null; // Only reachable in testing.
} else {
- if (results.rest.isEmpty) {
+ if (results.rest.isEmpty && !results['build-mode']) {
_showUsage(parser);
exitHandler(15);
return null; // Only reachable in testing.
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
index 1d2a841..c0f4f1c 100644
--- a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
+++ b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
@@ -1,4 +1,5 @@
analyzer:
+ strong-mode: true
errors:
unused_local_variable: ignore
missing_return: error
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 0b48331..6c85880 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -263,6 +263,15 @@
doDrive();
expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
});
+
+ test('strongMode', () {
+ doDrive();
+ expect(driver.context.analysisOptions.strongMode, isTrue);
+ //https://github.com/dart-lang/sdk/issues/26129
+ AnalysisContext sdkContext =
+ driver.context.sourceFactory.dartSdk.context;
+ expect(sdkContext.analysisOptions.strongMode, isTrue);
+ });
});
group('with flags', () {
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 620c047..29bde19 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -257,6 +257,12 @@
expect(options.buildMode, isTrue);
}
+ test_buildMode_allowsEmptyFileList() {
+ _parse(['--build-mode']);
+ expect(options.buildMode, isTrue);
+ expect(options.sourceFiles, isEmpty);
+ }
+
test_buildSummaryFallback() {
_parse([
'--build-mode',
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 0b9f990..250a038 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -57,6 +57,8 @@
Iterable<ConstantExpression> get constantLiterals {
return const <ConstantExpression>[];
}
+
+ Iterable<dynamic> get nativeData => const <dynamic>[];
}
/// A language feature seen during resolution.
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 629d457..724e6f6 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -29,6 +29,9 @@
/// The [ConstantSystem] used by this environment.
ConstantSystem get constantSystem;
+ /// Returns `true` if a value has been computed for [expression].
+ bool hasConstantValue(ConstantExpression expression);
+
/// Returns the constant value computed for [expression].
// TODO(johnniwinther): Support directly evaluation of [expression].
ConstantValue getConstantValue(ConstantExpression expression);
@@ -287,6 +290,10 @@
return null;
}
+ bool hasConstantValue(ConstantExpression expression) {
+ return constantValueMap.containsKey(expression);
+ }
+
ConstantValue getConstantValue(ConstantExpression expression) {
return constantValueMap[expression];
}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 4aa08fd..7dbee2a 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1932,15 +1932,12 @@
ResolvedAst getResolvedAst(ExecutableElement element) {
assert(invariant(element, element.isDeclaration,
message: "Element $element must be the declaration."));
- if (hasResolvedAst(element)) {
- if (compiler.serialization.isDeserialized(element)) {
- return compiler.serialization.getResolvedAst(element);
- }
- return element.resolvedAst;
- }
assert(invariant(element, hasResolvedAst(element),
message: "ResolvedAst not available for $element."));
- return null;
+ if (compiler.serialization.isDeserialized(element)) {
+ return compiler.serialization.getResolvedAst(element);
+ }
+ return element.resolvedAst;
}
@override
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 4019e16..3b4317f 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -124,6 +124,21 @@
'ConstantExpression.toString()');
return toDartText();
}
+
+ /// Returns `true` if this expression is implicitly constant, that is, that
+ /// it doesn't declare its constness with the 'const' keyword.
+ ///
+ /// Implicit constants are simple literals, like bool, int and string
+ /// literals, constant references and compositions of implicit constants.
+ /// Explicit constants are constructor constants, and constant map and list
+ /// literals.
+ bool get isImplicit => true;
+
+ /// Returns `true` if this expression is only potentially constant, that is,
+ /// if it contains positional or named references, used to define constant
+ /// constructors.
+ // TODO(johnniwinther): Maybe make this final if we use it outside assertions.
+ bool get isPotential => true;
}
/// A synthetic constant used to recover from errors.
@@ -183,6 +198,12 @@
}
ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC;
+
+ @override
+ bool get isPotential => false;
+
+ @override
+ bool get isImplicit => false;
}
/// A boolean, int, double, string, or null constant.
@@ -422,6 +443,12 @@
@override
DartType getKnownType(CoreTypes coreTypes) => type;
+
+ @override
+ bool get isImplicit => false;
+
+ @override
+ bool get isPotential => values.any((e) => e.isPotential);
}
/// Literal map constant.
@@ -491,6 +518,14 @@
@override
DartType getKnownType(CoreTypes coreTypes) => type;
+
+ @override
+ bool get isImplicit => false;
+
+ @override
+ bool get isPotential {
+ return keys.any((e) => e.isPotential) || values.any((e) => e.isPotential);
+ }
}
/// Invocation of a const constructor.
@@ -571,6 +606,14 @@
}
return true;
}
+
+ @override
+ bool get isImplicit => false;
+
+ @override
+ bool get isPotential {
+ return arguments.any((e) => e.isPotential);
+ }
}
/// String literal with juxtaposition and/or interpolations.
@@ -650,6 +693,11 @@
@override
DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
+
+ @override
+ bool get isPotential {
+ return expressions.any((e) => e.isPotential);
+ }
}
/// Symbol literal.
@@ -895,6 +943,11 @@
right == other.right;
}
+ @override
+ bool get isPotential {
+ return left.isPotential || right.isPotential;
+ }
+
static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const {
BinaryOperatorKind.EQ: 6,
BinaryOperatorKind.NOT_EQ: 6,
@@ -968,6 +1021,11 @@
@override
DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
+
+ @override
+ bool get isPotential {
+ return left.isPotential || right.isPotential;
+ }
}
/// A unary constant expression like `-a`.
@@ -1021,6 +1079,11 @@
return expression.getKnownType(coreTypes);
}
+ @override
+ bool get isPotential {
+ return expression.isPotential;
+ }
+
static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const {
UnaryOperatorKind.NOT: 14,
UnaryOperatorKind.COMPLEMENT: 14,
@@ -1076,6 +1139,11 @@
@override
DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
+
+ @override
+ bool get isPotential {
+ return expression.isPotential;
+ }
}
/// A constant conditional expression like `a ? b : c`.
@@ -1149,6 +1217,11 @@
}
return null;
}
+
+ @override
+ bool get isPotential {
+ return condition.isPotential || trueExp.isPotential || falseExp.isPotential;
+ }
}
/// A reference to a position parameter.
@@ -1185,6 +1258,11 @@
Environment environment, ConstantSystem constantSystem) {
throw new UnsupportedError('PositionalArgumentReference.evaluate');
}
+
+ @override
+ bool get isPotential {
+ return true;
+ }
}
/// A reference to a named parameter.
@@ -1221,6 +1299,11 @@
Environment environment, ConstantSystem constantSystem) {
throw new UnsupportedError('NamedArgumentReference.evaluate');
}
+
+ @override
+ bool get isPotential {
+ return true;
+ }
}
abstract class FromEnvironmentConstantExpression extends ConstantExpression {
@@ -1238,6 +1321,17 @@
bool _equals(FromEnvironmentConstantExpression other) {
return name == other.name && defaultValue == other.defaultValue;
}
+
+ @override
+ bool get isImplicit {
+ return false;
+ }
+
+ @override
+ bool get isPotential {
+ return name.isPotential ||
+ (defaultValue != null && defaultValue.isPotential);
+ }
}
/// A `const bool.fromEnvironment` constant.
@@ -1471,6 +1565,11 @@
accept(ConstantExpressionVisitor visitor, [context]) {
return visitor.visitDeferred(this, context);
}
+
+ @override
+ bool get isPotential {
+ return expression.isPotential;
+ }
}
abstract class ConstantExpressionVisitor<R, A> {
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index d8cef91..5f3eed9 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -465,6 +465,11 @@
ConstantSystem get constantSystem => constantCompiler.constantSystem;
@override
+ bool hasConstantValue(ConstantExpression expression) {
+ return constantCompiler.hasConstantValue(expression);
+ }
+
+ @override
ConstantValue getConstantValue(ConstantExpression expression) {
return constantCompiler.getConstantValue(expression);
}
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index b75a6ab..bbd91ae 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -336,14 +336,29 @@
TreeElements treeElements = analyzableElement.resolvedAst.elements;
assert(treeElements != null);
+ // TODO(johnniwinther): Add only expressions that are actually needed.
+ // Currently we have some noise here: Some potential expressions are
+ // seen that should never be added (for instance field initializers
+ // in constant constructors, like `this.field = parameter`). And some
+ // implicit constant expression are seen that we should be able to add
+ // (like primitive constant literals like `true`, `"foo"` and `0`).
+ // See dartbug.com/26406 for context.
treeElements
.forEachConstantNode((Node node, ConstantExpression expression) {
// Explicitly depend on the backend constants.
- ConstantValue value = backend.constants.getConstantValue(expression);
- assert(invariant(node, value != null,
- message:
- "No constant value for ${expression.toStructuredText()}."));
- constants.add(value);
+ if (backend.constants.hasConstantValue(expression)) {
+ ConstantValue value =
+ backend.constants.getConstantValue(expression);
+ assert(invariant(node, value != null,
+ message: "Constant expression without value: "
+ "${expression.toStructuredText()}."));
+ constants.add(value);
+ } else {
+ assert(invariant(node,
+ expression.isImplicit || expression.isPotential,
+ message: "Unexpected unevaluated constant expression: "
+ "${expression.toStructuredText()}."));
+ }
});
}
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 62a9efd..1cac7aa 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -856,6 +856,9 @@
if (constant != null) {
ConstantValue value =
compiler.backend.constants.getConstantValue(constant);
+ assert(invariant(fieldElement, value != null,
+ message: "Constant expression without value: "
+ "${constant.toStructuredText()}."));
if (value.isFunction) {
FunctionConstantValue functionConstant = value;
type = types.allocateClosure(node, functionConstant.element);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index f5eac4a..15b8de4 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -1477,6 +1477,9 @@
ConstantExpression constant = variableElement.constant;
if (constant != null) {
ConstantValue initialValue = constants.getConstantValue(constant);
+ assert(invariant(variableElement, initialValue != null,
+ message: "Constant expression without value: "
+ "${constant.toStructuredText()}."));
registerCompileTimeConstant(initialValue, work.registry);
addCompileTimeConstantForEmission(initialValue);
// We don't need to generate code for static or top-level
@@ -2623,6 +2626,11 @@
BackendImpacts get impacts => backend.impacts;
+ // TODO(johnniwinther): Avoid this dependency.
+ ResolutionEnqueuer get resolutionEnqueuer {
+ return backend.compiler.enqueuer.resolution;
+ }
+
@override
WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
TransformedWorldImpact transformed =
@@ -2782,8 +2790,7 @@
registerBackendImpact(transformed, impacts.closure);
LocalFunctionElement closure = staticUse.element;
if (closure.type.containsTypeVariables) {
- backend.compiler.enqueuer.resolution.universe
- .closuresWithFreeTypeVariables
+ resolutionEnqueuer.universe.closuresWithFreeTypeVariables
.add(closure);
registerBackendImpact(transformed, impacts.computeSignature);
}
@@ -2813,6 +2820,11 @@
}
}
+ for (native.NativeBehavior behavior in worldImpact.nativeData) {
+ resolutionEnqueuer.nativeEnqueuer
+ .registerNativeBehavior(behavior, worldImpact);
+ }
+
return transformed;
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 2383662..5aefd39 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -26,6 +26,11 @@
ConstantSystem get constantSystem => dartConstantCompiler.constantSystem;
@override
+ bool hasConstantValue(ConstantExpression expression) {
+ return dartConstantCompiler.hasConstantValue(expression);
+ }
+
+ @override
ConstantValue getConstantValue(ConstantExpression expression) {
return dartConstantCompiler.getConstantValue(expression);
}
@@ -249,7 +254,11 @@
ConstantValue getConstantValue(ConstantExpression expression) {
assert(invariant(CURRENT_ELEMENT_SPANNABLE, expression != null,
message: "ConstantExpression is null in getConstantValue."));
- evaluate(expression);
+ // TODO(johhniwinther): ensure expressions have been evaluated at this
+ // point. This can't be enabled today due to dartbug.com/26406.
+ if (compiler.serialization.supportsDeserialization) {
+ evaluate(expression);
+ }
ConstantValue value = super.getConstantValue(expression);
if (value == null &&
expression != null &&
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index c04509b..e15f185 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -606,11 +606,8 @@
*
*/
NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
- NativeBehavior behavior = NativeBehavior.ofJsCall(
+ return NativeBehavior.ofJsCall(
node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
- // TODO(johnniwinther): Move registration to the world impact application.
- registerNativeBehavior(behavior, node);
- return behavior;
}
/**
@@ -624,11 +621,8 @@
*/
NativeBehavior resolveJsEmbeddedGlobalCall(
Send node, ForeignResolver resolver) {
- NativeBehavior behavior = NativeBehavior.ofJsEmbeddedGlobalCall(
+ return NativeBehavior.ofJsEmbeddedGlobalCall(
node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
- // TODO(johnniwinther): Move registration to the world impact application.
- registerNativeBehavior(behavior, node);
- return behavior;
}
/**
@@ -641,11 +635,8 @@
*
*/
NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) {
- NativeBehavior behavior = NativeBehavior.ofJsBuiltinCall(
+ return NativeBehavior.ofJsBuiltinCall(
node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
- // TODO(johnniwinther): Move registration to the world impact application.
- registerNativeBehavior(behavior, node);
- return behavior;
}
}
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 9a81401..c9c60f69 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -38,5 +38,7 @@
return _allowedDartSchemePaths.contains(uri.path);
}
- return allowedTestLibrary() || allowedDartLibary();
+ return allowedTestLibrary() ||
+ allowedDartLibary() ||
+ compiler.options.allowNativeExtensions;
}
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 0cd21ac..6fe019c 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -755,7 +755,8 @@
throw new ParserError(message);
}
- void reportError(Spannable spannable, MessageKind errorCode,
+ @override
+ void reportErrorHelper(Spannable spannable, MessageKind errorCode,
[Map arguments = const {}]) {
if (currentMemberHasParseError) return; // Error already reported.
if (suppressParseErrors) return;
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 1294bf1..afd2997 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -548,6 +548,15 @@
void reportError(Spannable spannable, MessageKind messageKind,
[Map arguments = const {}]) {
+ if (spannable is ErrorToken) {
+ reportErrorToken(spannable);
+ } else {
+ reportErrorHelper(spannable, messageKind, arguments);
+ }
+ }
+
+ void reportErrorHelper(Spannable spannable, MessageKind messageKind,
+ [Map arguments = const {}]) {
MessageTemplate template = MessageTemplate.TEMPLATES[messageKind];
String message = template.message(arguments, true).toString();
Token token;
@@ -568,7 +577,7 @@
String padding = "0000".substring(hex.length);
hex = "$padding$hex";
}
- reportError(
+ reportErrorHelper(
token, MessageKind.BAD_INPUT_CHARACTER, {'characterHex': hex});
} else if (token is UnterminatedToken) {
MessageKind kind;
@@ -601,11 +610,11 @@
kind = MessageKind.UNTERMINATED_TOKEN;
break;
}
- reportError(token, kind, arguments);
+ reportErrorHelper(token, kind, arguments);
} else if (token is UnmatchedToken) {
String begin = token.begin.value;
String end = closeBraceFor(begin);
- reportError(
+ reportErrorHelper(
token, MessageKind.UNMATCHED_TOKEN, {'begin': begin, 'end': end});
} else {
throw new SpannableAssertionFailure(token, token.assertionMessage);
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 7008c9a..7de89c2 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -36,6 +36,7 @@
Setlet<ListLiteralUse> _listLiterals;
Setlet<String> _constSymbolNames;
Setlet<ConstantExpression> _constantLiterals;
+ Setlet<dynamic> _nativeData;
_ResolutionWorldImpact(this.name);
@@ -104,6 +105,19 @@
: const <ConstantExpression>[];
}
+ void registerNativeData(dynamic nativeData) {
+ assert(nativeData != null);
+ if (_nativeData == null) {
+ _nativeData = new Setlet<dynamic>();
+ }
+ _nativeData.add(nativeData);
+ }
+
+ @override
+ Iterable<dynamic> get nativeData {
+ return _nativeData != null ? _nativeData : const <dynamic>[];
+ }
+
String toString() {
StringBuffer sb = new StringBuffer();
sb.write('_ResolutionWorldImpact($name)');
@@ -359,7 +373,9 @@
var nativeData = backend.resolveForeignCall(node, element, callStructure,
new ForeignResolutionResolver(visitor, this));
if (nativeData != null) {
+ // Split impact from resolution result.
mapping.registerNativeData(node, nativeData);
+ worldImpact.registerNativeData(nativeData);
}
}
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index 969ef40..be8ff7f 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -276,6 +276,13 @@
}
}
+/// Returns `true` if nodes [a] and [b] are equivalent.
+bool areNodesEquivalent(Node node1, Node node2) {
+ if (identical(node1, node2)) return true;
+ if (node1 == null || node2 == null) return false;
+ return node1.accept1(const NodeEquivalenceVisitor(), node2);
+}
+
/// Strategy for testing equivalence.
///
/// Use this strategy to determine equivalence without failing on inequivalence.
@@ -323,6 +330,11 @@
List<ConstantExpression> list1, List<ConstantExpression> list2) {
return areConstantListsEquivalent(list1, list2);
}
+
+ bool testNodes(
+ Object object1, Object object2, String property, Node node1, Node node2) {
+ return areNodesEquivalent(node1, node2);
+ }
}
/// Visitor that checks for equivalence of [Element]s.
@@ -765,15 +777,33 @@
// Nothing more to check.
return true;
}
- return strategy.testElements(resolvedAst1, resolvedAst2, 'element',
+ bool result = strategy.testElements(resolvedAst1, resolvedAst2, 'element',
resolvedAst1.element, resolvedAst2.element) &&
- new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
- 'node', resolvedAst1.node, resolvedAst2.node) &&
- new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
- 'body', resolvedAst1.body, resolvedAst2.body) &&
+ strategy.testNodes(resolvedAst1, resolvedAst2, 'node', resolvedAst1.node,
+ resolvedAst2.node) &&
+ strategy.testNodes(resolvedAst1, resolvedAst2, 'body', resolvedAst1.body,
+ resolvedAst2.body) &&
testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy) &&
strategy.test(resolvedAst1, resolvedAst2, 'sourceUri',
resolvedAst1.sourceUri, resolvedAst2.sourceUri);
+ if (resolvedAst1.element is FunctionElement) {
+ FunctionElement element1 = resolvedAst1.element;
+ FunctionElement element2 = resolvedAst2.element;
+ for (int index = 0; index < element1.parameters.length; index++) {
+ var parameter1 = element1.parameters[index];
+ var parameter2 = element2.parameters[index];
+ result = result &&
+ strategy.testNodes(parameter1, parameter2, 'node',
+ parameter1.implementation.node, parameter2.implementation.node) &&
+ strategy.testNodes(
+ parameter1,
+ parameter2,
+ 'initializer',
+ parameter1.implementation.initializer,
+ parameter2.implementation.initializer);
+ }
+ }
+ return result;
}
/// Tests the equivalence of the data stored in the [TreeElements] of
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
index 7e74259..b2aa0455 100644
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/impact_serialization.dart
@@ -25,8 +25,10 @@
final ListEncoder staticUses;
final ListEncoder dynamicUses;
final ListEncoder typeUses;
+ final SerializerPlugin nativeDataSerializer;
- ImpactSerializer(this.element, ObjectEncoder objectEncoder)
+ ImpactSerializer(
+ this.element, ObjectEncoder objectEncoder, this.nativeDataSerializer)
: this.objectEncoder = objectEncoder,
staticUses = objectEncoder.createList(Key.STATIC_USES),
dynamicUses = objectEncoder.createList(Key.DYNAMIC_USES),
@@ -56,6 +58,12 @@
useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
}
}
+ if (resolutionImpact.nativeData.isNotEmpty) {
+ ListEncoder encoder = objectEncoder.createList(Key.NATIVE);
+ for (dynamic data in resolutionImpact.nativeData) {
+ nativeDataSerializer.onData(data, encoder.createObject());
+ }
+ }
}
@override
@@ -91,6 +99,7 @@
final Iterable<MapLiteralUse> mapLiterals;
final Iterable<StaticUse> staticUses;
final Iterable<TypeUse> typeUses;
+ final Iterable<dynamic> nativeData;
DeserializedResolutionImpact(
{this.constSymbolNames: const <String>[],
@@ -100,7 +109,8 @@
this.listLiterals: const <ListLiteralUse>[],
this.mapLiterals: const <MapLiteralUse>[],
this.staticUses: const <StaticUse>[],
- this.typeUses: const <TypeUse>[]})
+ this.typeUses: const <TypeUse>[],
+ this.nativeData: const <dynamic>[]})
: this._features = features;
Iterable<Feature> get features {
@@ -112,8 +122,8 @@
class ImpactDeserializer {
/// Deserializes a [WorldImpact] from [objectDecoder].
- static ResolutionImpact deserializeImpact(
- Element element, ObjectDecoder objectDecoder) {
+ static ResolutionImpact deserializeImpact(Element element,
+ ObjectDecoder objectDecoder, DeserializerPlugin nativeDataDeserializer) {
ListDecoder staticUseDecoder = objectDecoder.getList(Key.STATIC_USES);
List<StaticUse> staticUses = <StaticUse>[];
for (int index = 0; index < staticUseDecoder.length; index++) {
@@ -180,6 +190,20 @@
}
}
+ ListDecoder nativeDataDecoder =
+ objectDecoder.getList(Key.NATIVE, isOptional: true);
+ List<dynamic> nativeData = const <dynamic>[];
+ if (nativeDataDecoder != null) {
+ nativeData = <dynamic>[];
+ for (int i = 0; i < nativeDataDecoder.length; i++) {
+ dynamic data =
+ nativeDataDeserializer.onData(nativeDataDecoder.getObject(i));
+ if (data != null) {
+ nativeData.add(data);
+ }
+ }
+ }
+
return new DeserializedResolutionImpact(
constSymbolNames: constSymbolNames,
constantLiterals: constantLiterals,
@@ -188,6 +212,7 @@
listLiterals: listLiterals,
mapLiterals: mapLiterals,
staticUses: staticUses,
- typeUses: typeUses);
+ typeUses: typeUses,
+ nativeData: nativeData);
}
}
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index b280d69..7772956 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -1867,13 +1867,13 @@
@override
FunctionSignature get functionSignature => _unsupported('functionSignature');
- // TODO(johnniwinther): HACK. Remove [initializer] and [node] on
+ // TODO(johnniwinther): Remove [initializer] and [node] on
// [ParameterElementZ] when the inference does need these.
@override
- Expression get initializer => null;
+ Expression initializer;
@override
- Node get node => null;
+ Node node;
@override
bool get isNamed => _decoder.getBool(Key.IS_NAMED);
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index 613bd61..633b65e 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -22,6 +22,7 @@
import '../universe/selector.dart';
import '../util/util.dart';
import 'keys.dart';
+import 'modelz.dart';
import 'serialization.dart';
import 'serialization_util.dart';
@@ -165,6 +166,19 @@
serializeLabelDefinition(labelDefinition, list.createObject());
}
}
+ if (element is FunctionElement) {
+ FunctionElement function = element;
+ function.functionSignature.forEachParameter((ParameterElement parameter) {
+ ParameterElement parameterImpl = parameter.implementation;
+ // TODO(johnniwinther): Should we support element->node mapping as well?
+ getNodeDataEncoder(parameterImpl.node)
+ .setElement(PARAMETER_NODE, parameter);
+ if (parameter.initializer != null) {
+ getNodeDataEncoder(parameterImpl.initializer)
+ .setElement(PARAMETER_INITIALIZER, parameter);
+ }
+ });
+ }
}
/// Serialize [target] into [encoder].
@@ -203,7 +217,9 @@
/// Computes the [ObjectEncoder] for serializing data for [node].
ObjectEncoder getNodeDataEncoder(Node node) {
+ assert(invariant(element, node != null, message: "Node must be non-null."));
int id = nodeIndices[node];
+ assert(invariant(element, id != null, message: "Node without id: $node"));
return nodeData.putIfAbsent(id, () {
ObjectEncoder objectEncoder = nodeDataEncoder.createObject();
objectEncoder.setInt(Key.ID, id);
@@ -650,6 +666,18 @@
resolvedAstMap[function] = new ParsedResolvedAst(function,
functionExpression, functionExpression.body, elements, uri);
}
+ // TODO(johnniwinther): Remove these when inference doesn't need `.node`
+ // and `.initializer` of [ParameterElement]s.
+ ParameterElementZ parameter =
+ objectDecoder.getElement(PARAMETER_NODE, isOptional: true);
+ if (parameter != null) {
+ parameter.node = node;
+ }
+ parameter =
+ objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true);
+ if (parameter != null) {
+ parameter.initializer = node;
+ }
}
}
assert(invariant(element, !resolvedAstMap.containsKey(element),
@@ -658,3 +686,6 @@
new ParsedResolvedAst(element, root, body, elements, uri);
}
}
+
+const Key PARAMETER_NODE = const Key('parameter.node');
+const Key PARAMETER_INITIALIZER = const Key('parameter.initializer');
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 1639c32..6ca4636 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -34,6 +34,9 @@
// retained, for instance impacts, resolution data etc.
bool supportSerialization = false;
+ /// If `true`, deserialized data is supported.
+ bool get supportsDeserialization => deserializer != null;
+
/// Returns the [LibraryElement] for [resolvedUri] if available from
/// serialization.
Future<LibraryElement> readLibrary(Uri resolvedUri) {
diff --git a/pkg/meta/.analysis_options b/pkg/meta/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/pkg/meta/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/pkg/pkg.status b/pkg/pkg.status
index c991ab2..a78a08d6c 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -22,6 +22,9 @@
[ $runtime == vm && $mode == debug ]
analysis_server/test/completion_test: Pass, Slow
+[ $runtime == vm && $checked ]
+analysis_server/test/completion_test: Pass, Slow
+
[ $runtime == vm && $system == windows]
analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index bd091d9a..ad030b8 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -26,6 +26,8 @@
# this unspecified results in automatic target architecture detection.
# Available options are: arm, arm64, mips, x64 and ia32
dart_target_arch = ""
+
+ dart_experimental_interpreter = false
}
config("dart_public_config") {
@@ -70,13 +72,19 @@
print("Debug and release mode are mutually exclusive.")
}
assert(!dart_debug)
- defines += ["DART_PRECOMPILED_RUNTIME"]
+
+ if (!dart_experimental_interpreter) {
+ defines += ["DART_PRECOMPILED_RUNTIME"]
+ }
} else if (dart_runtime_mode == "profile") {
if (dart_debug) {
print("Debug and profile mode are mutually exclusive.")
}
assert(!dart_debug)
- defines += ["DART_PRECOMPILED_RUNTIME"]
+
+ if (!dart_experimental_interpreter) {
+ defines += ["DART_PRECOMPILED_RUNTIME"]
+ }
}
}
@@ -89,6 +97,10 @@
config("dart_config") {
defines = []
+ if (dart_experimental_interpreter) {
+ dart_target_arch = "dbc"
+ }
+
if (dart_target_arch != "") {
if (dart_target_arch == "arm") {
defines += [ "TARGET_ARCH_ARM" ]
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index b5ce6e6..bff1387 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -5,6 +5,7 @@
declare_args() {
dart_io_support = false
+ dart_boringssl_path = "../../third_party/boringssl"
}
@@ -330,7 +331,7 @@
]
} else {
deps = [
- "../../third_party/boringssl",
+ rebase_path(dart_boringssl_path, "."),
]
}
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 0018712..3905ad7 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -8,6 +8,18 @@
'io_cc_file': '<(gen_source_dir)/io_gen.cc',
'io_patch_cc_file': '<(gen_source_dir)/io_patch_gen.cc',
+ 'html_cc_file': '<(gen_source_dir)/html_gen.cc',
+ 'html_common_cc_file': '<(gen_source_dir)/html_common_gen.cc',
+ 'js_cc_file': '<(gen_source_dir)/js_gen.cc',
+ 'blink_cc_file': '<(gen_source_dir)/blink_gen.cc',
+ 'indexeddb_cc_file': '<(gen_source_dir)/indexeddb_gen.cc',
+ 'cached_patches_cc_file': '<(gen_source_dir)/cached_patches_gen.cc',
+ 'web_gl_cc_file': '<(gen_source_dir)/web_gl_gen.cc',
+ 'metadata_cc_file': '<(gen_source_dir)/metadata_gen.cc',
+ 'websql_cc_file': '<(gen_source_dir)/websql_gen.cc',
+ 'svg_cc_file': '<(gen_source_dir)/svg_gen.cc',
+ 'webaudio_cc_file': '<(gen_source_dir)/webaudio_gen.cc',
+
'builtin_in_cc_file': 'builtin_in.cc',
'builtin_cc_file': '<(gen_source_dir)/builtin_gen.cc',
'snapshot_in_cc_file': 'snapshot_in.cc',
@@ -120,6 +132,364 @@
]
},
{
+ 'target_name': 'generate_html_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/html/dartium/html_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_html_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(html_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(html_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::html_source_paths_',
+ '--library_name', 'dart:html',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(html_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_html_common_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/html/html_common/html_common.dart',
+ '../../sdk/lib/html/html_common/css_class_set.dart',
+ '../../sdk/lib/html/html_common/device.dart',
+ '../../sdk/lib/html/html_common/filtered_element_list.dart',
+ '../../sdk/lib/html/html_common/lists.dart',
+ '../../sdk/lib/html/html_common/conversions.dart',
+ '../../sdk/lib/html/html_common/conversions_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_html_common_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(html_common_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(html_common_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::html_common_source_paths_',
+ '--library_name', 'dart:html_common',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(html_common_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_js_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/js/dartium/js_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_js_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(js_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(js_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::js_source_paths_',
+ '--library_name', 'dart:js',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(js_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_blink_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/_blink/dartium/_blink_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_blink_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(blink_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(blink_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::blink_source_paths_',
+ '--library_name', 'dart:_blink',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(blink_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_indexeddb_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/indexed_db/dartium/indexed_db_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_indexeddb_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(indexeddb_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(indexeddb_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::indexeddb_source_paths_',
+ '--library_name', 'dart:indexed_db',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(indexeddb_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_cached_patches_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/js/dartium/cached_patches.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_cached_patches_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(cached_patches_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(cached_patches_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::cached_patches_source_paths_',
+ '--library_name', 'cached_patches.dart',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(cached_patches_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_web_gl_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/web_gl/dartium/web_gl_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_web_gl_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(web_gl_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(web_gl_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::web_gl_source_paths_',
+ '--library_name', 'dart:web_gl',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(web_gl_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_metadata_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/html/html_common/metadata.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_metadata_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(metadata_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(metadata_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::metadata_source_paths_',
+ '--library_name', 'metadata.dart',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(metadata_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_websql_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/web_sql/dartium/web_sql_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_websql_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(websql_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(websql_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::websql_source_paths_',
+ '--library_name', 'dart:web_sql',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(websql_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_svg_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/svg/dartium/svg_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_svg_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(svg_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(svg_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::svg_source_paths_',
+ '--library_name', 'dart:svg',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(svg_cc_file)'' file.'
+ },
+ ]
+ },
+ {
+ 'target_name': 'generate_webaudio_cc_file',
+ 'type': 'none',
+ 'toolsets':['host'],
+ 'sources': [
+ '../../sdk/lib/web_audio/dartium/web_audio_dartium.dart',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_webaudio_cc',
+ 'inputs': [
+ '../tools/gen_library_src_paths.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(webaudio_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/gen_library_src_paths.py',
+ '--output', '<(webaudio_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'bin/builtin.h',
+ '--var_name', 'dart::bin::Builtin::webaudio_source_paths_',
+ '--library_name', 'dart:web_audio',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(webaudio_cc_file)'' file.'
+ },
+ ]
+ },
+ {
'target_name': 'libdart_builtin',
'type': 'static_library',
'toolsets':['target','host'],
@@ -127,6 +497,17 @@
'generate_builtin_cc_file#host',
'generate_io_cc_file#host',
'generate_io_patch_cc_file#host',
+ 'generate_html_cc_file#host',
+ 'generate_html_common_cc_file#host',
+ 'generate_js_cc_file#host',
+ 'generate_blink_cc_file#host',
+ 'generate_indexeddb_cc_file#host',
+ 'generate_cached_patches_cc_file#host',
+ 'generate_web_gl_cc_file#host',
+ 'generate_metadata_cc_file#host',
+ 'generate_websql_cc_file#host',
+ 'generate_svg_cc_file#host',
+ 'generate_webaudio_cc_file#host',
],
'include_dirs': [
'..',
@@ -866,6 +1247,18 @@
'<(builtin_cc_file)',
'<(io_cc_file)',
'<(io_patch_cc_file)',
+ '<(html_cc_file)',
+ '<(html_common_cc_file)',
+ '<(js_cc_file)',
+ '<(blink_cc_file)',
+ '<(indexeddb_cc_file)',
+ '<(cached_patches_cc_file)',
+ '<(web_gl_cc_file)',
+ '<(metadata_cc_file)',
+ '<(websql_cc_file)',
+ '<(svg_cc_file)',
+ '<(webaudio_cc_file)',
+
'<(resources_cc_file)',
],
'defines': [
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 272976f..c26a762 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -18,9 +18,29 @@
{ DartUtils::kBuiltinLibURL, _builtin_source_paths_, NULL, NULL, true },
{ DartUtils::kIOLibURL, io_source_paths_,
DartUtils::kIOLibPatchURL, io_patch_paths_, true },
+
+#if defined(DART_NO_SNAPSHOT)
+ // Only include these libraries in the dart_bootstrap case for now.
+ { "dart:html", html_source_paths_, NULL, NULL, true },
+ { "dart:html_common", html_common_source_paths_, NULL, NULL, true},
+ { "dart:js", js_source_paths_, NULL, NULL, true},
+ { "dart:_blink", blink_source_paths_, NULL, NULL, true },
+ { "dart:indexed_db", indexeddb_source_paths_, NULL, NULL, true },
+ { "cached_patches.dart", cached_patches_source_paths_, NULL, NULL, true },
+ { "dart:web_gl", web_gl_source_paths_, NULL, NULL, true },
+ { "metadata.dart", metadata_source_paths_, NULL, NULL, true },
+ { "dart:web_sql", websql_source_paths_, NULL, NULL, true },
+ { "dart:svg", svg_source_paths_, NULL, NULL, true },
+ { "dart:web_audio", webaudio_source_paths_, NULL, NULL, true },
+#endif // defined(DART_NO_SNAPSHOT)
+
+ // End marker.
+ { NULL, NULL, NULL, NULL, false }
};
Dart_Port Builtin::load_port_ = ILLEGAL_PORT;
+const int Builtin::num_libs_ =
+ sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props);
// Patch all the specified patch files in the array 'patch_files' into the
// library specified in 'library'.
@@ -48,9 +68,8 @@
Dart_Handle Builtin::Source(BuiltinLibraryId id) {
- ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
- kInvalidLibrary);
- ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
// Try to read the source using the path specified for the uri.
const char* uri = builtin_libraries_[id].url_;
@@ -60,9 +79,8 @@
Dart_Handle Builtin::PartSource(BuiltinLibraryId id, const char* part_uri) {
- ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
- kInvalidLibrary);
- ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
// Try to read the source using the path specified for the uri.
const char** source_paths = builtin_libraries_[id].source_paths_;
@@ -97,6 +115,9 @@
Dart_Handle Builtin::LoadLibrary(Dart_Handle url, BuiltinLibraryId id) {
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
+
Dart_Handle library = Dart_LoadLibrary(url, Source(id), 0, 0);
if (!Dart_IsError(library) && (builtin_libraries_[id].has_natives_)) {
// Setup the native resolver for built in library functions.
@@ -113,10 +134,24 @@
}
+Builtin::BuiltinLibraryId Builtin::FindId(const char* url_string) {
+ int id = 0;
+ while (true) {
+ if (builtin_libraries_[id].url_ == NULL) {
+ return kInvalidLibrary;
+ }
+ if (strcmp(url_string, builtin_libraries_[id].url_) == 0) {
+ return static_cast<BuiltinLibraryId>(id);
+ }
+ id++;
+ }
+}
+
+
Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
- ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
- kInvalidLibrary);
- ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
+
Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
Dart_Handle library = Dart_LookupLibrary(url);
if (Dart_IsError(library)) {
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 59ccec3..f0c0cdc 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -67,6 +67,13 @@
// command line.
bool _traceLoading = false;
+// This is currently a build time flag only. We measure the time from the first
+// load request (opening the receive port) to completing the last load
+// request (closing the receive port). Future, deferred load operations will
+// add to this time.
+bool _timeLoading = false;
+Stopwatch _stopwatch;
+
// A port for communicating with the service isolate for I/O.
SendPort _loadPort;
// The receive port for a load request. Multiple sources can be fetched in
@@ -358,9 +365,10 @@
}
if (!_pendingLoads() && (_dataPort != null)) {
+ _stopwatch.stop();
// Close the _dataPort now that there are no more requests outstanding.
- if (_traceLoading) {
- _log("Closing loading port.");
+ if (_traceLoading || _timeLoading) {
+ _log("Closing loading port: ${_stopwatch.elapsedMilliseconds} ms");
}
_dataPort.close();
_dataPort = null;
@@ -408,8 +416,13 @@
if (_traceLoading) {
_log("Initializing load port.");
}
+ // Allocate the Stopwatch if necessary.
+ if (_stopwatch == null) {
+ _stopwatch = new Stopwatch();
+ }
assert(_dataPort == null);
_dataPort = new RawReceivePort(_handleLoaderReply);
+ _stopwatch.start();
}
// Register the load request and send it to the VM service isolate.
var req = new _LoadRequest(tag, uri, resourceUri, context);
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index ab871af..a4893d9 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -28,10 +28,9 @@
// Note: Changes to this enum should be accompanied with changes to
// the builtin_libraries_ array in builtin.cc and builtin_nolib.cc.
enum BuiltinLibraryId {
+ kInvalidLibrary = -1,
kBuiltinLibrary = 0,
- kIOLibrary,
-
- kInvalidLibrary,
+ kIOLibrary
};
// Get source corresponding to built in library specified in 'id'.
@@ -44,6 +43,7 @@
static void SetNativeResolver(BuiltinLibraryId id);
static Dart_Handle LoadLibrary(Dart_Handle url, BuiltinLibraryId id);
+ static BuiltinLibraryId FindId(const char* url_string);
// Check if built in library specified in 'id' is already loaded, if not
// load it.
@@ -66,7 +66,20 @@
static const char* _builtin_source_paths_[];
static const char* io_source_paths_[];
static const char* io_patch_paths_[];
+ static const char* html_source_paths_[];
+ static const char* html_common_source_paths_[];
+ static const char* js_source_paths_[];
+ static const char* blink_source_paths_[];
+ static const char* indexeddb_source_paths_[];
+ static const char* cached_patches_source_paths_[];
+ static const char* web_gl_source_paths_[];
+ static const char* metadata_source_paths_[];
+ static const char* websql_source_paths_[];
+ static const char* svg_source_paths_[];
+ static const char* webaudio_source_paths_[];
+
static Dart_Port load_port_;
+ static const int num_libs_;
typedef struct {
const char* url_;
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 96280df..dc6ee17 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -44,6 +44,12 @@
};
+void Builtin_DummyNative(Dart_NativeArguments args) {
+ UNREACHABLE();
+}
+
+
+
/**
* Looks up native functions in both libdart_builtin and libdart_io.
*/
@@ -51,8 +57,8 @@
int argument_count,
bool* auto_setup_scope) {
const char* function_name = NULL;
- Dart_Handle result = Dart_StringToCString(name, &function_name);
- DART_CHECK_VALID(result);
+ Dart_Handle err = Dart_StringToCString(name, &function_name);
+ DART_CHECK_VALID(err);
ASSERT(function_name != NULL);
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = true;
@@ -64,7 +70,12 @@
return reinterpret_cast<Dart_NativeFunction>(entry->function_);
}
}
- return IONativeLookup(name, argument_count, auto_setup_scope);
+ Dart_NativeFunction result =
+ IONativeLookup(name, argument_count, auto_setup_scope);
+ if (result == NULL) {
+ result = Builtin_DummyNative;
+ }
+ return result;
}
diff --git a/runtime/bin/builtin_nolib.cc b/runtime/bin/builtin_nolib.cc
index 428927f..5ccf5c8 100644
--- a/runtime/bin/builtin_nolib.cc
+++ b/runtime/bin/builtin_nolib.cc
@@ -17,9 +17,15 @@
/* { url_, source_, patch_url_, patch_source_, has_natives_ } */
{ DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true },
{ DartUtils::kIOLibURL, NULL, NULL, NULL, true },
+
+ // End marker.
+ { NULL, NULL, NULL, NULL, false }
};
Dart_Port Builtin::load_port_ = ILLEGAL_PORT;
+const int Builtin::num_libs_ =
+ sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props);
+
Dart_Handle Builtin::Source(BuiltinLibraryId id) {
return DartUtils::NewError("Unreachable code in Builtin::Source (%d).", id);
@@ -39,9 +45,9 @@
void Builtin::SetNativeResolver(BuiltinLibraryId id) {
- ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
- kInvalidLibrary);
- ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
+
if (builtin_libraries_[id].has_natives_) {
Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
Dart_Handle library = Dart_LookupLibrary(url);
@@ -59,10 +65,15 @@
}
+Builtin::BuiltinLibraryId Builtin::FindId(const char* url_string) {
+ return kInvalidLibrary;
+}
+
+
Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
- ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
- kInvalidLibrary);
- ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+ ASSERT(static_cast<int>(id) >= 0);
+ ASSERT(static_cast<int>(id) < num_libs_);
+
Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
Dart_Handle library = Dart_LookupLibrary(url);
return library;
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index e180479..02f6016 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -406,51 +406,45 @@
}
bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
- bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
+ bool is_dart_library = DartUtils::IsDartSchemeURL(library_url_string);
- // Handle URI canonicalization requests.
- if (tag == Dart_kCanonicalizeUrl) {
- // If this is a Dart Scheme URL or 'part' of a io library
- // then it is not modified as it will be handled internally.
- if (is_dart_scheme_url || is_io_library) {
+ // Handle canonicalization, 'import' and 'part' of 'dart:' libraries.
+ if (is_dart_scheme_url || is_dart_library) {
+ if (tag == Dart_kCanonicalizeUrl) {
+ // These will be handled internally.
return url;
- }
- // Resolve the url within the context of the library's URL.
- return ResolveUri(library_url, url);
- }
-
- // Handle 'import' of dart scheme URIs (i.e they start with 'dart:').
- if (is_dart_scheme_url) {
- if (tag == Dart_kImportTag) {
- // Handle imports of other built-in libraries present in the SDK.
- if (DartUtils::IsDartIOLibURL(url_string)) {
- return Builtin::LoadLibrary(url, Builtin::kIOLibrary);
+ } else if (tag == Dart_kImportTag) {
+ Builtin::BuiltinLibraryId id = Builtin::FindId(url_string);
+ if (id == Builtin::kInvalidLibrary) {
+ return NewError("The built-in library '%s' is not available"
+ " on the stand-alone VM.\n", url_string);
}
- return NewError("The built-in library '%s' is not available"
- " on the stand-alone VM.\n", url_string);
+ return Builtin::LoadLibrary(url, id);
} else {
ASSERT(tag == Dart_kSourceTag);
- return NewError("Unable to load source '%s' ", url_string);
- }
- }
-
- // Handle 'part' of IO library.
- if (is_io_library) {
- if (tag == Dart_kSourceTag) {
+ Builtin::BuiltinLibraryId id = Builtin::FindId(library_url_string);
+ if (id == Builtin::kInvalidLibrary) {
+ return NewError("The built-in library '%s' is not available"
+ " on the stand-alone VM. Trying to load"
+ " '%s'.\n", library_url_string, url_string);
+ }
// Prepend the library URI to form a unique script URI for the part.
intptr_t len = snprintf(NULL, 0, "%s/%s", library_url_string, url_string);
char* part_uri = reinterpret_cast<char*>(malloc(len + 1));
snprintf(part_uri, len + 1, "%s/%s", library_url_string, url_string);
Dart_Handle part_uri_obj = DartUtils::NewString(part_uri);
free(part_uri);
- return Dart_LoadSource(
- library,
- part_uri_obj,
- Builtin::PartSource(Builtin::kIOLibrary, url_string), 0, 0);
- } else {
- ASSERT(tag == Dart_kImportTag);
- return NewError("Unable to import '%s' ", url_string);
+ return Dart_LoadSource(library,
+ part_uri_obj,
+ Builtin::PartSource(id, url_string), 0, 0);
}
+ // All cases should have been handled above.
+ UNREACHABLE();
+ }
+
+ if (tag == Dart_kCanonicalizeUrl) {
+ // Resolve the url within the context of the library's URL.
+ return ResolveUri(library_url, url);
}
if (DartUtils::IsDartExtensionSchemeURL(url_string)) {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index fb8b338..ab45b95 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -52,10 +52,16 @@
* - Running the full application snapshot generated above :
* dart --run-full-snapshot=<filename> <script_uri> [<script_options>]
*/
-static bool generate_script_snapshot = false;
-static bool generate_full_snapshot_after_run = false;
-static bool run_full_snapshot = false;
+static bool run_app_snapshot = false;
static const char* snapshot_filename = NULL;
+enum SnapshotKind {
+ kNone,
+ kScript,
+ kAppAOT,
+ kAppJITAfterRun,
+ kAppAfterRun,
+};
+static SnapshotKind gen_snapshot_kind = kNone;
// Value of the --package-root flag.
// (This pointer points into an argv buffer and does not need to be
@@ -73,27 +79,11 @@
static bool compile_all = false;
-// Global flag that is used to indicate that we want to compile all the
-// dart functions before running main and not compile anything thereafter.
-static bool gen_precompiled_snapshot = false;
-
-
-// Global flag that is used to indicate that we want to run from a precompiled
-// snapshot.
-static bool run_precompiled_snapshot = false;
-
-
// Global flag that is used to indicate that we want to use blobs/mmap instead
// of assembly/shared libraries for precompilation.
static bool use_blobs = false;
-// Value of the --gen/run_precompiled_snapshot flag.
-// (This pointer points into an argv buffer and does not need to be
-// free'd.)
-static const char* precompiled_snapshot_directory = NULL;
-
-
// Global flag that is used to indicate that we want to compile everything in
// the same way as precompilation before main, then continue running in the
// same process.
@@ -108,14 +98,13 @@
extern const char* kPrecompiledLibraryName;
extern const char* kPrecompiledInstructionsSymbolName;
extern const char* kPrecompiledDataSymbolName;
-static const char* kPrecompiledVmIsolateName = "precompiled.vmisolate";
-static const char* kPrecompiledIsolateName = "precompiled.isolate";
-static const char* kPrecompiledAssemblyName = "precompiled.S";
-static const char* kPrecompiledInstructionsBlobName =
- "precompiled.instructions";
-static const char* kPrecompiledRodataBlobName = "precompiled.rodata";
-static const char* kVMIsolateSuffix = "vmisolate";
-static const char* kIsolateSuffix = "isolate";
+
+static const char* kVMIsolateSuffix = "snapshot.vmisolate";
+static const char* kIsolateSuffix = "snapshot.isolate";
+static const char* kAssemblySuffix = "snapshot.S";
+static const char* kInstructionsSuffix = "snapshot.instructions";
+static const char* kRODataSuffix = "snapshot.rodata";
+
// Global flag that is used to indicate that we want to trace resolution of
// URIs and the loading of libraries, parts and scripts.
@@ -345,97 +334,43 @@
}
-static bool ProcessGenPrecompiledSnapshotOption(
- const char* arg,
- CommandLineOptions* vm_options) {
-#if !defined(DART_PRECOMPILER)
- Log::PrintErr("Precompiled snapshots must be generated with "
- "dart_bootstrap.\n");
- return false;
-#else // defined(DART_PRECOMPILER)
- ASSERT(arg != NULL);
- if ((arg[0] == '=') || (arg[0] == ':')) {
- precompiled_snapshot_directory = &arg[1];
- } else {
- precompiled_snapshot_directory = arg;
- }
- gen_precompiled_snapshot = true;
- vm_options->AddArgument("--precompilation");
- return true;
-#endif // defined(DART_PRECOMPILER)
-}
-
-
-static bool ProcessRunPrecompiledSnapshotOption(
- const char* arg,
- CommandLineOptions* vm_options) {
- ASSERT(arg != NULL);
- precompiled_snapshot_directory = arg;
- if ((precompiled_snapshot_directory[0] == '=') ||
- (precompiled_snapshot_directory[0] == ':')) {
- precompiled_snapshot_directory = &precompiled_snapshot_directory[1];
- }
- run_precompiled_snapshot = true;
- vm_options->AddArgument("--precompilation");
- return true;
-}
-
-
-static bool ProcessSnapshotOptionHelper(const char* filename,
- bool* snapshot_option) {
- ASSERT((filename != NULL) && (strlen(filename) != 0));
+static bool ProcessSnapshotFilenameOption(const char* filename,
+ CommandLineOptions* vm_options) {
snapshot_filename = filename;
- *snapshot_option = true;
- if (generate_script_snapshot && generate_full_snapshot_after_run) {
- Log::PrintErr("--snapshot and --snapshot-after-run options"
- " cannot be specified at the same time\n");
- *snapshot_option = false;
- return false;
+ if (gen_snapshot_kind == kNone) {
+ gen_snapshot_kind = kScript; // Default behavior.
}
return true;
}
-static bool ProcessScriptSnapshotOption(const char* filename,
- CommandLineOptions* vm_options) {
- if ((filename == NULL) || (strlen(filename) == 0)) {
- return false;
+static bool ProcessSnapshotKindOption(const char* kind,
+ CommandLineOptions* vm_options) {
+ if (strcmp(kind, "script") == 0) {
+ gen_snapshot_kind = kScript;
+ return true;
+ } else if (strcmp(kind, "app-aot") == 0) {
+ gen_snapshot_kind = kAppAOT;
+ return true;
+ } else if (strcmp(kind, "app-jit-after-run") == 0) {
+ gen_snapshot_kind = kAppJITAfterRun;
+ return true;
+ } else if (strcmp(kind, "app-after-run") == 0) {
+ gen_snapshot_kind = kAppAfterRun;
+ return true;
}
- // Ensure that we are already running using a full snapshot.
- if (isolate_snapshot_buffer == NULL) {
- Log::PrintErr("Script snapshots cannot be generated in this version of"
- " Dart\n");
- return false;
- }
- return ProcessSnapshotOptionHelper(filename, &generate_script_snapshot);
-}
-
-
-static bool ProcessFullSnapshotAfterRunOption(
- const char* filename, CommandLineOptions* vm_options) {
- if ((filename == NULL) || (strlen(filename) == 0)) {
- return false;
- }
- // Ensure that we are running 'dart_bootstrap'.
- if (isolate_snapshot_buffer != NULL) {
- Log::PrintErr("Full Application snapshots must be generated with"
- " dart_bootstrap\n");
- return false;
- }
- return ProcessSnapshotOptionHelper(filename,
- &generate_full_snapshot_after_run);
-}
-
-
-static bool ProcessRunFullSnapshotOption(
- const char* filename, CommandLineOptions* vm_options) {
-#if !defined(PRODUCT)
- Log::PrintErr("Full Application snapshots can only be be run with"
- " product mode\n");
+ Log::PrintErr("Unrecognized snapshot kind: '%s'\nValid kinds are: "
+ "script, app-aot, app-jit-after-run, app-after-run\n", kind);
return false;
-#else
- return ProcessSnapshotOptionHelper(filename, &run_full_snapshot);
-#endif // defined(PRODUCT)
+}
+
+
+static bool ProcessRunAppSnapshotOption(
+ const char* filename, CommandLineOptions* vm_options) {
+ ASSERT(filename != NULL);
+ snapshot_filename = filename;
+ run_app_snapshot = true;
+ return true;
}
@@ -532,15 +467,13 @@
// VM specific options to the standalone dart program.
{ "--compile_all", ProcessCompileAllOption },
- { "--use_blobs", ProcessUseBlobsOption },
{ "--enable-vm-service", ProcessEnableVmServiceOption },
- { "--gen-precompiled-snapshot", ProcessGenPrecompiledSnapshotOption },
{ "--observe", ProcessObserveOption },
- { "--run-precompiled-snapshot", ProcessRunPrecompiledSnapshotOption },
{ "--shutdown", ProcessShutdownOption },
- { "--snapshot=", ProcessScriptSnapshotOption },
- { "--full-snapshot-after-run=", ProcessFullSnapshotAfterRunOption },
- { "--run-full-snapshot=", ProcessRunFullSnapshotOption },
+ { "--snapshot=", ProcessSnapshotFilenameOption },
+ { "--snapshot-kind=", ProcessSnapshotKindOption },
+ { "--run-app-snapshot=", ProcessRunAppSnapshotOption },
+ { "--use-blobs", ProcessUseBlobsOption },
{ "--trace-loading", ProcessTraceLoadingOption },
{ NULL, NULL }
};
@@ -657,25 +590,15 @@
"file is invalid.\n");
return -1;
}
- if (is_noopt) {
- if (gen_precompiled_snapshot) {
- Log::PrintErr("Running dart_noopt with --gen_precompiled_snapshot"
- " is invalid.\n");
- return -1;
- }
- if (run_precompiled_snapshot) {
- Log::PrintErr("Running dart_noopt with --run_precompiled_snapshot"
- " is invalid.\n");
- return -1;
- }
- }
- if (run_full_snapshot && run_precompiled_snapshot) {
- Log::PrintErr("Specifying --run_full_snapshot and"
- " --run_precompiled_snapshot is invalid.\n");
+ if (is_noopt && gen_snapshot_kind != kNone) {
+ Log::PrintErr("Generating a snapshot with dart_noopt is invalid.\n");
return -1;
}
- if ((generate_full_snapshot_after_run || gen_precompiled_snapshot) &&
- (run_full_snapshot || run_precompiled_snapshot)) {
+ if ((gen_snapshot_kind != kNone) && (snapshot_filename == NULL)) {
+ Log::PrintErr("Generating a snapshot requires a filename (--snapshot).\n");
+ return -1;
+ }
+ if ((gen_snapshot_kind != kNone) && run_app_snapshot) {
Log::PrintErr("Specifying an option to generate a snapshot and"
" run using a snapshot is invalid.\n");
return -1;
@@ -766,16 +689,16 @@
int* exit_code) {
ASSERT(script_uri != NULL);
+ const bool needs_load_port = !run_app_snapshot;
#if defined(PRODUCT)
- const bool run_service_isolate = !run_full_snapshot &&
- !run_precompiled_snapshot;
+ const bool run_service_isolate = needs_load_port;
#else
- const bool run_service_isolate = !run_full_snapshot;
+ // Always create the service isolate in DEBUG and RELEASE modes for profiling,
+ // even if we don't need it for loading.
+ const bool run_service_isolate = true;
#endif // PRODUCT
if (!run_service_isolate &&
(strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0)) {
- // We do not create a service isolate when running a full application
- // snapshot or a precompiled snapshot in product mode.
return NULL;
}
@@ -807,9 +730,10 @@
if (Dart_IsServiceIsolate(isolate)) {
// If this is the service isolate, load embedder specific bits and return.
+ bool skip_library_load = run_app_snapshot;
if (!VmService::Setup(vm_service_server_ip,
vm_service_server_port,
- run_precompiled_snapshot)) {
+ skip_library_load)) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
}
@@ -828,12 +752,9 @@
result = DartUtils::PrepareForScriptLoading(false, trace_loading);
CHECK_RESULT(result);
- if (!run_precompiled_snapshot && !run_full_snapshot) {
+ if (needs_load_port) {
// Set up the load port provided by the service isolate so that we can
// load scripts.
- // With a full snapshot or a precompiled snapshot in product mode, there is
- // no service isolate. A precompiled snapshot in release or debug mode does
- // have the service isolate, but it doesn't use it for loading.
result = DartUtils::SetupServiceLoadPort();
CHECK_RESULT(result);
}
@@ -845,7 +766,10 @@
result = Dart_SetEnvironmentCallback(EnvironmentCallback);
CHECK_RESULT(result);
- if (!run_precompiled_snapshot && !run_full_snapshot) {
+ if (run_app_snapshot) {
+ result = DartUtils::SetupIOLibrary(script_uri);
+ CHECK_RESULT(result);
+ } else {
// Load the specified application script into the newly created isolate.
result = DartUtils::LoadScript(script_uri);
CHECK_RESULT(result);
@@ -862,9 +786,6 @@
result = DartUtils::SetupIOLibrary(script_uri);
CHECK_RESULT(result);
- } else if (run_full_snapshot) {
- result = DartUtils::SetupIOLibrary(script_uri);
- CHECK_RESULT(result);
}
// Make the isolate runnable so that it is ready to handle messages.
@@ -1206,19 +1127,13 @@
qualified_libname = libname;
}
void* library = Extensions::LoadExtensionLibrary(qualified_libname);
- if (library == NULL) {
- Log::PrintErr("Error: Failed to load library '%s'\n", qualified_libname);
- Platform::Exit(kErrorExitCode);
- }
- void* symbol = Extensions::ResolveSymbol(library, symname);
- if (symbol == NULL) {
- Log::PrintErr("Error: Failed to load symbol '%s'\n", symname);
- Platform::Exit(kErrorExitCode);
- }
if (concat != NULL) {
delete concat;
}
- return symbol;
+ if (library == NULL) {
+ return NULL;
+ }
+ return Extensions::ResolveSymbol(library, symname);
}
@@ -1235,16 +1150,107 @@
}
-static void ComputeSnapshotFilenames(const char* filename,
- char** vm_snapshot_fname,
- char** isolate_snapshot_fname) {
- intptr_t len = snprintf(NULL, 0, "%s.%s", filename, kVMIsolateSuffix);
- *vm_snapshot_fname = new char[len + 1];
- snprintf(*vm_snapshot_fname, len + 1, "%s.%s", filename, kVMIsolateSuffix);
+static void GeneratePrecompiledSnapshot() {
+ uint8_t* vm_isolate_buffer = NULL;
+ intptr_t vm_isolate_size = 0;
+ uint8_t* isolate_buffer = NULL;
+ intptr_t isolate_size = 0;
+ uint8_t* assembly_buffer = NULL;
+ intptr_t assembly_size = 0;
+ uint8_t* instructions_blob_buffer = NULL;
+ intptr_t instructions_blob_size = 0;
+ uint8_t* rodata_blob_buffer = NULL;
+ intptr_t rodata_blob_size = 0;
+ Dart_Handle result;
+ if (use_blobs) {
+ result = Dart_CreatePrecompiledSnapshotBlob(
+ &vm_isolate_buffer,
+ &vm_isolate_size,
+ &isolate_buffer,
+ &isolate_size,
+ &instructions_blob_buffer,
+ &instructions_blob_size,
+ &rodata_blob_buffer,
+ &rodata_blob_size);
+ } else {
+ result = Dart_CreatePrecompiledSnapshotAssembly(
+ &vm_isolate_buffer,
+ &vm_isolate_size,
+ &isolate_buffer,
+ &isolate_size,
+ &assembly_buffer,
+ &assembly_size);
+ }
+ if (Dart_IsError(result)) {
+ ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+ }
+ WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
+ false,
+ vm_isolate_buffer,
+ vm_isolate_size);
+ WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
+ false,
+ isolate_buffer,
+ isolate_size);
+ if (use_blobs) {
+ WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
+ false,
+ instructions_blob_buffer,
+ instructions_blob_size);
+ WriteSnapshotFile(snapshot_filename, kRODataSuffix,
+ false,
+ rodata_blob_buffer,
+ rodata_blob_size);
+ } else {
+ WriteSnapshotFile(snapshot_filename, kAssemblySuffix,
+ false,
+ assembly_buffer,
+ assembly_size);
+ }
+}
- len = snprintf(NULL, 0, "%s.%s", filename, kIsolateSuffix);
- *isolate_snapshot_fname = new char[len + 1];
- snprintf(*isolate_snapshot_fname, len + 1, "%s.%s", filename, kIsolateSuffix);
+
+static void GeneratePrecompiledJITSnapshot() {
+ if (!use_blobs) {
+ ErrorExit(kErrorExitCode,
+ "Generating app JIT snapshots as assembly unimplemented\n");
+ }
+ uint8_t* vm_isolate_buffer = NULL;
+ intptr_t vm_isolate_size = 0;
+ uint8_t* isolate_buffer = NULL;
+ intptr_t isolate_size = 0;
+ uint8_t* instructions_blob_buffer = NULL;
+ intptr_t instructions_blob_size = 0;
+ uint8_t* rodata_blob_buffer = NULL;
+ intptr_t rodata_blob_size = 0;
+ Dart_Handle result = Dart_CreatePrecompiledJITSnapshotBlob(
+ &vm_isolate_buffer,
+ &vm_isolate_size,
+ &isolate_buffer,
+ &isolate_size,
+ &instructions_blob_buffer,
+ &instructions_blob_size,
+ &rodata_blob_buffer,
+ &rodata_blob_size);
+ if (Dart_IsError(result)) {
+ ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+ }
+ WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
+ false,
+ vm_isolate_buffer,
+ vm_isolate_size);
+ WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
+ false,
+ isolate_buffer,
+ isolate_size);
+ WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
+ false,
+ instructions_blob_buffer,
+ instructions_blob_size);
+ WriteSnapshotFile(snapshot_filename, kRODataSuffix,
+ false,
+ rodata_blob_buffer,
+ rodata_blob_size);
}
@@ -1255,8 +1261,6 @@
intptr_t vm_isolate_size = 0;
uint8_t* isolate_buffer = NULL;
intptr_t isolate_size = 0;
- char* vm_snapshot_fname = NULL;
- char* isolate_snapshot_fname = NULL;
result = Dart_CreateSnapshot(&vm_isolate_buffer,
&vm_isolate_size,
@@ -1266,17 +1270,13 @@
ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
}
- // Compute snapshot file names and write out the snapshot files.
- ComputeSnapshotFilenames(snapshot_filename,
- &vm_snapshot_fname,
- &isolate_snapshot_fname);
- WriteSnapshotFile(NULL,
- vm_snapshot_fname,
+ WriteSnapshotFile(snapshot_filename,
+ kVMIsolateSuffix,
false,
vm_isolate_buffer,
vm_isolate_size);
- WriteSnapshotFile(NULL,
- isolate_snapshot_fname,
+ WriteSnapshotFile(snapshot_filename,
+ kIsolateSuffix,
false,
isolate_buffer,
isolate_size);
@@ -1339,7 +1339,7 @@
Dart_EnterScope();
- if (generate_script_snapshot) {
+ if (gen_snapshot_kind == kScript) {
GenerateScriptSnapshot();
} else {
// Lookup the library of the root script.
@@ -1351,9 +1351,12 @@
result = Dart_LibraryImportLibrary(
isolate_data->builtin_lib(), root_lib, Dart_Null());
#if !defined(PRODUCT)
- if (is_noopt || gen_precompiled_snapshot) {
+ if (is_noopt ||
+ (gen_snapshot_kind == kAppAfterRun) ||
+ (gen_snapshot_kind == kAppAOT) ||
+ (gen_snapshot_kind == kAppJITAfterRun)) {
// Load the embedder's portion of the VM service's Dart code so it will
- // be included in the precompiled snapshot.
+ // be included in the app snapshot.
if (!VmService::LoadForGenPrecompiled()) {
fprintf(stderr,
"VM service loading failed: %s\n",
@@ -1369,7 +1372,7 @@
CHECK_RESULT(result);
}
- if (is_noopt || gen_precompiled_snapshot) {
+ if (is_noopt || (gen_snapshot_kind == kAppAOT)) {
Dart_QualifiedFunctionName standalone_entry_points[] = {
{ "dart:_builtin", "::", "_getMainClosure" },
{ "dart:_builtin", "::", "_getPrintClosure" },
@@ -1404,71 +1407,13 @@
{ NULL, NULL, NULL } // Must be terminated with NULL entries.
};
- const bool reset_fields = gen_precompiled_snapshot;
+ const bool reset_fields = gen_snapshot_kind == kAppAOT;
result = Dart_Precompile(standalone_entry_points, reset_fields);
CHECK_RESULT(result);
}
- if (gen_precompiled_snapshot) {
- uint8_t* vm_isolate_buffer = NULL;
- intptr_t vm_isolate_size = 0;
- uint8_t* isolate_buffer = NULL;
- intptr_t isolate_size = 0;
- uint8_t* assembly_buffer = NULL;
- intptr_t assembly_size = 0;
- uint8_t* instructions_blob_buffer = NULL;
- intptr_t instructions_blob_size = 0;
- uint8_t* rodata_blob_buffer = NULL;
- intptr_t rodata_blob_size = 0;
- if (use_blobs) {
- result = Dart_CreatePrecompiledSnapshotBlob(
- &vm_isolate_buffer,
- &vm_isolate_size,
- &isolate_buffer,
- &isolate_size,
- &instructions_blob_buffer,
- &instructions_blob_size,
- &rodata_blob_buffer,
- &rodata_blob_size);
- CHECK_RESULT(result);
- } else {
- result = Dart_CreatePrecompiledSnapshotAssembly(
- &vm_isolate_buffer,
- &vm_isolate_size,
- &isolate_buffer,
- &isolate_size,
- &assembly_buffer,
- &assembly_size);
- CHECK_RESULT(result);
- }
- WriteSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledVmIsolateName,
- false,
- vm_isolate_buffer,
- vm_isolate_size);
- WriteSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledIsolateName,
- false,
- isolate_buffer,
- isolate_size);
- if (use_blobs) {
- WriteSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledInstructionsBlobName,
- false,
- instructions_blob_buffer,
- instructions_blob_size);
- WriteSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledRodataBlobName,
- false,
- rodata_blob_buffer,
- rodata_blob_size);
- } else {
- WriteSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledAssemblyName,
- false,
- assembly_buffer,
- assembly_size);
- }
+ if (gen_snapshot_kind == kAppAOT) {
+ GeneratePrecompiledSnapshot();
} else {
if (Dart_IsNull(root_lib)) {
ErrorExit(kErrorExitCode,
@@ -1499,11 +1444,18 @@
// Keep handling messages until the last active receive port is closed.
result = Dart_RunLoop();
- // Generate a full snapshot after execution if specified.
- if (generate_full_snapshot_after_run) {
+ // Generate an app snapshot after execution if specified.
+ if ((gen_snapshot_kind == kAppAfterRun) ||
+ (gen_snapshot_kind == kAppJITAfterRun)) {
if (!Dart_IsCompilationError(result) &&
!Dart_IsVMRestartRequest(result)) {
- GenerateFullSnapshot();
+ if (gen_snapshot_kind == kAppAfterRun) {
+ GenerateFullSnapshot();
+ } else {
+ Dart_Handle prepare_result = Dart_PrecompileJIT();
+ CHECK_RESULT(prepare_result);
+ GeneratePrecompiledJITSnapshot();
+ }
}
}
CHECK_RESULT(result);
@@ -1661,18 +1613,17 @@
Platform::Exit(kErrorExitCode);
}
-#if !defined(PRODUCT)
- // Constant true in PRODUCT mode.
- if (generate_script_snapshot ||
- generate_full_snapshot_after_run ||
- run_full_snapshot) {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+ // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME.
+ if ((gen_snapshot_kind != kNone) || run_app_snapshot) {
vm_options.AddArgument("--load_deferred_eagerly");
}
#endif
-#if defined(DART_PRECOMPILER) && !defined(DART_NO_SNAPSHOT)
- // Always set --precompilation with dart_noopt.
- ASSERT(!gen_precompiled_snapshot && !run_precompiled_snapshot);
+ if ((gen_snapshot_kind == kAppAOT) || is_noopt) {
+ vm_options.AddArgument("--precompilation");
+ }
+#if defined(DART_PRECOMPILED_RUNTIME)
vm_options.AddArgument("--precompilation");
#endif
@@ -1684,43 +1635,27 @@
const uint8_t* instructions_snapshot = NULL;
const uint8_t* data_snapshot = NULL;
- if (run_precompiled_snapshot) {
- ReadSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledVmIsolateName,
+ if (run_app_snapshot) {
+ ReadSnapshotFile(snapshot_filename, kVMIsolateSuffix,
&vm_isolate_snapshot_buffer);
- ReadSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledIsolateName,
+ ReadSnapshotFile(snapshot_filename, kIsolateSuffix,
&isolate_snapshot_buffer);
if (use_blobs) {
- ReadExecutableSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledInstructionsBlobName,
+ ReadExecutableSnapshotFile(snapshot_filename,
+ kInstructionsSuffix,
&instructions_snapshot);
- ReadSnapshotFile(precompiled_snapshot_directory,
- kPrecompiledRodataBlobName,
+ ReadSnapshotFile(snapshot_filename, kRODataSuffix,
&data_snapshot);
} else {
instructions_snapshot = reinterpret_cast<const uint8_t*>(
- LoadLibrarySymbol(precompiled_snapshot_directory,
+ LoadLibrarySymbol(snapshot_filename,
kPrecompiledLibraryName,
kPrecompiledInstructionsSymbolName));
data_snapshot = reinterpret_cast<const uint8_t*>(
- LoadLibrarySymbol(precompiled_snapshot_directory,
+ LoadLibrarySymbol(snapshot_filename,
kPrecompiledLibraryName,
kPrecompiledDataSymbolName));
}
- } else if (run_full_snapshot) {
- char* vm_snapshot_fname;
- char* isolate_snapshot_fname;
-
- // Compute file names.
- ComputeSnapshotFilenames(snapshot_filename,
- &vm_snapshot_fname,
- &isolate_snapshot_fname);
-
- ReadSnapshotFile(NULL, vm_snapshot_fname, &vm_isolate_snapshot_buffer);
- ReadSnapshotFile(NULL, isolate_snapshot_fname, &isolate_snapshot_buffer);
- delete vm_snapshot_fname;
- delete isolate_snapshot_fname;
}
// Initialize the Dart VM.
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 2099ebb..3dccea7 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -40,7 +40,6 @@
void FUNCTION_NAME(Platform_ExecutableName)(Dart_NativeArguments args) {
- ASSERT(Platform::GetExecutableName() != NULL);
if (Dart_IsRunningPrecompiledCode()) {
// This is a work-around to be able to use most of the existing test suite
// for precompilation. Many tests do something like Process.run(
@@ -51,8 +50,12 @@
"Platform.executable not supported under precompilation"));
UNREACHABLE();
}
- Dart_SetReturnValue(
- args, Dart_NewStringFromCString(Platform::GetExecutableName()));
+ if (Platform::GetExecutableName() != NULL) {
+ Dart_SetReturnValue(
+ args, Dart_NewStringFromCString(Platform::GetExecutableName()));
+ } else {
+ Dart_SetReturnValue(args, Dart_Null());
+ }
}
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index b4c10a2..1f52ef9 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -69,7 +69,10 @@
static const char* GetResolvedExecutableName() {
if (resolved_executable_name_ == NULL) {
// Try to resolve the executable path using platform specific APIs.
- resolved_executable_name_ = strdup(Platform::ResolveExecutablePath());
+ const char* resolved_name = Platform::ResolveExecutablePath();
+ if (resolved_name != NULL) {
+ resolved_executable_name_ = strdup(resolved_name);
+ }
}
return resolved_executable_name_;
}
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index f713c9a..3d1a764 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -81,7 +81,7 @@
const char* Platform::ResolveExecutablePath() {
- return File::LinkTarget("/proc/self/exe");
+ return NULL;
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 5835660..c7390e7 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2957,15 +2957,36 @@
bool reset_fields);
+/**
+ * Creates a precompiled snapshot.
+ * - The VM must not have been started from a snapshot.
+ * - A root library must have been loaded.
+ * - Dart_Precompile must have been called.
+ *
+ * Outputs a vm isolate snapshot, an isolate snapshot, and an assembly file
+ * defining the symbols kInstructionsSnapshot and kDataSnapshot. The assembly
+ * should be compiled as a static or shared library and linked or loaded by the
+ * embedder.
+ * Running this snapshot requires a VM compiled with DART_PRECOMPILED_SNAPSHOT.
+ * The vm isolate snapshot, kInstructionsSnapshot and kDataSnapshot should be
+ * passed as arguments to Dart_Initialize. The isolate snapshot should be
+ * passed to Dart_CreateIsolate.
+ */
DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly(
uint8_t** vm_isolate_snapshot_buffer,
intptr_t* vm_isolate_snapshot_size,
uint8_t** isolate_snapshot_buffer,
intptr_t* isolate_snapshot_size,
- uint8_t** instructions_assembly_buffer,
- intptr_t* instructions_assembly_size);
+ uint8_t** assembly_buffer,
+ intptr_t* assembly_size);
+/**
+ * Same as Dart_CreatePrecompiledSnapshotAssembly, except the instruction and
+ * data snapshot pieces are provided directly as bytes that the embedder can
+ * load with mmap. The instructions piece must be loaded with read and
+ * execute permissions; the rodata piece may be loaded as read-only.
+ */
DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotBlob(
uint8_t** vm_isolate_snapshot_buffer,
intptr_t* vm_isolate_snapshot_size,
@@ -2977,6 +2998,35 @@
intptr_t* rodata_blob_size);
+DART_EXPORT Dart_Handle Dart_PrecompileJIT();
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledJITSnapshotBlob(
+ uint8_t** vm_isolate_snapshot_buffer,
+ intptr_t* vm_isolate_snapshot_size,
+ uint8_t** isolate_snapshot_buffer,
+ intptr_t* isolate_snapshot_size,
+ uint8_t** instructions_blob_buffer,
+ intptr_t* instructions_blob_size,
+ uint8_t** rodata_blob_buffer,
+ intptr_t* rodata_blob_size);
+
+
+/**
+ * Returns whether the VM only supports running from precompiled snapshots and
+ * not from any other kind of snapshot or no snapshot (that is, the VM was
+ * compiled with DART_PRECOMPILED_RUNTIME).
+ */
+DART_EXPORT bool Dart_IsPrecompiledRuntime();
+
+
+/**
+ * Returns whether the VM was initialized with a precompiled snapshot. Only
+ * valid after Dart_Initialize.
+ * DEPRECATED. This is currently used to disable Platform.executable and
+ * Platform.resolvedExecutable under precompilation to prevent process
+ * spawning tests from becoming fork-bombs.
+ */
DART_EXPORT bool Dart_IsRunningPrecompiledCode();
#endif /* INCLUDE_DART_API_H_ */ /* NOLINT */
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 29c14f5..98814f8 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -107,6 +107,12 @@
final String _msg;
}
+patch class UnsupportedError {
+ static _throwNew(String msg) {
+ throw new UnsupportedError(msg);
+ }
+}
+
patch class CyclicInitializationError {
static _throwNew(String variableName) {
throw new CyclicInitializationError(variableName);
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index fb51c07..54a55ee 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -345,7 +345,7 @@
GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
- if (Dart::IsRunningPrecompiledCode()) {
+ if (Snapshot::IncludesCode(Dart::snapshot_kind())) {
const Array& args = Array::Handle(Array::New(1));
args.SetAt(0, String::Handle(String::New(
"Isolate.spawnUri not supported under precompilation")));
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 33b61c6..1478f04 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1980,7 +1980,7 @@
DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
- Object& decl = Object::Handle();
+ Object& decl = Object::Handle(zone);
if (reflectee.IsMirrorReference()) {
const MirrorReference& decl_ref = MirrorReference::Cast(reflectee);
decl = decl_ref.referent();
@@ -1990,7 +1990,7 @@
UNREACHABLE();
}
- Script& script = Script::Handle();
+ Script& script = Script::Handle(zone);
TokenPosition token_pos = TokenPosition::kNoSource;
if (decl.IsFunction()) {
@@ -2018,7 +2018,7 @@
token_pos = field.token_pos();
} else if (decl.IsTypeParameter()) {
const TypeParameter& type_var = TypeParameter::Cast(decl);
- const Class& owner = Class::Handle(type_var.parameterized_class());
+ const Class& owner = Class::Handle(zone, type_var.parameterized_class());
script = owner.script();
token_pos = type_var.token_pos();
} else if (decl.IsLibrary()) {
@@ -2026,20 +2026,20 @@
if (lib.raw() == Library::NativeWrappersLibrary()) {
return Instance::null(); // No source.
}
- const Array& scripts = Array::Handle(lib.LoadedScripts());
+ const Array& scripts = Array::Handle(zone, lib.LoadedScripts());
for (intptr_t i = 0; i < scripts.Length(); i++) {
script ^= scripts.At(i);
if (script.kind() == RawScript::kLibraryTag) break;
}
ASSERT(!script.IsNull());
- const String& libname = String::Handle(lib.name());
+ const String& libname = String::Handle(zone, lib.name());
if (libname.Length() == 0) {
// No library declaration.
- const String& uri = String::Handle(script.url());
+ const String& uri = String::Handle(zone, script.url());
return CreateSourceLocation(uri, 1, 1);
}
- const TokenStream& stream = TokenStream::Handle(script.tokens());
- TokenStream::Iterator tkit(stream, TokenPosition::kMinSource);
+ const TokenStream& stream = TokenStream::Handle(zone, script.tokens());
+ TokenStream::Iterator tkit(zone, stream, TokenPosition::kMinSource);
if (tkit.CurrentTokenKind() == Token::kSCRIPTTAG) tkit.Advance();
token_pos = tkit.CurrentPosition();
}
@@ -2047,7 +2047,7 @@
ASSERT(!script.IsNull());
ASSERT(token_pos != TokenPosition::kNoSource);
- const String& uri = String::Handle(script.url());
+ const String& uri = String::Handle(zone, script.url());
intptr_t from_line = 0;
intptr_t from_col = 0;
if (script.HasSource()) {
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index f7aa83c..4352245 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -230,7 +230,7 @@
String operator [](int index) native "String_charAt";
- int codeUnitAt(int index) native "String_codeUnitAt";
+ int codeUnitAt(int index); // Implemented in the subclasses.
int get length native "String_getLength";
@@ -937,6 +937,8 @@
int get hashCode native "String_getHashCode";
+ int codeUnitAt(int index) native "String_codeUnitAt";
+
bool _isWhitespace(int codeUnit) {
return _StringBase._isOneByteWhitespace(codeUnit);
}
@@ -1240,6 +1242,8 @@
return _StringBase._isTwoByteWhitespace(codeUnit);
}
+ int codeUnitAt(int index) native "String_codeUnitAt";
+
bool operator ==(Object other) {
return super == other;
}
@@ -1256,6 +1260,8 @@
return _StringBase._isOneByteWhitespace(codeUnit);
}
+ int codeUnitAt(int index) native "String_codeUnitAt";
+
bool operator ==(Object other) {
return super == other;
}
@@ -1274,6 +1280,8 @@
return _StringBase._isTwoByteWhitespace(codeUnit);
}
+ int codeUnitAt(int index) native "String_codeUnitAt";
+
bool operator ==(Object other) {
return super == other;
}
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index df36a25..d8bef45 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -37,6 +37,11 @@
}
+DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0) {
+ return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew);
+}
+
+
DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) {
if (!FLAG_support_timeline) {
return Object::null();
@@ -108,7 +113,7 @@
return Object::null();
}
GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Integer, end, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3));
GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
@@ -124,24 +129,49 @@
return Object::null();
}
- int64_t duration = end.AsInt64Value() - start.AsInt64Value();
+ const int64_t end = OS::GetCurrentMonotonicMicros();
+ const int64_t end_cpu = OS::GetCurrentThreadCPUMicros();
+ const int64_t duration = end - start.AsInt64Value();
+ const int64_t duration_cpu = end_cpu - start_cpu.AsInt64Value();
int64_t pid = OS::ProcessId();
OSThread* os_thread = thread->os_thread();
ASSERT(os_thread != NULL);
int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id());
- char* json = OS::SCreate(zone,
- "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
- "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
- name.ToCString(),
- category.ToCString(),
- tid,
- pid,
- start.AsInt64Value(),
- duration,
- args.ToCString());
+ char* json = NULL;
- event->Duration("", start.AsInt64Value(), end.AsInt64Value());
+ if ((start_cpu.AsInt64Value() != -1) && (end_cpu != -1)) {
+ json = OS::SCreate(zone,
+ "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+ "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ","
+ "\"tdur\":%" Pd64 ",\"args\":%s}",
+ name.ToCString(),
+ category.ToCString(),
+ tid,
+ pid,
+ start.AsInt64Value(),
+ duration,
+ duration_cpu,
+ args.ToCString());
+ } else {
+ json = OS::SCreate(zone,
+ "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+ "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
+ name.ToCString(),
+ category.ToCString(),
+ tid,
+ pid,
+ start.AsInt64Value(),
+ duration,
+ args.ToCString());
+ }
+ ASSERT(json != NULL);
+
+ event->Duration("",
+ start.AsInt64Value(),
+ end,
+ start_cpu.AsInt64Value(),
+ end_cpu);
// json was allocated in the zone and a copy will be stored in event.
event->CompleteWithPreSerializedJSON(json);
diff --git a/runtime/lib/timeline.dart b/runtime/lib/timeline.dart
index 3a336e2..b4ecd44 100644
--- a/runtime/lib/timeline.dart
+++ b/runtime/lib/timeline.dart
@@ -6,6 +6,8 @@
patch int _getTraceClock() native "Timeline_getTraceClock";
+patch int _getThreadCpuClock() native "Timeline_getThreadCpuClock";
+
patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
patch int _getIsolateNum() native "Timeline_getIsolateNum";
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index c18b8ec..502f510 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -37,7 +37,7 @@
const String& library_url = Symbols::DartVMService();
ASSERT(!library_url.IsNull());
const Library& library =
- Library::Handle(Library::LookupLibrary(library_url));
+ Library::Handle(Library::LookupLibrary(thread, library_url));
ASSERT(!library.IsNull());
// Get function.
const String& function_name =
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 1b94f38..5776bc4 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -597,12 +597,15 @@
for (var range in sourceReport['ranges']) {
int startLine = script.tokenToLine(range['startPos']);
int endLine = script.tokenToLine(range['endPos']);
- for (var line = startLine; line <= endLine; line++) {
- var rangeList = _rangeMap[line];
- if (rangeList == null) {
- _rangeMap[line] = [range];
- } else {
- rangeList.add(range);
+ // TODO(turnidge): Track down the root cause of null startLine/endLine.
+ if ((startLine != null) && (endLine != null)) {
+ for (var line = startLine; line <= endLine; line++) {
+ var rangeList = _rangeMap[line];
+ if (rangeList == null) {
+ _rangeMap[line] = [range];
+ } else {
+ rangeList.add(range);
+ }
}
}
if (_includeProfile && range['profile'] != null) {
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 5bae881..9283031 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -13,7 +13,7 @@
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(4));
+ expect(result['minor'], equals(5));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 8de2b3b..025a0f4 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -132,16 +132,14 @@
cc/SourceReport_Coverage_ForceCompile: Skip
cc/SourceReport_Coverage_NestedFunctions: Skip
cc/SourceReport_Coverage_SimpleCall: Skip
+cc/SourceReport_Coverage_UnusedClass_NoForceCompile: Skip
+cc/SourceReport_Coverage_UnusedClass_ForceCompile: Skip
+cc/SourceReport_Coverage_UnusedClass_ForceCompileError: Skip
cc/SourceReport_MultipleReports: Skip
cc/Coverage_Empty: Skip
cc/Coverage_FilterFunction: Skip
cc/Coverage_MainWithClass: Skip
-# TODO(vegorov) DisassembleToJSONStream requires
-# DecodeLoadObjectFromPoolOrThread which is unimplemented.
-cc/Service_Code: Skip
-cc/PrintJSON: Skip
-
# TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp
# is switched on by default because they attempt to call regexp functions
# directly instead of going through JSSyntaxRegExp_ExecuteMatch.
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index bc3bf8b..0318786 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -789,7 +789,7 @@
return false;
}
} else {
- return d->IsStringFromCharCode();
+ return d->IsOneByteStringFromCharCode();
}
}
@@ -823,9 +823,10 @@
ConstantInstr* char_code_left = flow_graph()->GetConstant(
Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
left_val = new(Z) Value(char_code_left);
- } else if (left->IsStringFromCharCode()) {
+ } else if (left->IsOneByteStringFromCharCode()) {
// Use input of string-from-charcode as left value.
- StringFromCharCodeInstr* instr = left->AsStringFromCharCode();
+ OneByteStringFromCharCodeInstr* instr =
+ left->AsOneByteStringFromCharCode();
left_val = new(Z) Value(instr->char_code()->definition());
to_remove_left = instr;
} else {
@@ -835,9 +836,10 @@
Definition* to_remove_right = NULL;
Value* right_val = NULL;
- if (right->IsStringFromCharCode()) {
+ if (right->IsOneByteStringFromCharCode()) {
// Skip string-from-char-code, and use its input as right value.
- StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode();
+ OneByteStringFromCharCodeInstr* right_instr =
+ right->AsOneByteStringFromCharCode();
right_val = new(Z) Value(right_instr->char_code()->definition());
to_remove_right = right_instr;
} else {
@@ -1787,11 +1789,24 @@
return true;
}
- if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
- (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
- (ic_data.NumberOfChecks() == 1) &&
- ((class_ids[0] == kOneByteStringCid) ||
- (class_ids[0] == kTwoByteStringCid))) {
+ if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+ ASSERT(ic_data.NumberOfChecks() == 1);
+ ASSERT((class_ids[0] == kOneByteStringCid) ||
+ (class_ids[0] == kTwoByteStringCid) ||
+ (class_ids[0] == kExternalOneByteStringCid) ||
+ (class_ids[0] == kExternalTwoByteStringCid));
+ return TryReplaceInstanceCallWithInline(call);
+ }
+
+ if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
+ (ic_data.NumberOfChecks() == 1)) {
+ ASSERT((class_ids[0] == kOneByteStringCid) ||
+ (class_ids[0] == kTwoByteStringCid) ||
+ (class_ids[0] == kExternalOneByteStringCid) ||
+ (class_ids[0] == kExternalTwoByteStringCid));
return TryReplaceInstanceCallWithInline(call);
}
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
index 2941f20..11e579e 100644
--- a/runtime/vm/assembler_dbc_test.cc
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -6,6 +6,7 @@
#if defined(TARGET_ARCH_DBC)
#include "vm/assembler.h"
+#include "vm/stack_frame.h"
#include "vm/unit_test.h"
namespace dart {
@@ -42,6 +43,18 @@
}
+// Called from assembler_test.cc.
+// FP[-kParamEndSlotFromFp - 1]: growable array
+// FP[-kParamEndSlotFromFp - 2]: value
+ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
+ __ Frame(2);
+ __ Move(0, -kParamEndSlotFromFp - 1);
+ __ Move(1, -kParamEndSlotFromFp - 2);
+ __ StoreField(0, GrowableObjectArray::data_offset() / kWordSize, 1);
+ __ Return(0);
+}
+
+
// - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
// GreaterThanTOS;
//
@@ -704,6 +717,317 @@
EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsError());
}
+
+// - Drop1; DropR n; Drop n
+//
+// Drop 1 or n values from the stack, if instruction is DropR push the first
+// dropped value to the stack;
+ASSEMBLER_TEST_GENERATE(Drop1, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ Drop1();
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(Drop1, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Drop, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ Drop(11);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(Drop, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DropR, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ PushConstant(Smi::Handle(Smi::New(41)));
+ __ DropR(11);
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(DropR, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - Frame D
+//
+// Reserve and initialize with null space for D local variables.
+ASSEMBLER_TEST_GENERATE(FrameInitialized1, assembler) {
+ __ Frame(1);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(FrameInitialized1, test) {
+ EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsNull());
+}
+
+
+ASSEMBLER_TEST_GENERATE(FrameInitialized, assembler) {
+ Label error;
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ Frame(4);
+ __ PushConstant(Object::null_object());
+ __ IfNeStrictTOS();
+ __ Jump(&error);
+ __ PushConstant(Object::null_object());
+ __ IfNeStrictTOS();
+ __ Jump(&error);
+ __ PushConstant(Object::null_object());
+ __ IfNeStrictTOS();
+ __ Jump(&error);
+ __ PushConstant(Object::null_object());
+ __ IfNeStrictTOS();
+ __ Jump(&error);
+ __ ReturnTOS();
+
+ // If a frame slot was not initialized to null.
+ __ Bind(&error);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(FrameInitialized, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - StoreLocal rX; PopLocal rX
+//
+// Store top of the stack into FP[rX] and pop it if needed.
+//
+// - Push rX
+//
+// Push FP[rX] to the stack.
+ASSEMBLER_TEST_GENERATE(StoreLocalPush, assembler) {
+ __ Frame(1);
+ __ PushConstant(Smi::Handle(Smi::New(21)));
+ __ StoreLocal(0);
+ __ Push(0);
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(StoreLocalPush, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(PopLocalPush, assembler) {
+ __ Frame(1);
+ __ PushConstant(Smi::Handle(Smi::New(21)));
+ __ PopLocal(0);
+ __ Push(0);
+ __ Push(0);
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(PopLocalPush, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LoadConstantPush, assembler) {
+ __ Frame(1);
+ __ LoadConstant(0, Smi::Handle(Smi::New(21)));
+ __ Push(0);
+ __ Push(0);
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LoadConstantPush, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - Move rA, rX
+//
+// FP[rA] <- FP[rX]
+// Note: rX is signed so it can be used to address parameters which are
+// at negative indices with respect to FP.
+ASSEMBLER_TEST_GENERATE(MoveLocalLocal, assembler) {
+ __ Frame(2);
+ __ PushConstant(Smi::Handle(Smi::New(21)));
+ __ PopLocal(0);
+ __ Move(1, 0);
+ __ Push(0);
+ __ Push(1);
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(MoveLocalLocal, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - Return R; ReturnTOS
+//
+// Return to the caller using either a value from the given register or a
+// value from the top-of-stack as a result.
+ASSEMBLER_TEST_GENERATE(Return1, assembler) {
+ __ Frame(1);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ StoreLocal(0);
+ __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(Return1, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Return2, assembler) {
+ __ Frame(2);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ StoreLocal(1);
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(Return2, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Loop, assembler) {
+ __ Frame(2);
+ __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+ __ LoadConstant(1, Smi::Handle(Smi::New(0)));
+
+ Label loop_entry, error;
+ __ Bind(&loop_entry);
+ // Add 1 to FP[1].
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ Push(1);
+ __ AddTOS();
+ __ Jump(&error);
+ __ PopLocal(1);
+
+ // Subtract 1 from FP[0].
+ __ Push(0);
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ SubTOS();
+ __ Jump(&error);
+
+ // Jump to loop_entry if FP[0] != 0.
+ __ StoreLocal(0);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ IfNeStrictNumTOS();
+ __ Jump(&loop_entry);
+
+ __ Return(1);
+
+ __ Bind(&error);
+ __ LoadConstant(1, Smi::Handle(Smi::New(-42)));
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(Loop, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - LoadClassIdTOS, LoadClassId rA, D
+//
+// LoadClassIdTOS loads the class id from the object at SP[0] and stores it
+// to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to
+// FP[D].
+ASSEMBLER_TEST_GENERATE(LoadClassIdTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ LoadClassIdTOS();
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LoadClassIdTOS, test) {
+ EXPECT_EQ(kSmiCid, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LoadClassId, assembler) {
+ __ Frame(2);
+ __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+ __ LoadClassId(1, 0);
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(LoadClassId, test) {
+ EXPECT_EQ(kSmiCid, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - CreateArrayTOS
+//
+// Allocate array of length SP[0] with type arguments SP[-1].
+ASSEMBLER_TEST_GENERATE(CreateArrayTOS, assembler) {
+ __ PushConstant(Object::null_object());
+ __ PushConstant(Smi::Handle(Smi::New(10)));
+ __ CreateArrayTOS();
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(CreateArrayTOS, test) {
+ const Object& obj = EXECUTE_TEST_CODE_OBJECT(test->code());
+ EXPECT(obj.IsArray());
+ Array& array = Array::Handle();
+ array ^= obj.raw();
+ EXPECT_EQ(10, array.Length());
+}
+
} // namespace dart
#endif // defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/assembler_test.cc b/runtime/vm/assembler_test.cc
index 88ff667..fbbd994 100644
--- a/runtime/vm/assembler_test.cc
+++ b/runtime/vm/assembler_test.cc
@@ -11,8 +11,6 @@
namespace dart {
-// TODO(vegorov) assembler part of this test is not implemented.
-#if !defined(TARGET_ARCH_DBC)
ASSEMBLER_TEST_EXTERN(StoreIntoObject);
ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
@@ -62,6 +60,5 @@
EXPECT(old_array.raw() == grow_new_array.data());
EXPECT(!thread->StoreBufferContains(grow_new_array.raw()));
}
-#endif
} // namespace dart
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 13184af..790e94c 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -616,7 +616,7 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(PrimaryNode);
};
-// In asynchronous code that gets suspeded and resumed, return nodes
+// In asynchronous code that gets suspended and resumed, return nodes
// can be of different types:
// * A regular return node that in the case of async functions
// gets replaced with appropriate completer calls. (kRegular)
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 8e4975b..1d56af7 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -528,8 +528,7 @@
&vm_isolate_snapshot_buffer,
&isolate_snapshot_buffer,
&malloc_allocator,
- NULL, /* instructions_writer */
- true /* vm_isolate_is_symbolic */);
+ NULL /* instructions_writer */);
writer.WriteFullSnapshot();
const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
ASSERT(snapshot->kind() == Snapshot::kCore);
@@ -565,8 +564,7 @@
&vm_isolate_snapshot_buffer,
&isolate_snapshot_buffer,
&malloc_allocator,
- NULL, /* instructions_writer */
- true /* vm_isolate_is_symbolic */);
+ NULL /* instructions_writer */);
writer.WriteFullSnapshot();
const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
ASSERT(snapshot->kind() == Snapshot::kCore);
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 9bde826..ed97340 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -301,11 +301,11 @@
}
#endif // !PRODUCT
uri = Symbols::New(thread, bootstrap_libraries[i].uri_);
- lib = Library::LookupLibrary(uri);
+ lib = Library::LookupLibrary(thread, uri);
if (lib.IsNull()) {
lib = Library::NewLibraryHelper(uri, false);
lib.SetLoadRequested();
- lib.Register();
+ lib.Register(thread);
}
isolate->object_store()->set_bootstrap_library(
bootstrap_libraries[i].index_, lib);
@@ -321,7 +321,7 @@
}
#endif // PRODUCT
uri = Symbols::New(thread, bootstrap_libraries[i].uri_);
- lib = Library::LookupLibrary(uri);
+ lib = Library::LookupLibrary(thread, uri);
ASSERT(!lib.IsNull());
source = GetLibrarySource(lib, uri, false);
if (source.IsNull()) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 81d46ec..31b800c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -161,6 +161,7 @@
V(Timeline_getIsolateNum, 0) \
V(Timeline_getNextAsyncId, 0) \
V(Timeline_getTraceClock, 0) \
+ V(Timeline_getThreadCpuClock, 0) \
V(Timeline_reportCompleteEvent, 5) \
V(Timeline_reportInstantEvent, 4) \
V(Timeline_reportTaskEvent, 6) \
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index 0d0a1a4..7316da0 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -38,7 +38,7 @@
TestCase::LoadTestScript(kScriptChars, NULL);
EXPECT(ClassFinalizer::ProcessPendingClasses());
const String& name = String::Handle(String::New(TestCase::url()));
- const Library& lib = Library::Handle(Library::LookupLibrary(name));
+ const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
EXPECT(!lib.IsNull());
const Class& class_a = Class::Handle(
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 3cc1ef9..99b5b57 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -218,7 +218,7 @@
EXPECT(ClassFinalizer::ProcessPendingClasses());
const String& name = String::Handle(String::New(TestCase::url()));
- const Library& lib = Library::Handle(Library::LookupLibrary(name));
+ const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
EXPECT(!lib.IsNull());
Class& cls = Class::Handle(
lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 1d26af8..3f01605 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -449,9 +449,9 @@
const SubtypeTestCache& cache =
SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(3));
ASSERT(type.IsFinalized());
- ASSERT(!type.IsDynamicType()); // No need to check assignment.
ASSERT(!type.IsMalformed()); // Already checked in code generator.
ASSERT(!type.IsMalbounded()); // Already checked in code generator.
+ ASSERT(!type.IsDynamicType()); // No need to check assignment.
Error& bound_error = Error::Handle(zone);
const Bool& result =
Bool::Get(instance.IsInstanceOf(type,
@@ -495,9 +495,9 @@
const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(3));
const SubtypeTestCache& cache =
SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(4));
- ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator.
+ ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
Error& bound_error = Error::Handle(zone);
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index b532cf1..54a9174 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -213,14 +213,16 @@
static Library& MakeTestLibrary(const char* url) {
- const String& lib_url = String::ZoneHandle(Symbols::New(Thread::Current(),
- url));
- Library& lib = Library::ZoneHandle(Library::New(lib_url));
- lib.Register();
- Library& core_lib = Library::Handle(Library::CoreLibrary());
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+
+ const String& lib_url = String::ZoneHandle(zone, Symbols::New(thread, url));
+ Library& lib = Library::ZoneHandle(zone, Library::New(lib_url));
+ lib.Register(thread);
+ Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
ASSERT(!core_lib.IsNull());
- const Namespace& core_ns = Namespace::Handle(
- Namespace::New(core_lib, Array::Handle(), Array::Handle()));
+ const Namespace& core_ns = Namespace::Handle(zone,
+ Namespace::New(core_lib, Array::Handle(zone), Array::Handle(zone)));
lib.AddImport(core_ns);
return lib;
}
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 49796c1..e084f16 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1341,10 +1341,7 @@
} else if (FLAG_disassemble_optimized &&
optimized &&
FlowGraphPrinter::ShouldPrint(function)) {
- // TODO(fschneider): Print unoptimized code along with the optimized code.
- THR_Print("*** BEGIN CODE\n");
Disassembler::DisassembleCode(function, true);
- THR_Print("*** END CODE\n");
}
DEBUG_ONLY(CheckInliningIntervals(function));
return Error::null();
@@ -1538,6 +1535,11 @@
if (!func.HasCode() &&
!func.is_abstract() &&
!func.IsRedirectingFactory()) {
+ if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
+ func.HasOptionalParameters()) {
+ // Skipping optional parameters in mixin application.
+ continue;
+ }
error = CompileFunction(thread, func);
if (!error.IsNull()) {
return error.raw();
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d23e6f0..d15df53 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -31,7 +31,8 @@
}
obj_ = raw_obj;
if (obj_.GetClassId() == TokenStream::kClassId) {
- TokenStream::Iterator tkit(TokenStream::Cast(obj_),
+ TokenStream::Iterator tkit(Thread::Current()->zone(),
+ TokenStream::Cast(obj_),
TokenPosition::kMinSource,
TokenStream::Iterator::kNoNewlines);
Token::Kind kind = tkit.CurrentTokenKind();
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 0b8d617..4409f3f 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -403,12 +403,6 @@
}
-void ConstantPropagator::VisitPushTemp(PushTempInstr* instr) {
- // Instruction is eliminated when translating to SSA.
- UNREACHABLE();
-}
-
-
void ConstantPropagator::VisitDropTemps(DropTempsInstr* instr) {
// Instruction is eliminated when translating to SSA.
UNREACHABLE();
@@ -610,8 +604,8 @@
}
-void ConstantPropagator::VisitStringFromCharCode(
- StringFromCharCodeInstr* instr) {
+void ConstantPropagator::VisitOneByteStringFromCharCode(
+ OneByteStringFromCharCodeInstr* instr) {
const Object& o = instr->char_code()->definition()->constant_value();
if (o.IsNull() || IsNonConstant(o)) {
SetValue(instr, non_constant_);
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index f4144d6..54fc66b 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -302,6 +302,12 @@
// match patched call's argument count so that Return instructions continue
// to work.
//
+// - LoadClassIdTOS, LoadClassId rA, D
+//
+// LoadClassIdTOS loads the class id from the object at SP[0] and stores it
+// to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to
+// FP[D].
+//
// TODO(vegorov) the way we replace calls with DebugBreak does not work
// with our smi fast paths because DebugBreak is simply skipped.
//
@@ -462,6 +468,12 @@
#endif
return (call >> 8) & 0xFF;
}
+
+ static Instr At(uword pc) { return *reinterpret_cast<Instr*>(pc); }
+
+ private:
+ DISALLOW_ALLOCATION();
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecode);
};
// Various dummy declarations to make shared code compile.
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index cd7dbde..0bc7a50 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -47,6 +47,7 @@
ThreadPool* Dart::thread_pool_ = NULL;
DebugInfo* Dart::pprof_symbol_generator_ = NULL;
ReadOnlyHandles* Dart::predefined_handles_ = NULL;
+Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid;
const uint8_t* Dart::instructions_snapshot_buffer_ = NULL;
const uint8_t* Dart::data_snapshot_buffer_ = NULL;
Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL;
@@ -131,15 +132,6 @@
if (vm_isolate_ != NULL || !Flags::Initialized()) {
return "VM already initialized or flags not initialized.";
}
-#if defined(DART_PRECOMPILED_RUNTIME)
- if (instructions_snapshot == NULL) {
- return "Precompiled runtime requires a precompiled snapshot";
- }
-#else
- if (instructions_snapshot != NULL) {
- return "JIT runtime cannot run a precompiled snapshot";
- }
-#endif
set_thread_exit_callback(thread_exit);
SetFileCallbacks(file_open, file_read, file_write, file_close);
set_entropy_source_callback(entropy_source);
@@ -178,14 +170,12 @@
ASSERT(vm_isolate_ == NULL);
ASSERT(Flags::Initialized());
const bool is_vm_isolate = true;
- const bool precompiled = instructions_snapshot != NULL;
// Setup default flags for the VM isolate.
Dart_IsolateFlags api_flags;
Isolate::FlagsInitialize(&api_flags);
vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate);
start_time_ = vm_isolate_->start_time();
- vm_isolate_->set_compilation_allowed(!precompiled);
// Verify assumptions about executing in the VM isolate.
ASSERT(vm_isolate_ == Isolate::Current());
ASSERT(vm_isolate_ == Thread::Current()->isolate());
@@ -200,24 +190,48 @@
Object::InitOnce(vm_isolate_);
ArgumentsDescriptor::InitOnce();
ICData::InitOnce();
- // When precompiled the stub code is initialized from the snapshot.
- if (!precompiled) {
- StubCode::InitOnce();
- }
if (vm_isolate_snapshot != NULL) {
NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
"VMIsolateSnapshot"));
- if (instructions_snapshot != NULL) {
- vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
- }
- if (data_snapshot != NULL) {
- vm_isolate_->SetupDataSnapshotPage(data_snapshot);
- }
const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot);
if (snapshot == NULL) {
- return "Invalid vm isolate snapshot seen.";
+ return "Invalid vm isolate snapshot seen";
}
- ASSERT(Snapshot::IsFull(snapshot->kind()));
+ snapshot_kind_ = snapshot->kind();
+ if (Snapshot::IncludesCode(snapshot_kind_)) {
+ if (snapshot_kind_ == Snapshot::kAppNoJIT) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ vm_isolate_->set_compilation_allowed(false);
+ if (!FLAG_precompiled_runtime) {
+ return "Flag --precompilation was not specified";
+ }
+#else
+ return "JIT runtime cannot run a precompiled snapshot";
+#endif
+ }
+ if (instructions_snapshot == NULL) {
+ return "Missing instructions snapshot";
+ }
+ if (data_snapshot == NULL) {
+ return "Missing rodata snapshot";
+ }
+ vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
+ vm_isolate_->SetupDataSnapshotPage(data_snapshot);
+ } else if (Snapshot::IsFull(snapshot_kind_)) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return "Precompiled runtime requires a precompiled snapshot";
+#else
+ if (instructions_snapshot != NULL) {
+ return "Unexpected instructions snapshot";
+ }
+ if (data_snapshot != NULL) {
+ return "Unexpected rodata snapshot";
+ }
+ StubCode::InitOnce();
+#endif
+ } else {
+ return "Invalid vm isolate snapshot seen";
+ }
VmIsolateSnapshotReader reader(snapshot->kind(),
snapshot->content(),
snapshot->length(),
@@ -226,7 +240,7 @@
T);
const Error& error = Error::Handle(reader.ReadVmIsolateSnapshot());
if (!error.IsNull()) {
- return error.ToCString();
+ return error.ToErrorCString();
}
NOT_IN_PRODUCT(if (tds.enabled()) {
tds.SetNumArguments(2);
@@ -247,7 +261,13 @@
OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
}
} else {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return "Precompiled runtime requires a precompiled snapshot";
+#else
+ snapshot_kind_ = Snapshot::kNone;
+ StubCode::InitOnce();
Symbols::InitOnce(vm_isolate_);
+#endif
}
// We need to initialize the constants here for the vm isolate thread due to
// bootstrapping issues.
@@ -487,6 +507,7 @@
return ApiError::New(message);
}
ASSERT(Snapshot::IsFull(snapshot->kind()));
+ ASSERT(snapshot->kind() == snapshot_kind_);
if (FLAG_trace_isolates) {
OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length());
}
@@ -511,11 +532,7 @@
MegamorphicCacheTable::PrintSizes(I);
}
} else {
- // Populate the isolate's symbol table with all symbols from the
- // VM isolate. We do this so that when we generate a full snapshot
- // for the isolate we have a unified symbol table that we can then
- // read into the VM isolate.
- Symbols::AddPredefinedSymbolsToIsolate();
+ ASSERT(snapshot_kind_ == Snapshot::kNone);
}
Object::VerifyBuiltinVtables();
@@ -530,7 +547,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
// When running precompiled, the megamorphic miss function/code comes from the
// snapshot.
- if (!Dart::IsRunningPrecompiledCode()) {
+ if (!Snapshot::IncludesCode(Dart::snapshot_kind())) {
MegamorphicCacheTable::InitMissHandler(I);
}
#endif
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index afa2499..a21dab2 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -7,6 +7,7 @@
#include "include/dart_api.h"
#include "vm/allocation.h"
+#include "vm/snapshot.h"
namespace dart {
@@ -60,16 +61,15 @@
static uword AllocateReadOnlyHandle();
static bool IsReadOnlyHandle(uword address);
+ static Snapshot::Kind snapshot_kind() {
+ return snapshot_kind_;
+ }
static const uint8_t* instructions_snapshot_buffer() {
return instructions_snapshot_buffer_;
}
static void set_instructions_snapshot_buffer(const uint8_t* buffer) {
instructions_snapshot_buffer_ = buffer;
}
- static bool IsRunningPrecompiledCode() {
- return instructions_snapshot_buffer_ != NULL;
- }
-
static const uint8_t* data_snapshot_buffer() {
return data_snapshot_buffer_;
}
@@ -121,6 +121,7 @@
static ThreadPool* thread_pool_;
static DebugInfo* pprof_symbol_generator_;
static ReadOnlyHandles* predefined_handles_;
+ static Snapshot::Kind snapshot_kind_;
static const uint8_t* instructions_snapshot_buffer_;
static const uint8_t* data_snapshot_buffer_;
static Dart_ThreadExitCallback thread_exit_callback_;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 9dcaa4b..e980f09 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1148,9 +1148,6 @@
Dart_FileCloseCallback file_close,
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets) {
- if ((instructions_snapshot != NULL) && !FLAG_precompiled_runtime) {
- return strdup("Flag --precompilation was not specified.");
- }
if (interrupt != NULL) {
return strdup("Dart_Initialize: "
"Setting of interrupt callback is not supported.");
@@ -1485,20 +1482,19 @@
if (::Dart_IsError(state)) {
return state;
}
- I->heap()->CollectAllGarbage();
I->StopBackgroundCompiler();
#if defined(DEBUG)
+ I->heap()->CollectAllGarbage();
FunctionVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
-#endif // #if defined(DEBUG).
+#endif // #if defined(DEBUG)
FullSnapshotWriter writer(Snapshot::kCore,
vm_isolate_snapshot_buffer,
isolate_snapshot_buffer,
ApiReallocate,
- NULL, /* instructions_writer */
- true /* vm_isolate_is_symbolic */);
+ NULL /* instructions_writer */);
writer.WriteFullSnapshot();
*vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
*isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -1528,11 +1524,13 @@
} else {
lib ^= Api::UnwrapHandle(library);
}
- I->heap()->CollectAllGarbage();
+
#if defined(DEBUG)
+ I->heap()->CollectAllGarbage();
FunctionVisitor check_canonical(T);
I->heap()->IterateObjects(&check_canonical);
-#endif // #if defined(DEBUG).
+#endif // #if defined(DEBUG)
+
ScriptSnapshotWriter writer(buffer, ApiReallocate);
writer.WriteScriptSnapshot(lib);
*size = writer.BytesWritten();
@@ -2841,8 +2839,8 @@
// Lookup the class ArgumentError in dart:core.
const String& lib_url = String::Handle(String::New("dart:core"));
const String& class_name = String::Handle(String::New("ArgumentError"));
- const Library& lib =
- Library::Handle(zone, Library::LookupLibrary(lib_url));
+ const Library& lib = Library::Handle(zone,
+ Library::LookupLibrary(thread, lib_url));
if (lib.IsNull()) {
const String& message = String::Handle(
String::NewFormatted("%s: library '%s' not found.",
@@ -3829,7 +3827,7 @@
}
if (constructor.IsGenerativeConstructor()) {
#if defined(DEBUG)
- if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+ if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
@@ -3924,7 +3922,7 @@
}
const Class& cls = Class::Handle(Z, type_obj.type_class());
#if defined(DEBUG)
- if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+ if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
@@ -3954,7 +3952,7 @@
}
const Class& cls = Class::Handle(Z, type_obj.type_class());
#if defined(DEBUG)
- if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+ if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
@@ -4122,6 +4120,15 @@
cls_name.ToCString(),
function_name.ToCString());
}
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const String& cls_name = String::Handle(Z, cls.Name());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ cls_name.ToCString(),
+ function_name.ToCString());
+ });
// Setup args and check for malformed arguments in the arguments list.
result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
if (!::Dart_IsError(result)) {
@@ -4157,6 +4164,17 @@
}
return result;
}
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const Class& cls = Class::Handle(Z, instance.clazz());
+ ASSERT(!cls.IsNull());
+ const String& cls_name = String::Handle(Z, cls.Name());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ cls_name.ToCString(),
+ function_name.ToCString());
+ });
// Setup args and check for malformed arguments in the arguments list.
result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
if (!::Dart_IsError(result)) {
@@ -4182,6 +4200,17 @@
CURRENT_FUNC,
function_name.ToCString());
}
+
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const String& lib_name = String::Handle(Z, lib.url());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ lib_name.ToCString(),
+ function_name.ToCString());
+ });
+
// LookupFunctionAllowPrivate does not check argument arity, so we
// do it here.
String& error_message = String::Handle(Z);
@@ -4272,6 +4301,15 @@
getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
}
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const String& cls_name = String::Handle(cls.Name());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ cls_name.ToCString(), field_name.ToCString());
+ });
+
if (!getter.IsNull()) {
// Invoke the getter and return the result.
return Api::NewHandle(
@@ -4298,6 +4336,15 @@
cls = cls.SuperClass();
}
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const String& cls_name = String::Handle(cls.Name());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ cls_name.ToCString(), field_name.ToCString());
+ });
+
// Invoke the getter and return the result.
const int kNumArgs = 1;
const Array& args = Array::Handle(Z, Array::New(kNumArgs));
@@ -4337,6 +4384,15 @@
getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
}
+ NOT_IN_PRODUCT(if (tds.enabled()) {
+ const String& lib_name = String::Handle(lib.url());
+ tds.SetNumArguments(1);
+ tds.FormatArgument(0,
+ "name",
+ "%s.%s",
+ lib_name.ToCString(), field_name.ToCString());
+ });
+
if (!getter.IsNull()) {
// Invoke the getter and return the result.
return Api::NewHandle(
@@ -4984,6 +5040,14 @@
return Symbols::False().raw();
}
+ if (name.Equals(Symbols::DartVMProduct())) {
+#ifdef PRODUCT
+ return Symbols::True().raw();
+#else
+ return Symbols::False().raw();
+#endif
+ }
+
const String& prefix = Symbols::DartLibrary();
if (name.StartsWith(prefix)) {
const String& library_name =
@@ -4994,7 +5058,7 @@
const String& dart_library_name =
String::Handle(String::Concat(Symbols::DartScheme(), library_name));
const Library& library =
- Library::Handle(Library::LookupLibrary(dart_library_name));
+ Library::Handle(Library::LookupLibrary(thread, dart_library_name));
if (!library.IsNull()) {
return Symbols::True().raw();
}
@@ -5147,7 +5211,7 @@
library = Library::New(url_str);
library.set_debuggable(true);
- library.Register();
+ library.Register(T);
I->object_store()->set_root_library(library);
const Script& script = Script::Handle(Z,
@@ -5348,7 +5412,8 @@
if (url_str.IsNull()) {
RETURN_TYPE_ERROR(Z, url, String);
}
- const Library& library = Library::Handle(Z, Library::LookupLibrary(url_str));
+ const Library& library = Library::Handle(Z,
+ Library::LookupLibrary(T, url_str));
if (library.IsNull()) {
return Api::NewError("%s: library '%s' not found.",
CURRENT_FUNC, url_str.ToCString());
@@ -5414,10 +5479,10 @@
NoHeapGrowthControlScope no_growth_control;
- Library& library = Library::Handle(Z, Library::LookupLibrary(url_str));
+ Library& library = Library::Handle(Z, Library::LookupLibrary(T, url_str));
if (library.IsNull()) {
library = Library::New(url_str);
- library.Register();
+ library.Register(T);
} else if (library.LoadInProgress() ||
library.Loaded() ||
library.LoadFailed()) {
@@ -6117,14 +6182,15 @@
if (assembly_size == NULL) {
RETURN_NULL_ERROR(assembly_size);
}
- I->heap()->CollectAllGarbage();
AssemblyInstructionsWriter instructions_writer(assembly_buffer,
ApiReallocate,
2 * MB /* initial_size */);
- PrecompiledSnapshotWriter writer(vm_isolate_snapshot_buffer,
- isolate_snapshot_buffer,
- ApiReallocate,
- &instructions_writer);
+ FullSnapshotWriter writer(Snapshot::kAppNoJIT,
+ vm_isolate_snapshot_buffer,
+ isolate_snapshot_buffer,
+ ApiReallocate,
+ &instructions_writer);
+
writer.WriteFullSnapshot();
*vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
*isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -6175,15 +6241,16 @@
if (rodata_blob_size == NULL) {
RETURN_NULL_ERROR(instructions_blob_size);
}
- I->heap()->CollectAllGarbage();
BlobInstructionsWriter instructions_writer(instructions_blob_buffer,
rodata_blob_buffer,
ApiReallocate,
2 * MB /* initial_size */);
- PrecompiledSnapshotWriter writer(vm_isolate_snapshot_buffer,
- isolate_snapshot_buffer,
- ApiReallocate,
- &instructions_writer);
+ FullSnapshotWriter writer(Snapshot::kAppNoJIT,
+ vm_isolate_snapshot_buffer,
+ isolate_snapshot_buffer,
+ ApiReallocate,
+ &instructions_writer);
+
writer.WriteFullSnapshot();
*vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
*isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -6195,8 +6262,112 @@
#endif // DART_PRECOMPILER
+DART_EXPORT Dart_Handle Dart_PrecompileJIT() {
+ API_TIMELINE_BEGIN_END;
+ DARTSCOPE(Thread::Current());
+ Isolate* I = T->isolate();
+ Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
+ if (::Dart_IsError(result)) {
+ return result;
+ }
+ CHECK_CALLBACK_STATE(T);
+ GrowableObjectArray& libraries =
+ GrowableObjectArray::Handle(Z, I->object_store()->libraries());
+ Library& lib = Library::Handle(Z);
+ Class& cls = Class::Handle(Z);
+ Error& error = Error::Handle(Z);
+ for (intptr_t i = 0; i < libraries.Length(); i++) {
+ lib ^= libraries.At(i);
+ ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+ while (it.HasNext()) {
+ cls = it.GetNextClass();
+ if (cls.IsDynamicClass()) {
+ continue; // class 'dynamic' is in the read-only VM isolate.
+ }
+ error = cls.EnsureIsFinalized(T);
+ if (!error.IsNull()) {
+ return Api::NewHandle(T, error.raw());
+ }
+ }
+ }
+ return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledJITSnapshotBlob(
+ uint8_t** vm_isolate_snapshot_buffer,
+ intptr_t* vm_isolate_snapshot_size,
+ uint8_t** isolate_snapshot_buffer,
+ intptr_t* isolate_snapshot_size,
+ uint8_t** instructions_blob_buffer,
+ intptr_t* instructions_blob_size,
+ uint8_t** rodata_blob_buffer,
+ intptr_t* rodata_blob_size) {
+ ASSERT(FLAG_load_deferred_eagerly);
+ API_TIMELINE_DURATION;
+ DARTSCOPE(Thread::Current());
+ Isolate* I = T->isolate();
+ if (vm_isolate_snapshot_buffer == NULL) {
+ RETURN_NULL_ERROR(vm_isolate_snapshot_buffer);
+ }
+ if (vm_isolate_snapshot_size == NULL) {
+ RETURN_NULL_ERROR(vm_isolate_snapshot_size);
+ }
+ if (isolate_snapshot_buffer == NULL) {
+ RETURN_NULL_ERROR(isolate_snapshot_buffer);
+ }
+ if (isolate_snapshot_size == NULL) {
+ RETURN_NULL_ERROR(isolate_snapshot_size);
+ }
+ if (instructions_blob_buffer == NULL) {
+ RETURN_NULL_ERROR(instructions_blob_buffer);
+ }
+ if (instructions_blob_size == NULL) {
+ RETURN_NULL_ERROR(instructions_blob_size);
+ }
+ if (rodata_blob_buffer == NULL) {
+ RETURN_NULL_ERROR(instructions_blob_buffer);
+ }
+ if (rodata_blob_size == NULL) {
+ RETURN_NULL_ERROR(instructions_blob_size);
+ }
+ // Finalize all classes if needed.
+ Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
+ if (::Dart_IsError(state)) {
+ return state;
+ }
+ I->StopBackgroundCompiler();
+
+ BlobInstructionsWriter instructions_writer(instructions_blob_buffer,
+ rodata_blob_buffer,
+ ApiReallocate,
+ 2 * MB /* initial_size */);
+ FullSnapshotWriter writer(Snapshot::kAppWithJIT,
+ vm_isolate_snapshot_buffer,
+ isolate_snapshot_buffer,
+ ApiReallocate,
+ &instructions_writer);
+ writer.WriteFullSnapshot();
+ *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
+ *isolate_snapshot_size = writer.IsolateSnapshotSize();
+ *instructions_blob_size = instructions_writer.InstructionsBlobSize();
+ *rodata_blob_size = instructions_writer.RodataBlobSize();
+
+ return Api::Success();
+}
+
+
DART_EXPORT bool Dart_IsRunningPrecompiledCode() {
- return Dart::IsRunningPrecompiledCode();
+ return Snapshot::IncludesCode(Dart::snapshot_kind());
+}
+
+
+DART_EXPORT bool Dart_IsPrecompiledRuntime() {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return true;
+#else
+ return false;
+#endif
}
} // namespace dart
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 02c28db..3b0f238 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6799,7 +6799,7 @@
kPatchNoClassChars };
const String& lib_url = String::Handle(String::New("theLibrary"));
- const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
+ const Library& lib = Library::Handle(Library::LookupLibrary(thread, lib_url));
for (int i = 0; i < 3; i++) {
const String& patch_url = String::Handle(String::New(patchNames[i]));
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 182fc7d..2d4e759 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -416,8 +416,8 @@
}
-Dart_CObject* ApiMessageReader::ReadVMSymbol(intptr_t object_id) {
- ASSERT(Symbols::IsVMSymbolId(object_id));
+Dart_CObject* ApiMessageReader::ReadPredefinedSymbol(intptr_t object_id) {
+ ASSERT(Symbols::IsPredefinedSymbolId(object_id));
intptr_t symbol_id = object_id - kMaxPredefinedObjectIds;
Dart_CObject* object;
if (vm_symbol_references_ != NULL &&
@@ -433,7 +433,7 @@
memset(vm_symbol_references_, 0, size);
}
- object = CreateDartCObjectString(Symbols::GetVMSymbol(object_id));
+ object = CreateDartCObjectString(Symbols::GetPredefinedSymbol(object_id));
ASSERT(vm_symbol_references_[symbol_id] == NULL);
vm_symbol_references_[symbol_id] = object;
return object;
@@ -547,8 +547,8 @@
if (object_id == kDoubleObject) {
return AllocateDartCObjectDouble(ReadDouble());
}
- if (Symbols::IsVMSymbolId(object_id)) {
- return ReadVMSymbol(object_id);
+ if (Symbols::IsPredefinedSymbolId(object_id)) {
+ return ReadPredefinedSymbol(object_id);
}
// No other VM isolate objects are supported.
return AllocateDartCObjectNull();
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index f4675c4..bb1efa2 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -115,7 +115,7 @@
Dart_CObject* ReadInlinedObject(intptr_t object_id);
Dart_CObject* ReadObjectImpl();
Dart_CObject* ReadIndexedObject(intptr_t object_id);
- Dart_CObject* ReadVMSymbol(intptr_t object_id);
+ Dart_CObject* ReadPredefinedSymbol(intptr_t object_id);
Dart_CObject* ReadObjectRef();
Dart_CObject* ReadObject();
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3cb92b2..6d11f18 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -766,8 +766,8 @@
ASSERT(!type.IsNull());
// Uninstantiated types are not added to ExceptionHandlers data.
ASSERT(type.IsInstantiated());
- if (type.IsDynamicType()) return frame;
if (type.IsMalformed()) continue;
+ if (type.IsDynamicType()) return frame;
if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
return frame;
}
@@ -1693,9 +1693,11 @@
}
-static TokenPosition LastTokenOnLine(const TokenStream& tokens,
+static TokenPosition LastTokenOnLine(Zone* zone,
+ const TokenStream& tokens,
TokenPosition pos) {
- TokenStream::Iterator iter(tokens,
+ TokenStream::Iterator iter(zone,
+ tokens,
pos,
TokenStream::Iterator::kAllTokens);
ASSERT(iter.IsValid());
@@ -1780,10 +1782,11 @@
last_token_pos = func.end_token_pos();
}
- Script& script = Script::Handle(func.script());
- Code& code = Code::Handle(func.unoptimized_code());
+ Zone* zone = Thread::Current()->zone();
+ Script& script = Script::Handle(zone, func.script());
+ Code& code = Code::Handle(zone, func.unoptimized_code());
ASSERT(!code.IsNull());
- PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
+ PcDescriptors& desc = PcDescriptors::Handle(zone, code.pc_descriptors());
// First pass: find the safe point which is closest to the beginning
// of the given token range.
@@ -1830,10 +1833,11 @@
// the token on the line which is at the best fit column (if column
// was specified) and has the lowest code address.
if (best_fit_pos != TokenPosition::kMaxSource) {
- const Script& script = Script::Handle(func.script());
- const TokenStream& tokens = TokenStream::Handle(script.tokens());
+ const Script& script = Script::Handle(zone, func.script());
+ const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
const TokenPosition begin_pos = best_fit_pos;
- const TokenPosition end_of_line_pos = LastTokenOnLine(tokens, begin_pos);
+ const TokenPosition end_of_line_pos =
+ LastTokenOnLine(zone, tokens, begin_pos);
uword lowest_pc_offset = kUwordMax;
PcDescriptors::Iterator iter(desc, kSafepointKind);
while (iter.MoveNext()) {
@@ -2662,13 +2666,15 @@
bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
- Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation());
+ Zone* zone = Thread::Current()->zone();
+ Object& closure_or_null =
+ Object::Handle(zone, top_frame->GetAsyncOperation());
if (!closure_or_null.IsNull()) {
ASSERT(closure_or_null.IsInstance());
ASSERT(Instance::Cast(closure_or_null).IsClosure());
- const Script& script = Script::Handle(top_frame->SourceScript());
- const TokenStream& tokens = TokenStream::Handle(script.tokens());
- TokenStream::Iterator iter(tokens, top_frame->TokenPos());
+ const Script& script = Script::Handle(zone, top_frame->SourceScript());
+ const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
+ TokenStream::Iterator iter(zone, tokens, top_frame->TokenPos());
if ((iter.CurrentTokenKind() == Token::kIDENT) &&
((iter.CurrentLiteral() == Symbols::Await().raw()) ||
(iter.CurrentLiteral() == Symbols::YieldKw().raw()))) {
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index f98b60a..4bfcae1 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -789,13 +789,14 @@
UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
- const Library& library = Library::Handle(Library::LookupLibrary(library_url));
+ const Library& library = Library::Handle(Z,
+ Library::LookupLibrary(T, library_url));
if (library.IsNull()) {
return Api::NewError("%s: library '%s' not found",
CURRENT_FUNC, library_url.ToCString());
}
- const Script& script = Script::Handle(library.LookupScript(script_url));
+ const Script& script = Script::Handle(Z, library.LookupScript(script_url));
if (script.IsNull()) {
return Api::NewError("%s: script '%s' not found in library '%s'",
CURRENT_FUNC, script_url.ToCString(),
@@ -810,17 +811,18 @@
DARTSCOPE(Thread::Current());
UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
- const Library& library = Library::Handle(Library::LookupLibrary(library_url));
+ const Library& library = Library::Handle(Z,
+ Library::LookupLibrary(T, library_url));
if (library.IsNull()) {
return Api::NewError("%s: library '%s' not found",
CURRENT_FUNC, library_url.ToCString());
}
- const Array& loaded_scripts = Array::Handle(library.LoadedScripts());
+ const Array& loaded_scripts = Array::Handle(Z, library.LoadedScripts());
ASSERT(!loaded_scripts.IsNull());
intptr_t num_scripts = loaded_scripts.Length();
- const Array& script_list = Array::Handle(Array::New(num_scripts));
- Script& script = Script::Handle();
- String& url = String::Handle();
+ const Array& script_list = Array::Handle(Z, Array::New(num_scripts));
+ Script& script = Script::Handle(Z);
+ String& url = String::Handle(Z);
for (int i = 0; i < num_scripts; i++) {
script ^= loaded_scripts.At(i);
url = script.url();
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 8c69bc7..bac0c4b 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -1080,8 +1080,8 @@
// 2a. Handle uses:
// Update the expression stack renaming environment for each use by
// removing the renamed value.
- // For each use of a LoadLocal, StoreLocal, or Constant: Replace it with
- // the renamed value.
+ // For each use of a LoadLocal, StoreLocal, DropTemps or Constant: Replace
+ // it with the renamed value.
for (intptr_t i = current->InputCount() - 1; i >= 0; --i) {
Value* v = current->InputAt(i);
// Update expression stack.
@@ -1089,13 +1089,11 @@
Definition* reaching_defn = env->RemoveLast();
Definition* input_defn = v->definition();
- if (input_defn->IsLoadLocal() ||
- input_defn->IsStoreLocal() ||
- input_defn->IsPushTemp() ||
- input_defn->IsDropTemps() ||
- input_defn->IsConstant()) {
- // Remove the load/store from the graph.
- input_defn->RemoveFromGraph();
+ if (input_defn != reaching_defn) {
+ ASSERT(input_defn->IsLoadLocal() ||
+ input_defn->IsStoreLocal() ||
+ input_defn->IsDropTemps() ||
+ input_defn->IsConstant());
// Assert we are not referencing nulls in the initial environment.
ASSERT(reaching_defn->ssa_temp_index() != -1);
v->set_definition(reaching_defn);
@@ -1109,17 +1107,15 @@
env->RemoveLast();
}
- // 2b. Handle LoadLocal, StoreLocal, and Constant.
+ // 2b. Handle LoadLocal, StoreLocal, DropTemps and Constant.
Definition* definition = current->AsDefinition();
if (definition != NULL) {
LoadLocalInstr* load = definition->AsLoadLocal();
StoreLocalInstr* store = definition->AsStoreLocal();
- PushTempInstr* push = definition->AsPushTemp();
DropTempsInstr* drop = definition->AsDropTemps();
ConstantInstr* constant = definition->AsConstant();
if ((load != NULL) ||
(store != NULL) ||
- (push != NULL) ||
(drop != NULL) ||
(constant != NULL)) {
Definition* result = NULL;
@@ -1158,12 +1154,6 @@
intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
captured_parameters_->Add(index);
}
-
- } else if (push != NULL) {
- result = push->value()->definition();
- env->Add(result);
- it.RemoveCurrentFromGraph();
- continue;
} else if (drop != NULL) {
// Drop temps from the environment.
for (intptr_t j = 0; j < drop->num_temps(); j++) {
@@ -1181,13 +1171,10 @@
if (definition->HasTemp()) {
ASSERT(result != NULL);
env->Add(result);
- // We remove load/store/constant instructions when we find their
- // use in 2a.
- } else {
- it.RemoveCurrentFromGraph();
}
+ it.RemoveCurrentFromGraph();
} else {
- // Not a load, store, or constant.
+ // Not a load, store, drop or constant.
if (definition->HasTemp()) {
// Assign fresh SSA temporary and update expression stack.
AllocateSSAIndexes(definition);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 0a78c7b..b968585 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2247,9 +2247,6 @@
LocalVariable* EffectGraphVisitor::EnterTempLocalScope(
Value* value, TokenPosition token_pos) {
- Do(new(Z) PushTempInstr(value));
- owner()->AllocateTemp();
-
ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
intptr_t index = GetCurrentTempLocalIndex();
char name[64];
@@ -2278,12 +2275,9 @@
ValueGraphVisitor for_value(owner());
node->InitializerAt(i)->Visit(&for_value);
Append(for_value);
- Value* temp_val = for_value.value();
ASSERT(!node->TempAt(i)->HasIndex() ||
(node->TempAt(i)->index() == GetCurrentTempLocalIndex()));
node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
- Do(new(Z) PushTempInstr(temp_val));
- owner()->AllocateTemp();
}
}
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 006053f..71fcec4 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -1400,7 +1400,7 @@
}
// Allocate all unallocated input locations.
- const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
+ const bool should_pop = !instr->IsPushArgument();
for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
Location loc = locs->in(i);
Register reg = kNoRegister;
@@ -1932,7 +1932,6 @@
switch (instr->tag()) {
case Instruction::kPushArgument:
- case Instruction::kPushTemp:
// Do nothing.
break;
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 2f3ff8e..92ba799 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -132,7 +132,6 @@
(defn->tag() != Instruction::kStoreLocal) &&
(defn->tag() != Instruction::kStoreInstanceField) &&
(defn->tag() != Instruction::kDropTemps) &&
- (defn->tag() != Instruction::kPushTemp) &&
!defn->HasTemp()) {
__ Drop1();
}
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 471c511..c360c98 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -2803,6 +2803,25 @@
call->env(),
FlowGraph::kEffect);
+ // For external strings: Load backing store.
+ if (cid == kExternalOneByteStringCid) {
+ str = new LoadUntaggedInstr(new Value(str),
+ ExternalOneByteString::external_data_offset());
+ cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+ str = new LoadUntaggedInstr(
+ new Value(str),
+ RawExternalOneByteString::ExternalData::data_offset());
+ cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+ } else if (cid == kExternalTwoByteStringCid) {
+ str = new LoadUntaggedInstr(new Value(str),
+ ExternalTwoByteString::external_data_offset());
+ cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+ str = new LoadUntaggedInstr(
+ new Value(str),
+ RawExternalTwoByteString::ExternalData::data_offset());
+ cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+ }
+
LoadIndexedInstr* load_indexed = new(Z) LoadIndexedInstr(
new(Z) Value(str),
new(Z) Value(index),
@@ -2823,8 +2842,7 @@
intptr_t cid,
TargetEntryInstr** entry,
Definition** last) {
- // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
- if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
+ if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) {
return false;
}
Definition* str = call->ArgumentAt(0);
@@ -2836,8 +2854,8 @@
*last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
- StringFromCharCodeInstr* char_at = new(Z) StringFromCharCodeInstr(
- new(Z) Value(*last), cid);
+ OneByteStringFromCharCodeInstr* char_at =
+ new(Z) OneByteStringFromCharCodeInstr(new(Z) Value(*last));
flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue);
*last = char_at;
@@ -2852,11 +2870,6 @@
intptr_t cid,
TargetEntryInstr** entry,
Definition** last) {
- // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
- if (RawObject::IsExternalStringClassId(cid)) {
- return false;
- }
-
Definition* str = call->ArgumentAt(0);
Definition* index = call->ArgumentAt(1);
@@ -3097,7 +3110,10 @@
receiver_cid,
kTypedDataInt32x4ArrayCid,
entry, last);
- case MethodRecognizer::kStringBaseCodeUnitAt:
+ case MethodRecognizer::kOneByteStringCodeUnitAt:
+ case MethodRecognizer::kTwoByteStringCodeUnitAt:
+ case MethodRecognizer::kExternalOneByteStringCodeUnitAt:
+ case MethodRecognizer::kExternalTwoByteStringCodeUnitAt:
return InlineStringCodeUnitAt(
flow_graph, call, receiver_cid, entry, last);
case MethodRecognizer::kStringBaseCharAt:
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index b4a5f3b..d0391db 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -910,11 +910,6 @@
}
-CompileType PushTempInstr::ComputeType() const {
- return CompileType::Dynamic();
-}
-
-
CompileType DropTempsInstr::ComputeType() const {
return *value()->Type();
}
@@ -926,8 +921,8 @@
}
-CompileType StringFromCharCodeInstr::ComputeType() const {
- return CompileType::FromCid(cid_);
+CompileType OneByteStringFromCharCodeInstr::ComputeType() const {
+ return CompileType::FromCid(kOneByteStringCid);
}
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index ef4e14c..2c92b17 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -381,6 +381,7 @@
UpdatePretenurePolicy();
RecordAfterGC(kNew);
PrintStats();
+ NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
EndNewSpaceGC();
if ((reason == kNewSpace) && old_space_.NeedsGarbageCollection()) {
// Old collections should call the API callbacks.
@@ -403,6 +404,7 @@
old_space_.MarkSweep(invoke_api_callbacks);
RecordAfterGC(kOld);
PrintStats();
+ NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
EndOldSpaceGC();
}
}
@@ -834,6 +836,66 @@
}
+void Heap::PrintStatsToTimeline(TimelineEventScope* event) {
+#if !defined(PRODUCT)
+ if ((event == NULL) || !event->enabled()) {
+ return;
+ }
+ event->SetNumArguments(12);
+ event->FormatArgument(0,
+ "Before.New.Used (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.new_.used_in_words));
+ event->FormatArgument(1,
+ "After.New.Used (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.new_.used_in_words));
+ event->FormatArgument(2,
+ "Before.Old.Used (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.old_.used_in_words));
+ event->FormatArgument(3,
+ "After.Old.Used (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.old_.used_in_words));
+
+ event->FormatArgument(4,
+ "Before.New.Capacity (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.new_.capacity_in_words));
+ event->FormatArgument(5,
+ "After.New.Capacity (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.new_.capacity_in_words));
+ event->FormatArgument(6,
+ "Before.Old.Capacity (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.old_.capacity_in_words));
+ event->FormatArgument(7,
+ "After.Old.Capacity (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.old_.capacity_in_words));
+
+ event->FormatArgument(8,
+ "Before.New.External (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.new_.external_in_words));
+ event->FormatArgument(9,
+ "After.New.External (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.new_.external_in_words));
+ event->FormatArgument(10,
+ "Before.Old.External (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.before_.old_.external_in_words));
+ event->FormatArgument(11,
+ "After.Old.External (kB)",
+ "%" Pd "",
+ RoundWordsToKB(stats_.after_.old_.external_in_words));
+#endif // !defined(PRODUCT)
+}
+
+
NoHeapGrowthControlScope::NoHeapGrowthControlScope()
: StackResource(Thread::Current()) {
Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 1526424..c5a7693 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -22,6 +22,7 @@
class ObjectPointerVisitor;
class ObjectSet;
class ServiceEvent;
+class TimelineEventScope;
class VirtualMemory;
class Heap {
@@ -327,6 +328,7 @@
void PrintStats();
void UpdateClassHeapStatsBeforeGC(Heap::Space space);
void UpdatePretenurePolicy();
+ void PrintStatsToTimeline(TimelineEventScope* event);
// Updates gc in progress flags.
bool BeginNewSpaceGC(Thread* thread);
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index 38b69f4..ec7945f 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -109,10 +109,40 @@
}
+static bool HasLoadFromPool(Instr instr) {
+ switch (Bytecode::DecodeOpcode(instr)) {
+ case Bytecode::kLoadConstant:
+ case Bytecode::kPushConstant:
+ case Bytecode::kStaticCall:
+ case Bytecode::kInstanceCall:
+ case Bytecode::kInstanceCall2:
+ case Bytecode::kInstanceCall3:
+ case Bytecode::kStoreStaticTOS:
+ case Bytecode::kPushStatic:
+ case Bytecode::kAllocate:
+ case Bytecode::kInstantiateType:
+ case Bytecode::kInstantiateTypeArgumentsTOS:
+ case Bytecode::kAssertAssignable:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
bool DecodeLoadObjectFromPoolOrThread(uword pc,
const Code& code,
Object* obj) {
- UNIMPLEMENTED();
+ ASSERT(code.ContainsInstructionAt(pc));
+ Instr instr = Bytecode::At(pc);
+ if (HasLoadFromPool(instr)) {
+ uint16_t index = Bytecode::DecodeD(instr);
+ const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+ if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+ *obj = pool.ObjectAt(index);
+ return true;
+ }
+ }
return false;
}
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 3869329..3950f3e 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2969,21 +2969,6 @@
}
-LocationSummary* PushTempInstr::MakeLocationSummary(Zone* zone,
- bool optimizing) const {
- return LocationSummary::Make(zone,
- 1,
- Location::NoLocation(),
- LocationSummary::kNoCall);
-}
-
-
-void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- ASSERT(!compiler->is_optimizing());
- // Nothing to do.
-}
-
-
LocationSummary* DropTempsInstr::MakeLocationSummary(Zone* zone,
bool optimizing) const {
return (InputCount() == 1)
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 1536cf4..a7f522d 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -454,7 +454,6 @@
M(PolymorphicInstanceCall) \
M(StaticCall) \
M(LoadLocal) \
- M(PushTemp) \
M(DropTemps) \
M(StoreLocal) \
M(StrictCompare) \
@@ -515,7 +514,7 @@
M(CheckArrayBound) \
M(Constraint) \
M(StringToCharCode) \
- M(StringFromCharCode) \
+ M(OneByteStringFromCharCode) \
M(StringInterpolate) \
M(InvokeMathCFunction) \
M(MergedMath) \
@@ -3368,34 +3367,6 @@
};
-class PushTempInstr : public TemplateDefinition<1, NoThrow> {
- public:
- explicit PushTempInstr(Value* value) {
- SetInputAt(0, value);
- }
-
- DECLARE_INSTRUCTION(PushTemp)
-
- Value* value() const { return inputs_[0]; }
-
- virtual CompileType ComputeType() const;
-
- virtual bool CanDeoptimize() const { return false; }
-
- virtual EffectSet Effects() const {
- UNREACHABLE(); // Eliminated by SSA construction.
- return EffectSet::None();
- }
-
- virtual TokenPosition token_pos() const {
- return TokenPosition::kTempMove;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PushTempInstr);
-};
-
-
class DropTempsInstr : public Definition {
public:
DropTempsInstr(intptr_t num_temps, Value* value)
@@ -3958,17 +3929,14 @@
};
-class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
+class OneByteStringFromCharCodeInstr
+ : public TemplateDefinition<1, NoThrow, Pure> {
public:
- StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
- ASSERT(char_code != NULL);
- ASSERT(char_code->definition()->IsLoadIndexed());
- ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
- kOneByteStringCid);
+ explicit OneByteStringFromCharCodeInstr(Value* char_code) {
SetInputAt(0, char_code);
}
- DECLARE_INSTRUCTION(StringFromCharCode)
+ DECLARE_INSTRUCTION(OneByteStringFromCharCode)
virtual CompileType ComputeType() const;
Value* char_code() const { return inputs_[0]; }
@@ -3976,13 +3944,11 @@
virtual bool CanDeoptimize() const { return false; }
virtual bool AttributesEqual(Instruction* other) const {
- return other->AsStringFromCharCode()->cid_ == cid_;
+ return true;
}
private:
- const intptr_t cid_;
-
- DISALLOW_COPY_AND_ASSIGN(StringFromCharCodeInstr);
+ DISALLOW_COPY_AND_ASSIGN(OneByteStringFromCharCodeInstr);
};
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 2c7d44e..4123a2a 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -968,8 +968,8 @@
}
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+ Zone* zone, bool opt) const {
const intptr_t kNumInputs = 1;
// TODO(fschneider): Allow immediate operands for the char code.
return LocationSummary::Make(zone,
@@ -979,7 +979,8 @@
}
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+ FlowGraphCompiler* compiler) {
ASSERT(compiler->is_optimizing());
const Register char_code = locs()->in(0).reg();
const Register result = locs()->out(0).reg();
@@ -1111,6 +1112,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return CompileType::FromCid(kSmiCid);
case kTypedDataInt32ArrayCid:
@@ -1137,6 +1140,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return kTagged;
case kTypedDataInt32ArrayCid:
return kUnboxedInt32;
@@ -1314,6 +1319,7 @@
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ case kExternalOneByteStringCid:
ASSERT(index_scale() == 1);
__ ldrb(result, element_address);
__ SmiTag(result);
@@ -1324,6 +1330,7 @@
break;
case kTypedDataUint16ArrayCid:
case kTwoByteStringCid:
+ case kExternalTwoByteStringCid:
__ ldrh(result, element_address);
__ SmiTag(result);
break;
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index f627e6e..29eae7d 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -822,8 +822,8 @@
}
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+ Zone* zone, bool opt) const {
const intptr_t kNumInputs = 1;
// TODO(fschneider): Allow immediate operands for the char code.
return LocationSummary::Make(zone,
@@ -833,7 +833,8 @@
}
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+ FlowGraphCompiler* compiler) {
ASSERT(compiler->is_optimizing());
const Register char_code = locs()->in(0).reg();
const Register result = locs()->out(0).reg();
@@ -968,6 +969,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
case kTypedDataInt32ArrayCid:
case kTypedDataUint32ArrayCid:
return CompileType::FromCid(kSmiCid);
@@ -992,6 +995,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return kTagged;
case kTypedDataInt32ArrayCid:
return kUnboxedInt32;
@@ -1125,6 +1130,7 @@
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ case kExternalOneByteStringCid:
ASSERT(index_scale() == 1);
__ ldr(result, element_address, kUnsignedByte);
__ SmiTag(result);
@@ -1135,6 +1141,7 @@
break;
case kTypedDataUint16ArrayCid:
case kTwoByteStringCid:
+ case kExternalTwoByteStringCid:
__ ldr(result, element_address, kUnsignedHalfword);
__ SmiTag(result);
break;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 44d16ed..5a7d5ce 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -840,8 +840,8 @@
}
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+ Zone* zone, bool opt) const {
const intptr_t kNumInputs = 1;
// TODO(fschneider): Allow immediate operands for the char code.
return LocationSummary::Make(zone,
@@ -851,7 +851,8 @@
}
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+ FlowGraphCompiler* compiler) {
Register char_code = locs()->in(0).reg();
Register result = locs()->out(0).reg();
__ movl(result,
@@ -1000,6 +1001,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return CompileType::FromCid(kSmiCid);
case kTypedDataInt32ArrayCid:
@@ -1026,6 +1029,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return kTagged;
case kTypedDataInt32ArrayCid:
return kUnboxedInt32;
@@ -1159,6 +1164,7 @@
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ case kExternalOneByteStringCid:
ASSERT(index_scale() == 1);
__ movzxb(result, element_address);
__ SmiTag(result);
@@ -1169,6 +1175,7 @@
break;
case kTypedDataUint16ArrayCid:
case kTwoByteStringCid:
+ case kExternalTwoByteStringCid:
__ movzxw(result, element_address);
__ SmiTag(result);
break;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 7bbfb55..b1b078f 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1019,8 +1019,8 @@
}
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+ Zone* zone, bool opt) const {
const intptr_t kNumInputs = 1;
// TODO(fschneider): Allow immediate operands for the char code.
return LocationSummary::Make(zone,
@@ -1030,13 +1030,12 @@
}
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+ FlowGraphCompiler* compiler) {
ASSERT(compiler->is_optimizing());
Register char_code = locs()->in(0).reg();
Register result = locs()->out(0).reg();
- __ Comment("StringFromCharCodeInstr");
-
__ lw(result, Address(THR, Thread::predefined_symbols_address_offset()));
__ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
__ sll(TMP, char_code, 1); // Char code is a smi.
@@ -1169,6 +1168,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return CompileType::FromCid(kSmiCid);
case kTypedDataInt32ArrayCid:
@@ -1195,6 +1196,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return kTagged;
case kTypedDataInt32ArrayCid:
return kUnboxedInt32;
@@ -1321,6 +1324,7 @@
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ case kExternalOneByteStringCid:
ASSERT(index_scale() == 1);
__ lbu(result, element_address);
__ SmiTag(result);
@@ -1331,6 +1335,7 @@
break;
case kTypedDataUint16ArrayCid:
case kTwoByteStringCid:
+ case kExternalTwoByteStringCid:
__ lhu(result, element_address);
__ SmiTag(result);
break;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 87b1f2e..28159ed 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -812,8 +812,8 @@
}
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
- bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+ Zone* zone, bool opt) const {
const intptr_t kNumInputs = 1;
// TODO(fschneider): Allow immediate operands for the char code.
return LocationSummary::Make(zone,
@@ -823,7 +823,8 @@
}
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+ FlowGraphCompiler* compiler) {
ASSERT(compiler->is_optimizing());
Register char_code = locs()->in(0).reg();
Register result = locs()->out(0).reg();
@@ -973,6 +974,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
case kTypedDataInt32ArrayCid:
case kTypedDataUint32ArrayCid:
return CompileType::FromCid(kSmiCid);
@@ -1000,6 +1003,8 @@
case kTypedDataUint16ArrayCid:
case kOneByteStringCid:
case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
return kTagged;
case kTypedDataInt32ArrayCid:
return kUnboxedInt32;
@@ -1135,6 +1140,7 @@
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
case kOneByteStringCid:
+ case kExternalOneByteStringCid:
__ movzxb(result, element_address);
__ SmiTag(result);
break;
@@ -1144,6 +1150,7 @@
break;
case kTypedDataUint16ArrayCid:
case kTwoByteStringCid:
+ case kExternalTwoByteStringCid:
__ movzxw(result, element_address);
__ SmiTag(result);
break;
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 5615e58..27631b3 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -659,6 +659,68 @@
}
+static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
+ GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+ TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+ BlockBuilder builder(flow_graph, normal_entry);
+
+ Definition* index = builder.AddParameter(1);
+ Definition* str = builder.AddParameter(2);
+ PrepareIndexedOp(&builder, str, index, String::length_offset());
+
+ // For external strings: Load external data.
+ if (cid == kExternalOneByteStringCid) {
+ str = builder.AddDefinition(
+ new LoadUntaggedInstr(new Value(str),
+ ExternalOneByteString::external_data_offset()));
+ str = builder.AddDefinition(
+ new LoadUntaggedInstr(
+ new Value(str),
+ RawExternalOneByteString::ExternalData::data_offset()));
+ } else if (cid == kExternalTwoByteStringCid) {
+ str = builder.AddDefinition(
+ new LoadUntaggedInstr(new Value(str),
+ ExternalTwoByteString::external_data_offset()));
+ str = builder.AddDefinition(
+ new LoadUntaggedInstr(
+ new Value(str),
+ RawExternalTwoByteString::ExternalData::data_offset()));
+ }
+
+ Definition* result = builder.AddDefinition(
+ new LoadIndexedInstr(new Value(str),
+ new Value(index),
+ Instance::ElementSizeFor(cid),
+ cid,
+ Thread::kNoDeoptId,
+ builder.TokenPos()));
+ builder.AddIntrinsicReturn(new Value(result));
+ return true;
+}
+
+
+bool Intrinsifier::Build_OneByteStringCodeUnitAt(FlowGraph* flow_graph) {
+ return BuildCodeUnitAt(flow_graph, kOneByteStringCid);
+}
+
+
+bool Intrinsifier::Build_TwoByteStringCodeUnitAt(FlowGraph* flow_graph) {
+ return BuildCodeUnitAt(flow_graph, kTwoByteStringCid);
+}
+
+
+bool Intrinsifier::Build_ExternalOneByteStringCodeUnitAt(
+ FlowGraph* flow_graph) {
+ return BuildCodeUnitAt(flow_graph, kExternalOneByteStringCid);
+}
+
+
+bool Intrinsifier::Build_ExternalTwoByteStringCodeUnitAt(
+ FlowGraph* flow_graph) {
+ return BuildCodeUnitAt(flow_graph, kExternalTwoByteStringCid);
+}
+
+
static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 78ab5db..e878d03 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1574,38 +1574,6 @@
}
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
- Label fall_through, try_two_byte_string;
-
- __ ldr(R1, Address(SP, 0 * kWordSize)); // Index.
- __ ldr(R0, Address(SP, 1 * kWordSize)); // String.
- __ tst(R1, Operand(kSmiTagMask));
- __ b(&fall_through, NE); // Index is not a Smi.
- // Range check.
- __ ldr(R2, FieldAddress(R0, String::length_offset()));
- __ cmp(R1, Operand(R2));
- __ b(&fall_through, CS); // Runtime throws exception.
- __ CompareClassId(R0, kOneByteStringCid, R3);
- __ b(&try_two_byte_string, NE);
- __ SmiUntag(R1);
- __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
- __ ldrb(R0, Address(R0, R1));
- __ SmiTag(R0);
- __ Ret();
-
- __ Bind(&try_two_byte_string);
- __ CompareClassId(R0, kTwoByteStringCid, R3);
- __ b(&fall_through, NE);
- ASSERT(kSmiTagShift == 1);
- __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
- __ ldrh(R0, Address(R0, R1));
- __ SmiTag(R0);
- __ Ret();
-
- __ Bind(&fall_through);
-}
-
-
void GenerateSubstringMatchesSpecialization(Assembler* assembler,
intptr_t receiver_cid,
intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index ba2a6f1..88512e8 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -1655,38 +1655,6 @@
}
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
- Label fall_through, try_two_byte_string;
-
- __ ldr(R1, Address(SP, 0 * kWordSize)); // Index.
- __ ldr(R0, Address(SP, 1 * kWordSize)); // String.
- __ tsti(R1, Immediate(kSmiTagMask));
- __ b(&fall_through, NE); // Index is not a Smi.
- // Range check.
- __ ldr(R2, FieldAddress(R0, String::length_offset()));
- __ cmp(R1, Operand(R2));
- __ b(&fall_through, CS); // Runtime throws exception.
- __ CompareClassId(R0, kOneByteStringCid);
- __ b(&try_two_byte_string, NE);
- __ SmiUntag(R1);
- __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
- __ ldr(R0, Address(R0, R1), kUnsignedByte);
- __ SmiTag(R0);
- __ ret();
-
- __ Bind(&try_two_byte_string);
- __ CompareClassId(R0, kTwoByteStringCid);
- __ b(&fall_through, NE);
- ASSERT(kSmiTagShift == 1);
- __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
- __ ldr(R0, Address(R0, R1), kUnsignedHalfword);
- __ SmiTag(R0);
- __ ret();
-
- __ Bind(&fall_through);
-}
-
-
void GenerateSubstringMatchesSpecialization(Assembler* assembler,
intptr_t receiver_cid,
intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index fd2bc9f..8dc9e99 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1718,35 +1718,6 @@
}
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
- Label fall_through, try_two_byte_string;
- __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
- __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String.
- __ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
- // Range check.
- __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
- // Runtime throws exception.
- __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
- __ CompareClassId(EAX, kOneByteStringCid, EDI);
- __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
- __ SmiUntag(EBX);
- __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
- __ SmiTag(EAX);
- __ ret();
-
- __ Bind(&try_two_byte_string);
- __ CompareClassId(EAX, kTwoByteStringCid, EDI);
- __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
- ASSERT(kSmiTagShift == 1);
- __ movzxw(EAX, FieldAddress(EAX, EBX, TIMES_1, TwoByteString::data_offset()));
- __ SmiTag(EAX);
- __ ret();
-
- __ Bind(&fall_through);
-}
-
-
// bool _substringMatches(int start, String other)
void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
// For precompilation, not implemented on IA32.
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index e98fc1d..2398a7b 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1682,41 +1682,6 @@
}
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
- Label fall_through, try_two_byte_string;
-
- __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
- __ lw(T0, Address(SP, 1 * kWordSize)); // String.
-
- // Checks.
- __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
- __ bne(CMPRES1, ZR, &fall_through); // Index is not a Smi.
- __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
- // Runtime throws exception.
- __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
- __ LoadClassId(CMPRES1, T0); // Class ID check.
- __ BranchNotEqual(
- CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
-
- // Grab byte and return.
- __ SmiUntag(T1);
- __ addu(T2, T0, T1);
- __ lbu(V0, FieldAddress(T2, OneByteString::data_offset()));
- __ Ret();
- __ delay_slot()->SmiTag(V0);
-
- __ Bind(&try_two_byte_string);
- __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
- ASSERT(kSmiTagShift == 1);
- __ addu(T2, T0, T1);
- __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset()));
- __ Ret();
- __ delay_slot()->SmiTag(V0);
-
- __ Bind(&fall_through);
-}
-
-
void GenerateSubstringMatchesSpecialization(Assembler* assembler,
intptr_t receiver_cid,
intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index ab2fa94..402613e 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1573,35 +1573,6 @@
}
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
- Label fall_through, try_two_byte_string;
- __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
- __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String.
- __ testq(RCX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
- // Range check.
- __ cmpq(RCX, FieldAddress(RAX, String::length_offset()));
- // Runtime throws exception.
- __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
- __ CompareClassId(RAX, kOneByteStringCid);
- __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
- __ SmiUntag(RCX);
- __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
- __ SmiTag(RAX);
- __ ret();
-
- __ Bind(&try_two_byte_string);
- __ CompareClassId(RAX, kTwoByteStringCid);
- __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
- ASSERT(kSmiTagShift == 1);
- __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
- __ SmiTag(RAX);
- __ ret();
-
- __ Bind(&fall_through);
-}
-
-
void GenerateSubstringMatchesSpecialization(Assembler* assembler,
intptr_t receiver_cid,
intptr_t other_cid,
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 44127c5..57fb16a 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1403,11 +1403,6 @@
void Isolate::AddClosureFunction(const Function& function) const {
- // TODO(regis): remove once debugging complete.
- if (Compiler::IsBackgroundCompilation()) {
- NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /*native*/));
- UNREACHABLE();
- }
ASSERT(!Compiler::IsBackgroundCompilation());
GrowableObjectArray& closures =
GrowableObjectArray::Handle(object_store()->closure_functions());
@@ -2635,22 +2630,26 @@
RawObject* IsolateSpawnState::ResolveFunction() {
- const String& func_name = String::Handle(String::New(function_name()));
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+
+ const String& func_name = String::Handle(zone, String::New(function_name()));
if (library_url() == NULL) {
// Handle spawnUri lookup rules.
// Check whether the root library defines a main function.
- const Library& lib = Library::Handle(I->object_store()->root_library());
- Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
+ const Library& lib = Library::Handle(zone,
+ I->object_store()->root_library());
+ Function& func = Function::Handle(zone, lib.LookupLocalFunction(func_name));
if (func.IsNull()) {
// Check whether main is reexported from the root library.
- const Object& obj = Object::Handle(lib.LookupReExport(func_name));
+ const Object& obj = Object::Handle(zone, lib.LookupReExport(func_name));
if (obj.IsFunction()) {
func ^= obj.raw();
}
}
if (func.IsNull()) {
- const String& msg = String::Handle(String::NewFormatted(
+ const String& msg = String::Handle(zone, String::NewFormatted(
"Unable to resolve function '%s' in script '%s'.",
function_name(), script_url()));
return LanguageError::New(msg);
@@ -2660,19 +2659,21 @@
// Lookup the to be spawned function for the Isolate.spawn implementation.
// Resolve the library.
- const String& lib_url = String::Handle(String::New(library_url()));
- const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
+ const String& lib_url = String::Handle(zone, String::New(library_url()));
+ const Library& lib = Library::Handle(zone,
+ Library::LookupLibrary(thread, lib_url));
if (lib.IsNull() || lib.IsError()) {
- const String& msg = String::Handle(String::NewFormatted(
+ const String& msg = String::Handle(zone, String::NewFormatted(
"Unable to find library '%s'.", library_url()));
return LanguageError::New(msg);
}
// Resolve the function.
if (class_name() == NULL) {
- const Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
+ const Function& func = Function::Handle(zone,
+ lib.LookupLocalFunction(func_name));
if (func.IsNull()) {
- const String& msg = String::Handle(String::NewFormatted(
+ const String& msg = String::Handle(zone, String::NewFormatted(
"Unable to resolve function '%s' in library '%s'.",
function_name(), library_url()));
return LanguageError::New(msg);
@@ -2680,19 +2681,19 @@
return func.raw();
}
- const String& cls_name = String::Handle(String::New(class_name()));
- const Class& cls = Class::Handle(lib.LookupLocalClass(cls_name));
+ const String& cls_name = String::Handle(zone, String::New(class_name()));
+ const Class& cls = Class::Handle(zone, lib.LookupLocalClass(cls_name));
if (cls.IsNull()) {
- const String& msg = String::Handle(String::NewFormatted(
+ const String& msg = String::Handle(zone, String::NewFormatted(
"Unable to resolve class '%s' in library '%s'.",
class_name(),
(library_url() != NULL ? library_url() : script_url())));
return LanguageError::New(msg);
}
const Function& func =
- Function::Handle(cls.LookupStaticFunctionAllowPrivate(func_name));
+ Function::Handle(zone, cls.LookupStaticFunctionAllowPrivate(func_name));
if (func.IsNull()) {
- const String& msg = String::Handle(String::NewFormatted(
+ const String& msg = String::Handle(zone, String::NewFormatted(
"Unable to resolve static method '%s.%s' in library '%s'.",
class_name(), function_name(),
(library_url() != NULL ? library_url() : script_url())));
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index b0be614..f4d8757 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -755,7 +755,7 @@
return false;
}
} else {
- return d->IsStringFromCharCode();
+ return d->IsOneByteStringFromCharCode();
}
}
@@ -789,9 +789,10 @@
ConstantInstr* char_code_left = flow_graph()->GetConstant(
Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
left_val = new(Z) Value(char_code_left);
- } else if (left->IsStringFromCharCode()) {
+ } else if (left->IsOneByteStringFromCharCode()) {
// Use input of string-from-charcode as left value.
- StringFromCharCodeInstr* instr = left->AsStringFromCharCode();
+ OneByteStringFromCharCodeInstr* instr =
+ left->AsOneByteStringFromCharCode();
left_val = new(Z) Value(instr->char_code()->definition());
to_remove_left = instr;
} else {
@@ -801,9 +802,10 @@
Definition* to_remove_right = NULL;
Value* right_val = NULL;
- if (right->IsStringFromCharCode()) {
+ if (right->IsOneByteStringFromCharCode()) {
// Skip string-from-char-code, and use its input as right value.
- StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode();
+ OneByteStringFromCharCodeInstr* right_instr =
+ right->AsOneByteStringFromCharCode();
right_val = new(Z) Value(right_instr->char_code()->definition());
to_remove_right = right_instr;
} else {
@@ -1764,11 +1766,24 @@
return true;
}
- if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
- (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
- (ic_data.NumberOfChecks() == 1) &&
- ((class_ids[0] == kOneByteStringCid) ||
- (class_ids[0] == kTwoByteStringCid))) {
+ if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+ ASSERT(ic_data.NumberOfChecks() == 1);
+ ASSERT((class_ids[0] == kOneByteStringCid) ||
+ (class_ids[0] == kTwoByteStringCid) ||
+ (class_ids[0] == kExternalOneByteStringCid) ||
+ (class_ids[0] == kExternalTwoByteStringCid));
+ return TryReplaceInstanceCallWithInline(call);
+ }
+
+ if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
+ (ic_data.NumberOfChecks() == 1)) {
+ ASSERT((class_ids[0] == kOneByteStringCid) ||
+ (class_ids[0] == kTwoByteStringCid) ||
+ (class_ids[0] == kExternalOneByteStringCid) ||
+ (class_ids[0] == kExternalTwoByteStringCid));
return TryReplaceInstanceCallWithInline(call);
}
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index b793d35..3a55d5a 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -76,6 +76,8 @@
function.set_is_debuggable(false);
function.set_is_visible(false);
function.AttachCode(code);
+ // For inclusion in Snapshot::kAppWithJIT.
+ function.set_unoptimized_code(code);
isolate->object_store()->SetMegamorphicMissHandler(code, function);
}
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index a3e0eda..9ed5848 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -16,38 +16,38 @@
V(::, identical, ObjectIdentical, 317103244) \
V(ClassID, getID, ClassIDgetID, 1385157717) \
V(Object, Object., ObjectConstructor, 1746278398) \
- V(_List, ., ObjectArrayAllocate, 184405219) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 187609847) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1826086346) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1174755987) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1936358273) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 1123951931) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 853172551) \
- V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 1115954619) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 165422183) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1564825450) \
- V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1123952315) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 831892409) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 2043203289) \
- V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1759261408) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 267848339) \
- V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 350952121) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1170619358) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1325523969) \
- V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 935451230) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 541136999) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 365317124) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1766802707) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 2075229300) \
- V(_StringBase, _interpolate, StringBaseInterpolate, 1597087225) \
- V(_IntegerImplementation, toDouble, IntegerToDouble, 150718448) \
- V(_Double, _add, DoubleAdd, 1190606283) \
- V(_Double, _sub, DoubleSub, 1086286468) \
- V(_Double, _mul, DoubleMul, 166332351) \
- V(_Double, _div, DoubleDiv, 821396195) \
+ V(_List, ., ObjectArrayAllocate, 1661438741) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480) \
+ V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 1639388276) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744) \
+ V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1328908284) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1694054572) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336) \
+ V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 1970687707) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324) \
+ V(_StringBase, _interpolate, StringBaseInterpolate, 1872292681) \
+ V(_IntegerImplementation, toDouble, IntegerToDouble, 792762465) \
+ V(_Double, _add, DoubleAdd, 2213216) \
+ V(_Double, _sub, DoubleSub, 1100692582) \
+ V(_Double, _mul, DoubleMul, 436784097) \
+ V(_Double, _div, DoubleDiv, 953317135) \
V(::, min, MathMin, 1115051548) \
V(::, max, MathMax, 1410473322) \
- V(::, _doublePow, MathDoublePow, 562154128) \
+ V(::, _doublePow, MathDoublePow, 1770960781) \
V(Float32x4, Float32x4., Float32x4Constructor, 93751705) \
V(Float32x4, Float32x4.zero, Float32x4Zero, 1193954374) \
V(Float32x4, Float32x4.splat, Float32x4Splat, 12296613) \
@@ -56,21 +56,21 @@
V(Float32x4, shuffle, Float32x4Shuffle, 2015957023) \
V(Float32x4, shuffleMix, Float32x4ShuffleMix, 1099087979) \
V(Float32x4, get:signMask, Float32x4GetSignMask, 487049875) \
- V(Float32x4, _cmpequal, Float32x4Equal, 1069901308) \
- V(Float32x4, _cmpgt, Float32x4GreaterThan, 2112381651) \
- V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 1088241265) \
- V(Float32x4, _cmplt, Float32x4LessThan, 2001171012) \
- V(Float32x4, _cmplte, Float32x4LessThanOrEqual, 1568686387) \
- V(Float32x4, _cmpnequal, Float32x4NotEqual, 1833412828) \
- V(Float32x4, _min, Float32x4Min, 1194113943) \
- V(Float32x4, _max, Float32x4Max, 1876936155) \
- V(Float32x4, _scale, Float32x4Scale, 1176743640) \
- V(Float32x4, _sqrt, Float32x4Sqrt, 526238610) \
- V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 860560177) \
- V(Float32x4, _reciprocal, Float32x4Reciprocal, 1703468100) \
- V(Float32x4, _negate, Float32x4Negate, 1409902640) \
- V(Float32x4, _abs, Float32x4Absolute, 2116840471) \
- V(Float32x4, _clamp, Float32x4Clamp, 1789892357) \
+ V(Float32x4, _cmpequal, Float32x4Equal, 127403211) \
+ V(Float32x4, _cmpgt, Float32x4GreaterThan, 2118391173) \
+ V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 557807661) \
+ V(Float32x4, _cmplt, Float32x4LessThan, 1061691185) \
+ V(Float32x4, _cmplte, Float32x4LessThanOrEqual, 102608993) \
+ V(Float32x4, _cmpnequal, Float32x4NotEqual, 1873649982) \
+ V(Float32x4, _min, Float32x4Min, 1158016632) \
+ V(Float32x4, _max, Float32x4Max, 118915526) \
+ V(Float32x4, _scale, Float32x4Scale, 415757469) \
+ V(Float32x4, _sqrt, Float32x4Sqrt, 1934518992) \
+ V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 1586141174) \
+ V(Float32x4, _reciprocal, Float32x4Reciprocal, 1651466502) \
+ V(Float32x4, _negate, Float32x4Negate, 2142478676) \
+ V(Float32x4, _abs, Float32x4Absolute, 337704007) \
+ V(Float32x4, _clamp, Float32x4Clamp, 1107305005) \
V(Float32x4, withX, Float32x4WithX, 1311992575) \
V(Float32x4, withY, Float32x4WithY, 175290640) \
V(Float32x4, withZ, Float32x4WithZ, 837367384) \
@@ -81,7 +81,7 @@
V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, 792974246) \
V(Float64x2, get:x, Float64x2GetX, 1488958362) \
V(Float64x2, get:y, Float64x2GetY, 1022688506) \
- V(Float64x2, _negate, Float64x2Negate, 960840275) \
+ V(Float64x2, _negate, Float64x2Negate, 1693416311) \
V(Float64x2, abs, Float64x2Abs, 52403783) \
V(Float64x2, sqrt, Float64x2Sqrt, 2012680669) \
V(Float64x2, get:signMask, Float64x2GetSignMask, 668856717) \
@@ -100,48 +100,48 @@
V(Int32x4, get:signMask, Int32x4GetSignMask, 740215269) \
V(Int32x4, shuffle, Int32x4Shuffle, 549194518) \
V(Int32x4, shuffleMix, Int32x4ShuffleMix, 1550866145) \
- V(Int32x4, select, Int32x4Select, 614943686) \
+ V(Int32x4, select, Int32x4Select, 1368318775) \
V(Int32x4, withFlagX, Int32x4WithFlagX, 250974159) \
V(Int32x4, withFlagY, Int32x4WithFlagY, 1686481348) \
V(Int32x4, withFlagZ, Int32x4WithFlagZ, 645582330) \
V(Int32x4, withFlagW, Int32x4WithFlagW, 878364277) \
- V(Float32List, [], Float32ArrayGetIndexed, 1002307136) \
- V(Float32List, []=, Float32ArraySetIndexed, 279546769) \
- V(Int8List, [], Int8ArrayGetIndexed, 1141846285) \
- V(Int8List, []=, Int8ArraySetIndexed, 1486839324) \
- V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 513704632) \
- V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 1015846567) \
+ V(Float32List, [], Float32ArrayGetIndexed, 1451643535) \
+ V(Float32List, []=, Float32ArraySetIndexed, 453873887) \
+ V(Int8List, [], Int8ArrayGetIndexed, 110819507) \
+ V(Int8List, []=, Int8ArraySetIndexed, 865684695) \
+ V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685) \
+ V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488) \
V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed, \
- 513704632) \
+ 41288685) \
V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed, \
- 1015846567) \
- V(Int16List, [], Int16ArrayGetIndexed, 1826359619) \
- V(Int16List, []=, Int16ArraySetIndexed, 1108689116) \
- V(Uint16List, [], Uint16ArrayGetIndexed, 118958722) \
- V(Uint16List, []=, Uint16ArraySetIndexed, 658824450) \
- V(Int32List, [], Int32ArrayGetIndexed, 681203163) \
- V(Int32List, []=, Int32ArraySetIndexed, 1786886245) \
- V(Int64List, [], Int64ArrayGetIndexed, 1883155004) \
- V(Int64List, []=, Int64ArraySetIndexed, 905815059) \
- V(Float32x4List, [], Float32x4ArrayGetIndexed, 694822356) \
- V(Float32x4List, []=, Float32x4ArraySetIndexed, 1166109127) \
- V(Int32x4List, [], Int32x4ArrayGetIndexed, 668249259) \
- V(Int32x4List, []=, Int32x4ArraySetIndexed, 654739449) \
- V(Float64x2List, [], Float64x2ArrayGetIndexed, 196472005) \
- V(Float64x2List, []=, Float64x2ArraySetIndexed, 1421858500) \
- V(_Bigint, get:_neg, Bigint_getNeg, 1681019799) \
- V(_Bigint, get:_used, Bigint_getUsed, 1439136438) \
- V(_Bigint, get:_digits, Bigint_getDigits, 769722770) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2048715833) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1882796480) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, 942992497) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, 1410623019) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 1698421819) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1858754514) \
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 98745045) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 340628211) \
- V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 1340385546) \
- V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 638315987) \
+ 687206488) \
+ V(Int16List, [], Int16ArrayGetIndexed, 389863073) \
+ V(Int16List, []=, Int16ArraySetIndexed, 855133756) \
+ V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567) \
+ V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961) \
+ V(Int32List, [], Int32ArrayGetIndexed, 640610057) \
+ V(Int32List, []=, Int32ArraySetIndexed, 453358705) \
+ V(Int64List, [], Int64ArrayGetIndexed, 202150810) \
+ V(Int64List, []=, Int64ArraySetIndexed, 924110852) \
+ V(Float32x4List, [], Float32x4ArrayGetIndexed, 29819259) \
+ V(Float32x4List, []=, Float32x4ArraySetIndexed, 1458062250) \
+ V(Int32x4List, [], Int32x4ArrayGetIndexed, 137707405) \
+ V(Int32x4List, []=, Int32x4ArraySetIndexed, 496650149) \
+ V(Float64x2List, [], Float64x2ArrayGetIndexed, 1721439384) \
+ V(Float64x2List, []=, Float64x2ArraySetIndexed, 1994027006) \
+ V(_Bigint, get:_neg, Bigint_getNeg, 2079423063) \
+ V(_Bigint, get:_used, Bigint_getUsed, 1426329619) \
+ V(_Bigint, get:_digits, Bigint_getDigits, 1185333683) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812) \
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630) \
+ V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585) \
+ V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010) \
// List of intrinsics:
@@ -149,94 +149,94 @@
#define CORE_LIB_INTRINSIC_LIST(V) \
V(_Smi, ~, Smi_bitNegate, 1673522705) \
V(_Smi, get:bitLength, Smi_bitLength, 632480332) \
- V(_Bigint, _lsh, Bigint_lsh, 834311957) \
- V(_Bigint, _rsh, Bigint_rsh, 333337658) \
- V(_Bigint, _absAdd, Bigint_absAdd, 473436659) \
- V(_Bigint, _absSub, Bigint_absSub, 1018678324) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, 571005736) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, 372896038) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 540033329) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, 118781828) \
- V(_Double, >, Double_greaterThan, 1413076759) \
+ V(_Bigint, _lsh, Bigint_lsh, 1557746963) \
+ V(_Bigint, _rsh, Bigint_rsh, 761843937) \
+ V(_Bigint, _absAdd, Bigint_absAdd, 1227835493) \
+ V(_Bigint, _absSub, Bigint_absSub, 390740532) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219) \
+ V(_Double, >, Double_greaterThan, 1453001345) \
V(_Double, >=, Double_greaterEqualThan, 1815180096) \
V(_Double, <, Double_lessThan, 652059836) \
V(_Double, <=, Double_lessEqualThan, 512138528) \
- V(_Double, ==, Double_equal, 752327620) \
- V(_Double, +, Double_add, 854024064) \
- V(_Double, -, Double_sub, 685132889) \
- V(_Double, *, Double_mul, 542254390) \
- V(_Double, /, Double_div, 1145710768) \
+ V(_Double, ==, Double_equal, 1468668497) \
+ V(_Double, +, Double_add, 1269587413) \
+ V(_Double, -, Double_sub, 1644506555) \
+ V(_Double, *, Double_mul, 600860888) \
+ V(_Double, /, Double_div, 1220198876) \
V(_Double, get:isNaN, Double_getIsNaN, 184085483) \
V(_Double, get:isNegative, Double_getIsNegative, 978911030) \
- V(_Double, _mulFromInteger, Double_mulFromInteger, 543831179) \
- V(_Double, .fromInteger, DoubleFromInteger, 1453449234) \
+ V(_Double, _mulFromInteger, Double_mulFromInteger, 1893886883) \
+ V(_Double, .fromInteger, DoubleFromInteger, 2129942595) \
V(_List, []=, ObjectArraySetIndexed, 886228780) \
- V(_GrowableList, .withData, GrowableArray_Allocate, 131424500) \
- V(_GrowableList, add, GrowableArray_add, 242296201) \
- V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 2077783530) \
+ V(_GrowableList, .withData, GrowableArray_Allocate, 631736030) \
+ V(_GrowableList, add, GrowableArray_add, 219371757) \
+ V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 1614206970) \
V(Object, ==, ObjectEquals, 291909336) \
V(Object, get:runtimeType, ObjectRuntimeType, 15188587) \
V(_StringBase, get:hashCode, String_getHashCode, 2026040200) \
V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1958879178) \
- V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1436590579) \
- V(_StringBase, _substringMatches, StringBaseSubstringMatches, 1548648995) \
+ V(_StringBase, _substringMatches, StringBaseSubstringMatches, 797253099) \
V(_StringBase, [], StringBaseCharAt, 754527301) \
V(_OneByteString, get:hashCode, OneByteString_getHashCode, 2026040200) \
V(_OneByteString, _substringUncheckedNative, \
- OneByteString_substringUnchecked, 2063670029) \
- V(_OneByteString, _setAt, OneByteStringSetAt, 929822971) \
- V(_OneByteString, _allocate, OneByteString_allocate, 1737851380) \
+ OneByteString_substringUnchecked, 1670133538) \
+ V(_OneByteString, _setAt, OneByteStringSetAt, 1160066031) \
+ V(_OneByteString, _allocate, OneByteString_allocate, 1028631946) \
V(_OneByteString, ==, OneByteString_equality, 1062844160) \
V(_TwoByteString, ==, TwoByteString_equality, 1062844160) \
#define CORE_INTEGER_LIB_INTRINSIC_LIST(V) \
- V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 298045644)\
- V(_IntegerImplementation, +, Integer_add, 364498398) \
- V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 422157928)\
- V(_IntegerImplementation, -, Integer_sub, 1682674911) \
+ V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, \
+ 2042488139) \
+ V(_IntegerImplementation, +, Integer_add, 239272130) \
+ V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 957923759)\
+ V(_IntegerImplementation, -, Integer_sub, 216175811) \
V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, \
- 2074733333) \
- V(_IntegerImplementation, *, Integer_mul, 1651115456) \
+ 2032062140) \
+ V(_IntegerImplementation, *, Integer_mul, 1301152164) \
V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger, \
- 2100319763) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 108494012) \
+ 779285842) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256) \
V(_IntegerImplementation, unary-, Integer_negate, 1507648892) \
V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger, \
- 363854564) \
- V(_IntegerImplementation, &, Integer_bitAnd, 286231290) \
+ 503046514) \
+ V(_IntegerImplementation, &, Integer_bitAnd, 1500136766) \
V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger, \
- 1623085924) \
- V(_IntegerImplementation, |, Integer_bitOr, 1111108792) \
+ 1031383580) \
+ V(_IntegerImplementation, |, Integer_bitOr, 119412028) \
V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger, \
- 140783758) \
- V(_IntegerImplementation, ^, Integer_bitXor, 1884808537) \
+ 1339506501) \
+ V(_IntegerImplementation, ^, Integer_bitXor, 210430781) \
V(_IntegerImplementation, _greaterThanFromInteger, \
- Integer_greaterThanFromInt, 814932166) \
- V(_IntegerImplementation, >, Integer_greaterThan, 293890061) \
- V(_IntegerImplementation, ==, Integer_equal, 4489308) \
+ Integer_greaterThanFromInt, 780147656) \
+ V(_IntegerImplementation, >, Integer_greaterThan, 673741711) \
+ V(_IntegerImplementation, ==, Integer_equal, 272474439) \
V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, \
- 1818326386) \
+ 2004079901) \
V(_IntegerImplementation, <, Integer_lessThan, 652059836) \
V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528) \
V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096) \
- V(_IntegerImplementation, <<, Integer_shl, 293751452) \
- V(_IntegerImplementation, >>, Integer_sar, 125091101) \
+ V(_IntegerImplementation, <<, Integer_shl, 1127538624) \
+ V(_IntegerImplementation, >>, Integer_sar, 1243972513) \
V(_Double, toInt, DoubleToInteger, 653210699)
#define MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sqrt, MathSqrt, 1446681622) \
- V(_Random, _nextState, Random_nextState, 1241583299) \
+ V(::, sqrt, MathSqrt, 417912310) \
+ V(_Random, _nextState, Random_nextState, 508231939) \
#define GRAPH_MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sin, MathSin, 939048573) \
- V(::, cos, MathCos, 1148850331) \
- V(::, tan, MathTan, 179725235) \
- V(::, asin, MathAsin, 848695059) \
- V(::, acos, MathAcos, 337299516) \
- V(::, atan, MathAtan, 866406810) \
- V(::, atan2, MathAtan2, 1901969510) \
+ V(::, sin, MathSin, 65032) \
+ V(::, cos, MathCos, 2006233918) \
+ V(::, tan, MathTan, 1276867325) \
+ V(::, asin, MathAsin, 1678592173) \
+ V(::, acos, MathAcos, 1121218433) \
+ V(::, atan, MathAtan, 1109653625) \
+ V(::, atan2, MathAtan2, 894696289) \
#define TYPED_DATA_LIB_INTRINSIC_LIST(V) \
V(Int8List, ., TypedData_Int8Array_factory, 779569635) \
@@ -255,22 +255,22 @@
V(Float64x2List, ., TypedData_Float64x2Array_factory, 416019673) \
#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
- V(Uint8List, [], Uint8ArrayGetIndexed, 513704632) \
- V(Uint8List, []=, Uint8ArraySetIndexed, 2123520783) \
- V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 513704632) \
- V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 2123520783) \
- V(Uint32List, [], Uint32ArrayGetIndexed, 1179675338) \
- V(Uint32List, []=, Uint32ArraySetIndexed, 1455695417) \
- V(Float64List, []=, Float64ArraySetIndexed, 1929239576) \
- V(Float64List, [], Float64ArrayGetIndexed, 816943529) \
+ V(Uint8List, [], Uint8ArrayGetIndexed, 41288685) \
+ V(Uint8List, []=, Uint8ArraySetIndexed, 101536342) \
+ V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 41288685) \
+ V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 101536342) \
+ V(Uint32List, [], Uint32ArrayGetIndexed, 1614870523) \
+ V(Uint32List, []=, Uint32ArraySetIndexed, 978194713) \
+ V(Float64List, []=, Float64ArraySetIndexed, 328934501) \
+ V(Float64List, [], Float64ArrayGetIndexed, 2049378701) \
V(_TypedList, get:length, TypedDataLength, 546364442) \
V(Float32x4, get:x, Float32x4ShuffleX, 1674625343) \
V(Float32x4, get:y, Float32x4ShuffleY, 540293915) \
V(Float32x4, get:z, Float32x4ShuffleZ, 320347578) \
V(Float32x4, get:w, Float32x4ShuffleW, 1770606624) \
- V(Float32x4, _mul, Float32x4Mul, 861549065) \
- V(Float32x4, _sub, Float32x4Sub, 460363214) \
- V(Float32x4, _add, Float32x4Add, 1487592255) \
+ V(Float32x4, _mul, Float32x4Mul, 42807622) \
+ V(Float32x4, _sub, Float32x4Sub, 103774455) \
+ V(Float32x4, _add, Float32x4Add, 1352634374) \
#define GRAPH_CORE_INTRINSICS_LIST(V) \
V(_List, get:length, ObjectArrayLength, 630471378) \
@@ -278,18 +278,24 @@
V(_ImmutableList, get:length, ImmutableArrayLength, 630471378) \
V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496) \
V(_GrowableList, get:length, GrowableArrayLength, 417111542) \
- V(_GrowableList, get:_capacity, GrowableArrayCapacity, 193746510) \
- V(_GrowableList, _setData, GrowableArraySetData, 1496536873) \
- V(_GrowableList, _setLength, GrowableArraySetLength, 32203572) \
+ V(_GrowableList, get:_capacity, GrowableArrayCapacity, 41110914) \
+ V(_GrowableList, _setData, GrowableArraySetData, 210059283) \
+ V(_GrowableList, _setLength, GrowableArraySetLength, 335652822) \
V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650) \
V(_GrowableList, []=, GrowableArraySetIndexed, 225246870) \
V(_StringBase, get:length, StringBaseLength, 707533587) \
+ V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 1436590579) \
+ V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 1436590579) \
+ V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt, \
+ 1436590579) \
+ V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt, \
+ 1436590579) \
V(_Double, unary-, DoubleFlipSignBit, 1783281169) \
V(_Double, truncateToDouble, DoubleTruncate, 791143891) \
V(_Double, roundToDouble, DoubleRound, 797558034) \
V(_Double, floorToDouble, DoubleFloor, 1789426271) \
V(_Double, ceilToDouble, DoubleCeil, 453271198) \
- V(_Double, _modulo, DoubleMod, 1093862165)
+ V(_Double, _modulo, DoubleMod, 776062204)
#define GRAPH_INTRINSICS_LIST(V) \
@@ -299,8 +305,8 @@
#define DEVELOPER_LIB_INTRINSIC_LIST(V) \
V(_UserTag, makeCurrent, UserTag_makeCurrent, 187721469) \
- V(::, _getDefaultTag, UserTag_defaultTag, 1872263331) \
- V(::, _getCurrentTag, Profiler_getCurrentTag, 692104531) \
+ V(::, _getDefaultTag, UserTag_defaultTag, 350077879) \
+ V(::, _getCurrentTag, Profiler_getCurrentTag, 1215225901) \
#define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V) \
CORE_LIB_INTRINSIC_LIST(V) \
@@ -324,154 +330,153 @@
V(_ImmutableList, get:length, ImmutableArrayLength, 630471378) \
V(_TypedList, get:length, TypedDataLength, 546364442) \
V(_GrowableList, get:length, GrowableArrayLength, 417111542) \
- V(_GrowableList, add, GrowableListAdd, 242296201) \
- V(_GrowableList, removeLast, GrowableListRemoveLast, 1655383014) \
+ V(_GrowableList, add, GrowableListAdd, 219371757) \
+ V(_GrowableList, removeLast, GrowableListRemoveLast, 324891524) \
V(_StringBase, get:length, StringBaseLength, 707533587) \
- V(ListIterator, moveNext, ListIteratorMoveNext, 1467737539) \
- V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 784200630) \
+ V(ListIterator, moveNext, ListIteratorMoveNext, 1065954929) \
+ V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 1451346178) \
V(_GrowableList, get:iterator, GrowableArrayIterator, 1840323187) \
V(_GrowableList, forEach, GrowableArrayForEach, 620771070) \
- V(_List, ., ObjectArrayAllocate, 184405219) \
+ V(_List, ., ObjectArrayAllocate, 1661438741) \
V(_List, [], ObjectArrayGetIndexed, 360400496) \
V(_List, []=, ObjectArraySetIndexed, 886228780) \
V(ListMixin, get:isEmpty, ListMixinIsEmpty, 2021497798) \
- V(_List, get:iterator, ObjectArrayIterator, 1930956161) \
+ V(_List, get:iterator, ObjectArrayIterator, 295498778) \
V(_List, forEach, ObjectArrayForEach, 180150673) \
- V(_List, _slice, ObjectArraySlice, 1785552519) \
- V(_ImmutableList, get:iterator, ImmutableArrayIterator, 1930956161) \
+ V(_List, _slice, ObjectArraySlice, 840558357) \
+ V(_ImmutableList, get:iterator, ImmutableArrayIterator, 295498778) \
V(_ImmutableList, forEach, ImmutableArrayForEach, 180150673) \
V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496) \
V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650) \
V(_GrowableList, []=, GrowableArraySetIndexed, 225246870) \
- V(Float32List, [], Float32ArrayGetIndexed, 1002307136) \
- V(Float32List, []=, Float32ArraySetIndexed, 279546769) \
- V(Float64List, [], Float64ArrayGetIndexed, 816943529) \
- V(Float64List, []=, Float64ArraySetIndexed, 1929239576) \
- V(Int8List, [], Int8ArrayGetIndexed, 1141846285) \
- V(Int8List, []=, Int8ArraySetIndexed, 1486839324) \
- V(Uint8List, [], Uint8ArrayGetIndexed, 513704632) \
- V(Uint8List, []=, Uint8ArraySetIndexed, 2123520783) \
- V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 513704632) \
- V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 1015846567) \
- V(Uint16List, [], Uint16ArrayGetIndexed, 118958722) \
- V(Uint16List, []=, Uint16ArraySetIndexed, 658824450) \
- V(Int16List, [], Int16ArrayGetIndexed, 1826359619) \
- V(Int16List, []=, Int16ArraySetIndexed, 1108689116) \
- V(Int32List, [], Int32ArrayGetIndexed, 681203163) \
- V(Int32List, []=, Int32ArraySetIndexed, 1786886245) \
- V(Int64List, [], Int64ArrayGetIndexed, 1883155004) \
- V(Int64List, []=, Int64ArraySetIndexed, 905815059) \
- V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 215420949) \
- V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 1138146450) \
- V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 1003520035) \
- V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 225448326) \
- V(_ByteDataView, setInt8, ByteDataViewSetInt8, 1091734252) \
- V(_ByteDataView, setUint8, ByteDataViewSetUint8, 549773093) \
- V(_ByteDataView, setInt16, ByteDataViewSetInt16, 1580120352) \
- V(_ByteDataView, setUint16, ByteDataViewSetUint16, 948267909) \
- V(_ByteDataView, setInt32, ByteDataViewSetInt32, 2088513508) \
- V(_ByteDataView, setUint32, ByteDataViewSetUint32, 1125319) \
- V(_ByteDataView, setInt64, ByteDataViewSetInt64, 192928709) \
- V(_ByteDataView, setUint64, ByteDataViewSetUint64, 483118836) \
- V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1241910514) \
- V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1950485343) \
- V(_ByteDataView, getInt8, ByteDataViewGetInt8, 1939363561) \
- V(_ByteDataView, getUint8, ByteDataViewGetUint8, 121087953) \
- V(_ByteDataView, getInt16, ByteDataViewGetInt16, 591911343) \
- V(_ByteDataView, getUint16, ByteDataViewGetUint16, 2114157459) \
- V(_ByteDataView, getInt32, ByteDataViewGetInt32, 712570242) \
- V(_ByteDataView, getUint32, ByteDataViewGetUint32, 162058988) \
- V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1566486016) \
- V(_ByteDataView, getUint64, ByteDataViewGetUint64, 1397980812) \
- V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 1251636679) \
- V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 1940177769) \
- V(::, asin, MathASin, 848695059) \
- V(::, acos, MathACos, 337299516) \
- V(::, atan, MathATan, 866406810) \
- V(::, atan2, MathATan2, 1901969510) \
- V(::, cos, MathCos, 1148850331) \
- V(::, exp, MathExp, 1006863255) \
- V(::, log, MathLog, 817988874) \
+ V(Float32List, [], Float32ArrayGetIndexed, 1451643535) \
+ V(Float32List, []=, Float32ArraySetIndexed, 453873887) \
+ V(Float64List, [], Float64ArrayGetIndexed, 2049378701) \
+ V(Float64List, []=, Float64ArraySetIndexed, 328934501) \
+ V(Int8List, [], Int8ArrayGetIndexed, 110819507) \
+ V(Int8List, []=, Int8ArraySetIndexed, 865684695) \
+ V(Uint8List, [], Uint8ArrayGetIndexed, 41288685) \
+ V(Uint8List, []=, Uint8ArraySetIndexed, 101536342) \
+ V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685) \
+ V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488) \
+ V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567) \
+ V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961) \
+ V(Int16List, [], Int16ArrayGetIndexed, 389863073) \
+ V(Int16List, []=, Int16ArraySetIndexed, 855133756) \
+ V(Int32List, [], Int32ArrayGetIndexed, 640610057) \
+ V(Int32List, []=, Int32ArraySetIndexed, 453358705) \
+ V(Int64List, [], Int64ArrayGetIndexed, 202150810) \
+ V(Int64List, []=, Int64ArraySetIndexed, 924110852) \
+ V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 1338422227) \
+ V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 540212720) \
+ V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 302213458) \
+ V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 1837635160) \
+ V(_ByteDataView, setInt8, ByteDataViewSetInt8, 660389322) \
+ V(_ByteDataView, setUint8, ByteDataViewSetUint8, 1651986039) \
+ V(_ByteDataView, setInt16, ByteDataViewSetInt16, 2051262146) \
+ V(_ByteDataView, setUint16, ByteDataViewSetUint16, 1692244111) \
+ V(_ByteDataView, setInt32, ByteDataViewSetInt32, 862135882) \
+ V(_ByteDataView, setUint32, ByteDataViewSetUint32, 361732249) \
+ V(_ByteDataView, setInt64, ByteDataViewSetInt64, 1208972197) \
+ V(_ByteDataView, setUint64, ByteDataViewSetUint64, 1545853836) \
+ V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1333183642) \
+ V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1579015503) \
+ V(_ByteDataView, getInt8, ByteDataViewGetInt8, 29018237) \
+ V(_ByteDataView, getUint8, ByteDataViewGetUint8, 312322868) \
+ V(_ByteDataView, getInt16, ByteDataViewGetInt16, 1613243255) \
+ V(_ByteDataView, getUint16, ByteDataViewGetUint16, 284020105) \
+ V(_ByteDataView, getInt32, ByteDataViewGetInt32, 2036535169) \
+ V(_ByteDataView, getUint32, ByteDataViewGetUint32, 571293096) \
+ V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1971181000) \
+ V(_ByteDataView, getUint64, ByteDataViewGetUint64, 799775022) \
+ V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 947822534) \
+ V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 1402356525) \
+ V(::, asin, MathASin, 1678592173) \
+ V(::, acos, MathACos, 1121218433) \
+ V(::, atan, MathATan, 1109653625) \
+ V(::, atan2, MathATan2, 894696289) \
+ V(::, cos, MathCos, 2006233918) \
+ V(::, exp, MathExp, 1500946333) \
+ V(::, log, MathLog, 739403086) \
V(::, max, MathMax, 1410473322) \
V(::, min, MathMin, 1115051548) \
- V(::, pow, MathPow, 864430827) \
- V(::, sin, MathSin, 939048573) \
- V(::, sqrt, MathSqrt, 1446681622) \
- V(::, tan, MathTan, 179725235) \
+ V(::, pow, MathPow, 2058759335) \
+ V(::, sin, MathSin, 65032) \
+ V(::, sqrt, MathSqrt, 417912310) \
+ V(::, tan, MathTan, 1276867325) \
V(Lists, copy, ListsCopy, 564237562) \
- V(_Bigint, get:_neg, Bigint_getNeg, 1681019799) \
- V(_Bigint, get:_used, Bigint_getUsed, 1439136438) \
- V(_Bigint, get:_digits, Bigint_getDigits, 769722770) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2048715833) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1882796480) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, 942992497) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, 1410623019) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 1698421819) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1858754514) \
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 98745045) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 340628211) \
- V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 1340385546) \
- V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 638315987) \
+ V(_Bigint, get:_neg, Bigint_getNeg, 2079423063) \
+ V(_Bigint, get:_used, Bigint_getUsed, 1426329619) \
+ V(_Bigint, get:_digits, Bigint_getDigits, 1185333683) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812) \
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630) \
+ V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585) \
+ V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010) \
// A list of core function that should never be inlined.
#define INLINE_BLACK_LIST(V) \
- V(_Bigint, _lsh, Bigint_lsh, 834311957) \
- V(_Bigint, _rsh, Bigint_rsh, 333337658) \
- V(_Bigint, _absAdd, Bigint_absAdd, 473436659) \
- V(_Bigint, _absSub, Bigint_absSub, 1018678324) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, 571005736) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, 372896038) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 540033329) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, 118781828) \
- V(_Double, >, Double_greaterThan, 1413076759) \
+ V(_Bigint, _lsh, Bigint_lsh, 1557746963) \
+ V(_Bigint, _rsh, Bigint_rsh, 761843937) \
+ V(_Bigint, _absAdd, Bigint_absAdd, 1227835493) \
+ V(_Bigint, _absSub, Bigint_absSub, 390740532) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219) \
+ V(_Double, >, Double_greaterThan, 1453001345) \
V(_Double, >=, Double_greaterEqualThan, 1815180096) \
V(_Double, <, Double_lessThan, 652059836) \
V(_Double, <=, Double_lessEqualThan, 512138528) \
- V(_Double, ==, Double_equal, 752327620) \
- V(_Double, +, Double_add, 854024064) \
- V(_Double, -, Double_sub, 685132889) \
- V(_Double, *, Double_mul, 542254390) \
- V(_Double, /, Double_div, 1145710768) \
- V(_IntegerImplementation, +, Integer_add, 364498398) \
- V(_IntegerImplementation, -, Integer_sub, 1682674911) \
- V(_IntegerImplementation, *, Integer_mul, 1651115456) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 108494012) \
+ V(_Double, ==, Double_equal, 1468668497) \
+ V(_Double, +, Double_add, 1269587413) \
+ V(_Double, -, Double_sub, 1644506555) \
+ V(_Double, *, Double_mul, 600860888) \
+ V(_Double, /, Double_div, 1220198876) \
+ V(_IntegerImplementation, +, Integer_add, 239272130) \
+ V(_IntegerImplementation, -, Integer_sub, 216175811) \
+ V(_IntegerImplementation, *, Integer_mul, 1301152164) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256) \
V(_IntegerImplementation, unary-, Integer_negate, 1507648892) \
- V(_IntegerImplementation, &, Integer_bitAnd, 286231290) \
- V(_IntegerImplementation, |, Integer_bitOr, 1111108792) \
- V(_IntegerImplementation, ^, Integer_bitXor, 1884808537) \
- V(_IntegerImplementation, >, Integer_greaterThan, 293890061) \
- V(_IntegerImplementation, ==, Integer_equal, 4489308) \
+ V(_IntegerImplementation, &, Integer_bitAnd, 1500136766) \
+ V(_IntegerImplementation, |, Integer_bitOr, 119412028) \
+ V(_IntegerImplementation, ^, Integer_bitXor, 210430781) \
+ V(_IntegerImplementation, >, Integer_greaterThan, 673741711) \
+ V(_IntegerImplementation, ==, Integer_equal, 272474439) \
V(_IntegerImplementation, <, Integer_lessThan, 652059836) \
V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528) \
V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096) \
- V(_IntegerImplementation, <<, Integer_shl, 293751452) \
- V(_IntegerImplementation, >>, Integer_sar, 125091101) \
+ V(_IntegerImplementation, <<, Integer_shl, 1127538624) \
+ V(_IntegerImplementation, >>, Integer_sar, 1243972513) \
// A list of core functions that internally dispatch based on received id.
#define POLYMORPHIC_TARGET_LIST(V) \
V(_StringBase, [], StringBaseCharAt, 754527301) \
- V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1436590579) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 187609847) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1826086346) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1174755987) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1936358273) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 1123951931) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 853172551) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 165422183) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1564825450) \
- V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1123952315) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 831892409) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 2043203289) \
- V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1759261408) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 267848339) \
- V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 350952121) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1170619358) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1325523969) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 541136999) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 365317124) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1766802707) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 2075229300) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744) \
+ V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1328908284) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 1694054572) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324) \
// Forward declarations.
class Function;
@@ -511,9 +516,9 @@
// List of recognized list factories:
// (factory-name-symbol, result-cid, fingerprint).
#define RECOGNIZED_LIST_FACTORY_LIST(V) \
- V(_ListFactory, kArrayCid, 184405219) \
- V(_GrowableListWithData, kGrowableObjectArrayCid, 131424500) \
- V(_GrowableListFactory, kGrowableObjectArrayCid, 664918385) \
+ V(_ListFactory, kArrayCid, 1661438741) \
+ V(_GrowableListWithData, kGrowableObjectArrayCid, 631736030) \
+ V(_GrowableListFactory, kGrowableObjectArrayCid, 1330464656) \
V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 779569635) \
V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1790399545) \
V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 405875159) \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6f48c92..46320b4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1243,11 +1243,12 @@
// Pre-register the isolate library so the native class implementations
// can be hooked up before compiling it.
Library& isolate_lib =
- Library::Handle(zone, Library::LookupLibrary(Symbols::DartIsolate()));
+ Library::Handle(zone, Library::LookupLibrary(thread,
+ Symbols::DartIsolate()));
if (isolate_lib.IsNull()) {
isolate_lib = Library::NewLibraryHelper(Symbols::DartIsolate(), true);
isolate_lib.SetLoadRequested();
- isolate_lib.Register();
+ isolate_lib.Register(thread);
object_store->set_bootstrap_library(ObjectStore::kIsolate, isolate_lib);
}
ASSERT(!isolate_lib.IsNull());
@@ -1365,11 +1366,11 @@
// Pre-register the mirrors library so we can place the vm class
// MirrorReference there rather than the core library.
NOT_IN_PRODUCT(
- lib = Library::LookupLibrary(Symbols::DartMirrors());
+ lib = Library::LookupLibrary(thread, Symbols::DartMirrors());
if (lib.IsNull()) {
lib = Library::NewLibraryHelper(Symbols::DartMirrors(), true);
lib.SetLoadRequested();
- lib.Register();
+ lib.Register(thread);
object_store->set_bootstrap_library(ObjectStore::kMirrors, lib);
}
ASSERT(!lib.IsNull());
@@ -1381,11 +1382,11 @@
// Pre-register the collection library so we can place the vm class
// LinkedHashMap there rather than the core library.
- lib = Library::LookupLibrary(Symbols::DartCollection());
+ lib = Library::LookupLibrary(thread, Symbols::DartCollection());
if (lib.IsNull()) {
lib = Library::NewLibraryHelper(Symbols::DartCollection(), true);
lib.SetLoadRequested();
- lib.Register();
+ lib.Register(thread);
object_store->set_bootstrap_library(ObjectStore::kCollection, lib);
}
ASSERT(!lib.IsNull());
@@ -1400,17 +1401,17 @@
// Pre-register the developer library so we can place the vm class
// UserTag there rather than the core library.
- lib = Library::LookupLibrary(Symbols::DartDeveloper());
+ lib = Library::LookupLibrary(thread, Symbols::DartDeveloper());
if (lib.IsNull()) {
lib = Library::NewLibraryHelper(Symbols::DartDeveloper(), true);
lib.SetLoadRequested();
- lib.Register();
+ lib.Register(thread);
object_store->set_bootstrap_library(ObjectStore::kDeveloper, lib);
}
ASSERT(!lib.IsNull());
ASSERT(lib.raw() == Library::DeveloperLibrary());
- lib = Library::LookupLibrary(Symbols::DartDeveloper());
+ lib = Library::LookupLibrary(thread, Symbols::DartDeveloper());
ASSERT(!lib.IsNull());
cls = Class::New<UserTag>();
RegisterPrivateClass(cls, Symbols::_UserTag(), lib);
@@ -1423,11 +1424,11 @@
// Pre-register the typed_data library so the native class implementations
// can be hooked up before compiling it.
- lib = Library::LookupLibrary(Symbols::DartTypedData());
+ lib = Library::LookupLibrary(thread, Symbols::DartTypedData());
if (lib.IsNull()) {
lib = Library::NewLibraryHelper(Symbols::DartTypedData(), true);
lib.SetLoadRequested();
- lib.Register();
+ lib.Register(thread);
object_store->set_bootstrap_library(ObjectStore::kTypedData, lib);
}
ASSERT(!lib.IsNull());
@@ -1582,7 +1583,7 @@
MethodRecognizer::InitializeState();
// Adds static const fields (class ids) to the class 'ClassID');
- lib = Library::LookupLibrary(Symbols::DartInternal());
+ lib = Library::LookupLibrary(thread, Symbols::DartInternal());
ASSERT(!lib.IsNull());
cls = lib.LookupClassAllowPrivate(Symbols::ClassID());
ASSERT(!cls.IsNull());
@@ -3422,14 +3423,16 @@
if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) {
return token_pos();
}
- const Script& scr = Script::Handle(script());
+ Zone* zone = Thread::Current()->zone();
+ const Script& scr = Script::Handle(zone, script());
ASSERT(!scr.IsNull());
- const TokenStream& tkns = TokenStream::Handle(scr.tokens());
+ const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens());
if (tkns.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
return TokenPosition::kNoSource;
}
- TokenStream::Iterator tkit(tkns,
+ TokenStream::Iterator tkit(zone,
+ tkns,
token_pos(),
TokenStream::Iterator::kNoNewlines);
intptr_t level = 0;
@@ -6432,45 +6435,6 @@
}
AbstractType& param_type =
AbstractType::Handle(ParameterTypeAt(parameter_position));
-
- // TODO(regis): Remove this debugging code.
- if (param_type.IsNull()) {
- THR_Print("*** null param_type ***\n");
- THR_Print("parameter_position: %" Pd "\n", parameter_position);
- THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
- String& str = String::Handle();
- str = QualifiedScrubbedName();
- THR_Print("function name: %s\n", str.ToCString());
- str = other.QualifiedScrubbedName();
- THR_Print("other function name: %s\n", str.ToCString());
- Class& owner = Class::Handle();
- owner = Owner();
- THR_Print("function owner: %s\n", owner.ToCString());
- owner = other.Owner();
- THR_Print("other function owner: %s\n", owner.ToCString());
- THR_Print("other_param_type: %s\n", other_param_type.ToCString());
- AbstractType& type = AbstractType::Handle();
- if (parameter_position > 0) {
- type = ParameterTypeAt(0);
- THR_Print("receiver type: %s\n",
- type.IsNull()? "null" : type.ToCString());
- }
- THR_Print("has code: %s\n", HasCode() ? "yes" : "no");
- str = Report::PrependSnippet(Report::kWarning,
- Script::Handle(script()),
- token_pos(),
- Report::AtLocation,
- Symbols::Empty());
- THR_Print("function source: %s\n", str.ToCString());
- for (intptr_t i = 0; i < NumParameters(); i++) {
- THR_Print("function param %" Pd "\n", i);
- str = ParameterNameAt(i);
- THR_Print(" name: %s\n", str.IsNull() ? "null" : str.ToCString());
- type = ParameterTypeAt(i);
- THR_Print(" type: %s\n", type.IsNull() ? "null" : type.ToCString());
- }
- }
-
if (!param_type.IsInstantiated()) {
param_type = param_type.InstantiateFrom(type_arguments,
bound_error,
@@ -7077,20 +7041,20 @@
RawClass* Function::Owner() const {
- const Object& obj = Object::Handle(raw_ptr()->owner_);
- if (obj.IsClass()) {
- return Class::Cast(obj).raw();
+ if (raw_ptr()->owner_->IsClass()) {
+ return Class::RawCast(raw_ptr()->owner_);
}
+ const Object& obj = Object::Handle(raw_ptr()->owner_);
ASSERT(obj.IsPatchClass());
return PatchClass::Cast(obj).patched_class();
}
RawClass* Function::origin() const {
- const Object& obj = Object::Handle(raw_ptr()->owner_);
- if (obj.IsClass()) {
- return Class::Cast(obj).raw();
+ if (raw_ptr()->owner_->IsClass()) {
+ return Class::RawCast(raw_ptr()->owner_);
}
+ const Object& obj = Object::Handle(raw_ptr()->owner_);
ASSERT(obj.IsPatchClass());
return PatchClass::Cast(obj).origin_class();
}
@@ -7163,15 +7127,16 @@
// constructor from the mixin to use.
return String::null();
}
- const Script& func_script = Script::Handle(script());
- const TokenStream& stream = TokenStream::Handle(func_script.tokens());
+ Zone* zone = Thread::Current()->zone();
+ const Script& func_script = Script::Handle(zone, script());
+ const TokenStream& stream = TokenStream::Handle(zone, func_script.tokens());
if (!func_script.HasSource()) {
// When source is not available, avoid printing the whole token stream and
// doing expensive position calculations.
return stream.GenerateSource(token_pos(), end_token_pos().Next());
}
- const TokenStream::Iterator tkit(stream, end_token_pos());
+ const TokenStream::Iterator tkit(zone, stream, end_token_pos());
intptr_t from_line;
intptr_t from_col;
intptr_t to_line;
@@ -7188,10 +7153,10 @@
if ((tkit.CurrentTokenKind() == Token::kCOMMA) || // Case 1.
(tkit.CurrentTokenKind() == Token::kRPAREN) || // Case 2.
(tkit.CurrentTokenKind() == Token::kSEMICOLON &&
- String::Handle(name()).Equals("<anonymous closure>"))) { // Case 3.
+ String::Handle(zone, name()).Equals("<anonymous closure>"))) { // Cas 3.
last_tok_len = 0;
}
- const String& result = String::Handle(func_script.GetSnippet(
+ const String& result = String::Handle(zone, func_script.GetSnippet(
from_line, from_col, to_line, to_col + last_tok_len));
ASSERT(!result.IsNull());
return result.raw();
@@ -7202,10 +7167,13 @@
// arguments.
int32_t Function::SourceFingerprint() const {
uint32_t result = 0;
- TokenStream::Iterator tokens_iterator(TokenStream::Handle(
- Script::Handle(script()).tokens()), token_pos());
- Object& obj = Object::Handle();
- String& literal = String::Handle();
+ Zone* zone = Thread::Current()->zone();
+ TokenStream::Iterator tokens_iterator(
+ zone,
+ TokenStream::Handle(zone, Script::Handle(zone, script()).tokens()),
+ token_pos());
+ Object& obj = Object::Handle(zone);
+ String& literal = String::Handle(zone);
while (tokens_iterator.CurrentPosition() < end_token_pos()) {
uint32_t val = 0;
obj = tokens_iterator.CurrentToken();
@@ -8220,18 +8188,20 @@
RawString* TokenStream::GenerateSource(TokenPosition start_pos,
TokenPosition end_pos) const {
- Iterator iterator(*this, start_pos, Iterator::kAllTokens);
- const ExternalTypedData& data = ExternalTypedData::Handle(GetStream());
+ Zone* zone = Thread::Current()->zone();
+ Iterator iterator(zone, *this, start_pos, Iterator::kAllTokens);
+ const ExternalTypedData& data = ExternalTypedData::Handle(zone, GetStream());
const GrowableObjectArray& literals =
- GrowableObjectArray::Handle(GrowableObjectArray::New(data.Length()));
- const String& private_key = String::Handle(PrivateKey());
+ GrowableObjectArray::Handle(zone,
+ GrowableObjectArray::New(data.Length()));
+ const String& private_key = String::Handle(zone, PrivateKey());
intptr_t private_len = private_key.Length();
Token::Kind curr = iterator.CurrentTokenKind();
Token::Kind prev = Token::kILLEGAL;
// Handles used in the loop.
- Object& obj = Object::Handle();
- String& literal = String::Handle();
+ Object& obj = Object::Handle(zone);
+ String& literal = String::Handle(zone);
// Current indentation level.
int indent = 0;
@@ -8405,7 +8375,11 @@
TokenPosition TokenStream::ComputeSourcePosition(
TokenPosition tok_pos) const {
- Iterator iterator(*this, TokenPosition::kMinSource, Iterator::kAllTokens);
+ Zone* zone = Thread::Current()->zone();
+ Iterator iterator(zone,
+ *this,
+ TokenPosition::kMinSource,
+ Iterator::kAllTokens);
TokenPosition src_pos = TokenPosition::kMinSource;
Token::Kind kind = iterator.CurrentTokenKind();
while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) {
@@ -8669,15 +8643,16 @@
}
-TokenStream::Iterator::Iterator(const TokenStream& tokens,
+TokenStream::Iterator::Iterator(Zone* zone,
+ const TokenStream& tokens,
TokenPosition token_pos,
Iterator::StreamType stream_type)
- : tokens_(TokenStream::Handle(tokens.raw())),
- data_(ExternalTypedData::Handle(tokens.GetStream())),
+ : tokens_(TokenStream::Handle(zone, tokens.raw())),
+ data_(ExternalTypedData::Handle(zone, tokens.GetStream())),
stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()),
- token_objects_(Array::Handle(
- GrowableObjectArray::Handle(tokens.TokenObjects()).data())),
- obj_(Object::Handle()),
+ token_objects_(Array::Handle(zone,
+ GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())),
+ obj_(Object::Handle(zone)),
cur_token_pos_(token_pos.Pos()),
cur_token_kind_(Token::kILLEGAL),
cur_token_obj_index_(-1),
@@ -8822,7 +8797,7 @@
RawString* Script::GenerateSource() const {
const TokenStream& token_stream = TokenStream::Handle(tokens());
if (token_stream.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
return String::null();
}
return token_stream.GenerateSource();
@@ -8840,7 +8815,8 @@
Smi& value = Smi::Handle(zone);
String& tokenValue = String::Handle(zone);
ASSERT(!tkns.IsNull());
- TokenStream::Iterator tkit(tkns,
+ TokenStream::Iterator tkit(zone,
+ tkns,
TokenPosition::kMinSource,
TokenStream::Iterator::kAllTokens);
int current_line = -1;
@@ -8989,9 +8965,10 @@
intptr_t* column,
intptr_t* token_len) const {
ASSERT(line != NULL);
- const TokenStream& tkns = TokenStream::Handle(tokens());
+ Zone* zone = Thread::Current()->zone();
+ const TokenStream& tkns = TokenStream::Handle(zone, tokens());
if (tkns.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
*line = -1;
if (column != NULL) {
*column = -1;
@@ -9002,7 +8979,8 @@
return;
}
if (column == NULL) {
- TokenStream::Iterator tkit(tkns,
+ TokenStream::Iterator tkit(zone,
+ tkns,
TokenPosition::kMinSource,
TokenStream::Iterator::kAllTokens);
intptr_t cur_line = line_offset() + 1;
@@ -9015,7 +8993,7 @@
}
*line = cur_line;
} else {
- const String& src = String::Handle(Source());
+ const String& src = String::Handle(zone, Source());
TokenPosition src_pos = tkns.ComputeSourcePosition(token_pos);
Scanner scanner(src, Symbols::Empty());
scanner.ScanTo(src_pos);
@@ -9042,12 +9020,14 @@
TokenPosition* last_token_index) const {
ASSERT(first_token_index != NULL && last_token_index != NULL);
ASSERT(line_number > 0);
+ Zone* zone = Thread::Current()->zone();
*first_token_index = TokenPosition::kNoSource;
*last_token_index = TokenPosition::kNoSource;
- const TokenStream& tkns = TokenStream::Handle(tokens());
+ const TokenStream& tkns = TokenStream::Handle(zone, tokens());
line_number -= line_offset();
if (line_number < 1) line_number = 1;
- TokenStream::Iterator tkit(tkns,
+ TokenStream::Iterator tkit(zone,
+ tkns,
TokenPosition::kMinSource,
TokenStream::Iterator::kAllTokens);
// Scan through the token stream to the required line.
@@ -9090,7 +9070,7 @@
RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
const String& src = String::Handle(Source());
if (src.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
return Symbols::OptimizedOut().raw();
}
intptr_t relative_line_number = line_number - line_offset();
@@ -9132,7 +9112,7 @@
intptr_t to_column) const {
const String& src = String::Handle(Source());
if (src.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
return Symbols::OptimizedOut().raw();
}
intptr_t length = src.Length();
@@ -10545,19 +10525,21 @@
void Library::InitCoreLibrary(Isolate* isolate) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
const String& core_lib_url = Symbols::DartCore();
const Library& core_lib =
- Library::Handle(Library::NewLibraryHelper(core_lib_url, false));
+ Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false));
core_lib.SetLoadRequested();
- core_lib.Register();
+ core_lib.Register(thread);
isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib);
isolate->object_store()->set_root_library(Library::Handle());
// Hook up predefined classes without setting their library pointers. These
// classes are coming from the VM isolate, and are shared between multiple
// isolates so setting their library pointers would be wrong.
- const Class& cls = Class::Handle(Object::dynamic_class());
- core_lib.AddObject(cls, String::Handle(cls.Name()));
+ const Class& cls = Class::Handle(zone, Object::dynamic_class());
+ core_lib.AddObject(cls, String::Handle(zone, cls.Name()));
}
@@ -10583,7 +10565,7 @@
const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName();
native_flds_lib.SetName(native_flds_lib_name);
native_flds_lib.SetLoadRequested();
- native_flds_lib.Register();
+ native_flds_lib.Register(thread);
native_flds_lib.SetLoadInProgress();
isolate->object_store()->set_native_wrappers_library(native_flds_lib);
static const char* const kNativeWrappersClass = "NativeFieldWrapperClass";
@@ -10604,31 +10586,51 @@
}
+// LibraryLookupSet maps URIs to libraries.
+class LibraryLookupTraits {
+ public:
+ static const char* Name() { return "LibraryLookupTraits"; }
+ static bool ReportStats() { return false; }
+
+ static bool IsMatch(const Object& a, const Object& b) {
+ const String& a_str = String::Cast(a);
+ const String& b_str = String::Cast(b);
+
+ ASSERT(a_str.HasHash() && b_str.HasHash());
+ return a_str.Equals(b_str);
+ }
+
+ static uword Hash(const Object& key) {
+ return String::Cast(key).Hash();
+ }
+
+ static RawObject* NewKey(const String& str) {
+ return str.raw();
+ }
+};
+typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
+
+
// Returns library with given url in current isolate, or NULL.
-RawLibrary* Library::LookupLibrary(const String &url) {
- Thread* thread = Thread::Current();
+RawLibrary* Library::LookupLibrary(Thread* thread, const String &url) {
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
- Library& lib = Library::Handle(zone, Library::null());
- String& lib_url = String::Handle(zone, String::null());
- GrowableObjectArray& libs = GrowableObjectArray::Handle(
- zone, isolate->object_store()->libraries());
+ ObjectStore* object_store = isolate->object_store();
// Make sure the URL string has an associated hash code
// to speed up the repeated equality checks.
url.Hash();
- intptr_t len = libs.Length();
- for (intptr_t i = 0; i < len; i++) {
- lib ^= libs.At(i);
- lib_url ^= lib.url();
-
- ASSERT(url.HasHash() && lib_url.HasHash());
- if (lib_url.Equals(url)) {
- return lib.raw();
- }
+ // Use the libraries map to lookup the library by URL.
+ Library& lib = Library::Handle(zone);
+ if (object_store->libraries_map() == Array::null()) {
+ return Library::null();
+ } else {
+ LibraryLookupMap map(object_store->libraries_map());
+ lib ^= map.GetOrNull(url);
+ ASSERT(map.Release().raw() == object_store->libraries_map());
}
- return Library::null();
+ return lib.raw();
}
@@ -10652,35 +10654,32 @@
}
-bool Library::IsKeyUsed(intptr_t key) {
- intptr_t lib_key;
- const GrowableObjectArray& libs = GrowableObjectArray::Handle(
- Isolate::Current()->object_store()->libraries());
- Library& lib = Library::Handle();
- String& lib_url = String::Handle();
- for (int i = 0; i < libs.Length(); i++) {
- lib ^= libs.At(i);
- lib_url ^= lib.url();
- lib_key = lib_url.Hash();
- if (lib_key == key) {
- return true;
- }
- }
- return false;
-}
-
-
+// Create a private key for this library. It is based on the hash of the
+// library URI and the sequence number of the library to guarantee unique
+// private keys without having to verify.
void Library::AllocatePrivateKey() const {
- const String& url = String::Handle(this->url());
- intptr_t key_value = url.Hash() & kIntptrMax;
- while ((key_value == 0) || Library::IsKeyUsed(key_value)) {
- key_value = (key_value + 1) & kIntptrMax;
- }
- ASSERT(key_value > 0);
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
+
+ // Format of the private key is: "@<sequence number><6 digits of hash>
+ const intptr_t hash_mask = 0x7FFFF;
+
+ const String& url = String::Handle(zone, this->url());
+ intptr_t hash_value = url.Hash() & hash_mask;
+
+ const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
+ isolate->object_store()->libraries());
+ intptr_t sequence_value = libs.Length();
+
char private_key[32];
OS::SNPrint(private_key, sizeof(private_key),
- "%c%" Pd "", kPrivateKeySeparator, key_value);
- StorePointer(&raw_ptr()->private_key_, String::New(private_key, Heap::kOld));
+ "%c%" Pd "%06" Pd "",
+ kPrivateKeySeparator, sequence_value, hash_value);
+ const String& key = String::Handle(zone, String::New(private_key,
+ Heap::kOld));
+ key.Hash(); // This string may end up in the VM isolate.
+ StorePointer(&raw_ptr()->private_key_, key.raw());
}
@@ -10721,12 +10720,14 @@
RawLibrary* Library::GetLibrary(intptr_t index) {
- Isolate* isolate = Isolate::Current();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
const GrowableObjectArray& libs =
- GrowableObjectArray::Handle(isolate->object_store()->libraries());
+ GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
ASSERT(!libs.IsNull());
if ((0 <= index) && (index < libs.Length())) {
- Library& lib = Library::Handle();
+ Library& lib = Library::Handle(zone);
lib ^= libs.At(index);
return lib.raw();
}
@@ -10734,15 +10735,53 @@
}
-void Library::Register() const {
- ASSERT(Library::LookupLibrary(String::Handle(url())) == Library::null());
- ASSERT(String::Handle(url()).HasHash());
- ObjectStore* object_store = Isolate::Current()->object_store();
- GrowableObjectArray& libs =
- GrowableObjectArray::Handle(object_store->libraries());
+void Library::Register(Thread* thread) const {
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
+ ObjectStore* object_store = isolate->object_store();
+
+ // A library is "registered" in two places:
+ // - A growable array mapping from index to library.
+ const String& lib_url = String::Handle(zone, url());
+ ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null());
+ ASSERT(lib_url.HasHash());
+ GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
+ object_store->libraries());
ASSERT(!libs.IsNull());
set_index(libs.Length());
libs.Add(*this);
+
+ // - A map from URL string to library.
+ if (object_store->libraries_map() == Array::null()) {
+ LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld));
+ object_store->set_libraries_map(map.Release());
+ }
+
+ LibraryLookupMap map(object_store->libraries_map());
+ bool present = map.UpdateOrInsert(lib_url, *this);
+ ASSERT(!present);
+ object_store->set_libraries_map(map.Release());
+}
+
+
+void Library::RegisterLibraries(Thread* thread,
+ const GrowableObjectArray& libs) {
+ Zone* zone = thread->zone();
+ Isolate* isolate = thread->isolate();
+ Library& lib = Library::Handle(zone);
+ String& lib_url = String::Handle(zone);
+
+ LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld));
+
+ intptr_t len = libs.Length();
+ for (intptr_t i = 0; i < len; i++) {
+ lib ^= libs.At(i);
+ lib_url = lib.url();
+ map.InsertNewOrGetValue(lib_url, lib);
+ }
+ // Now rememeber these in the isolate's object store.
+ isolate->object_store()->set_libraries(libs);
+ isolate->object_store()->set_libraries_map(map.Release());
}
@@ -10981,7 +11020,7 @@
}
ASSERT(is_deferred_load());
ASSERT(num_imports() == 1);
- if (Dart::IsRunningPrecompiledCode()) {
+ if (Dart::snapshot_kind() == Snapshot::kAppNoJIT) {
// The library list was tree-shaken away.
this->set_is_loaded();
return true;
@@ -13550,7 +13589,7 @@
uword code_entry = instrs.EntryPoint();
const Array& table = Array::Handle(deopt_info_array());
if (table.IsNull()) {
- ASSERT(Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
return TypedData::null();
}
// Linear search for the PC offset matching the target PC.
@@ -15495,7 +15534,8 @@
intptr_t Instance::DataOffsetFor(intptr_t cid) {
- if (RawObject::IsExternalTypedDataClassId(cid)) {
+ if (RawObject::IsExternalTypedDataClassId(cid) ||
+ RawObject::IsExternalStringClassId(cid)) {
// Elements start at offset 0 of the external data.
return 0;
}
@@ -15605,15 +15645,6 @@
bool AbstractType::IsInstantiated(TrailPtr trail) const {
// AbstractType is an abstract class.
-#if !defined(PRODUCT)
- // TODO(srdjan) : Remove temporary code.
-NOT_IN_PRODUCT(
- Profiler::DumpStackTrace(true); // Only native stack trace.
-)
- if (Compiler::IsBackgroundCompilation()) {
- UNREACHABLE();
- }
-#endif
UNREACHABLE();
return false;
}
@@ -15967,6 +15998,19 @@
}
+bool AbstractType::IsDynamicType() const {
+ if (IsCanonical()) {
+ return raw() == Object::dynamic_type().raw();
+ }
+ return HasResolvedTypeClass() && (type_class() == Object::dynamic_class());
+}
+
+
+bool AbstractType::IsVoidType() const {
+ return raw() == Object::void_type().raw();
+}
+
+
bool AbstractType::IsNullType() const {
return !IsFunctionType() &&
HasResolvedTypeClass() &&
@@ -16352,10 +16396,11 @@
if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) {
return false; // Valid type, but not a function type.
}
- const LanguageError& type_error = LanguageError::Handle(error());
- if (type_error.IsNull()) {
+ if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
return false; // Valid function type.
}
+ const LanguageError& type_error = LanguageError::Handle(error());
+ ASSERT(!type_error.IsNull());
return type_error.kind() == Report::kMalformedType;
}
@@ -16367,10 +16412,11 @@
if (!Isolate::Current()->type_checks()) {
return false;
}
- const LanguageError& type_error = LanguageError::Handle(error());
- if (type_error.IsNull()) {
+ if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
return false; // Valid function type.
}
+ const LanguageError& type_error = LanguageError::Handle(error());
+ ASSERT(!type_error.IsNull());
return type_error.kind() == Report::kMalboundedType;
}
@@ -16392,9 +16438,8 @@
RawLanguageError* Type::error() const {
- const Object& type_error = Object::Handle(raw_ptr()->sig_or_err_.error_);
- if (type_error.IsLanguageError()) {
- return LanguageError::RawCast(type_error.raw());
+ if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
+ return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_);
}
return LanguageError::null();
}
@@ -16406,14 +16451,14 @@
RawFunction* Type::signature() const {
- if (raw_ptr()->sig_or_err_.signature_ == Function::null()) {
+ intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId();
+ if (cid == kNullCid) {
return Function::null();
}
- const Object& obj = Object::Handle(raw_ptr()->sig_or_err_.signature_);
- if (obj.IsFunction()) {
- return Function::RawCast(obj.raw());
+ if (cid == kFunctionCid) {
+ return Function::RawCast(raw_ptr()->sig_or_err_.signature_);
}
- ASSERT(obj.IsLanguageError()); // Type is malformed or malbounded.
+ ASSERT(cid == kLanguageErrorCid); // Type is malformed or malbounded.
return Function::null();
}
@@ -16778,9 +16823,29 @@
const LanguageError& bound_error = LanguageError::Handle(zone, error());
clone.set_error(bound_error);
}
+ TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
+ bool type_args_cloned = false;
// Clone the signature if this type represents a function type.
const Function& fun = Function::Handle(zone, signature());
if (!fun.IsNull()) {
+ // If the scope class is not a typedef and if it is generic, it must be the
+ // mixin class, set it to the new owner.
+ if (!type_cls.IsTypedefClass() && type_cls.IsGeneric()) {
+ clone.set_type_class(new_owner);
+ AbstractType& decl_type = AbstractType::Handle(zone);
+#ifdef DEBUG
+ decl_type = type_cls.DeclarationType();
+ ASSERT(decl_type.IsFinalized());
+ const TypeArguments& decl_type_args =
+ TypeArguments::Handle(zone, decl_type.arguments());
+ ASSERT(type_args.Equals(decl_type_args));
+#endif // DEBUG
+ decl_type = new_owner.DeclarationType();
+ ASSERT(decl_type.IsFinalized());
+ type_args = decl_type.arguments();
+ clone.set_arguments(type_args);
+ type_args_cloned = true;
+ }
Function& fun_clone = Function::Handle(zone,
Function::NewSignatureFunction(new_owner, TokenPosition::kNoSource));
AbstractType& type = AbstractType::Handle(zone, fun.result_type());
@@ -16800,13 +16865,14 @@
fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names()));
clone.set_signature(fun_clone);
}
- TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
- // Upper bounds of uninstantiated type arguments may form a cycle.
- if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
- AddOnlyBuddyToTrail(&trail, clone);
+ if (!type_args_cloned) {
+ // Upper bounds of uninstantiated type arguments may form a cycle.
+ if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
+ AddOnlyBuddyToTrail(&trail, clone);
+ }
+ type_args = type_args.CloneUninstantiated(new_owner, trail);
+ clone.set_arguments(type_args);
}
- type_args = type_args.CloneUninstantiated(new_owner, trail);
- clone.set_arguments(type_args);
clone.SetIsFinalized();
return clone.raw();
}
@@ -16823,7 +16889,15 @@
Isolate* isolate = thread->isolate();
AbstractType& type = Type::Handle(zone);
const Class& cls = Class::Handle(zone, type_class());
- if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
+ // Since void is a keyword, we never have to canonicalize the void type after
+ // it is canonicalized once by the vm isolate. The parser does the mapping.
+ ASSERT((cls.raw() != Object::void_class()) ||
+ (isolate == Dart::vm_isolate()));
+ // Since dynamic is not a keyword, the parser builds a type that requires
+ // canonicalization.
+ if ((cls.raw() == Object::dynamic_class()) &&
+ (isolate != Dart::vm_isolate())) {
+ ASSERT(Object::dynamic_type().IsCanonical());
return Object::dynamic_type().raw();
}
// Fast canonical lookup/registry for simple types.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 564db72..a2f8d21 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3307,7 +3307,8 @@
kAllTokens
};
- Iterator(const TokenStream& tokens,
+ Iterator(Zone* zone,
+ const TokenStream& tokens,
TokenPosition token_pos,
Iterator::StreamType stream_type = kNoNewlines);
@@ -3632,7 +3633,9 @@
StoreNonPointer(&raw_ptr()->index_, value);
}
- void Register() const;
+ void Register(Thread* thread) const;
+ static void RegisterLibraries(Thread* thread,
+ const GrowableObjectArray& libs);
bool IsDebuggable() const {
return raw_ptr()->debuggable_;
@@ -3654,7 +3657,7 @@
inline intptr_t UrlHash() const;
- static RawLibrary* LookupLibrary(const String& url);
+ static RawLibrary* LookupLibrary(Thread* thread, const String& url);
static RawLibrary* GetLibrary(intptr_t index);
static void InitCoreLibrary(Isolate* isolate);
@@ -3738,7 +3741,6 @@
bool import_core_lib);
RawObject* LookupEntry(const String& name, intptr_t *index) const;
- static bool IsKeyUsed(intptr_t key);
void AllocatePrivateKey() const;
RawString* MakeMetadataName(const Object& obj) const;
@@ -5472,23 +5474,17 @@
// type.
RawString* ClassName() const;
- // Check if this type represents the 'dynamic' type.
- bool IsDynamicType() const {
- return !IsFunctionType() &&
- HasResolvedTypeClass() &&
- (type_class() == Object::dynamic_class());
- }
+ // Check if this type represents the 'dynamic' type or if it is malformed,
+ // since a malformed type is mapped to 'dynamic'.
+ // Call IsMalformed() first, if distinction is required.
+ bool IsDynamicType() const;
+
+ // Check if this type represents the 'void' type.
+ bool IsVoidType() const;
// Check if this type represents the 'Null' type.
bool IsNullType() const;
- // Check if this type represents the 'void' type.
- bool IsVoidType() const {
- return !IsFunctionType() &&
- HasResolvedTypeClass() &&
- (type_class() == Object::void_class());
- }
-
bool IsObjectType() const {
return !IsFunctionType() &&
HasResolvedTypeClass() &&
diff --git a/runtime/vm/object_dbc_test.cc b/runtime/vm/object_dbc_test.cc
new file mode 100644
index 0000000..464350d
--- /dev/null
+++ b/runtime/vm/object_dbc_test.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2016, 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.
+
+#include "platform/assert.h"
+#include "vm/globals.h"
+#if defined(TARGET_ARCH_DBC)
+
+#include "vm/assembler.h"
+#include "vm/object.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#define __ assembler->
+
+// Generate a simple dart code sequence.
+// This is used to test Code and Instruction object creation.
+void GenerateIncrement(Assembler* assembler) {
+ __ Frame(1);
+ __ LoadConstant(0, Smi::Handle(Smi::New(0)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ Push(0);
+ __ AddTOS();
+ __ Trap();
+ __ PopLocal(0);
+ __ Return(0);
+}
+
+
+// Generate a dart code sequence that embeds a string object in it.
+// This is used to test Embedded String objects in the instructions.
+void GenerateEmbedStringInCode(Assembler* assembler, const char* str) {
+ const String& string_object =
+ String::ZoneHandle(String::New(str, Heap::kOld));
+ __ PushConstant(string_object);
+ __ ReturnTOS();
+}
+
+
+// Generate a dart code sequence that embeds a smi object in it.
+// This is used to test Embedded Smi objects in the instructions.
+void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value) {
+ const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
+ __ PushConstant(smi_object);
+ __ ReturnTOS();
+}
+
+} // namespace dart
+
+#endif // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3cfc25b..41290fb 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1038,7 +1038,6 @@
GrowableArray<Class*> classes;
Class& cls = Class::Handle(this->clazz());
do {
- cls.Print();
classes.Add(&Class::Handle(cls.raw()));
cls = cls.SuperClass();
} while (!cls.IsNull());
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index a0feb38..95810d2 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -73,6 +73,7 @@
typed_data_library_(Library::null()),
vmservice_library_(Library::null()),
libraries_(GrowableObjectArray::null()),
+ libraries_map_(Array::null()),
closure_functions_(GrowableObjectArray::null()),
pending_classes_(GrowableObjectArray::null()),
pending_deferred_loads_(GrowableObjectArray::null()),
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 534e516..eb868fb 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -332,6 +332,11 @@
libraries_ = value.raw();
}
+ RawArray* libraries_map() const { return libraries_map_; }
+ void set_libraries_map(const Array& value) {
+ libraries_map_ = value.raw();
+ }
+
RawGrowableObjectArray* closure_functions() const {
return closure_functions_;
}
@@ -548,6 +553,7 @@
RawLibrary* typed_data_library_;
RawLibrary* vmservice_library_;
RawGrowableObjectArray* libraries_;
+ RawArray* libraries_map_;
RawGrowableObjectArray* closure_functions_;
RawGrowableObjectArray* pending_classes_;
RawGrowableObjectArray* pending_deferred_loads_;
@@ -582,6 +588,8 @@
return to();
case Snapshot::kScript:
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index aa75ee9..7d9be08 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -162,15 +162,16 @@
VM_TEST_CASE(TokenStream) {
- String& source = String::Handle(String::New("= ( 9 , ."));
- String& private_key = String::Handle(String::New(""));
+ Zone* zone = Thread::Current()->zone();
+ String& source = String::Handle(zone, String::New("= ( 9 , ."));
+ String& private_key = String::Handle(zone, String::New(""));
Scanner scanner(source, private_key);
const Scanner::GrowableTokenStream& ts = scanner.GetStream();
EXPECT_EQ(6, ts.length());
EXPECT_EQ(Token::kLPAREN, ts[1].kind);
const TokenStream& token_stream = TokenStream::Handle(
- TokenStream::New(ts, private_key, false));
- TokenStream::Iterator iterator(token_stream, TokenPosition::kMinSource);
+ zone, TokenStream::New(ts, private_key, false));
+ TokenStream::Iterator iterator(zone, token_stream, TokenPosition::kMinSource);
// EXPECT_EQ(6, token_stream.Length());
iterator.Advance(); // Advance to '(' token.
EXPECT_EQ(Token::kLPAREN, iterator.CurrentTokenKind());
@@ -2686,7 +2687,6 @@
}
-#if !defined(TARGET_ARCH_DBC)
static RawLibrary* CreateDummyLibrary(const String& library_name) {
return Library::New(library_name);
}
@@ -2968,7 +2968,6 @@
EXPECT_EQ(false, iter.MoveNext());
}
-#endif // !defined(TARGET_ARCH_DBC)
static RawClass* CreateTestClass(const char* name) {
@@ -4011,7 +4010,7 @@
TestCase::LoadTestScript(kScriptChars, NULL);
EXPECT(ClassFinalizer::ProcessPendingClasses());
const String& name = String::Handle(String::New(TestCase::url()));
- const Library& lib = Library::Handle(Library::LookupLibrary(name));
+ const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
EXPECT(!lib.IsNull());
const Class& class_a = Class::Handle(
@@ -4076,7 +4075,7 @@
// With no breakpoint, function A.b is inlineable.
const String& name = String::Handle(String::New(TestCase::url()));
- const Library& vmlib = Library::Handle(Library::LookupLibrary(name));
+ const Library& vmlib = Library::Handle(Library::LookupLibrary(thread, name));
EXPECT(!vmlib.IsNull());
const Class& class_a = Class::Handle(
vmlib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index cd570c4..9064322 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -56,6 +56,13 @@
// Returns the frequency of the monotonic clock.
static int64_t GetCurrentMonotonicFrequency();
+ // Returns the value of current thread's CPU usage clock in microseconds.
+ // NOTE: This clock will return different values depending on the calling
+ // thread. It is only expected to increase in value as the thread uses
+ // CPU time.
+ // NOTE: This function will return -1 on OSs that are not supported.
+ static int64_t GetCurrentThreadCPUMicros();
+
// Returns a cleared aligned array of type T with n entries.
// Alignment must be >= 16 and a power of two.
template<typename T>
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 3269b12..1c22b7c 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -168,6 +168,19 @@
}
+int64_t OS::GetCurrentThreadCPUMicros() {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+ UNREACHABLE();
+ return -1;
+ }
+ int64_t result = ts.tv_sec;
+ result *= kMicrosecondsPerSecond;
+ result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+ return result;
+}
+
+
void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
const int kMinimumAlignment = 16;
ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 0fc90c7..7d7c7e0 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -175,6 +175,19 @@
}
+int64_t OS::GetCurrentThreadCPUMicros() {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+ UNREACHABLE();
+ return -1;
+ }
+ int64_t result = ts.tv_sec;
+ result *= kMicrosecondsPerSecond;
+ result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+ return result;
+}
+
+
void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
const int kMinimumAlignment = 16;
ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index d2d5576..6d2d02a 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -139,6 +139,27 @@
}
+int64_t OS::GetCurrentThreadCPUMicros() {
+ mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
+ thread_basic_info_data_t info_data;
+ thread_basic_info_t info = &info_data;
+ mach_port_t thread_port = mach_thread_self();
+ if (thread_port == MACH_PORT_NULL) {
+ return -1;
+ }
+ kern_return_t r = thread_info(thread_port, THREAD_BASIC_INFO,
+ (thread_info_t)info, &count);
+ mach_port_deallocate(mach_task_self(), thread_port);
+ ASSERT(r == KERN_SUCCESS);
+ int64_t thread_cpu_micros =
+ (info->system_time.seconds + info->user_time.seconds);
+ thread_cpu_micros *= kMicrosecondsPerSecond;
+ thread_cpu_micros += info->user_time.microseconds;
+ thread_cpu_micros += info->system_time.microseconds;
+ return thread_cpu_micros;
+}
+
+
void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
const int kMinimumAlignment = 16;
ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index e0b41ac..1bd2193 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -173,7 +173,6 @@
static intptr_t ThreadIdToIntPtr(ThreadId id);
static ThreadId ThreadIdFromIntPtr(intptr_t id);
static bool Compare(ThreadId a, ThreadId b);
- static void GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage);
// Called at VM startup and shutdown.
static void InitOnce();
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index 9b93cbe..b184f61 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
#include "platform/globals.h" // NOLINT
+
+
#if defined(TARGET_OS_ANDROID)
#include "vm/os_thread.h"
@@ -11,6 +13,7 @@
#include <sys/time.h> // NOLINT
#include "platform/assert.h"
+#include "platform/signal_blocker.h"
#include "platform/utils.h"
namespace dart {
@@ -83,6 +86,21 @@
};
+// Spawned threads inherit their spawner's signal mask. We sometimes spawn
+// threads for running Dart code from a thread that is blocking SIGPROF.
+// This function explicitly unblocks SIGPROF so the profiler continues to
+// sample this thread.
+static void UnblockSIGPROF() {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGPROF);
+ int r = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ USE(r);
+ ASSERT(r == 0);
+ ASSERT(!CHECK_IS_BLOCKING(SIGPROF));
+}
+
+
// Dispatch to the thread start function provided by the caller. This trampoline
// is used to ensure that the thread is properly destroyed if the thread just
// exits.
@@ -99,7 +117,7 @@
if (thread != NULL) {
OSThread::SetCurrent(thread);
thread->set_name(name);
-
+ UnblockSIGPROF();
// Call the supplied thread start function handing it its parameters.
function(parameter);
}
@@ -202,17 +220,6 @@
}
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
- ASSERT(thread_id == GetCurrentThreadId());
- ASSERT(cpu_usage != NULL);
- struct timespec ts;
- int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- ASSERT(r == 0);
- *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
- kNanosecondsPerMicrosecond;
-}
-
-
Mutex::Mutex() {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index a0e68f1..bd9bfaf 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
#include "platform/globals.h" // NOLINT
+
#if defined(TARGET_OS_LINUX)
#include "vm/os_thread.h"
@@ -13,6 +14,7 @@
#include <sys/time.h> // NOLINT
#include "platform/assert.h"
+#include "platform/signal_blocker.h"
#include "platform/utils.h"
namespace dart {
@@ -85,6 +87,21 @@
};
+// Spawned threads inherit their spawner's signal mask. We sometimes spawn
+// threads for running Dart code from a thread that is blocking SIGPROF.
+// This function explicitly unblocks SIGPROF so the profiler continues to
+// sample this thread.
+static void UnblockSIGPROF() {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGPROF);
+ int r = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ USE(r);
+ ASSERT(r == 0);
+ ASSERT(!CHECK_IS_BLOCKING(SIGPROF));
+}
+
+
// Dispatch to the thread start function provided by the caller. This trampoline
// is used to ensure that the thread is properly destroyed if the thread just
// exits.
@@ -101,7 +118,7 @@
if (thread != NULL) {
OSThread::SetCurrent(thread);
thread->set_name(name);
-
+ UnblockSIGPROF();
// Call the supplied thread start function handing it its parameters.
function(parameter);
}
@@ -204,17 +221,6 @@
}
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
- ASSERT(thread_id == GetCurrentThreadId());
- ASSERT(cpu_usage != NULL);
- struct timespec ts;
- int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- ASSERT(r == 0);
- *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
- kNanosecondsPerMicrosecond;
-}
-
-
Mutex::Mutex() {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index 42dd360..4c7d094 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -195,30 +195,6 @@
}
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
- ASSERT(thread_id == GetCurrentThreadId());
- ASSERT(cpu_usage != NULL);
- // TODO(johnmccutchan): Enable this after fixing issue with macos directory
- // watcher.
- const bool get_cpu_usage = false;
- if (get_cpu_usage) {
- mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
- thread_basic_info_data_t info_data;
- thread_basic_info_t info = &info_data;
- mach_port_t thread_port = mach_thread_self();
- kern_return_t r = thread_info(thread_port, THREAD_BASIC_INFO,
- (thread_info_t)info, &count);
- mach_port_deallocate(mach_task_self(), thread_port);
- if (r == KERN_SUCCESS) {
- *cpu_usage = (info->user_time.seconds * kMicrosecondsPerSecond) +
- info->user_time.microseconds;
- return;
- }
- }
- *cpu_usage = 0;
-}
-
-
Mutex::Mutex() {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index 9d282bc..e4083dc 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -173,38 +173,6 @@
}
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
- static const int64_t kTimeEpoc = 116444736000000000LL;
- static const int64_t kTimeScaler = 10; // 100 ns to us.
- // Although win32 uses 64-bit integers for representing timestamps,
- // these are packed into a FILETIME structure. The FILETIME
- // structure is just a struct representing a 64-bit integer. The
- // TimeStamp union allows access to both a FILETIME and an integer
- // representation of the timestamp. The Windows timestamp is in
- // 100-nanosecond intervals since January 1, 1601.
- union TimeStamp {
- FILETIME ft_;
- int64_t t_;
- };
- ASSERT(cpu_usage != NULL);
- TimeStamp created;
- TimeStamp exited;
- TimeStamp kernel;
- TimeStamp user;
- HANDLE handle = OpenThread(THREAD_QUERY_INFORMATION, false, thread_id);
- BOOL result = GetThreadTimes(handle,
- &created.ft_,
- &exited.ft_,
- &kernel.ft_,
- &user.ft_);
- CloseHandle(handle);
- if (!result) {
- FATAL1("GetThreadCpuUsage failed %d\n", GetLastError());
- }
- *cpu_usage = (user.t_ - kTimeEpoc) / kTimeScaler;
-}
-
-
void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) {
ASSERT(key != kUnsetThreadLocalKey);
BOOL result = TlsSetValue(key, reinterpret_cast<void*>(value));
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 2548a4c..bb2d634 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -160,6 +160,12 @@
}
+int64_t OS::GetCurrentThreadCPUMicros() {
+ // TODO(johnmccutchan): Implement. See base/time_win.cc for details.
+ return -1;
+}
+
+
void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
const int kMinimumAlignment = 16;
ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 05e01fb..64b1d5e 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -211,7 +211,7 @@
} else {
// Should not allocate executable pages when running from a precompiled
// snapshot.
- ASSERT(!Dart::IsRunningPrecompiledCode());
+ ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
if (exec_pages_ == NULL) {
exec_pages_ = page;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 80c6021..0ace98b 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -364,10 +364,11 @@
Parser::Parser(const Script& script,
const Library& library,
TokenPosition token_pos)
- : isolate_(Thread::Current()->isolate()),
- thread_(Thread::Current()),
+ : thread_(Thread::Current()),
+ isolate_(thread()->isolate()),
script_(Script::Handle(zone(), script.raw())),
- tokens_iterator_(TokenStream::Handle(zone(), script.tokens()),
+ tokens_iterator_(zone(),
+ TokenStream::Handle(zone(), script.tokens()),
token_pos),
token_kind_(Token::kILLEGAL),
current_block_(NULL),
@@ -395,10 +396,11 @@
Parser::Parser(const Script& script,
ParsedFunction* parsed_function,
TokenPosition token_pos)
- : isolate_(Thread::Current()->isolate()),
- thread_(Thread::Current()),
+ : thread_(Thread::Current()),
+ isolate_(thread()->isolate()),
script_(Script::Handle(zone(), script.raw())),
- tokens_iterator_(TokenStream::Handle(zone(), script.tokens()),
+ tokens_iterator_(zone(),
+ TokenStream::Handle(zone(), script.tokens()),
token_pos),
token_kind_(Token::kILLEGAL),
current_block_(NULL),
@@ -1254,12 +1256,11 @@
field.token_pos()));
initializer.set_result_type(AbstractType::Handle(zone, field.type()));
// Static initializer functions are hidden from the user.
- // Since they are only executed once, we avoid optimizing
- // and inlining them. After the field is initialized, the
- // compiler can eliminate the call to the static initializer.
+ // Since they are only executed once, we avoid inlining them.
+ // After the field is initialized, the compiler can eliminate
+ // the call to the static initializer.
initializer.set_is_reflectable(false);
initializer.set_is_debuggable(false);
- initializer.SetIsOptimizable(false);
initializer.set_is_inlinable(false);
ParsedFunction* parsed_function = new ParsedFunction(thread, initializer);
@@ -2749,8 +2750,8 @@
// no existing names.
nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array()));
- AstNode* nsm_call =
- MakeStaticCall(Symbols::NoSuchMethodError(),
+ AstNode* nsm_call = MakeStaticCall(
+ Symbols::NoSuchMethodError(),
Library::PrivateCoreLibName(Symbols::ThrowNew()),
nsm_args);
@@ -3297,7 +3298,9 @@
// The number of parameters and their type are not yet set in local
// functions, since they are not 'top-level' parsed.
- if (func.IsLocalFunction()) {
+ // However, they are already set when the local function is compiled, since
+ // the local function was parsed when its parent was compiled.
+ if (func.parameter_types() == Object::empty_array().raw()) {
AddFormalParamsToFunction(¶ms, func);
}
SetupDefaultsForOptionalParams(params);
@@ -5920,10 +5923,10 @@
CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url));
// Create a new library if it does not exist yet.
- Library& library = Library::Handle(Z, Library::LookupLibrary(canon_url));
+ Library& library = Library::Handle(Z, Library::LookupLibrary(T, canon_url));
if (library.IsNull()) {
library = Library::New(canon_url);
- library.Register();
+ library.Register(T);
}
// If loading hasn't been requested yet, and if this is not a deferred
@@ -7287,6 +7290,8 @@
params->has_optional_positional_parameters);
const int num_parameters = params->parameters->length();
ASSERT(num_parameters == func.NumParameters());
+ ASSERT(func.parameter_types() == Object::empty_array().raw());
+ ASSERT(func.parameter_names() == Object::empty_array().raw());
func.set_parameter_types(Array::Handle(Array::New(num_parameters,
Heap::kOld)));
func.set_parameter_names(Array::Handle(Array::New(num_parameters,
@@ -10022,6 +10027,56 @@
ReportError(expr_pos, "generator functions may not return a value");
}
AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
+ if (I->type_checks() &&
+ current_function().IsAsyncClosure() &&
+ (current_block_->scope->function_level() == 0)) {
+ // In checked mode, when the declared result type is Future<T>, verify
+ // that the returned expression is of type T or Future<T> as follows:
+ // return temp = expr, temp is Future ? temp as Future<T> : temp as T;
+ // In case of a mismatch, we need a TypeError and not a CastError, so
+ // we do not actually implement an "as" test, but an "assignable" test.
+ const Function& async_func =
+ Function::Handle(Z, current_function().parent_function());
+ const AbstractType& result_type =
+ AbstractType::ZoneHandle(Z, async_func.result_type());
+ const Class& future_class =
+ Class::ZoneHandle(Z, I->object_store()->future_class());
+ ASSERT(!future_class.IsNull());
+ if (result_type.type_class() == future_class.raw()) {
+ const TypeArguments& result_type_args =
+ TypeArguments::ZoneHandle(Z, result_type.arguments());
+ if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) {
+ const AbstractType& result_type_arg =
+ AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0));
+ LetNode* checked_expr = new(Z) LetNode(expr_pos);
+ LocalVariable* temp = checked_expr->AddInitializer(expr);
+ temp->set_is_final();
+ const AbstractType& future_type =
+ AbstractType::ZoneHandle(Z, future_class.RareType());
+ AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp);
+ is_future = new(Z) ComparisonNode(expr_pos,
+ Token::kIS,
+ is_future,
+ new(Z) TypeNode(expr_pos,
+ future_type));
+ AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp);
+ as_future_t = new(Z) AssignableNode(expr_pos,
+ as_future_t,
+ result_type,
+ Symbols::FunctionResult());
+ AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp);
+ as_t = new(Z) AssignableNode(expr_pos,
+ as_t,
+ result_type_arg,
+ Symbols::FunctionResult());
+ checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos,
+ is_future,
+ as_future_t,
+ as_t));
+ expr = checked_expr;
+ }
+ }
+ }
statement = new(Z) ReturnNode(statement_pos, expr);
} else {
if (current_function().IsSyncGenClosure() &&
@@ -11994,7 +12049,7 @@
return HashValue(String::HashRawSymbol(key.script_url.raw()),
key.token_pos.value());
}
- // Used by CachConstantValue if a new constant is added to the map.
+ // Used by CacheConstantValue if a new constant is added to the map.
static RawObject* NewKey(const ConstantPosKey& key) {
const Array& key_obj = Array::Handle(Array::New(2));
key_obj.SetAt(0, key.script_url);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index dcd03a6..eb9f54a 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -850,8 +850,8 @@
Isolate* isolate() const { return isolate_; }
Zone* zone() const { return thread_->zone(); }
+ Thread* thread_; // Cached current thread.
Isolate* isolate_; // Cached current isolate.
- Thread* thread_;
Script& script_;
TokenStream::Iterator tokens_iterator_;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 0bb6669..924d8a1 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -54,6 +54,7 @@
DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
"Max number of attempts with speculative inlining (precompilation only)");
+DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations");
DECLARE_FLAG(bool, allocation_sinking);
DECLARE_FLAG(bool, common_subexpression_elimination);
@@ -168,8 +169,7 @@
// because their class hasn't been finalized yet.
FinalizeAllClasses();
- const intptr_t kPrecompilerRounds = 1;
- for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
+ for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
if (FLAG_trace_precompiler) {
THR_Print("Precompiler round %" Pd "\n", round);
}
@@ -229,16 +229,24 @@
zone_ = NULL;
}
- intptr_t dropped_symbols_count = Symbols::Compact(I);
+ intptr_t symbols_before = -1;
+ intptr_t symbols_after = -1;
+ intptr_t capacity = -1;
+ if (FLAG_trace_precompiler) {
+ Symbols::GetStats(I, &symbols_before, &capacity);
+ }
+
+ Symbols::Compact(I);
if (FLAG_trace_precompiler) {
+ Symbols::GetStats(I, &symbols_after, &capacity);
THR_Print("Precompiled %" Pd " functions,", function_count_);
THR_Print(" %" Pd " dynamic types,", class_count_);
THR_Print(" %" Pd " dynamic selectors.\n", selector_count_);
THR_Print("Dropped %" Pd " functions,", dropped_function_count_);
THR_Print(" %" Pd " fields,", dropped_field_count_);
- THR_Print(" %" Pd " symbols,", dropped_symbols_count);
+ THR_Print(" %" Pd " symbols,", symbols_before - symbols_after);
THR_Print(" %" Pd " types,", dropped_type_count_);
THR_Print(" %" Pd " type arguments,", dropped_typearg_count_);
THR_Print(" %" Pd " classes,", dropped_class_count_);
@@ -354,7 +362,7 @@
class_name = Symbols::New(thread(), entry_points[i].class_name);
function_name = Symbols::New(thread(), entry_points[i].function_name);
- lib = Library::LookupLibrary(library_uri);
+ lib = Library::LookupLibrary(T, library_uri);
if (lib.IsNull()) {
String& msg = String::Handle(Z, String::NewFormatted(
"Cannot find entry point %s\n", entry_points[i].library_uri));
@@ -760,22 +768,18 @@
const bool is_initialized = value.raw() != Object::sentinel().raw();
if (is_initialized && !reset_fields_) return;
- if (!field.HasPrecompiledInitializer()) {
+ if (!field.HasPrecompiledInitializer() ||
+ !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
if (FLAG_trace_precompiler) {
THR_Print("Precompiling initializer for %s\n", field.ToCString());
}
- ASSERT(!Dart::IsRunningPrecompiledCode());
- field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
+ ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
const Function& initializer =
- Function::Handle(CompileStaticInitializer(field));
- if (!initializer.IsNull()) {
- field.SetPrecompiledInitializer(initializer);
- }
+ Function::Handle(Z, CompileStaticInitializer(field));
+ ASSERT(!initializer.IsNull());
+ field.SetPrecompiledInitializer(initializer);
+ AddCalleesOf(initializer);
}
-
- const Function& function =
- Function::Handle(Z, field.PrecompiledInitializer());
- AddCalleesOf(function);
}
}
}
@@ -783,23 +787,24 @@
RawFunction* Precompiler::CompileStaticInitializer(const Field& field) {
ASSERT(field.is_static());
- if (field.HasPrecompiledInitializer()) {
- // TODO(rmacnak): Investigate why this happens for _enum_names.
- THR_Print("Warning: Ignoring repeated request for initializer for %s\n",
- field.ToCString());
- return Function::null();
- }
+ ASSERT(!field.HasPrecompiledInitializer());
Thread* thread = Thread::Current();
StackZone zone(thread);
ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field);
parsed_function->AllocateVariables();
- // Non-optimized code generator.
DartCompilationPipeline pipeline;
PrecompileParsedFunctionHelper helper(parsed_function,
- /* optimized = */ false);
- helper.Compile(&pipeline);
+ /* optimized = */ true);
+ bool success = helper.Compile(&pipeline);
+ ASSERT(success);
+
+ if ((FLAG_disassemble || FLAG_disassemble_optimized) &&
+ FlowGraphPrinter::ShouldPrint(parsed_function->function())) {
+ Disassembler::DisassembleCode(parsed_function->function(),
+ /* optimized = */ true);
+ }
return parsed_function->function().raw();
}
@@ -818,8 +823,6 @@
Function& initializer = Function::Handle();
if (!field.HasPrecompiledInitializer()) {
initializer = CompileStaticInitializer(field);
- Code::Handle(initializer.unoptimized_code()).set_var_descriptors(
- Object::empty_var_descriptors());
} else {
initializer ^= field.PrecompiledInitializer();
}
@@ -1638,7 +1641,8 @@
void Precompiler::DropLibraries() {
const GrowableObjectArray& retained_libraries =
GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
- Library& root_lib = Library::Handle(Z, I->object_store()->root_library());
+ const Library& root_lib = Library::Handle(Z,
+ I->object_store()->root_library());
Library& lib = Library::Handle(Z);
for (intptr_t i = 0; i < libraries_.Length(); i++) {
@@ -1668,7 +1672,7 @@
}
}
- I->object_store()->set_libraries(retained_libraries);
+ Library::RegisterLibraries(T, retained_libraries);
libraries_ = retained_libraries.raw();
}
@@ -1959,6 +1963,8 @@
Library& lib = Library::Handle(Z);
Class& cls = Class::Handle(Z);
Array& functions = Array::Handle(Z);
+ Array& fields = Array::Handle(Z);
+ Field& field = Field::Handle(Z);
Object& object = Object::Handle(Z);
Function& function = Function::Handle(Z);
GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
@@ -1990,6 +1996,14 @@
visitor->VisitFunction(function);
}
}
+ fields = cls.fields();
+ for (intptr_t j = 0; j < fields.Length(); j++) {
+ field ^= fields.At(j);
+ if (field.is_static() && field.HasPrecompiledInitializer()) {
+ function ^= field.PrecompiledInitializer();
+ visitor->VisitFunction(function);
+ }
+ }
}
}
closures = isolate()->object_store()->closure_functions();
@@ -2130,6 +2144,8 @@
ASSERT(FLAG_precompiled_mode);
const Function& function = parsed_function()->function();
if (optimized() && !function.IsOptimizable()) {
+ // All functions compiled by precompiler must be optimizable.
+ UNREACHABLE();
return false;
}
bool is_compiled = false;
@@ -2705,7 +2721,7 @@
per_compile_timer.Stop();
- if (trace_compiler && success) {
+ if (trace_compiler) {
THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
function.ToFullyQualifiedCString(),
Code::Handle(function.CurrentCode()).EntryPoint(),
@@ -2718,10 +2734,7 @@
} else if (FLAG_disassemble_optimized &&
optimized &&
FlowGraphPrinter::ShouldPrint(function)) {
- // TODO(fschneider): Print unoptimized code along with the optimized code.
- THR_Print("*** BEGIN CODE\n");
Disassembler::DisassembleCode(function, true);
- THR_Print("*** END CODE\n");
}
return Error::null();
} else {
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index c0ac69d..4d5c4a5 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -2544,12 +2544,13 @@
// No function.
return NULL;
}
- const Script& script = Script::Handle(function.script());
+ Zone* zone = Thread::Current()->zone();
+ const Script& script = Script::Handle(zone, function.script());
if (script.IsNull()) {
// No script.
return NULL;
}
- const TokenStream& token_stream = TokenStream::Handle(script.tokens());
+ const TokenStream& token_stream = TokenStream::Handle(zone, script.tokens());
if (token_stream.IsNull()) {
// No token position.
return NULL;
@@ -2567,8 +2568,8 @@
if (token_pos.IsSynthetic()) {
token_pos = token_pos.FromSynthetic();
}
- TokenStream::Iterator iterator(token_stream, token_pos);
- const String& str = String::Handle(iterator.CurrentLiteral());
+ TokenStream::Iterator iterator(zone, token_stream, token_pos);
+ const String& str = String::Handle(zone, iterator.CurrentLiteral());
if (str.IsNull()) {
return NULL;
}
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 12d5234..977ba55 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -432,38 +432,32 @@
return TryAcquireTagBit<RememberedBit>();
}
- bool IsDartInstance() {
- return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
+#define DEFINE_IS_CID(clazz) \
+ bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
+CLASS_LIST(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz) \
+ bool IsTypedData##clazz() const { \
+ return ((GetClassId() == kTypedData##clazz##Cid)); \
+ } \
+ bool IsTypedDataView##clazz() const { \
+ return ((GetClassId() == kTypedData##clazz##ViewCid)); \
+ } \
+ bool IsExternalTypedData##clazz() const { \
+ return ((GetClassId() == kExternalTypedData##clazz##Cid)); \
}
- bool IsFreeListElement() {
- return ((GetClassId() == kFreeListElement));
- }
- bool IsScript() {
- return ((GetClassId() == kScriptCid));
- }
- bool IsField() {
- return ((GetClassId() == kFieldCid));
- }
- bool IsFunction() {
- return ((GetClassId() == kFunctionCid));
- }
- bool IsInstructions() {
- return ((GetClassId() == kInstructionsCid));
- }
- bool IsCode() {
- return ((GetClassId() == kCodeCid));
- }
- bool IsString() {
+CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+ bool IsStringInstance() const {
return IsStringClassId(GetClassId());
}
- bool IsStackmap() {
- return ((GetClassId() == kStackmapCid));
+ bool IsDartInstance() const {
+ return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
}
- bool IsPcDescriptors() {
- return ((GetClassId() == kPcDescriptorsCid));
- }
- bool IsOneByteString() {
- return ((GetClassId() == kOneByteStringCid));
+ bool IsFreeListElement() const {
+ return ((GetClassId() == kFreeListElement));
}
intptr_t Size() const {
@@ -721,6 +715,8 @@
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
@@ -949,6 +945,8 @@
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->initializer_);
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
@@ -1029,6 +1027,8 @@
case Snapshot::kScript:
return reinterpret_cast<RawObject**>(&ptr()->tokens_);
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
@@ -1515,6 +1515,8 @@
case Snapshot::kAppWithJIT:
return to();
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
@@ -1646,6 +1648,8 @@
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->importer_);
case Snapshot::kMessage:
+ case Snapshot::kNone:
+ case Snapshot::kInvalid:
break;
}
UNREACHABLE();
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index eec2523..196e145 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -644,13 +644,12 @@
// Context scope.
if (ptr()->context_scope_ == Object::empty_context_scope().raw()) {
writer->WriteVMIsolateObject(kEmptyContextScopeObject);
+ } else if (ptr()->context_scope_->ptr()->is_implicit_ ||
+ (kind == Snapshot::kAppWithJIT)) {
+ writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
} else {
- if (ptr()->context_scope_->ptr()->is_implicit_) {
- writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
- } else {
- // We don't write non implicit context scopes in the snapshot.
- writer->WriteVMIsolateObject(kNullObject);
- }
+ // We don't write non implicit context scopes in the snapshot.
+ writer->WriteVMIsolateObject(kNullObject);
}
// Parent function.
@@ -730,7 +729,7 @@
func.set_kind_tag(reader->Read<uint32_t>());
func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
func.set_usage_counter(0);
func.set_deoptimization_counter(0);
func.set_optimized_instruction_count(0);
@@ -748,12 +747,23 @@
func.raw()->from(), func.raw()->to_snapshot(),
kAsReference);
// Initialize all fields that are not part of the snapshot.
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
+ // Read the code object and fixup entry point.
func.ClearICDataArray();
func.ClearCode();
- // Read the code object and fixup entry point.
(*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
func.SetInstructions(*reader->CodeHandle());
+ } else if (kind == Snapshot::kAppWithJIT) {
+ (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
+ func.set_ic_data_array(*reader->ArrayHandle());
+ (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
+ func.set_unoptimized_code(*reader->CodeHandle());
+ if (!reader->CodeHandle()->IsNull()) {
+ func.SetInstructions(*reader->CodeHandle());
+ func.set_was_compiled(true);
+ } else {
+ func.ClearCode();
+ }
} else {
bool is_optimized = func.usage_counter() != 0;
if (is_optimized) {
@@ -784,7 +794,7 @@
intptr_t tags = writer->GetObjectTags(ptr()->owner_);
intptr_t cid = ClassIdTag::decode(tags);
owner_is_class = (cid == kClassCid);
- is_in_fullsnapshot = owner_is_class ?
+ is_in_fullsnapshot = owner_is_class ?
Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(ptr()->owner_)) :
PatchClass::IsInFullSnapshot(
reinterpret_cast<RawPatchClass*>(ptr()->owner_));
@@ -811,7 +821,7 @@
writer->Write<int16_t>(ptr()->num_fixed_parameters_);
writer->Write<int16_t>(ptr()->num_optional_parameters_);
writer->Write<uint32_t>(ptr()->kind_tag_);
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
// Omit fields used to support de/reoptimization.
} else {
if (is_optimized) {
@@ -827,15 +837,16 @@
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
visitor.VisitPointers(from(), to_snapshot());
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
ASSERT(ptr()->ic_data_array_ == Array::null());
ASSERT((ptr()->code_ == ptr()->unoptimized_code_) ||
(ptr()->unoptimized_code_ == Code::null()));
- // Write out the code object as we are generating a precompiled snapshot.
writer->WriteObjectImpl(ptr()->code_, kAsInlinedObject);
+ } else if (kind == Snapshot::kAppWithJIT) {
+ writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
+ writer->WriteObjectImpl(ptr()->unoptimized_code_, kAsInlinedObject);
} else if (is_optimized) {
- // Write out the ic data array as the function is optimized or
- // we are generating a precompiled snapshot.
+ // Write out the ic data array as the function is optimized.
writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
}
} else {
@@ -922,6 +933,9 @@
// For precompiled static fields, the value was already reset and
// initializer_ now contains a Function.
writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
+ } else if (Field::ConstBit::decode(ptr()->kind_bits_)) {
+ // Do not reset const fields.
+ writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
} else {
// Otherwise, for static fields we write out the initial static value.
writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
@@ -1132,7 +1146,7 @@
if ((kind == Snapshot::kScript) && is_in_fullsnapshot) {
// Lookup the object as it should already exist in the heap.
*reader->StringHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
- library = Library::LookupLibrary(*reader->StringHandle());
+ library = Library::LookupLibrary(reader->thread(), *reader->StringHandle());
ASSERT(library.is_in_fullsnapshot());
} else {
// Allocate library object.
@@ -1174,7 +1188,7 @@
if (!Snapshot::IsFull(kind)) {
// The cache of resolved names in library scope is not serialized.
library.InitResolvedNamesCache(kInitialNameCacheSize);
- library.Register();
+ library.Register(reader->thread());
} else {
library.InitResolvedNamesCache(kInitialNameCacheSize, reader);
}
@@ -1436,9 +1450,21 @@
intptr_t pointer_offsets_length =
Code::PtrOffBits::decode(ptr()->state_bits_);
if (pointer_offsets_length != 0) {
- // Should only be IA32.
FATAL("Cannot serialize code with embedded pointers");
}
+ if (kind == Snapshot::kAppNoJIT) {
+ // No disabled code in precompilation.
+ ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
+ } else {
+ ASSERT(kind == Snapshot::kAppWithJIT);
+ // We never include optimized code in JIT precompilation. Deoptimization
+ // requires code patching and we cannot patch code that is shared between
+ // isolates and should not mutate memory allocated by the embedder.
+ bool is_optimized = Code::PtrOffBits::decode(ptr()->state_bits_);
+ if (is_optimized) {
+ FATAL("Cannot include optimized code in a JIT snapshot");
+ }
+ }
// Write out the serialization header value for this object.
writer->WriteInlinedObjectHeader(object_id);
@@ -1450,9 +1476,6 @@
// Write out all the non object fields.
writer->Write<int32_t>(ptr()->state_bits_);
- // No disabled code in precompilation.
- ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
-
RawInstructions* instr = ptr()->instructions_;
int32_t text_offset = writer->GetInstructionsId(instr, this);
writer->Write<int32_t>(text_offset);
@@ -1912,7 +1935,7 @@
// Allocate context object.
bool is_implicit = reader->Read<bool>();
if (is_implicit) {
- ContextScope& context_scope = ContextScope::ZoneHandle();
+ ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
if (Snapshot::IsFull(kind)) {
context_scope = reader->NewContextScope(1);
context_scope.set_is_implicit(true);
@@ -1932,6 +1955,19 @@
context_scope.SetContextIndexAt(0, 0);
context_scope.SetContextLevelAt(0, 0);
return context_scope.raw();
+ } else if (kind == Snapshot::kAppWithJIT) {
+ int32_t num_vars = reader->Read<int32_t>();
+
+ ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
+ context_scope = reader->NewContextScope(num_vars);
+ context_scope.set_is_implicit(false);
+ reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
+
+ READ_OBJECT_FIELDS(context_scope,
+ context_scope.raw()->from(),
+ context_scope.raw()->to(num_vars),
+ kAsInlinedObject);
+ return context_scope.raw();
}
UNREACHABLE();
return NULL;
@@ -1962,6 +1998,23 @@
writer->WriteObjectImpl(var->type, kAsInlinedObject);
return;
+ } else if (kind == Snapshot::kAppWithJIT) {
+ // Write out the serialization header value for this object.
+ writer->WriteInlinedObjectHeader(object_id);
+
+ // Write out the class and tags information.
+ writer->WriteVMIsolateObject(kContextScopeCid);
+ writer->WriteTags(writer->GetObjectTags(this));
+
+ // Write out is_implicit flag for the context scope.
+ writer->Write<bool>(false);
+ int32_t num_vars = ptr()->num_variables_;
+ writer->Write<int32_t>(num_vars);
+
+ SnapshotWriterVisitor visitor(writer, kAsInlinedObject);
+ visitor.VisitPointers(from(), to(num_vars));
+
+ return;
}
UNREACHABLE();
}
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 52aa4b6..2252e23 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -19,6 +19,9 @@
const char* test_class_name,
const char* test_static_function_name,
bool is_static) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+
// Setup a dart class and function.
char script_chars[1024];
OS::SNPrint(script_chars,
@@ -35,16 +38,16 @@
is_static ? "static" : "",
test_static_function_name);
- String& url = String::Handle(is_static ?
- String::New("dart-test:DartStaticResolve") :
- String::New("dart-test:DartDynamicResolve"));
- String& source = String::Handle(String::New(script_chars));
- Script& script = Script::Handle(Script::New(url,
- source,
- RawScript::kScriptTag));
- const String& lib_name = String::Handle(String::New(test_library_name));
- Library& lib = Library::Handle(Library::New(lib_name));
- lib.Register();
+ String& url = String::Handle(zone,
+ is_static ?
+ String::New("dart-test:DartStaticResolve") :
+ String::New("dart-test:DartDynamicResolve"));
+ String& source = String::Handle(zone, String::New(script_chars));
+ Script& script = Script::Handle(zone,
+ Script::New(url, source, RawScript::kScriptTag));
+ const String& lib_name = String::Handle(zone, String::New(test_library_name));
+ Library& lib = Library::Handle(zone, Library::New(lib_name));
+ lib.Register(thread);
EXPECT(CompilerTest::TestCompileScript(lib, script));
EXPECT(ClassFinalizer::ProcessPendingClasses());
}
@@ -87,7 +90,7 @@
const String& library_name = String::Handle(String::New(test_library_name));
const Library& library =
- Library::Handle(Library::LookupLibrary(library_name));
+ Library::Handle(Library::LookupLibrary(thread, library_name));
const String& class_name = String::Handle(String::New(test_class_name));
const String& static_function_name =
String::Handle(String::New(test_static_function_name));
@@ -155,7 +158,8 @@
// Now create an instance object of the class and try to
// resolve a function in it.
const String& lib_name = String::Handle(String::New(test_library_name));
- const Library& lib = Library::Handle(Library::LookupLibrary(lib_name));
+ const Library& lib = Library::Handle(Library::LookupLibrary(thread,
+ lib_name));
ASSERT(!lib.IsNull());
const Class& cls = Class::Handle(lib.LookupClass(
String::Handle(Symbols::New(thread, test_class_name))));
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index efed3c0..197c77f 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3597,7 +3597,7 @@
JSONObject jsobj(js);
jsobj.AddProperty("type", "Version");
jsobj.AddProperty("major", static_cast<intptr_t>(3));
- jsobj.AddProperty("minor", static_cast<intptr_t>(4));
+ jsobj.AddProperty("minor", static_cast<intptr_t>(5));
jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0));
jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0));
return true;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 47e77f4..e37643c 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.4
+# Dart VM Service Protocol 3.5
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.4_ of the Dart VM Service Protocol. This
+This document describes of _version 3.5_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -120,7 +120,7 @@
"result": {
"type": "Version",
"major": 3,
- "minor": 0
+ "minor": 5
}
"id": "1"
}
@@ -311,7 +311,7 @@
"result": {
"type": "Version",
"major": 3,
- "minor": 0
+ "minor": 5
}
```
@@ -2317,6 +2317,10 @@
// Has this range been compiled by the Dart VM?
bool compiled;
+ // The error while attempting to compile this range, if this
+ // report was generated with forceCompile=true.
+ @Error error [optional];
+
// Code coverage information for this range. Provided only when the
// Coverage report has been requested and the range has been
// compiled.
@@ -2519,4 +2523,5 @@
3.2 | Isolate objects now include the runnable bit and many debugger related RPCs will return an error if executed on an isolate before it is runnable.
3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
3.4 | Add the superType and mixin fields to Class. Added new pause event 'None'.
+3.5 | Add the error field to SourceReportRange.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index cb14557..fa8cd95 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -336,6 +336,7 @@
OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
ServiceIsolate::SetServiceIsolate(NULL);
ServiceIsolate::FinishedInitializing();
+ ServiceIsolate::FinishedExiting();
return;
}
@@ -501,8 +502,9 @@
void ServiceIsolate::BootVmServiceLibrary() {
+ Thread* thread = Thread::Current();
const Library& vmservice_library =
- Library::Handle(Library::LookupLibrary(Symbols::DartVMService()));
+ Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService()));
ASSERT(!vmservice_library.IsNull());
const String& boot_function_name = String::Handle(String::New("boot"));
const Function& boot_function =
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index d9ff04e..e732409 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1129,6 +1129,7 @@
{
BYTECODE(DebugBreak, A);
+#if !defined(PRODUCT)
{
const uint32_t original_bc =
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(
@@ -1141,6 +1142,10 @@
INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args)
DISPATCH_OP(original_bc);
}
+#else
+ // There should be no debug breaks in product mode.
+ UNREACHABLE();
+#endif
DISPATCH();
}
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 2f2ca6a..33570ae 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -253,7 +253,7 @@
AddBackRef(object_id, &cls, kIsDeserialized);
// Read the library/class information and lookup the class.
str_ ^= ReadObjectImpl(class_header, kAsInlinedObject, kInvalidPatchIndex, 0);
- library_ = Library::LookupLibrary(str_);
+ library_ = Library::LookupLibrary(thread(), str_);
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Invalid object found in message.");
}
@@ -280,7 +280,7 @@
AddBackRef(object_id, &func, kIsDeserialized);
// Read the library/class/function information and lookup the function.
str_ ^= ReadObjectImpl(func_header, kAsInlinedObject, kInvalidPatchIndex, 0);
- library_ = Library::LookupLibrary(str_);
+ library_ = Library::LookupLibrary(thread(), str_);
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Expected a library name, but found an invalid name.");
}
@@ -316,7 +316,7 @@
// Read the library/class/function information and lookup the function.
str_ ^= ReadObjectImpl(kAsInlinedObject);
- library_ = Library::LookupLibrary(str_);
+ library_ = Library::LookupLibrary(thread(), str_);
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Invalid Library object found in message.");
}
@@ -625,7 +625,7 @@
}
}
- if (Snapshot::IncludesCode(kind_)) {
+ if (kind_ == Snapshot::kAppNoJIT) {
ICData& ic = ICData::Handle(thread->zone());
Object& funcOrCode = Object::Handle(thread->zone());
Code& code = Code::Handle(thread->zone());
@@ -1562,8 +1562,8 @@
}
}
- ASSERT(Symbols::IsVMSymbolId(object_id));
- return Symbols::GetVMSymbol(object_id); // return VM symbol.
+ ASSERT(Symbols::IsPredefinedSymbolId(object_id));
+ return Symbols::GetPredefinedSymbol(object_id); // return VM symbol.
}
@@ -1764,7 +1764,7 @@
new ZoneGrowableArray<BackRefNode>(
kNumInitialReferencesInFullSnapshot),
thread) {
- isolate()->set_compilation_allowed(instructions_buffer_ == NULL);
+ isolate()->set_compilation_allowed(kind != Snapshot::kAppNoJIT);
ASSERT(Snapshot::IsFull(kind));
}
@@ -1818,7 +1818,7 @@
ForwardList* forward_list,
InstructionsWriter* instructions_writer,
bool can_send_any_object,
- bool vm_isolate_is_symbolic)
+ bool writing_vm_isolate)
: BaseWriter(buffer, alloc, initial_size),
thread_(thread),
kind_(kind),
@@ -1830,7 +1830,7 @@
exception_msg_(NULL),
unmarked_objects_(false),
can_send_any_object_(can_send_any_object),
- vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
+ writing_vm_isolate_(writing_vm_isolate) {
ASSERT(forward_list_ != NULL);
}
@@ -1922,9 +1922,15 @@
}
}
+ if (writing_vm_isolate_) {
+ // When we are writing the VM isolate snapshot, write out the object
+ // itself instead of a VM object id.
+ return false;
+ }
+
if (Snapshot::IsFull(kind())) {
// Check it is a predefined symbol in the VM isolate.
- id = Symbols::LookupVMSymbol(rawobj);
+ id = Symbols::LookupPredefinedSymbol(rawobj);
if (id != kInvalidIndex) {
WriteVMIsolateObject(id);
return true;
@@ -1960,10 +1966,6 @@
}
}
- if (!vm_isolate_is_symbolic()) {
- return false;
- }
-
const Object& obj = Object::Handle(rawobj);
FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString());
return false;
@@ -2011,8 +2013,7 @@
uint8_t** vm_isolate_snapshot_buffer,
uint8_t** isolate_snapshot_buffer,
ReAlloc alloc,
- InstructionsWriter* instructions_writer,
- bool vm_isolate_is_symbolic)
+ InstructionsWriter* instructions_writer)
: thread_(Thread::Current()),
kind_(kind),
vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
@@ -2023,8 +2024,8 @@
forward_list_(NULL),
instructions_writer_(instructions_writer),
scripts_(Array::Handle(zone())),
- symbol_table_(Array::Handle(zone())),
- vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
+ saved_symbol_table_(Array::Handle(zone())),
+ new_vm_symbol_table_(Array::Handle(zone())) {
ASSERT(isolate_snapshot_buffer_ != NULL);
ASSERT(alloc_ != NULL);
ASSERT(isolate() != NULL);
@@ -2033,31 +2034,49 @@
ASSERT(heap() != NULL);
ObjectStore* object_store = isolate()->object_store();
ASSERT(object_store != NULL);
- // Ensure the class table is valid.
+
#if defined(DEBUG)
+ // Ensure the class table is valid.
isolate()->ValidateClassTable();
#endif
+ // Can't have any mutation happening while we're serializing.
+ ASSERT(isolate()->background_compiler() == NULL);
- // Collect all the script objects and their accompanying token stream objects
- // into an array so that we can write it out as part of the VM isolate
- // snapshot. We first count the number of script objects, allocate an array
- // and then fill it up with the script objects.
- ScriptVisitor scripts_counter(thread());
- heap()->IterateOldObjects(&scripts_counter);
- intptr_t count = scripts_counter.count();
- scripts_ = Array::New(count, Heap::kOld);
- ScriptVisitor script_visitor(thread(), &scripts_);
- heap()->IterateOldObjects(&script_visitor);
-
+ intptr_t first_object_id = -1;
if (vm_isolate_snapshot_buffer != NULL) {
- // Stash the symbol table away for writing and reading into the vm isolate,
- // and reset the symbol table for the regular isolate so that we do not
- // write these symbols into the snapshot of a regular dart isolate.
- symbol_table_ = object_store->symbol_table();
+ // Collect all the script objects and their accompanying token stream
+ // objects into an array so that we can write it out as part of the VM
+ // isolate snapshot. We first count the number of script objects, allocate
+ // an array and then fill it up with the script objects.
+ ScriptVisitor scripts_counter(thread());
+ heap()->IterateOldObjects(&scripts_counter);
+ Dart::vm_isolate()->heap()->IterateOldObjects(&scripts_counter);
+ intptr_t count = scripts_counter.count();
+ scripts_ = Array::New(count, Heap::kOld);
+ ScriptVisitor script_visitor(thread(), &scripts_);
+ heap()->IterateOldObjects(&script_visitor);
+ Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor);
+ ASSERT(script_visitor.count() == count);
+
+ // Tuck away the current symbol table.
+ saved_symbol_table_ = object_store->symbol_table();
+
+ // Create a unified symbol table that will be written as the vm isolate's
+ // symbol table.
+ new_vm_symbol_table_ = Symbols::UnifiedSymbolTable();
+
+ // Create an empty symbol table that will be written as the isolate's symbol
+ // table.
Symbols::SetupSymbolTable(isolate());
+
+ first_object_id = kMaxPredefinedObjectIds;
+ } else {
+ intptr_t max_vm_isolate_object_id =
+ Object::vm_isolate_snapshot_object_table().Length();
+ first_object_id = kMaxPredefinedObjectIds + max_vm_isolate_object_id;
}
- forward_list_ = new ForwardList(thread(), SnapshotWriter::FirstObjectId());
+ forward_list_ = new ForwardList(thread(), first_object_id);
ASSERT(forward_list_ != NULL);
}
@@ -2065,10 +2084,11 @@
FullSnapshotWriter::~FullSnapshotWriter() {
delete forward_list_;
// We may run Dart code afterwards, restore the symbol table if needed.
- if (!symbol_table_.IsNull()) {
- isolate()->object_store()->set_symbol_table(symbol_table_);
- symbol_table_ = Array::null();
+ if (!saved_symbol_table_.IsNull()) {
+ isolate()->object_store()->set_symbol_table(saved_symbol_table_);
+ saved_symbol_table_ = Array::null();
}
+ new_vm_symbol_table_ = Array::null();
scripts_ = Array::null();
}
@@ -2083,7 +2103,7 @@
forward_list_,
instructions_writer_,
true, /* can_send_any_object */
- vm_isolate_is_symbolic_);
+ true /* writing_vm_isolate */);
// Write full snapshot for the VM isolate.
// Setup for long jump in case there is an exception while writing
// the snapshot.
@@ -2099,10 +2119,10 @@
* Now Write out the following
* - the symbol table
* - all the scripts and token streams for these scripts
- *
+ * - the stub code (precompiled snapshots only)
**/
// Write out the symbol table.
- writer.WriteObject(symbol_table_.raw());
+ writer.WriteObject(new_vm_symbol_table_.raw());
// Write out all the script objects and the accompanying token streams
// for the bootstrap libraries so that they are in the VM isolate
@@ -2110,11 +2130,9 @@
writer.WriteObject(scripts_.raw());
if (Snapshot::IncludesCode(kind_)) {
- ASSERT(!vm_isolate_is_symbolic_);
StubCode::WriteTo(&writer);
}
-
writer.FillHeader(writer.kind());
vm_isolate_snapshot_size_ = writer.BytesWritten();
@@ -2133,7 +2151,7 @@
forward_list_,
instructions_writer_,
true, /* can_send_any_object */
- true /* vm_isolate_is_symbolic */);
+ false /* writing_vm_isolate */);
ObjectStore* object_store = isolate()->object_store();
ASSERT(object_store != NULL);
@@ -2188,28 +2206,12 @@
}
-PrecompiledSnapshotWriter::PrecompiledSnapshotWriter(
- uint8_t** vm_isolate_snapshot_buffer,
- uint8_t** isolate_snapshot_buffer,
- ReAlloc alloc,
- InstructionsWriter* instructions_writer)
- : FullSnapshotWriter(Snapshot::kAppNoJIT,
- vm_isolate_snapshot_buffer,
- isolate_snapshot_buffer,
- alloc,
- instructions_writer,
- false /* vm_isolate_is_symbolic */) {
-}
-
-
-PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {}
-
-
ForwardList::ForwardList(Thread* thread, intptr_t first_object_id)
: thread_(thread),
first_object_id_(first_object_id),
nodes_(),
first_unprocessed_object_id_(first_object_id) {
+ ASSERT(first_object_id > 0);
}
@@ -2228,7 +2230,6 @@
Node* node = new Node(&obj, state);
ASSERT(node != NULL);
nodes_.Add(node);
- ASSERT(SnapshotWriter::FirstObjectId() > 0);
ASSERT(object_id != 0);
heap()->SetObjectId(raw, object_id);
return object_id;
@@ -2237,7 +2238,6 @@
intptr_t ForwardList::FindObject(RawObject* raw) {
NoSafepointScope no_safepoint;
- ASSERT(SnapshotWriter::FirstObjectId() > 0);
intptr_t id = heap()->GetObjectId(raw);
ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw);
return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id;
@@ -2696,13 +2696,6 @@
}
-intptr_t SnapshotWriter::FirstObjectId() {
- intptr_t max_vm_isolate_object_id =
- Object::vm_isolate_snapshot_object_table().Length();
- return kMaxPredefinedObjectIds + max_vm_isolate_object_id;
-}
-
-
ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
ReAlloc alloc)
: SnapshotWriter(Thread::Current(),
@@ -2713,7 +2706,7 @@
&forward_list_,
NULL, /* instructions_writer */
true, /* can_send_any_object */
- true /* vm_isolate_is_symbolic */),
+ false /* writing_vm_isolate */),
forward_list_(thread(), kMaxPredefinedObjectIds) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
@@ -2769,7 +2762,7 @@
&forward_list_,
NULL, /* instructions_writer */
can_send_any_object,
- true /* vm_isolate_is_symbolic */),
+ false /* writing_vm_isolate */),
forward_list_(thread(), kMaxPredefinedObjectIds) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 3dc6aae..1c0fddb 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -152,6 +152,8 @@
public:
enum Kind {
kCore = 0, // Full snapshot of core libraries. No root library, no code.
+ kScript, // A partial snapshot of only the application script.
+ kMessage, // A partial snapshot used only for isolate messaging.
kAppWithJIT, // Full snapshot of core libraries and application. Has some
// code, but may compile in the future because we haven't
// necessarily included code for every function or to
@@ -159,8 +161,8 @@
kAppNoJIT, // Full snapshot of core libraries and application. Has
// complete code for the application that never deopts. Will
// not compile in the future.
- kScript, // A partial snapshot of only the application script.
- kMessage, // A partial snapshot used only for isolate messaging.
+ kNone, // dart_bootstrap/gen_snapshot
+ kInvalid
};
static const int kHeaderSize = 2 * sizeof(int64_t);
@@ -919,7 +921,8 @@
ReAlloc alloc,
intptr_t initial_size)
: InstructionsWriter(),
- assembly_stream_(assembly_buffer, alloc, initial_size) {
+ assembly_stream_(assembly_buffer, alloc, initial_size),
+ binary_size_(0) {
}
virtual void Write();
@@ -986,7 +989,7 @@
ForwardList* forward_list,
InstructionsWriter* instructions_writer,
bool can_send_any_object,
- bool vm_isolate_is_symbolic);
+ bool writing_vm_isolate = false);
public:
// Snapshot kind.
@@ -1012,14 +1015,12 @@
exception_msg_ = msg;
}
bool can_send_any_object() const { return can_send_any_object_; }
- bool vm_isolate_is_symbolic() const { return vm_isolate_is_symbolic_; }
+ bool writing_vm_isolate() const { return writing_vm_isolate_; }
void ThrowException(Exceptions::ExceptionType type, const char* msg);
// Write a version string for the snapshot.
void WriteVersion();
- static intptr_t FirstObjectId();
-
int32_t GetInstructionsId(RawInstructions* instructions, RawCode* code) {
return instructions_writer_->GetOffsetFor(instructions, code);
}
@@ -1065,15 +1066,6 @@
bool AllowObjectsInDartLibrary(RawLibrary* library);
intptr_t FindVmSnapshotObject(RawObject* rawobj);
- void InitializeForwardList(ForwardList* forward_list) {
- ASSERT(forward_list_ == NULL);
- forward_list_ = forward_list;
- }
- void ResetForwardList() {
- ASSERT(forward_list_ != NULL);
- forward_list_ = NULL;
- }
-
ObjectStore* object_store() const { return object_store_; }
private:
@@ -1087,7 +1079,7 @@
const char* exception_msg_; // Message associated with exception.
bool unmarked_objects_; // True if marked objects have been unmarked.
bool can_send_any_object_; // True if any Dart instance can be sent.
- bool vm_isolate_is_symbolic_;
+ bool writing_vm_isolate_;
friend class FullSnapshotWriter;
friend class RawArray;
@@ -1128,8 +1120,7 @@
uint8_t** vm_isolate_snapshot_buffer,
uint8_t** isolate_snapshot_buffer,
ReAlloc alloc,
- InstructionsWriter* instructions_writer,
- bool vm_isolate_is_symbolic);
+ InstructionsWriter* instructions_writer);
~FullSnapshotWriter();
uint8_t** vm_isolate_snapshot_buffer() {
@@ -1172,23 +1163,13 @@
ForwardList* forward_list_;
InstructionsWriter* instructions_writer_;
Array& scripts_;
- Array& symbol_table_;
- bool vm_isolate_is_symbolic_;
+ Array& saved_symbol_table_;
+ Array& new_vm_symbol_table_;
DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter);
};
-class PrecompiledSnapshotWriter : public FullSnapshotWriter {
- public:
- PrecompiledSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
- uint8_t** isolate_snapshot_buffer,
- ReAlloc alloc,
- InstructionsWriter* instructions_writer);
- ~PrecompiledSnapshotWriter();
-};
-
-
class ScriptSnapshotWriter : public SnapshotWriter {
public:
static const intptr_t kInitialSize = 64 * KB;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index ef7a10c..52db512 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -835,8 +835,7 @@
kInitialSize,
&forward_list_,
NULL, /* test_writer */
- true, /* can_send_any_object */
- true /* vm_isolate_is_symbolic */),
+ true /* can_send_any_object */),
forward_list_(thread(), kMaxPredefinedObjectIds) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
@@ -859,27 +858,32 @@
// Check if we are able to generate the source from the token stream.
// Rescan this source and compare the token stream to see if they are
// the same.
- const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
+ Zone* zone = Thread::Current()->zone();
+ const TokenStream& expected_tokens =
+ TokenStream::Handle(zone, script.tokens());
TokenStream::Iterator expected_iterator(
+ zone,
expected_tokens,
TokenPosition::kMinSource,
TokenStream::Iterator::kAllTokens);
- const String& str = String::Handle(expected_tokens.GenerateSource());
- const String& private_key = String::Handle(expected_tokens.PrivateKey());
+ const String& str = String::Handle(zone, expected_tokens.GenerateSource());
+ const String& private_key =
+ String::Handle(zone, expected_tokens.PrivateKey());
Scanner scanner(str, private_key);
const TokenStream& reconstructed_tokens =
- TokenStream::Handle(TokenStream::New(scanner.GetStream(),
- private_key,
- false));
+ TokenStream::Handle(zone, TokenStream::New(scanner.GetStream(),
+ private_key,
+ false));
expected_iterator.SetCurrentPosition(TokenPosition::kMinSource);
TokenStream::Iterator reconstructed_iterator(
+ zone,
reconstructed_tokens,
TokenPosition::kMinSource,
TokenStream::Iterator::kAllTokens);
Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
Token::Kind reconstructed_kind = reconstructed_iterator.CurrentTokenKind();
- String& expected_literal = String::Handle();
- String& actual_literal = String::Handle();
+ String& expected_literal = String::Handle(zone);
+ String& actual_literal = String::Handle(zone);
while (expected_kind != Token::kEOS && reconstructed_kind != Token::kEOS) {
EXPECT_EQ(expected_kind, reconstructed_kind);
expected_literal ^= expected_iterator.CurrentLiteral();
@@ -937,14 +941,15 @@
" }\n"
"}\n";
- String& url = String::Handle(String::New("dart-test:SerializeScript"));
- String& source = String::Handle(String::New(kScriptChars));
- Script& script = Script::Handle(Script::New(url,
- source,
- RawScript::kScriptTag));
- const String& lib_url = String::Handle(Symbols::New(thread, "TestLib"));
- Library& lib = Library::Handle(Library::New(lib_url));
- lib.Register();
+ Zone* zone = thread->zone();
+ String& url = String::Handle(zone, String::New("dart-test:SerializeScript"));
+ String& source = String::Handle(zone, String::New(kScriptChars));
+ Script& script = Script::Handle(zone, Script::New(url,
+ source,
+ RawScript::kScriptTag));
+ const String& lib_url = String::Handle(zone, Symbols::New(thread, "TestLib"));
+ Library& lib = Library::Handle(zone, Library::New(lib_url));
+ lib.Register(thread);
EXPECT(CompilerTest::TestCompileScript(lib, script));
// Write snapshot with script content.
@@ -954,27 +959,30 @@
// Read object back from the snapshot.
ScriptSnapshotReader reader(buffer, writer.BytesWritten(), thread);
- Script& serialized_script = Script::Handle(thread->zone());
+ Script& serialized_script = Script::Handle(zone);
serialized_script ^= reader.ReadObject();
// Check if the serialized script object matches the original script.
- String& expected_literal = String::Handle();
- String& actual_literal = String::Handle();
- String& str = String::Handle();
+ String& expected_literal = String::Handle(zone);
+ String& actual_literal = String::Handle(zone);
+ String& str = String::Handle(zone);
str ^= serialized_script.url();
EXPECT(url.Equals(str));
- const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
+ const TokenStream& expected_tokens =
+ TokenStream::Handle(zone, script.tokens());
const TokenStream& serialized_tokens =
- TokenStream::Handle(serialized_script.tokens());
+ TokenStream::Handle(zone, serialized_script.tokens());
const ExternalTypedData& expected_data =
- ExternalTypedData::Handle(expected_tokens.GetStream());
+ ExternalTypedData::Handle(zone, expected_tokens.GetStream());
const ExternalTypedData& serialized_data =
- ExternalTypedData::Handle(serialized_tokens.GetStream());
+ ExternalTypedData::Handle(zone, serialized_tokens.GetStream());
EXPECT_EQ(expected_data.Length(), serialized_data.Length());
- TokenStream::Iterator expected_iterator(expected_tokens,
+ TokenStream::Iterator expected_iterator(zone,
+ expected_tokens,
TokenPosition::kMinSource);
- TokenStream::Iterator serialized_iterator(serialized_tokens,
+ TokenStream::Iterator serialized_iterator(zone,
+ serialized_tokens,
TokenPosition::kMinSource);
Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
Token::Kind serialized_kind = serialized_iterator.CurrentTokenKind();
@@ -1187,8 +1195,7 @@
NULL,
&isolate_snapshot_buffer,
&malloc_allocator,
- NULL, /* instructions_writer */
- true);
+ NULL /* instructions_writer */);
writer.WriteFullSnapshot();
}
}
@@ -1248,8 +1255,7 @@
NULL,
&isolate_snapshot_buffer,
&malloc_allocator,
- NULL, /* instructions_writer */
- true /* vm_isolate_is_symbolic */);
+ NULL /* instructions_writer */);
writer.WriteFullSnapshot();
}
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 1d3e818..ee8858d6 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -145,8 +145,16 @@
RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
while (iter.MoveNext()) {
HANDLESCOPE(thread());
+ // TODO(zra): Remove this bailout once DBC has reliable ICData.
+#if defined(TARGET_ARCH_DBC)
+ if (iter.DeoptId() >= ic_data_array->length()) {
+ continue;
+ }
+#else
+ ASSERT(iter.DeoptId() < ic_data_array->length());
+#endif
const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
- if (!ic_data->IsNull()) {
+ if (ic_data != NULL) {
const TokenPosition token_pos = iter.TokenPos();
if ((token_pos < begin_pos) || (token_pos > end_pos)) {
// Does not correspond to a valid source position.
@@ -158,6 +166,7 @@
}
}
+
void SourceReport::PrintCoverageData(JSONObject* jsobj,
const Function& function,
const Code& code) {
@@ -186,8 +195,16 @@
RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
while (iter.MoveNext()) {
HANDLESCOPE(thread());
+ // TODO(zra): Remove this bailout once DBC has reliable ICData.
+#if defined(TARGET_ARCH_DBC)
+ if (iter.DeoptId() >= ic_data_array->length()) {
+ continue;
+ }
+#else
+ ASSERT(iter.DeoptId() < ic_data_array->length());
+#endif
const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
- if (!ic_data->IsNull()) {
+ if (ic_data != NULL) {
const TokenPosition token_pos = iter.TokenPos();
if ((token_pos < begin_pos) || (token_pos > end_pos)) {
// Does not correspond to a valid source position.
@@ -226,6 +243,7 @@
}
}
+
void SourceReport::PrintPossibleBreakpointsData(JSONObject* jsobj,
const Function& func,
const Code& code) {
@@ -338,8 +356,16 @@
Code& code = Code::Handle(zone(), func.unoptimized_code());
if (code.IsNull()) {
if (func.HasCode() || (compile_mode_ == kForceCompile)) {
- if (Compiler::EnsureUnoptimizedCode(thread(), func) != Error::null()) {
- // Ignore the error and this function entirely.
+ const Error& err =
+ Error::Handle(Compiler::EnsureUnoptimizedCode(thread(), func));
+ if (!err.IsNull()) {
+ // Emit an uncompiled range for this function with error information.
+ JSONObject range(jsarr);
+ range.AddProperty("scriptIndex", GetScriptIndex(script));
+ range.AddProperty("startPos", begin_pos);
+ range.AddProperty("endPos", end_pos);
+ range.AddProperty("compiled", false);
+ range.AddProperty("error", err);
return;
}
code = func.unoptimized_code();
@@ -393,9 +419,36 @@
Class& cls = Class::Handle(zone());
Array& functions = Array::Handle(zone());
Function& func = Function::Handle(zone());
+ Script& script = Script::Handle(zone());
ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
while (it.HasNext()) {
cls = it.GetNextClass();
+ if (!cls.is_finalized()) {
+ if (compile_mode_ == kForceCompile) {
+ const Error& err = Error::Handle(cls.EnsureIsFinalized(thread()));
+ if (!err.IsNull()) {
+ // Emit an uncompiled range for this class with error information.
+ JSONObject range(jsarr);
+ script = cls.script();
+ range.AddProperty("scriptIndex", GetScriptIndex(script));
+ range.AddProperty("startPos", cls.token_pos());
+ range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("compiled", false);
+ range.AddProperty("error", err);
+ continue;
+ }
+ } else {
+ // Emit one range for the whole uncompiled class.
+ JSONObject range(jsarr);
+ script = cls.script();
+ range.AddProperty("scriptIndex", GetScriptIndex(script));
+ range.AddProperty("startPos", cls.token_pos());
+ range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("compiled", false);
+ continue;
+ }
+ }
+
functions = cls.functions();
for (int i = 0; i < functions.Length(); i++) {
func ^= functions.At(i);
@@ -451,5 +504,4 @@
PrintScriptTable(&scripts);
}
-
} // namespace dart
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index ca02001..ad00dec 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -143,6 +143,140 @@
}
+TEST_CASE(SourceReport_Coverage_UnusedClass_NoForceCompile) {
+ char buffer[1024];
+ const char* kScript =
+ "helper0() {}\n"
+ "class Unused {\n"
+ " helper1() { helper0(); }\n"
+ "}\n"
+ "main() {\n"
+ " helper0();\n"
+ "}";
+
+ Library& lib = Library::Handle();
+ lib ^= ExecuteScript(kScript);
+ ASSERT(!lib.IsNull());
+ const Script& script = Script::Handle(lib.LookupScript(
+ String::Handle(String::New("test-lib"))));
+
+ SourceReport report(SourceReport::kCoverage);
+ JSONStream js;
+ report.PrintJSON(&js, script);
+ ElideJSONSubstring("classes", js.ToCString(), buffer);
+ ElideJSONSubstring("libraries", buffer, buffer);
+ EXPECT_STREQ(
+ "{\"type\":\"SourceReport\",\"ranges\":["
+
+ // UnusedClass is not compiled.
+ "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":20,\"compiled\":false},"
+
+ // helper0 is compiled.
+ "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+ // One range with a hit (main).
+ "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+ // Only one script in the script table.
+ "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+ "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+ buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompile) {
+ char buffer[1024];
+ const char* kScript =
+ "helper0() {}\n"
+ "class Unused {\n"
+ " helper1() { helper0(); }\n"
+ "}\n"
+ "main() {\n"
+ " helper0();\n"
+ "}";
+
+ Library& lib = Library::Handle();
+ lib ^= ExecuteScript(kScript);
+ ASSERT(!lib.IsNull());
+ const Script& script = Script::Handle(lib.LookupScript(
+ String::Handle(String::New("test-lib"))));
+
+ SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+ JSONStream js;
+ report.PrintJSON(&js, script);
+ ElideJSONSubstring("classes", js.ToCString(), buffer);
+ ElideJSONSubstring("libraries", buffer, buffer);
+ EXPECT_STREQ(
+ "{\"type\":\"SourceReport\",\"ranges\":["
+
+ // UnusedClass.helper1 is compiled.
+ "{\"scriptIndex\":0,\"startPos\":10,\"endPos\":18,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[],\"misses\":[14]}},"
+
+ // helper0 is compiled.
+ "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+ // One range with a hit (main).
+ "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+ // Only one script in the script table.
+ "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+ "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+ buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompileError) {
+ char buffer[1024];
+ const char* kScript =
+ "helper0() {}\n"
+ "class Unused {\n"
+ " helper1() { helper0()+ }\n" // syntax error
+ "}\n"
+ "main() {\n"
+ " helper0();\n"
+ "}";
+
+ Library& lib = Library::Handle();
+ lib ^= ExecuteScript(kScript);
+ ASSERT(!lib.IsNull());
+ const Script& script = Script::Handle(lib.LookupScript(
+ String::Handle(String::New("test-lib"))));
+
+ SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+ JSONStream js;
+ report.PrintJSON(&js, script);
+ ElideJSONSubstring("classes", js.ToCString(), buffer);
+ ElideJSONSubstring("libraries", buffer, buffer);
+ EXPECT_STREQ(
+ "{\"type\":\"SourceReport\",\"ranges\":["
+
+ // UnusedClass has a syntax error.
+ "{\"scriptIndex\":0,\"startPos\":10,\"endPos\":18,\"compiled\":false,"
+ "\"error\":{\"type\":\"@Error\",\"_vmType\":\"LanguageError\","
+ "\"kind\":\"LanguageError\",\"id\":\"objects\\/0\","
+ "\"message\":\"'test-lib': error: line 3 pos 26: unexpected token '}'\\n"
+ " helper1() { helper0()+ }\\n ^\\n\"}},"
+
+ // helper0 is compiled.
+ "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+ // One range with a hit (main).
+ "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+ // Only one script in the script table.
+ "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+ "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+ buffer);
+}
+
+
TEST_CASE(SourceReport_Coverage_NestedFunctions) {
char buffer[1024];
const char* kScript =
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index 0a7644b..a2198aa 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -75,6 +75,9 @@
void FUNCTION_NAME(StackFrame_validateFrame)(Dart_NativeArguments args) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+
Dart_Handle index = Dart_GetNativeArgument(args, 0);
Dart_Handle name = Dart_GetNativeArgument(args, 1);
const Smi& frame_index_smi = Smi::CheckedHandle(Api::UnwrapHandle(index));
@@ -89,18 +92,18 @@
// Find the function corresponding to this frame and check if it
// matches the function name passed in.
const Function& function =
- Function::Handle(frame->LookupDartFunction());
+ Function::Handle(zone, frame->LookupDartFunction());
if (function.IsNull()) {
FATAL("StackFrame_validateFrame fails, invalid dart frame.\n");
}
const char* name = function.ToFullyQualifiedCString();
// Currently all unit tests are loaded as being part of dart:core-lib.
- String& url = String::Handle(String::New(TestCase::url()));
- const Library& lib = Library::Handle(Library::LookupLibrary(url));
+ String& url = String::Handle(zone, String::New(TestCase::url()));
+ const Library& lib = Library::Handle(zone,
+ Library::LookupLibrary(thread, url));
ASSERT(!lib.IsNull());
- const char* lib_name = String::Handle(lib.url()).ToCString();
- char* full_name = OS::SCreate(Thread::Current()->zone(),
- "%s_%s", lib_name, expected_name);
+ const char* lib_name = String::Handle(zone, lib.url()).ToCString();
+ char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name);
if (strcmp(full_name, name) != 0) {
FATAL("StackFrame_validateFrame fails, incorrect frame.\n");
}
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index 0042f2d..0f66414 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -26,9 +26,6 @@
DEFINE_FLAG(bool, use_slow_path, false,
"Set to true for debugging & verifying the slow paths.");
DECLARE_FLAG(bool, trace_optimized_ic_calls);
-DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, support_debugger);
-DECLARE_FLAG(bool, lazy_dispatchers);
void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
__ Compile();
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index a138437..a0b6c83 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -307,41 +307,6 @@
}
-void Symbols::AddPredefinedSymbolsToIsolate() {
- // Should only be run by regular Dart isolates.
- Thread* thread = Thread::Current();
- Isolate* isolate = thread->isolate();
- Zone* zone = thread->zone();
- ASSERT(isolate != Dart::vm_isolate());
- String& str = String::Handle(zone);
-
- SymbolTable table(zone, isolate->object_store()->symbol_table());
-
- // Set up all the predefined string symbols and create symbols for
- // language keywords.
- for (intptr_t i = 1; i < Symbols::kNullCharId; i++) {
- str = OneByteString::New(names[i], Heap::kOld);
- str.Hash();
- str ^= table.InsertOrGet(str);
- str.SetCanonical(); // Make canonical once entered.
- }
-
- // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast.
- for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) {
- intptr_t idx = (kNullCharId + c);
- ASSERT(idx < kMaxPredefinedId);
- ASSERT(Utf::IsLatin1(c));
- uint8_t ch = static_cast<uint8_t>(c);
- str = OneByteString::New(&ch, 1, Heap::kOld);
- str.Hash();
- str ^= table.InsertOrGet(str);
- str.SetCanonical(); // Make canonical once entered.
- }
-
- isolate->object_store()->set_symbol_table(table.Release());
-}
-
-
void Symbols::SetupSymbolTable(Isolate* isolate) {
ASSERT(isolate != NULL);
@@ -354,48 +319,54 @@
}
-intptr_t Symbols::Compact(Isolate* isolate) {
- ASSERT(isolate != Dart::vm_isolate());
+RawArray* Symbols::UnifiedSymbolTable() {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ Zone* zone = thread->zone();
- Zone* zone = Thread::Current()->zone();
- intptr_t initial_size = -1;
- intptr_t final_size = -1;
+ ASSERT(thread->IsMutatorThread());
+ ASSERT(isolate->background_compiler() == NULL);
- // 1. Build a collection of all the predefined symbols so they are
- // strongly referenced (the read only handles are not traced).
- {
- SymbolTable table(zone, isolate->object_store()->symbol_table());
- initial_size = table.NumOccupied();
+ SymbolTable vm_table(zone,
+ Dart::vm_isolate()->object_store()->symbol_table());
+ SymbolTable table(zone, isolate->object_store()->symbol_table());
+ intptr_t unified_size = vm_table.NumOccupied() + table.NumOccupied();
+ SymbolTable unified_table(zone, HashTables::New<SymbolTable>(unified_size,
+ Heap::kOld));
+ String& symbol = String::Handle(zone);
- if (Object::vm_isolate_snapshot_object_table().Length() == 0) {
- GrowableObjectArray& predefined_symbols = GrowableObjectArray::Handle(
- GrowableObjectArray::New(kMaxPredefinedId));
- String& symbol = String::Handle();
- for (intptr_t i = 1; i < Symbols::kNullCharId; i++) {
- const unsigned char* name =
- reinterpret_cast<const unsigned char*>(names[i]);
- symbol ^= table.GetOrNull(Latin1Array(name, strlen(names[i])));
- ASSERT(!symbol.IsNull());
- predefined_symbols.Add(symbol);
- }
- for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) {
- intptr_t idx = (kNullCharId + c);
- ASSERT(idx < kMaxPredefinedId);
- ASSERT(Utf::IsLatin1(c));
- uint8_t ch = static_cast<uint8_t>(c);
- symbol ^= table.GetOrNull(Latin1Array(&ch, 1));
- ASSERT(!symbol.IsNull());
- predefined_symbols.Add(symbol);
- }
- }
- table.Release();
+ SymbolTable::Iterator vm_iter(&vm_table);
+ while (vm_iter.MoveNext()) {
+ symbol ^= vm_table.GetKey(vm_iter.Current());
+ ASSERT(!symbol.IsNull());
+ bool present = unified_table.Insert(symbol);
+ ASSERT(!present);
}
+ vm_table.Release();
- // 2. Knock out the symbol table and do a full garbage collection.
+ SymbolTable::Iterator iter(&table);
+ while (iter.MoveNext()) {
+ symbol ^= table.GetKey(iter.Current());
+ ASSERT(!symbol.IsNull());
+ bool present = unified_table.Insert(symbol);
+ ASSERT(!present);
+ }
+ table.Release();
+
+ return unified_table.Release().raw();
+}
+
+
+#if defined(DART_PRECOMPILER)
+void Symbols::Compact(Isolate* isolate) {
+ ASSERT(isolate != Dart::vm_isolate());
+ Zone* zone = Thread::Current()->zone();
+
+ // 1. Drop the symbol table and do a full garbage collection.
isolate->object_store()->set_symbol_table(Object::empty_array());
isolate->heap()->CollectAllGarbage();
- // 3. Walk the heap and build a new table from surviving symbols.
+ // 2. Walk the heap to find surviving symbols.
GrowableArray<String*> symbols;
class SymbolCollector : public ObjectVisitor {
public:
@@ -405,7 +376,7 @@
zone_(thread->zone()) {}
void VisitObject(RawObject* obj) {
- if (obj->IsString() && obj->IsCanonical()) {
+ if (obj->IsCanonical() && obj->IsStringInstance()) {
symbols_->Add(&String::ZoneHandle(zone_, String::RawCast(obj)));
}
}
@@ -418,24 +389,21 @@
SymbolCollector visitor(Thread::Current(), &symbols);
isolate->heap()->IterateObjects(&visitor);
- {
- Array& array =
- Array::Handle(HashTables::New<SymbolTable>(symbols.length() * 4 / 3,
- Heap::kOld));
- SymbolTable table(zone, array.raw());
- for (intptr_t i = 0; i < symbols.length(); i++) {
- String& symbol = *symbols[i];
- ASSERT(symbol.IsString());
- ASSERT(symbol.IsCanonical());
- bool present = table.Insert(symbol);
- ASSERT(!present);
- }
- final_size = table.NumOccupied();
- isolate->object_store()->set_symbol_table(table.Release());
+ // 3. Build a new table from the surviving symbols.
+ Array& array =
+ Array::Handle(zone, HashTables::New<SymbolTable>(symbols.length() * 4 / 3,
+ Heap::kOld));
+ SymbolTable table(zone, array.raw());
+ for (intptr_t i = 0; i < symbols.length(); i++) {
+ String& symbol = *symbols[i];
+ ASSERT(symbol.IsString());
+ ASSERT(symbol.IsCanonical());
+ bool present = table.Insert(symbol);
+ ASSERT(!present);
}
-
- return initial_size - final_size;
+ isolate->object_store()->set_symbol_table(table.Release());
}
+#endif // DART_PRECOMPILER
void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) {
@@ -655,7 +623,6 @@
symbol ^= table.GetOrNull(str);
table.Release();
}
-
ASSERT(symbol.IsNull() || symbol.IsSymbol());
ASSERT(symbol.IsNull() || symbol.HasHash());
return symbol.raw();
@@ -758,7 +725,7 @@
}
-intptr_t Symbols::LookupVMSymbol(RawObject* obj) {
+intptr_t Symbols::LookupPredefinedSymbol(RawObject* obj) {
for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
if (symbol_handles_[i]->raw() == obj) {
return (i + kMaxPredefinedObjectIds);
@@ -768,8 +735,8 @@
}
-RawObject* Symbols::GetVMSymbol(intptr_t object_id) {
- ASSERT(IsVMSymbolId(object_id));
+RawObject* Symbols::GetPredefinedSymbol(intptr_t object_id) {
+ ASSERT(IsPredefinedSymbolId(object_id));
intptr_t i = (object_id - kMaxPredefinedObjectIds);
if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
return symbol_handles_[i]->raw();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 83c7458..7057da2 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -332,6 +332,7 @@
V(DartTypedData, "dart:typed_data") \
V(DartVMService, "dart:_vmservice") \
V(DartIOLibName, "dart.io") \
+ V(DartVMProduct, "dart.vm.product") \
V(EvalSourceUri, "evaluate:source") \
V(_Random, "_Random") \
V(_state, "_state") \
@@ -555,19 +556,15 @@
static void InitOnce(Isolate* isolate);
static void InitOnceFromSnapshot(Isolate* isolate);
- // Add all the symbols that were cached in the VM isolate to this isolate,
- // we do this when an Isolate is not created from the snapshot so that
- // we get a unified symbol table that can be be dumped into the VM isolate
- // snapshot.
- static void AddPredefinedSymbolsToIsolate();
-
// Initialize and setup a symbol table for the isolate.
static void SetupSymbolTable(Isolate* isolate);
- // Treat the symbol table as weak and collect garbage. Answer the number of
- // symbols deleted from the symbol table because they where not referenced
- // from anywhere else.
- static intptr_t Compact(Isolate* isolate);
+ static RawArray* UnifiedSymbolTable();
+
+#if defined(DART_PRECOMPILER)
+ // Treat the symbol table as weak and collect garbage.
+ static void Compact(Isolate* isolate);
+#endif
// Creates a Symbol given a C string that is assumed to contain
// UTF-8 encoded characters and '\0' is considered a termination character.
@@ -644,22 +641,22 @@
static RawString* LookupFromSet(Thread* thread, const String& str);
static RawString* LookupFromDot(Thread* thread, const String& str);
+ static void GetStats(Isolate* isolate,
+ intptr_t* size,
+ intptr_t* capacity);
+
private:
enum {
kInitialVMIsolateSymtabSize = 1024,
kInitialSymtabSize = 2048
};
- static void GetStats(Isolate* isolate,
- intptr_t* size,
- intptr_t* capacity);
-
template<typename StringType>
static RawString* NewSymbol(Thread* thread, const StringType& str);
- static intptr_t LookupVMSymbol(RawObject* obj);
- static RawObject* GetVMSymbol(intptr_t object_id);
- static bool IsVMSymbolId(intptr_t object_id) {
+ static intptr_t LookupPredefinedSymbol(RawObject* obj);
+ static RawObject* GetPredefinedSymbol(intptr_t object_id);
+ static bool IsPredefinedSymbolId(intptr_t object_id) {
return (object_id >= kMaxPredefinedObjectIds &&
object_id < (kMaxPredefinedObjectIds + kMaxPredefinedId));
}
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 0adf841..8b9eaf0 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -308,6 +308,8 @@
TimelineEvent::TimelineEvent()
: timestamp0_(0),
timestamp1_(0),
+ thread_timestamp0_(-1),
+ thread_timestamp1_(-1),
arguments_(NULL),
arguments_length_(0),
state_(0),
@@ -370,15 +372,19 @@
void TimelineEvent::DurationBegin(const char* label,
- int64_t micros) {
+ int64_t micros,
+ int64_t thread_micros) {
Init(kDuration, label);
set_timestamp0(micros);
+ set_thread_timestamp0(thread_micros);
}
-void TimelineEvent::DurationEnd(int64_t micros) {
+void TimelineEvent::DurationEnd(int64_t micros,
+ int64_t thread_micros) {
ASSERT(timestamp1_ == 0);
set_timestamp1(micros);
+ set_thread_timestamp1(thread_micros);
}
@@ -391,24 +397,32 @@
void TimelineEvent::Duration(const char* label,
int64_t start_micros,
- int64_t end_micros) {
+ int64_t end_micros,
+ int64_t thread_start_micros,
+ int64_t thread_end_micros) {
Init(kDuration, label);
set_timestamp0(start_micros);
set_timestamp1(end_micros);
+ set_thread_timestamp0(thread_start_micros);
+ set_thread_timestamp1(thread_end_micros);
}
void TimelineEvent::Begin(const char* label,
- int64_t micros) {
+ int64_t micros,
+ int64_t thread_micros) {
Init(kBegin, label);
set_timestamp0(micros);
+ set_thread_timestamp0(thread_micros);
}
void TimelineEvent::End(const char* label,
- int64_t micros) {
+ int64_t micros,
+ int64_t thread_micros) {
Init(kEnd, label);
set_timestamp0(micros);
+ set_thread_timestamp0(thread_micros);
}
@@ -522,6 +536,8 @@
state_ = 0;
timestamp0_ = 0;
timestamp1_ = 0;
+ thread_timestamp0_ = -1;
+ thread_timestamp1_ = -1;
OSThread* os_thread = OSThread::Current();
ASSERT(os_thread != NULL);
thread_ = os_thread->trace_id();
@@ -588,7 +604,9 @@
obj.AddProperty64("tid", tid);
obj.AddProperty64("pid", pid);
obj.AddPropertyTimeMicros("ts", TimeOrigin());
-
+ if (HasThreadCPUTime()) {
+ obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin());
+ }
switch (event_type()) {
case kBegin: {
obj.AddProperty("ph", "B");
@@ -601,6 +619,9 @@
case kDuration: {
obj.AddProperty("ph", "X");
obj.AddPropertyTimeMicros("dur", TimeDuration());
+ if (HasThreadCPUTime()) {
+ obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration());
+ }
}
break;
case kInstant: {
@@ -668,6 +689,28 @@
}
+bool TimelineEvent::HasThreadCPUTime() const {
+ return (thread_timestamp0_ != -1);
+}
+
+
+
+int64_t TimelineEvent::ThreadCPUTimeOrigin() const {
+ ASSERT(HasThreadCPUTime());
+ return thread_timestamp0_;
+}
+
+
+int64_t TimelineEvent::ThreadCPUTimeDuration() const {
+ ASSERT(HasThreadCPUTime());
+ if (thread_timestamp1_ == -1) {
+ // This duration is still open, use current time as end.
+ return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_;
+ }
+ return thread_timestamp1_ - thread_timestamp0_;
+}
+
+
TimelineStream::TimelineStream()
: name_(NULL),
enabled_(false),
@@ -831,6 +874,7 @@
return;
}
timestamp_ = OS::GetCurrentMonotonicMicros();
+ thread_timestamp_ = OS::GetCurrentThreadCPUMicros();
}
@@ -842,6 +886,7 @@
return;
}
timestamp_ = OS::GetCurrentMonotonicMicros();
+ thread_timestamp_ = OS::GetCurrentThreadCPUMicros();
}
@@ -859,7 +904,11 @@
}
ASSERT(event != NULL);
// Emit a duration event.
- event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros());
+ event->Duration(label(),
+ timestamp_,
+ OS::GetCurrentMonotonicMicros(),
+ thread_timestamp_,
+ OS::GetCurrentThreadCPUMicros());
StealArguments(event);
event->Complete();
}
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index f78b516..1646d99 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -156,20 +156,27 @@
int64_t micros = OS::GetCurrentMonotonicMicros());
void DurationBegin(const char* label,
- int64_t micros = OS::GetCurrentMonotonicMicros());
- void DurationEnd(int64_t micros = OS::GetCurrentMonotonicMicros());
+ int64_t micros = OS::GetCurrentMonotonicMicros(),
+ int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
+ void DurationEnd(int64_t micros = OS::GetCurrentMonotonicMicros(),
+ int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
+
void Instant(const char* label,
int64_t micros = OS::GetCurrentMonotonicMicros());
void Duration(const char* label,
int64_t start_micros,
- int64_t end_micros);
+ int64_t end_micros,
+ int64_t thread_start_micros = -1,
+ int64_t thread_end_micros = -1);
void Begin(const char* label,
- int64_t micros = OS::GetCurrentMonotonicMicros());
+ int64_t micros = OS::GetCurrentMonotonicMicros(),
+ int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
void End(const char* label,
- int64_t micros = OS::GetCurrentMonotonicMicros());
+ int64_t micros = OS::GetCurrentMonotonicMicros(),
+ int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
void Counter(const char* label,
int64_t micros = OS::GetCurrentMonotonicMicros());
@@ -204,6 +211,10 @@
return (event_type() == kDuration) && (timestamp1_ > timestamp0_);
}
+ bool HasThreadCPUTime() const;
+ int64_t ThreadCPUTimeDuration() const;
+ int64_t ThreadCPUTimeOrigin() const;
+
int64_t TimeOrigin() const;
int64_t AsyncId() const;
int64_t TimeDuration() const;
@@ -311,6 +322,16 @@
timestamp1_ = value;
}
+ void set_thread_timestamp0(int64_t value) {
+ ASSERT(thread_timestamp0_ == -1);
+ thread_timestamp0_ = value;
+ }
+
+ void set_thread_timestamp1(int64_t value) {
+ ASSERT(thread_timestamp1_ == -1);
+ thread_timestamp1_ = value;
+ }
+
bool pre_serialized_json() const {
return PreSerializedJSON::decode(state_);
}
@@ -337,6 +358,8 @@
int64_t timestamp0_;
int64_t timestamp1_;
+ int64_t thread_timestamp0_;
+ int64_t thread_timestamp1_;
TimelineEventArgument* arguments_;
intptr_t arguments_length_;
uword state_;
@@ -486,6 +509,7 @@
private:
int64_t timestamp_;
+ int64_t thread_timestamp_;
DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope);
};
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 60f4057..a8224c5 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -430,6 +430,29 @@
reinterpret_cast<intptr_t>(arg3),
0, fp_return, fp_args);
}
+#elif defined(USING_SIMULATOR) && defined(TARGET_ARCH_DBC)
+ template<typename ResultType,
+ typename Arg1Type,
+ typename Arg2Type,
+ typename Arg3Type>
+ ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) {
+ // TODO(fschneider): Support double arguments for simulator calls.
+ COMPILE_ASSERT(is_void<ResultType>::value);
+ COMPILE_ASSERT(!is_double<Arg1Type>::value);
+ COMPILE_ASSERT(!is_double<Arg2Type>::value);
+ COMPILE_ASSERT(!is_double<Arg3Type>::value);
+ const Object& arg1obj = Object::Handle(reinterpret_cast<RawObject*>(arg1));
+ const Object& arg2obj = Object::Handle(reinterpret_cast<RawObject*>(arg2));
+ const Array& argdesc = Array::Handle(ArgumentsDescriptor::New(2));
+ const Array& arguments = Array::Handle(Array::New(2));
+ arguments.SetAt(0, arg1obj);
+ arguments.SetAt(1, arg2obj);
+ Simulator::Current()->Call(
+ code(),
+ argdesc,
+ arguments,
+ reinterpret_cast<Thread*>(arg3));
+ }
#else
template<typename ResultType> ResultType InvokeWithCodeAndThread() {
Thread* thread = Thread::Current();
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index d51185b..210cfcd 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -304,6 +304,7 @@
'object.h',
'object_arm_test.cc',
'object_arm64_test.cc',
+ 'object_dbc_test.cc',
'object_graph.cc',
'object_graph.h',
'object_graph_test.cc',
diff --git a/runtime/vm/weak_table.h b/runtime/vm/weak_table.h
index aca86fc..01a607b 100644
--- a/runtime/vm/weak_table.h
+++ b/runtime/vm/weak_table.h
@@ -154,7 +154,7 @@
void Rehash();
static intptr_t Hash(RawObject* key) {
- return reinterpret_cast<intptr_t>(key) >> kObjectAlignmentLog2;
+ return reinterpret_cast<intptr_t>(key) * 92821;
}
// data_ contains size_ tuples of key/value.
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index d56f946..7a2c5a6 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -59,8 +59,14 @@
int _clockValue = 0;
@patch
+int _getThreadCpuClock() {
+ return -1;
+}
+
+
+@patch
void _reportCompleteEvent(int start,
- int end,
+ int startCpu,
String category,
String name,
String argumentsAsJson) {
diff --git a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
index 6041760..a7f13ab 100644
--- a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
@@ -3,13 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
-import 'dart:_internal' show FixedLengthListMixin;
-import 'dart:_foreign_helper' show JS;
-import 'dart:math' as Math;
-import 'dart:_internal';
-import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31;
-import 'dart:_js_helper'
- show Creates, JavaScriptIndexingBehavior, JSName, Returns, patch;
+import 'dart:_js_helper' show patch;
import 'dart:_native_typed_data';
@patch class ByteData {
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index a47838b..c11ea2e 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -454,7 +454,7 @@
* The [namedArguments] is a map from [Symbol]s to the values of named
* arguments that the method was called with.
*
- * The optional [exisitingArgumentNames] is the expected parameters of a
+ * The optional [existingArgumentNames] is the expected parameters of a
* method with the same name on the receiver, if available. This is
* the signature of the method that would have been called if the parameters
* had matched.
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 4f7fcf8..ac4581f 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -244,7 +244,7 @@
* The values of [this].
*
* The values are iterated in the order of their corresponding keys.
- * This means that iterating [keys] and [values] in parrallel will
+ * This means that iterating [keys] and [values] in parallel will
* provided matching pairs of keys and values.
*
* The returned iterable has an efficient `length` method based on the
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index e66e13a..74c9d50 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -8,9 +8,9 @@
/// as a result of developer feedback. This library is platform dependent and
/// therefore it has implementations for both dart2js and the Dart VM. Both are
/// under development and may not support all operations yet.
-///
+///
/// To use this library in your code:
-///
+///
/// import 'dart:developer';
///
library dart.developer;
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 362832d..fbdad8b 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -4,6 +4,8 @@
part of dart.developer;
+const bool _isProduct = const bool.fromEnvironment("dart.vm.product");
+
typedef dynamic TimelineSyncFunction();
typedef Future TimelineAsyncFunction();
@@ -13,12 +15,15 @@
/// a [Map] of [arguments]. This operation must be finished before
/// returning to the event queue.
static void startSync(String name, {Map arguments}) {
+ if (_isProduct) {
+ return;
+ }
if (name is! String) {
throw new ArgumentError.value(name,
'name',
'Must be a String');
}
- var block = new _SyncBlock._(name, _getTraceClock());
+ var block = new _SyncBlock._(name, _getTraceClock(), _getThreadCpuClock());
if (arguments is Map) {
block._appendArguments(arguments);
}
@@ -27,6 +32,9 @@
/// Finish the last synchronous operation that was started.
static void finishSync() {
+ if (_isProduct) {
+ return;
+ }
if (_stack.length == 0) {
throw new StateError(
'Uneven calls to startSync and finishSync');
@@ -39,6 +47,9 @@
/// Emit an instant event.
static void instantSync(String name, {Map arguments}) {
+ if (_isProduct) {
+ return;
+ }
if (name is! String) {
throw new ArgumentError.value(name,
'name',
@@ -101,6 +112,9 @@
/// Start a synchronous operation within this task named [name].
/// Optionally takes a [Map] of [arguments].
void start(String name, {Map arguments}) {
+ if (_isProduct) {
+ return;
+ }
if (name is! String) {
throw new ArgumentError.value(name,
'name',
@@ -116,6 +130,9 @@
/// Emit an instant event for this task.
void instant(String name, {Map arguments}) {
+ if (_isProduct) {
+ return;
+ }
if (name is! String) {
throw new ArgumentError.value(name,
'name',
@@ -135,6 +152,9 @@
/// Finish the last synchronous operation that was started.
void finish() {
+ if (_isProduct) {
+ return;
+ }
if (_stack.length == 0) {
throw new StateError(
'Uneven calls to start and finish');
@@ -215,16 +235,19 @@
Map _arguments;
// The start time stamp.
final int _start;
+ // The start time stamp of the thread cpu clock.
+ final int _startCpu;
_SyncBlock._(this.name,
- this._start);
+ this._start,
+ this._startCpu);
/// Finish this block of time. At this point, this block can no longer be
/// used.
void finish() {
// Report event to runtime.
_reportCompleteEvent(_start,
- _getTraceClock(),
+ _startCpu,
category,
name,
_argumentsAsJson(_arguments));
@@ -261,6 +284,9 @@
/// Returns the current value from the trace clock.
external int _getTraceClock();
+/// Returns the current value from the thread CPU usage clock.
+external int _getThreadCpuClock();
+
/// Returns the isolate's main port number.
external int _getIsolateNum();
@@ -274,7 +300,7 @@
/// Reports a complete synchronous event.
external void _reportCompleteEvent(int start,
- int end,
+ int startCpu,
String category,
String name,
String argumentsAsJson);
diff --git a/sdk/lib/io/bytes_builder.dart b/sdk/lib/io/bytes_builder.dart
index 2882402..a4b611f 100644
--- a/sdk/lib/io/bytes_builder.dart
+++ b/sdk/lib/io/bytes_builder.dart
@@ -153,7 +153,7 @@
class _BytesBuilder implements BytesBuilder {
int _length = 0;
- final List _chunks = [];
+ final _chunks = <List<int>>[];
void add(List<int> bytes) {
if (bytes is! Uint8List) {
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 0972e84..ec1320a 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -58,7 +58,8 @@
* will lead to undefined behaviour.
*/
// TODO(ajohnsen): make this transformer reusable?
-class _WebSocketProtocolTransformer implements StreamTransformer, EventSink {
+class _WebSocketProtocolTransformer
+ implements StreamTransformer<List<int>, dynamic>, EventSink<List<int>> {
static const int START = 0;
static const int LEN_FIRST = 1;
static const int LEN_REST = 2;
@@ -114,7 +115,8 @@
/**
* Process data received from the underlying communication channel.
*/
- void add(Uint8List buffer) {
+ void add(List<int> bytes) {
+ var buffer = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes);
int index = 0;
int lastIndex = buffer.length;
if (_state == CLOSED) {
@@ -626,9 +628,10 @@
}
// TODO(ajohnsen): Make this transformer reusable.
-class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink {
+class _WebSocketOutgoingTransformer
+ implements StreamTransformer<dynamic, List<int>>, EventSink {
final _WebSocketImpl webSocket;
- EventSink _eventSink;
+ EventSink<List<int>> _eventSink;
_WebSocketPerMessageDeflate _deflateHelper;
@@ -636,8 +639,8 @@
_deflateHelper = webSocket._deflate;
}
- Stream bind(Stream stream) {
- return new Stream.eventTransformed(stream, (EventSink eventSink) {
+ Stream<List<int>> bind(Stream stream) {
+ return new Stream.eventTransformed(stream, (eventSink) {
if (_eventSink != null) {
throw new StateError("WebSocket transformer already used");
}
@@ -662,11 +665,12 @@
opcode = _WebSocketOpcode.TEXT;
data = UTF8.encode(message);
} else {
- if (message is! List<int>) {
+ if (message is List<int>) {
+ data = message;
+ opcode = _WebSocketOpcode.BINARY;
+ } else {
throw new ArgumentError(message);
}
- opcode = _WebSocketOpcode.BINARY;
- data = message;
}
if (_deflateHelper != null) {
@@ -708,7 +712,7 @@
_eventSink.add(e);
});
- static Iterable createFrame(
+ static Iterable<List<int>> createFrame(
int opcode, List<int> data, bool serverSide, bool compressed) {
bool mask = !serverSide; // Masking not implemented for server.
int dataLength = data == null ? 0 : data.length;
@@ -1218,7 +1222,7 @@
Map _toJSON(bool ref) {
var name = '${_socket.address.host}:${_socket.port}';
- var r = {
+ var r = <String, dynamic>{
'id': _servicePath,
'type': _serviceType(ref),
'name': name,
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index fa1267b..aa0daa9 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -31,6 +31,8 @@
# co19 issue #615: Expect import missing
LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
+Language/Generics/syntax_t04: StaticWarning # co19 issue #56
+
LibTest/isolate/IsolateStream/any_A01_t01: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/IsolateStream/contains_A01_t01: Fail # co19-roll r706: Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f8105cc..d12cbfc 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -658,40 +658,18 @@
LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, Timeout # Please triage this failure
LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css/background-clip-text_t01: RuntimeError # Issue 54
LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
@@ -919,6 +897,7 @@
LayoutTests/fast/dom/SelectorAPI/dumpNodeList_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Issue 55
LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/getMatchedCSSRules-nested-rules_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex_t01: RuntimeError # Please triage this failure
@@ -949,6 +928,7 @@
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/26422
LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
@@ -1607,6 +1587,9 @@
LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/error-reporting_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/get-active-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Please triage this failure
@@ -1615,8 +1598,11 @@
LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-getstring_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Please triage this failure
@@ -1642,9 +1628,26 @@
LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/shader-precision-format_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 2d771fb..e0a9948 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -12,8 +12,8 @@
import '../../utils/dummy_compiler_test.dart' as dummy;
import 'package:compiler/compiler.dart';
import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/diagnostics/messages.dart' show
- MessageKind, MessageTemplate;
+import 'package:compiler/src/diagnostics/messages.dart'
+ show MessageKind, MessageTemplate;
import 'output_collector.dart';
@@ -175,12 +175,31 @@
});
// --analyze-signatures-only implies --analyze-only
+ runCompiler("", [Flags.analyzeSignaturesOnly, Flags.analyzeAll],
+ (String code, List errors, List warnings) {
+ Expect.isNull(code);
+ Expect.isTrue(errors.isEmpty);
+ Expect.isTrue(warnings.isEmpty);
+ });
+
+ // Test that --allow-native-extensions works.
runCompiler(
- "",
- [Flags.analyzeSignaturesOnly, Flags.analyzeAll],
- (String code, List errors, List warnings) {
- Expect.isNull(code);
- Expect.isTrue(errors.isEmpty);
- Expect.isTrue(warnings.isEmpty);
- });
+ """main() {}
+ foo() native 'foo';""",
+ [Flags.analyzeOnly, Flags.allowNativeExtensions],
+ (String code, List errors, List warnings) {
+ Expect.isNull(code);
+ Expect.isTrue(errors.isEmpty);
+ Expect.isTrue(warnings.isEmpty);
+ });
+ runCompiler(
+ """main() {}
+ foo() native 'foo';""",
+ [Flags.analyzeOnly],
+ (String code, List errors, List warnings) {
+ Expect.isNull(code);
+ Expect.isTrue(
+ errors.single.startsWith("'native' modifier is not supported."));
+ Expect.isTrue(warnings.isEmpty);
+ });
}
diff --git a/tests/compiler/dart2js/error_token_test.dart b/tests/compiler/dart2js/error_token_test.dart
new file mode 100644
index 0000000..2000f1a
--- /dev/null
+++ b/tests/compiler/dart2js/error_token_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2016, 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.
+
+// Test that we don't report invalid modifier on error tokens.
+
+library dart2js.test.error_token;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import "package:compiler/src/diagnostics/messages.dart";
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+Future runTest(String code, {MessageKind error}) async {
+ DiagnosticCollector diagnostics = new DiagnosticCollector();
+ OutputCollector output = new OutputCollector();
+ await runCompiler(
+ entryPoint: Uri.parse('memory:main.dart'),
+ memorySourceFiles: {'main.dart': code},
+ diagnosticHandler: diagnostics,
+ outputProvider: output);
+
+ Expect.equals(error != null ? 1 : 0, diagnostics.errors.length);
+ if (error != null) {
+ Expect.equals(error, diagnostics.errors.first.message.kind);
+ }
+ Expect.equals(0, diagnostics.warnings.length);
+ Expect.equals(0, diagnostics.hints.length);
+ Expect.equals(0, diagnostics.infos.length);
+}
+
+void main() {
+ asyncTest(() async {
+ await runTest('''
+main() {}
+class Foo {
+ static void bar() {
+ baz());
+ }
+}
+''', error: MessageKind.UNMATCHED_TOKEN);
+
+ await runTest('''
+main() {}
+class C {
+ C(v) {
+ throw '');
+ }
+}''', error: MessageKind.UNMATCHED_TOKEN);
+ });
+}
diff --git a/tests/compiler/dart2js/generic_method_type_usage_test.dart b/tests/compiler/dart2js/generic_method_type_usage_test.dart
new file mode 100644
index 0000000..9ec4fbe
--- /dev/null
+++ b/tests/compiler/dart2js/generic_method_type_usage_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2016, 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.
+
+/// Dart test verifying that method type variables are considered to denote
+/// the type `dynamic`.
+///
+/// NB: This test is intended to succeed with a `dart2js` with the option
+/// '--generic-method-syntax', but it should fail with a full implementation
+/// of generic method support, and it should fail with every other tool than
+/// `dart2js`.
+
+library dart2js.test.generic_method_type_usage;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import "package:compiler/src/diagnostics/messages.dart";
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+ 'type_variable_is_dynamic.dart': '''
+class C {
+ bool aMethod<X>(X x) {
+ // `dynamic` is assignable to both `int` and `String`: no warnings.
+ int i = x;
+ String s = x;
+ try {
+ // Only `dynamic` allows unknown member lookup without a warning.
+ var y = x.undefinedMember;
+ } on NoSuchMethodError catch (_) {
+ return true;
+ }
+ return false;
+ }
+}
+
+bool aFunction<X>(X x) {
+ // `dynamic` is assignable to both `int` and `String`: no warnings.
+ int i = x;
+ String s = x;
+ try {
+ // Only `dynamic` allows unknown member lookup without a warning.
+ var y = x.undefinedMember;
+ } on NoSuchMethodError catch (_) {
+ return true;
+ }
+ return false;
+}
+
+main() {
+ print(new C().aMethod<Set>(null));
+ print(aFunction<Set>(null));
+}
+''',
+
+ 'cannot_new_method_type_variable.dart': '''
+class C {
+ X aMethod<X>() => new X();
+}
+
+main() {
+ new C().aMethod<Set>();
+}
+''',
+
+ 'cannot_new_function_type_variable.dart': '''
+X aFunction<X>() => new X(42);
+
+main() {
+ aFunction<Set>();
+}
+''',
+};
+
+
+Future runTest(Uri main, {MessageKind warning, MessageKind info}) async {
+ print("----\nentry-point: $main\n");
+
+ DiagnosticCollector diagnostics = new DiagnosticCollector();
+ OutputCollector output = new OutputCollector();
+ await runCompiler(
+ entryPoint: main,
+ options: const <String>["--generic-method-syntax"],
+ memorySourceFiles: MEMORY_SOURCE_FILES,
+ diagnosticHandler: diagnostics,
+ outputProvider: output);
+
+ Expect.isFalse(output.hasExtraOutput);
+ Expect.equals(0, diagnostics.errors.length);
+ Expect.equals(warning != null ? 1 : 0, diagnostics.warnings.length);
+ if (warning != null) {
+ Expect.equals(warning, diagnostics.warnings.first.message.kind);
+ }
+ Expect.equals(info != null ? 1 : 0, diagnostics.infos.length);
+ if (info != null) {
+ Expect.equals(info, diagnostics.infos.first.message.kind);
+ }
+ Expect.equals(0, diagnostics.hints.length);
+}
+
+void main() {
+ asyncTest(() async {
+ await runTest(
+ Uri.parse('memory:type_variable_is_dynamic.dart'));
+
+ await runTest(
+ Uri.parse('memory:cannot_new_method_type_variable.dart'),
+ warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE);
+
+ await runTest(
+ Uri.parse('memory:cannot_new_function_type_variable.dart'),
+ warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE);
+ });
+}
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index c7719b3..095915b 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -103,11 +103,14 @@
assert(compiler.serialization.supportSerialization);
Serializer serializer = new Serializer();
- serializer.plugins.add(compiler.backend.serialization.serializer);
- serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution));
+ SerializerPlugin backendSerializer =
+ compiler.backend.serialization.serializer;
+ serializer.plugins.add(backendSerializer);
+ serializer.plugins.add(new ResolutionImpactSerializer(
+ compiler.resolution, backendSerializer));
if (serializeResolvedAst) {
- serializer.plugins.add(
- new ResolvedAstSerializerPlugin(compiler.resolution, compiler.backend));
+ serializer.plugins.add(new ResolvedAstSerializerPlugin(
+ compiler.resolution, backendSerializer));
}
for (LibraryElement library in libraries) {
@@ -137,28 +140,34 @@
class ResolutionImpactSerializer extends SerializerPlugin {
final Resolution resolution;
+ final SerializerPlugin nativeDataSerializer;
- ResolutionImpactSerializer(this.resolution);
+ ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
@override
void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
if (resolution.hasBeenResolved(element)) {
ResolutionImpact impact = resolution.getResolutionImpact(element);
ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
- new ImpactSerializer(element, encoder).serialize(impact);
+ new ImpactSerializer(element, encoder, nativeDataSerializer)
+ .serialize(impact);
}
}
}
class ResolutionImpactDeserializer extends DeserializerPlugin {
Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
+ final DeserializerPlugin nativeDataDeserializer;
+
+ ResolutionImpactDeserializer(this.nativeDataDeserializer);
@override
void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
if (decoder != null) {
impactMap[element] =
- ImpactDeserializer.deserializeImpact(element, decoder);
+ ImpactDeserializer.deserializeImpact(
+ element, decoder, nativeDataDeserializer);
}
}
}
@@ -167,34 +176,53 @@
final Compiler _compiler;
final Deserializer _deserializer;
final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
- final ResolutionImpactDeserializer _resolutionImpactDeserializer =
- new ResolutionImpactDeserializer();
+ final ResolutionImpactDeserializer _resolutionImpactDeserializer;
final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
final ImpactTransformer _impactTransformer;
- final bool _deserializeResolvedAst;
+ final bool deserializeResolvedAst;
- _DeserializerSystem(
+ factory _DeserializerSystem(
Compiler compiler,
+ Deserializer deserializer,
+ ImpactTransformer impactTransformer,
+ {bool deserializeResolvedAst: false}) {
+ List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
+ DeserializerPlugin backendDeserializer =
+ compiler.backend.serialization.deserializer;
+ deserializer.plugins.add(backendDeserializer);
+ ResolutionImpactDeserializer resolutionImpactDeserializer =
+ new ResolutionImpactDeserializer(backendDeserializer);
+ deserializer.plugins.add(resolutionImpactDeserializer);
+ ResolvedAstDeserializerPlugin resolvedAstDeserializer;
+ if (deserializeResolvedAst) {
+ resolvedAstDeserializer = new ResolvedAstDeserializerPlugin(
+ compiler.parsingContext, backendDeserializer);
+ deserializer.plugins.add(resolvedAstDeserializer);
+ }
+ return new _DeserializerSystem._(
+ compiler,
+ deserializer,
+ impactTransformer,
+ resolutionImpactDeserializer,
+ resolvedAstDeserializer,
+ deserializeResolvedAst: deserializeResolvedAst);
+ }
+
+ _DeserializerSystem._(
+ this._compiler,
this._deserializer,
this._impactTransformer,
- {bool deserializeResolvedAst: false})
- : this._compiler = compiler,
- this._deserializeResolvedAst = deserializeResolvedAst,
- this._resolvedAstDeserializer = deserializeResolvedAst
- ? new ResolvedAstDeserializerPlugin(
- compiler.parsingContext, compiler.backend) : null {
- _deserializer.plugins.add(_resolutionImpactDeserializer);
- if (_deserializeResolvedAst) {
- _deserializer.plugins.add(_resolvedAstDeserializer);
- }
- }
+ this._resolutionImpactDeserializer,
+ this._resolvedAstDeserializer,
+ {this.deserializeResolvedAst: false});
+
@override
Future<LibraryElement> readLibrary(Uri resolvedUri) {
LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
if (library != null) {
deserializedLibraries.add(library);
- if (_deserializeResolvedAst) {
+ if (deserializeResolvedAst) {
return Future.forEach(library.compilationUnits,
(CompilationUnitElement compilationUnit) {
ScriptZ script = compilationUnit.script;
@@ -274,9 +302,9 @@
class ResolvedAstSerializerPlugin extends SerializerPlugin {
final Resolution resolution;
- final Backend backend;
+ final SerializerPlugin nativeDataSerializer;
- ResolvedAstSerializerPlugin(this.resolution, this.backend);
+ ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
@override
void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
@@ -290,14 +318,14 @@
new ResolvedAstSerializer(
objectEncoder,
resolvedAst,
- backend.serialization.serializer).serialize();
+ nativeDataSerializer).serialize();
}
}
}
class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
final ParsingContext parsingContext;
- final Backend backend;
+ final DeserializerPlugin nativeDataDeserializer;
final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
Map<ExecutableElement, ResolvedAst> _resolvedAstMap =
@@ -306,7 +334,8 @@
<MemberElement, ObjectDecoder>{};
Map<Uri, Token> beginTokenMap = <Uri, Token>{};
- ResolvedAstDeserializerPlugin(this.parsingContext, this.backend);
+ ResolvedAstDeserializerPlugin(
+ this.parsingContext, this.nativeDataDeserializer);
bool hasResolvedAst(ExecutableElement element) {
return _resolvedAstMap.containsKey(element) ||
@@ -320,7 +349,7 @@
if (decoder != null) {
ResolvedAstDeserializer.deserialize(
element.memberContext, decoder, parsingContext, findToken,
- backend.serialization.deserializer,
+ nativeDataDeserializer,
_resolvedAstMap);
_decoderMap.remove(element);
resolvedAst = _resolvedAstMap[element];
diff --git a/tests/compiler/dart2js/serialization/model_test.dart b/tests/compiler/dart2js/serialization/model_test.dart
index 66ac6c5..0229b02 100644
--- a/tests/compiler/dart2js/serialization/model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test.dart
@@ -95,8 +95,6 @@
compilerDeserialized.resolverWorld.instantiatedTypes,
"Instantiated types mismatch",
areTypesEquivalent,
- // TODO(johnniwinther): Ensure that all instantiated types are tracked.
- failOnUnfound: false,
verbose: verbose);
checkSets(
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index 1a05c98..d753b53 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -21,7 +21,7 @@
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';
-
+import 'package:compiler/src/tree/nodes.dart';
/// Strategy for checking equivalence.
///
@@ -97,6 +97,13 @@
List<ConstantExpression> list2) {
return checkConstantLists(object1, object2, property, list1, list2);
}
+
+ @override
+ bool testNodes(Object object1, Object object2, String property,
+ Node node1, Node node2) {
+ return new NodeEquivalenceVisitor(this).testNodes(
+ object1, object2, property, node1, node2);
+ }
}
/// Check that the values [property] of [object1] and [object2], [value1] and
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index bde5681..897d5b3 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -53,7 +53,7 @@
bailout8_test: Fail, OK # Mismatch in thrown exception.
[ $compiler == dart2js && $runtime == d8 && $system == windows ]
-deferred/*: Skip # Issue 17458
+deferred/*: Pass,RuntimeError # Issue 17458
[ $compiler == dart2js && $csp ]
deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart
new file mode 100644
index 0000000..49d9558
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, 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 is a regression test for dartbug.com/26406. We test that the deferred
+// loader analyzer doesn't trip over constant expression evaluation.
+//
+// Today the task uses constant values to calculate dependencies, and only uses
+// those values that were previously computed by resolution. A change to compute
+// the value on-demmand made the deferred task evaluate more expressions,
+// including expressions with free variables (which can't be evaluated). See the
+// dartbug.com/26406 for details on how we plan to make the task more robust.
+
+// import is only used to trigger the deferred task
+import 'deferred_class_library.dart' deferred as lib;
+
+class A {
+ final int x;
+
+ const A(bool foo)
+ // The deferred task would crash trying to compute the value here, where
+ // [foo] is a free variable.
+ : x = foo ? 1 : 0;
+}
+
+main() => const A(true);
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 60a6bc5..62f45da 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -139,7 +139,7 @@
from_environment_const_type_undefined_test/16: CompileTimeError
[ $compiler == dart2analyzer ]
-int_parse_radix_test: fail
+int_parse_radix_bad_handler_test: fail
list_insert_test: fail
list_removeat_test: fail
hash_set_type_check_test: StaticWarning, OK # Tests failing type tests.
diff --git a/tests/corelib/int_parse_radix_bad_handler_test.dart b/tests/corelib/int_parse_radix_bad_handler_test.dart
new file mode 100644
index 0000000..58009fa
--- /dev/null
+++ b/tests/corelib/int_parse_radix_bad_handler_test.dart
@@ -0,0 +1,15 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+void main() {
+ // If handleError isn't an unary function, and it's called, it also throws
+ // (either TypeError in checked mode, or some failure in unchecked mode).
+
+ // These are compile time errors for strong mode.
+ Expect.throws(() => int.parse("9", radix: 8, onError: "not a function"));
+ Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
+ Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
+}
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index fbe9205..03af528 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -7,7 +7,7 @@
void main() {
bool checkedMode = false;
- assert(checkedMode = true);
+ assert((checkedMode = true));
const String oneByteWhiteSpace = "\x09\x0a\x0b\x0c\x0d\x20"
"\x85" /// 01: ok
"\xa0";
@@ -116,7 +116,7 @@
}
// In checked mode, it's always a TypeError.
Expect.throws(() => int.parse(source, radix: radix, onError: (s) => 0),
- (e) => e is TypeError);
+ (e) => e is TypeError || e is CastError);
}
testBadTypes(9, 10);
@@ -135,11 +135,7 @@
testBadArguments("0", 1);
testBadArguments("0", 37);
- // If handleError isn't an unary function, and it's called, it also throws
- // (either TypeError in checked mode, or some failure in unchecked mode).
- Expect.throws(() => int.parse("9", radix: 8, onError: "not a function"));
- Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
- Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
+ // See also int_parse_radix_bad_handler_test.dart
}
bool isFail(e) => e == "FAIL";
diff --git a/tests/corelib/string_operations_with_null_test.dart b/tests/corelib/string_operations_with_null_test.dart
index 7288001..cac0c7c 100644
--- a/tests/corelib/string_operations_with_null_test.dart
+++ b/tests/corelib/string_operations_with_null_test.dart
@@ -3,11 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
-import "../language/compiler_annotations.dart";
-@DontInline()
+@NoInline()
+@AssumeDynamic()
returnStringOrNull() {
- () => 42;
return new DateTime.now().millisecondsSinceEpoch == 0 ? 'foo' : null;
}
diff --git a/tests/language/async_return_types_test.dart b/tests/language/async_return_types_test.dart
index 1134e25..f8d194d 100644
--- a/tests/language/async_return_types_test.dart
+++ b/tests/language/async_return_types_test.dart
@@ -14,7 +14,7 @@
return 3;
}
-Future<int> /// wrongTypeParameter: static type warning
+Future<int> /// wrongTypeParameter: static type warning, dynamic type error
foo3() async {
return "String";
}
@@ -35,7 +35,7 @@
return new Future<int>.value(3);
}
-Future<Future<int>> /// nestedFuture: static type warning
+Future<Future<int>> /// nestedFuture: static type warning, dynamic type error
foo7() async {
return new Future<int>.value(3);
}
diff --git a/tests/language/generic_functions_test.dart b/tests/language/generic_functions_test.dart
index 814163a..e3f6caf 100644
--- a/tests/language/generic_functions_test.dart
+++ b/tests/language/generic_functions_test.dart
@@ -55,19 +55,16 @@
}
}
-// Use fresh type variables.
BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
}
-// Reuse type variables [K], [V] to test shadowing.
BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>(
BinaryTreeNode<K, V> t, U f(V x)) {
return (t == null) ? null : t.map<U>(f);
}
-// Use fresh [K2], shadowing [V].
S foldPreOpt<K2 extends Comparable<K2>, V, S>(
BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
return (t == null) ? init : t.foldPre<S>(init, f);
diff --git a/tests/language/language.status b/tests/language/language.status
index ca50f91..5eacbfa 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -49,6 +49,7 @@
generic_functions_test: CompiletimeError # Issue 25869
generic_local_functions_test: CompiletimeError # Issue 25869
generic_sends_test: CompiletimeError # Issue 25869
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25869
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
@@ -94,6 +95,7 @@
generic_functions_test: RuntimeError # Issue 25869
generic_local_functions_test: RuntimeError # Issue 25869
generic_sends_test: RuntimeError # Issue 25869
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25869
config_import_test: Skip # Issue 26250
[ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a588be3..9cc27c9 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -491,23 +491,6 @@
mixin_supertype_subclass4_test/04: MissingStaticWarning # Issue 25614
mixin_supertype_subclass4_test/05: MissingStaticWarning # Issue 25614
-mixin_of_mixin_test/01: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/02: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/04: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/05: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/06: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/08: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/09: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/10: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/12: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/13: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/15: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/16: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/17: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/19: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/20: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/21: MissingStaticWarning # Issue 25605
-
accessor_conflict_export2_test: StaticWarning # Issue 25624
accessor_conflict_export_test: StaticWarning # Issue 25624
accessor_conflict_import2_test: StaticWarning # Issue 25624
@@ -523,3 +506,4 @@
generic_local_functions_test: CompileTimeError # Issue 25868
generic_methods_test: CompileTimeError # Issue 25868
generic_sends_test: CompileTimeError # Issue 25868
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25868
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 4a95853..025d91a 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -40,6 +40,7 @@
generic_local_functions_test: CompileTimeError # Issue 25835
generic_methods_test: CompileTimeError # Issue 25835
generic_sends_test: CompileTimeError # Issue 25835
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25835
[ $compiler == dart2js && $runtime == jsshell ]
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
@@ -112,6 +113,9 @@
multiline_newline_test/none: RuntimeError # Issue 23888
[ $compiler == dart2js && $checked ]
+async_return_types_test/nestedFuture: Fail # Issue 26429
+async_return_types_test/wrongTypeParameter: Fail # Issue 26429
+regress_26133_test: RuntimeError # Issue 26429
type_variable_bounds_test/02: Fail # Issue 12702
type_variable_bounds2_test/01: Fail # Issue 12702
type_variable_bounds2_test/04: Fail # Issue 12702
diff --git a/tests/language/mixin_of_mixin_test.dart b/tests/language/mixin_of_mixin_test.dart
index 005f959..a15b20c 100644
--- a/tests/language/mixin_of_mixin_test.dart
+++ b/tests/language/mixin_of_mixin_test.dart
@@ -34,26 +34,27 @@
class T6 extends D with M3 {} // extends a class which declares m3()
main() {
+ /// none: static type warning, ok
new T1().a(); /// 01: static type warning, runtime error
new T1().b(); /// 02: static type warning, runtime error
- new T1().c(); /// 03: ok
+ new T1().c(); /// 03: static type warning, ok
new T2().a(); /// 04: static type warning, runtime error
new T2().b(); /// 05: static type warning, runtime error
new T2().c(); /// 06: static type warning, runtime error
- new T2().m2(); /// 07: ok
+ new T2().m2(); /// 07: static type warning, ok
new T3().a(); /// 08: static type warning, runtime error
new T3().b(); /// 09: static type warning, runtime error
new T3().c(); /// 10: static type warning, runtime error
- new T3().m3(); /// 11: ok
+ new T3().m3(); /// 11: static type warning, ok
new T4().a(); /// 12: static type warning, runtime error
new T4().b(); /// 13: static type warning, runtime error
- new T4().c(); /// 14: ok
+ new T4().c(); /// 14: static type warning, ok
new T5().a(); /// 15: static type warning, runtime error
new T5().b(); /// 16: static type warning, runtime error
new T5().c(); /// 17: static type warning, runtime error
- new T5().m2(); /// 18: ok
+ new T5().m2(); /// 18: static type warning, ok
new T6().a(); /// 19: static type warning, runtime error
new T6().b(); /// 20: static type warning, runtime error
new T6().c(); /// 21: static type warning, runtime error
- new T6().m3(); /// 22: ok
+ new T6().m3(); /// 22: static type warning, ok
}
diff --git a/tests/language/regress_26133_test.dart b/tests/language/regress_26133_test.dart
new file mode 100644
index 0000000..9c6bbb5
--- /dev/null
+++ b/tests/language/regress_26133_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, 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:async';
+import 'package:expect/expect.dart';
+
+isCheckedMode() {
+ try {
+ var i = 1;
+ String s = i;
+ return false;
+ } on TypeError {
+ return true;
+ }
+}
+
+var x = 'a';
+
+Future<int> foo() async {
+ return x;
+}
+
+main() {
+ foo().then(
+ (_) {
+ Expect.isFalse(isCheckedMode());
+ },
+ onError: (e) {
+ Expect.isTrue(isCheckedMode() && (e is TypeError));
+ }
+ );
+}
+
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index c0a201e..ec94cf6 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -294,8 +294,8 @@
mirrors/regress_16321_test/01: MissingCompileTimeError # Issue 16391
[ $compiler == dart2js && $runtime == d8 && $system == windows ]
-async/*deferred*: Skip # Issue 17458
-mirrors/*deferred*: Skip # Issue 17458
+async/*deferred*: Pass,RuntimeError # Issue 17458
+mirrors/*deferred*: Pass,RuntimeError # Issue 17458
[ $compiler == dart2js && $mode == debug ]
mirrors/native_class_test: Pass, Slow
diff --git a/tests/standalone/io/code_collection_test.dart b/tests/standalone/io/code_collection_test.dart
index 696be6e..3747399 100644
--- a/tests/standalone/io/code_collection_test.dart
+++ b/tests/standalone/io/code_collection_test.dart
@@ -11,6 +11,9 @@
int foo(int x) {
x = x + 1;
+ // Print marker message while foo is on the stack so the code cannot be
+ // collected.
+ print("foo=$x");
return x;
}
@@ -25,18 +28,18 @@
doTest() {
var i = 0;
var ret = foo(1); // Initial call to compile.
- print("foo=$ret");
// Time passes, GC runs, foo's code is dropped.
var ms = const Duration(milliseconds: 100);
var t = new Timer.periodic(ms, (timer) {
i++;
+ // Calling bar will trigger GC without foo being on the stack. This way
+ // the method can be collected.
bar();
if (i > 1) {
timer.cancel();
// foo is called again to make sure we can still run it even after
// its code has been detached.
var ret = foo(2);
- print("foo=$ret");
}
});
}
@@ -48,7 +51,8 @@
} else {
// Run the test and capture stdout.
var pr = Process.runSync(Platform.executable,
- ["--collect-code",
+ ["--verbose-gc",
+ "--collect-code",
"--code-collection-interval-in-us=0",
"--old_gen_growth_rate=10",
"--log-code-drop",
@@ -61,6 +65,7 @@
// Code drops are logged with --log-code-drop. Look through stdout for the
// message that foo's code was dropped.
+ print(pr.stdout);
var count = 0;
pr.stdout.split("\n").forEach((line) {
if (line.contains("foo=2")) {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index adb3a7d..30a1101 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -114,6 +114,7 @@
[ ($runtime == vm || $runtime == dart_product) && ($arch == arm || $arch == arm64) ]
io/file_stream_test: Skip # Issue 26109
+io/file_typed_data_test: Skip # Issue 26109
[ $compiler == dart2js && $jscl ]
assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
diff --git a/tools/VERSION b/tools/VERSION
index ec6b498..ea11638 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 17
PATCH 0
-PRERELEASE 2
+PRERELEASE 3
PRERELEASE_PATCH 0
diff --git a/tools/build.py b/tools/build.py
index 4b9df2a..518a015 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -56,7 +56,7 @@
result.add_option("-a", "--arch",
help='Target architectures (comma-separated).',
metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
- 'simmips,mips,simarm64,arm64,simdbc,]',
+ 'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
default=utils.GuessArchitecture())
result.add_option("--os",
help='Target OSs (comma-separated).',
@@ -88,7 +88,7 @@
def ProcessOptions(options, args):
if options.arch == 'all':
- options.arch = 'ia32,x64,simarm,simmips,simarm64'
+ options.arch = 'ia32,x64,simarm,simarm64,simmips,simdbc'
if options.mode == 'all':
options.mode = 'debug,release,product'
if options.os == 'all':
@@ -103,7 +103,7 @@
for arch in options.arch:
archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
- 'simdbc', 'simdbc64']
+ 'simdbc', 'simdbc64', 'armsimdbc']
if not arch in archs:
print "Unknown arch %s" % arch
return False
@@ -154,7 +154,7 @@
'supported on Linux.')
# For ARM Linux, by default use the Linux distribution's cross-compiler.
- if arch == 'arm':
+ if arch == 'arm' or arch == 'armsimdbc':
# To use a non-hf compiler, specify on the command line with --toolchain.
return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/arm-linux-gnueabihf")
if arch == 'arm64':
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index b7500f2..960cf72 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,7 +8,7 @@
# Now we need to override some settings and add some new ones.
vars.update({
- "dartium_chromium_commit": "18554681ff1dfb53a553375c1b0c641fb3d63a1a",
+ "dartium_chromium_commit": "81ac1404ddd8fde55b9eb28a97c8a6d8b75e264f",
"dartium_webkit_commit": "ef30dc04127c86283c1f5c5c6b0094d73b1e29df",
"chromium_base_revision": "338390",
diff --git a/tools/gyp/configurations.gypi b/tools/gyp/configurations.gypi
index e5ab11a..29f457e 100644
--- a/tools/gyp/configurations.gypi
+++ b/tools/gyp/configurations.gypi
@@ -387,6 +387,15 @@
],
},
+ 'ProductSIMDBC': {
+ 'inherit_from': [
+ 'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+ 'Dart_<(dart_target_os)_Base',
+ 'Dart_<(dart_target_os)_simdbc_Base',
+ 'Dart_<(dart_target_os)_Product',
+ ],
+ },
+
'DebugSIMDBC64': {
'inherit_from': [
'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
@@ -408,6 +417,47 @@
],
},
+ 'ProductSIMDBC64': {
+ 'inherit_from': [
+ 'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+ 'Dart_<(dart_target_os)_Base',
+ 'Dart_<(dart_target_os)_simdbc64_Base',
+ 'Dart_<(dart_target_os)_Product',
+ ],
+ },
+
+ # Special Linux-only targets to enable SIMDBC cross compilation for
+ # non-Android ARM devices.
+ 'DebugXARMSIMDBC': {
+ 'inherit_from': [
+ 'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
+ 'Dart_Linux_Base',
+ 'Dart_Linux_xarm_Base',
+ 'Dart_Linux_Debug',
+ ],
+ 'defines': [
+ 'DEBUG',
+ ],
+ },
+
+ 'ReleaseXARMSIMDBC': {
+ 'inherit_from': [
+ 'Dart_Base', 'Dart_simdbc_Base', 'Dart_Release',
+ 'Dart_Linux_Base',
+ 'Dart_Linux_xarm_Base',
+ 'Dart_Linux_Release',
+ ],
+ },
+
+ 'ProductXARMSIMDBC': {
+ 'inherit_from': [
+ 'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+ 'Dart_Linux_Base',
+ 'Dart_Linux_xarm_Base',
+ 'Dart_Linux_Product',
+ ],
+ },
+
# ARM and MIPS hardware configurations are only for Linux and Android.
'DebugXARM': {
'inherit_from': [
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index bf83128..615d5b0 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -333,7 +333,10 @@
if (index >= 0) {
exitCode = int.parse(
lines.last.substring(index + MARKER.length).trim());
- exitCode = exitCode.toSigned(8);
+ if (exitCode > 128 && exitCode <= 128 + 31) {
+ // Return negative exit codes for signals 1..31 (128+N for signal N)
+ exitCode = 128 - exitCode;
+ }
} else {
// In case of timeouts, for example, we won't get the exitcode marker.
assert(result.exitCode != 0);
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 7c0945e..5781e83 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -342,9 +342,10 @@
Map<String, String> environmentOverrides) {
var exec = "$buildDir/dart_bootstrap";
var args = new List();
- args.add("--gen-precompiled-snapshot=$tempDir");
+ args.add("--snapshot=$tempDir");
+ args.add("--snapshot-kind=app-aot");
if (useBlobs) {
- args.add("--use_blobs");
+ args.add("--use-blobs");
}
if (isAndroid && arch == 'arm') {
args.add('--no-sim-use-hardfp');
@@ -375,7 +376,7 @@
throw "Platform not supported: ${Platform.operatingSystem}";
}
if (isAndroid) {
- // TODO: If we're not using "--use_blobs" we need to use the arm cross
+ // TODO: If we're not using "--use-blobs" we need to use the arm cross
// compiler instead of just 'gcc' for .
}
@@ -403,7 +404,7 @@
args.addAll([
'-o',
'$tempDir/$libname',
- '$tempDir/precompiled.S'
+ '$tempDir/snapshot.S'
]);
return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
@@ -419,7 +420,7 @@
List arguments,
Map<String, String> environmentOverrides) {
var exec = 'rm';
- var args = ['$tempDir/precompiled.S'];
+ var args = ['$tempDir/snapshot.S'];
return commandBuilder.getCompilationCommand(
'remove_assembly',
@@ -490,32 +491,27 @@
CommandBuilder commandBuilder,
List arguments,
Map<String, String> environmentOverrides) {
- String outputName = computeOutputName(tempDir);
return new CommandArtifact(<Command>[
- this.computeCompilationCommand(outputName, buildDir,
+ this.computeCompilationCommand(tempDir, buildDir,
CommandBuilder.instance, arguments, environmentOverrides)
- ], outputName, 'application/dart-snapshot');
- }
-
- String computeOutputName(String tempDir) {
- var randName = TestUtils.getRandomNumber().toString();
- return '$tempDir/test.$randName';
+ ], tempDir, 'application/dart-snapshot');
}
CompilationCommand computeCompilationCommand(
- String outputName,
+ String tempDir,
String buildDir,
CommandBuilder commandBuilder,
List arguments,
Map<String, String> environmentOverrides) {
var exec = "$buildDir/dart_bootstrap";
var args = new List();
- args.add("--full-snapshot-after-run=$outputName");
+ args.add("--snapshot=$tempDir");
+ args.add("--snapshot-kind=app-after-run");
args.addAll(arguments);
return commandBuilder.getCompilationCommand(
'dart2snapshot',
- outputName,
+ tempDir,
!useSdk,
bootstrapDependencies(buildDir),
exec,
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index b8e9e3d7..67a739a 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -238,7 +238,7 @@
}
var augmentedArgs = new List();
- augmentedArgs.add("--run-full-snapshot=${artifact.filename}");
+ augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
augmentedArgs.addAll(arguments);
return <Command>[
@@ -265,9 +265,9 @@
}
var augmentedArgs = new List();
- augmentedArgs.add("--run-precompiled-snapshot=${artifact.filename}");
+ augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
if (useBlobs) {
- augmentedArgs.add("--use_blobs");
+ augmentedArgs.add("--use-blobs");
}
augmentedArgs.addAll(arguments);
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index bc83dc0..dfca779 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -693,7 +693,7 @@
List<Map> _expandConfigurations(Map configuration) {
// Expand the pseudo-values such as 'all'.
if (configuration['arch'] == 'all') {
- configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips';
+ configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips,simdbc';
}
if (configuration['mode'] == 'all') {
configuration['mode'] = 'debug,release,product';
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 8d189ae..d862db5 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -2543,9 +2543,9 @@
// pushhing it for every single test (this is bad for SSD cycle time, test
// timing).
steps.add(() => device.runAdbCommand(
- ['push', runner, '$devicedir/runner']));
+ ['push', runner, '$devicedir/dart_precompiled_runtime']));
steps.add(() => device.runAdbShellCommand(
- ['chmod', '777', '$devicedir/runner']));
+ ['chmod', '777', '$devicedir/dart_precompiled_runtime']));
for (var file in files) {
steps.add(() => device.runAdbCommand(
@@ -2554,12 +2554,16 @@
if (command.useBlobs) {
steps.add(() => device.runAdbShellCommand(
- ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
- '--use_blobs', 'ignored.dart'], timeout: timeoutDuration));
+ ['$devicedir/dart_precompiled_runtime',
+ '--run-app-snapshot=$deviceTestDir',
+ '--use-blobs', 'ignored.dart'],
+ timeout: timeoutDuration));
} else {
steps.add(() => device.runAdbShellCommand(
- ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
- 'ignored.dart'], timeout: timeoutDuration));
+ ['$devicedir/dart_precompiled_runtime',
+ '--run-app-snapshot=$deviceTestDir',
+ 'ignored.dart'],
+ timeout: timeoutDuration));
}
var stopwatch = new Stopwatch()..start();
diff --git a/tools/utils.py b/tools/utils.py
index 02fe8ef..c4be5af 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -242,6 +242,7 @@
'simarm64': 'ia32',
'simdbc': 'ia32',
'simdbc64': 'ia32',
+ 'armsimdbc': 'arm',
}
ARCH_GUESS = GuessArchitecture()